From c36d9a4964169d432147267c6e43e61094ef2583 Mon Sep 17 00:00:00 2001 From: mine_diver Date: Thu, 2 May 2024 18:11:58 +0500 Subject: [PATCH 01/25] First version of tool items update --- .../sltest/block/Blocks.java | 2 +- .../sltest/item/ItemListener.java | 4 +- .../tags/blocks/mineable/pickaxe.json | 5 ++ .../tags/blocks/needs_iron_tool.json | 5 ++ .../tags/blocks/needs_tool_level_modded.json | 6 +++ .../api/item/tool/StationHoeItem.java | 1 - .../api/item/tool/StationShearsItem.java | 1 - .../api/item/tool/StationSwordItem.java | 1 - .../api/item/tool/StationToolItem.java | 1 - .../api/item/tool/StationToolMaterial.java | 36 +------------- .../stationapi/api/item/tool/ToolLevel.java | 1 - .../api/item/tool/ToolMaterialFactory.java | 1 - .../impl/item/HijackShearsImplV1.java | 1 - .../impl/item/ToolEffectivenessImplV1.java | 30 ++++++++++-- .../mixin/tools/ToolMaterialMixin.java | 47 ++----------------- .../item/tool/VanillaToolFixImpl.java | 11 ++--- .../tags/blocks/needs_diamond_tool.json | 1 + .../tags/blocks/needs_iron_tool.json | 1 + 18 files changed, 60 insertions(+), 95 deletions(-) create mode 100644 src/test/resources/data/minecraft/stationapi/tags/blocks/mineable/pickaxe.json create mode 100644 src/test/resources/data/minecraft/stationapi/tags/blocks/needs_iron_tool.json create mode 100644 src/test/resources/data/sltest/stationapi/tags/blocks/needs_tool_level_modded.json diff --git a/src/test/java/net/modificationstation/sltest/block/Blocks.java b/src/test/java/net/modificationstation/sltest/block/Blocks.java index b30536a68..278cf6bfd 100644 --- a/src/test/java/net/modificationstation/sltest/block/Blocks.java +++ b/src/test/java/net/modificationstation/sltest/block/Blocks.java @@ -16,7 +16,7 @@ public enum Blocks { - TEST_BLOCK("test_block", "testBlock", id -> new TemplateBlock(id, Material.CLAY).setHardness(1)), + TEST_BLOCK("test_block", "testBlock", id -> new TemplateBlock(id, Material.STONE).setHardness(1)), TEST_ANIMATED_BLOCK("test_animated_block", "testAnimatedBlock", id -> new ModdedMetaBlock(id, Material.NETHER_PORTAL)), CUSTOM_MODEL_BLOCK("farlands_block", "farlands_block", id -> new ModdedModelBlock(id, Material.SOIL).setHardness(1)), FREEZER("freezer", "freezer", id -> new BlockFreezer(id).setHardness(2.5F).setSoundGroup(TemplateBlock.DEFAULT_SOUND_GROUP)), diff --git a/src/test/java/net/modificationstation/sltest/item/ItemListener.java b/src/test/java/net/modificationstation/sltest/item/ItemListener.java index ee725ed40..523a847b3 100644 --- a/src/test/java/net/modificationstation/sltest/item/ItemListener.java +++ b/src/test/java/net/modificationstation/sltest/item/ItemListener.java @@ -7,8 +7,10 @@ import net.modificationstation.sltest.block.VariationBlock; import net.modificationstation.stationapi.api.event.registry.ItemRegistryEvent; import net.modificationstation.stationapi.api.item.tool.ToolMaterialFactory; +import net.modificationstation.stationapi.api.registry.BlockRegistry; import net.modificationstation.stationapi.api.registry.ItemRegistry; import net.modificationstation.stationapi.api.registry.Registry; +import net.modificationstation.stationapi.api.tag.TagKey; import net.modificationstation.stationapi.api.template.item.BlockStateItem; import static net.modificationstation.sltest.SLTest.NAMESPACE; @@ -18,7 +20,7 @@ public class ItemListener { @EventListener public void registerItems(ItemRegistryEvent event) { testItem = new ModdedItem(NAMESPACE.id("test_item")).setTranslationKey(NAMESPACE, "testItem"); //8475 - testMaterial = ToolMaterialFactory.create("testMaterial", 3, Integer.MAX_VALUE, Float.MAX_VALUE, Integer.MAX_VALUE - 2); + testMaterial = ToolMaterialFactory.create("testMaterial", 3, Integer.MAX_VALUE, Float.MAX_VALUE, Integer.MAX_VALUE - 2).miningLevelTag(TagKey.of(BlockRegistry.KEY, NAMESPACE.id("needs_tool_level_modded"))); testPickaxe = new ModdedPickaxeItem(NAMESPACE.id("test_pickaxe"), testMaterial).setTranslationKey(NAMESPACE, "testPickaxe"); //8476 testNBTItem = new NBTItem(NAMESPACE.id("nbt_item")).setTranslationKey(NAMESPACE, "nbt_item"); //8477 testModelItem = new ModelItem(NAMESPACE.id("model_item")).setMaxCount(1).setTranslationKey(NAMESPACE, "idkSomething"); diff --git a/src/test/resources/data/minecraft/stationapi/tags/blocks/mineable/pickaxe.json b/src/test/resources/data/minecraft/stationapi/tags/blocks/mineable/pickaxe.json new file mode 100644 index 000000000..04f9bde83 --- /dev/null +++ b/src/test/resources/data/minecraft/stationapi/tags/blocks/mineable/pickaxe.json @@ -0,0 +1,5 @@ +{ + "values": [ + "sltest:test_block" + ] +} \ No newline at end of file diff --git a/src/test/resources/data/minecraft/stationapi/tags/blocks/needs_iron_tool.json b/src/test/resources/data/minecraft/stationapi/tags/blocks/needs_iron_tool.json new file mode 100644 index 000000000..2dd664728 --- /dev/null +++ b/src/test/resources/data/minecraft/stationapi/tags/blocks/needs_iron_tool.json @@ -0,0 +1,5 @@ +{ + "values": [ + "#sltest:needs_tool_level_modded" + ] +} \ No newline at end of file diff --git a/src/test/resources/data/sltest/stationapi/tags/blocks/needs_tool_level_modded.json b/src/test/resources/data/sltest/stationapi/tags/blocks/needs_tool_level_modded.json new file mode 100644 index 000000000..b15b2bb24 --- /dev/null +++ b/src/test/resources/data/sltest/stationapi/tags/blocks/needs_tool_level_modded.json @@ -0,0 +1,6 @@ +{ + "values": [ + "#needs_stone_tool", + "sltest:test_block" + ] +} \ No newline at end of file diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationHoeItem.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationHoeItem.java index 5f6ca48dc..9115fe99e 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationHoeItem.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationHoeItem.java @@ -7,7 +7,6 @@ import net.modificationstation.stationapi.api.util.Util; public interface StationHoeItem extends ToolLevel { - @Override default void setEffectiveBlocks(TagKey effectiveBlocks) { Util.assertImpl(); diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationShearsItem.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationShearsItem.java index f0d24982d..b6904d204 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationShearsItem.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationShearsItem.java @@ -7,7 +7,6 @@ import net.modificationstation.stationapi.api.util.Util; public interface StationShearsItem extends ToolLevel { - @Override default void setEffectiveBlocks(TagKey effectiveBlocks) { Util.assertImpl(); diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationSwordItem.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationSwordItem.java index 2cac4fec5..0f648e8d9 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationSwordItem.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationSwordItem.java @@ -7,7 +7,6 @@ import net.modificationstation.stationapi.api.util.Util; public interface StationSwordItem extends ToolLevel { - @Override default void setEffectiveBlocks(TagKey effectiveBlocks) { Util.assertImpl(); diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationToolItem.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationToolItem.java index 57998fd5a..f23cdbc75 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationToolItem.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationToolItem.java @@ -7,7 +7,6 @@ import net.modificationstation.stationapi.api.util.Util; public interface StationToolItem extends ToolLevel { - @Override default void setEffectiveBlocks(TagKey effectiveBlocks) { Util.assertImpl(); diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationToolMaterial.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationToolMaterial.java index b9676af8a..e404b21bb 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationToolMaterial.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationToolMaterial.java @@ -1,48 +1,16 @@ package net.modificationstation.stationapi.api.item.tool; -import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; -import it.unimi.dsi.fastutil.objects.ReferenceSet; import net.minecraft.block.Block; import net.minecraft.item.ToolMaterial; -import net.modificationstation.stationapi.api.block.BlockState; -import net.modificationstation.stationapi.api.util.Identifier; import net.modificationstation.stationapi.api.tag.TagKey; import net.modificationstation.stationapi.api.util.Util; -import java.util.function.BiPredicate; -import java.util.function.Predicate; - public interface StationToolMaterial { - - ReferenceSet> ALL_TOOL_MATERIAL_TAGS = new ReferenceOpenHashSet<>(); - - default ToolMaterial inheritsFrom(ToolMaterial... toolMaterials) { + default ToolMaterial miningLevelTag(TagKey tag) { return Util.assertImpl(); } - default ToolMaterial requiredBlockTag(Identifier tag) { + default TagKey getMiningLevelTag() { return Util.assertImpl(); } - - default ReferenceSet getParentMaterials() { - return Util.assertImpl(); - } - - default TagKey getRequiredBlockTag() { - return Util.assertImpl(); - } - - default boolean matches(BlockState state) { - return ALL_TOOL_MATERIAL_TAGS.stream().noneMatch(state::isIn) || matches0(state); - } - - private boolean matches0(BlockState state) { - TagKey tag = getRequiredBlockTag(); - if (tag != null) { - if (state.isIn(tag)) return true; - BiPredicate matches0 = StationToolMaterial::matches0; - Predicate matchesThis = t -> matches0.test(t, state); - return getParentMaterials().stream().anyMatch(matchesThis); - } else return false; - } } diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/ToolLevel.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/ToolLevel.java index 84bb3fb87..d12cf4528 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/ToolLevel.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/ToolLevel.java @@ -6,7 +6,6 @@ import net.modificationstation.stationapi.api.tag.TagKey; public interface ToolLevel { - void setEffectiveBlocks(TagKey effectiveBlocks); TagKey getEffectiveBlocks(ItemStack stack); diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/ToolMaterialFactory.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/ToolMaterialFactory.java index e0b52131a..8ecfecadd 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/ToolMaterialFactory.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/ToolMaterialFactory.java @@ -4,7 +4,6 @@ import net.modificationstation.stationapi.api.factory.EnumFactory; public class ToolMaterialFactory { - public static ToolMaterial create(String materialName, int miningLevel, int durability, float miningSpeed, int attackDamage) { return EnumFactory.addEnum( ToolMaterial.class, materialName, diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/HijackShearsImplV1.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/HijackShearsImplV1.java index ef0f81f1a..873ee30c3 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/HijackShearsImplV1.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/HijackShearsImplV1.java @@ -7,7 +7,6 @@ @EventListener(phase = StationAPI.INTERNAL_PHASE) public class HijackShearsImplV1 { - //TODO: Make this match anything that has shear tool properties. Not sure how to go around this at the moment. @EventListener private static void hijackShearsEvent(ShearsOverrideEvent event) { diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/ToolEffectivenessImplV1.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/ToolEffectivenessImplV1.java index 258205d1d..791131f69 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/ToolEffectivenessImplV1.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/ToolEffectivenessImplV1.java @@ -3,6 +3,7 @@ import net.mine_diver.unsafeevents.listener.EventListener; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.item.ToolMaterial; import net.modificationstation.stationapi.api.StationAPI; import net.modificationstation.stationapi.api.block.BlockState; import net.modificationstation.stationapi.api.event.item.IsItemSuitableForStateEvent; @@ -17,6 +18,7 @@ import net.modificationstation.stationapi.api.util.Namespace; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -25,7 +27,6 @@ @Entrypoint(eventBus = @EventBusPolicy(registerInstance = false)) @EventListener(phase = StationAPI.INTERNAL_PHASE) public class ToolEffectivenessImplV1 { - public static final List VANILLA_TOOLS = new ArrayList<>(); @EventListener(priority = LOW) @@ -55,15 +56,36 @@ private static void getItems(ItemRegistryEvent event) { @EventListener private static void isEffective(IsItemSuitableForStateEvent event) { - event.suitable = event.suitable || isSuitable(event.itemStack, event.state); + // Disable custom tool logic if both the block and the tool are vanilla + // This is done to preserve the vanilla mining speeds + if (VANILLA_TOOLS.contains(ItemRegistry.INSTANCE.getId(event.itemStack.getItem())) + && Objects.requireNonNull(BlockRegistry.INSTANCE.getId(event.state.getBlock())).namespace == Namespace.MINECRAFT) return; + + event.suitable = isSuitable(event.itemStack, event.state); } @EventListener private static void getStrength(ItemMiningSpeedMultiplierOnStateEvent event) { - if (!(VANILLA_TOOLS.contains(ItemRegistry.INSTANCE.getId(event.itemStack.getItem())) && Objects.requireNonNull(BlockRegistry.INSTANCE.getId(event.state.getBlock())).namespace == Namespace.MINECRAFT) && isSuitable(event.itemStack, event.state)) event.miningSpeedMultiplier = ((ToolLevel) event.itemStack.getItem()).getMaterial(event.itemStack).getMiningSpeedMultiplier(); + // Disable custom tool logic if both the block and the tool are vanilla + // This is done to preserve the vanilla mining speeds + if (VANILLA_TOOLS.contains(ItemRegistry.INSTANCE.getId(event.itemStack.getItem())) + && Objects.requireNonNull(BlockRegistry.INSTANCE.getId(event.state.getBlock())).namespace == Namespace.MINECRAFT) return; + + if (!isSuitable(event.itemStack, event.state)) return; + + event.miningSpeedMultiplier = ((ToolLevel) event.itemStack.getItem()).getMaterial(event.itemStack).getMiningSpeedMultiplier(); } private static boolean isSuitable(ItemStack item, BlockState state) { - return item.getItem() instanceof ToolLevel toolLevel && state.isIn(toolLevel.getEffectiveBlocks(item)) && toolLevel.getMaterial(item).matches(state); + return item.getItem() instanceof ToolLevel toolLevel + && state.isIn(toolLevel.getEffectiveBlocks(item)) + && + ( + state.isIn(toolLevel.getMaterial(item).getMiningLevelTag()) + || Arrays + .stream(ToolMaterial.values()) + .filter(toolMaterial -> toolMaterial.getMiningLevelTag() != null) + .noneMatch(toolMaterial -> state.isIn(toolMaterial.getMiningLevelTag())) + ); } } diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/ToolMaterialMixin.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/ToolMaterialMixin.java index 3429c86b5..820859da2 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/ToolMaterialMixin.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/ToolMaterialMixin.java @@ -1,64 +1,27 @@ package net.modificationstation.stationapi.mixin.tools; -import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; -import it.unimi.dsi.fastutil.objects.ReferenceSet; -import it.unimi.dsi.fastutil.objects.ReferenceSets; import net.minecraft.block.Block; import net.minecraft.item.ToolMaterial; import net.modificationstation.stationapi.api.item.tool.StationToolMaterial; -import net.modificationstation.stationapi.api.registry.BlockRegistry; import net.modificationstation.stationapi.api.tag.TagKey; -import net.modificationstation.stationapi.api.util.Identifier; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.Collections; @Mixin(ToolMaterial.class) class ToolMaterialMixin implements StationToolMaterial { @Unique - private TagKey stationapi_requiredBlockTag; - @Unique - private ReferenceSet stationapi_parentMaterials; - @Unique - private ReferenceSet stationapi_parentMaterialsView; - - @Inject( - method = "(Ljava/lang/String;IIIFI)V", - at = @At("RETURN") - ) - private void stationapi_init(String i, int j, int k, int f, float l, int par6, CallbackInfo ci) { - stationapi_parentMaterials = new ReferenceOpenHashSet<>(); - stationapi_parentMaterialsView = ReferenceSets.unmodifiable(stationapi_parentMaterials); - } - - @Override - @Unique - public ToolMaterial inheritsFrom(ToolMaterial... toolMaterials) { - Collections.addAll(stationapi_parentMaterials, toolMaterials); - return ToolMaterial.class.cast(this); - } + private TagKey stationapi_miningLevelTag; @Override @Unique - public ToolMaterial requiredBlockTag(Identifier tag) { - ALL_TOOL_MATERIAL_TAGS.remove(stationapi_requiredBlockTag); - ALL_TOOL_MATERIAL_TAGS.add(stationapi_requiredBlockTag = TagKey.of(BlockRegistry.INSTANCE.getKey(), tag)); + public ToolMaterial miningLevelTag(TagKey tag) { + stationapi_miningLevelTag = tag; return ToolMaterial.class.cast(this); } @Override @Unique - public ReferenceSet getParentMaterials() { - return stationapi_parentMaterialsView; - } - - @Override - @Unique - public TagKey getRequiredBlockTag() { - return stationapi_requiredBlockTag; + public TagKey getMiningLevelTag() { + return stationapi_miningLevelTag; } } diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/impl/vanillafix/item/tool/VanillaToolFixImpl.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/impl/vanillafix/item/tool/VanillaToolFixImpl.java index c9cffd6bc..0c9cedfa7 100644 --- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/impl/vanillafix/item/tool/VanillaToolFixImpl.java +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/impl/vanillafix/item/tool/VanillaToolFixImpl.java @@ -6,6 +6,8 @@ import net.modificationstation.stationapi.api.event.registry.ItemRegistryEvent; import net.modificationstation.stationapi.api.mod.entrypoint.Entrypoint; import net.modificationstation.stationapi.api.mod.entrypoint.EventBusPolicy; +import net.modificationstation.stationapi.api.registry.BlockRegistry; +import net.modificationstation.stationapi.api.tag.TagKey; import static net.modificationstation.stationapi.api.util.Identifier.of; @@ -17,11 +19,8 @@ private static void fixToolMaterials(ItemRegistryEvent event) { ToolMaterial stone = ToolMaterial.STONE; ToolMaterial iron = ToolMaterial.IRON; ToolMaterial diamond = ToolMaterial.DIAMOND; - stone.inheritsFrom(ToolMaterial.WOOD, ToolMaterial.GOLD); - stone.requiredBlockTag(of("needs_stone_tool")); - iron.inheritsFrom(ToolMaterial.STONE); - iron.requiredBlockTag(of("needs_iron_tool")); - diamond.inheritsFrom(ToolMaterial.IRON); - diamond.requiredBlockTag(of("needs_diamond_tool")); + stone.miningLevelTag(TagKey.of(BlockRegistry.KEY, of("needs_stone_tool"))); + iron.miningLevelTag(TagKey.of(BlockRegistry.KEY, of("needs_iron_tool"))); + diamond.miningLevelTag(TagKey.of(BlockRegistry.KEY, of("needs_diamond_tool"))); } } diff --git a/station-vanilla-fix-v0/src/main/resources/data/minecraft/stationapi/tags/blocks/needs_diamond_tool.json b/station-vanilla-fix-v0/src/main/resources/data/minecraft/stationapi/tags/blocks/needs_diamond_tool.json index 54d961641..7e914dc50 100644 --- a/station-vanilla-fix-v0/src/main/resources/data/minecraft/stationapi/tags/blocks/needs_diamond_tool.json +++ b/station-vanilla-fix-v0/src/main/resources/data/minecraft/stationapi/tags/blocks/needs_diamond_tool.json @@ -1,5 +1,6 @@ { "values": [ + "#needs_iron_tool", "obsidian" ] } \ No newline at end of file diff --git a/station-vanilla-fix-v0/src/main/resources/data/minecraft/stationapi/tags/blocks/needs_iron_tool.json b/station-vanilla-fix-v0/src/main/resources/data/minecraft/stationapi/tags/blocks/needs_iron_tool.json index 58f40dc96..d0bdd018c 100644 --- a/station-vanilla-fix-v0/src/main/resources/data/minecraft/stationapi/tags/blocks/needs_iron_tool.json +++ b/station-vanilla-fix-v0/src/main/resources/data/minecraft/stationapi/tags/blocks/needs_iron_tool.json @@ -1,5 +1,6 @@ { "values": [ + "#needs_stone_tool", "diamond_block", "diamond_ore", "gold_block", From 433fa82c627193c731b648bf0c499937c52e19cb Mon Sep 17 00:00:00 2001 From: mine_diver Date: Wed, 8 May 2024 03:02:38 +0500 Subject: [PATCH 02/25] Mining levels graph --- .../sltest/item/ItemListener.java | 10 +++++- .../tags/blocks/needs_iron_tool.json | 5 --- .../tags/blocks/needs_tool_level_modded.json | 1 - .../api/item/tool/MiningLevelManager.java | 33 +++++++++++++++++++ .../api/item/tool/StationToolMaterial.java | 6 ++-- .../impl/item/ToolEffectivenessImplV1.java | 14 +++----- .../mixin/tools/ToolMaterialMixin.java | 13 ++++---- .../item/tool/VanillaToolFixImpl.java | 16 +++++---- .../tags/blocks/needs_diamond_tool.json | 1 - .../tags/blocks/needs_iron_tool.json | 1 - 10 files changed, 64 insertions(+), 36 deletions(-) delete mode 100644 src/test/resources/data/minecraft/stationapi/tags/blocks/needs_iron_tool.json create mode 100644 station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/MiningLevelManager.java diff --git a/src/test/java/net/modificationstation/sltest/item/ItemListener.java b/src/test/java/net/modificationstation/sltest/item/ItemListener.java index 523a847b3..89a2a712d 100644 --- a/src/test/java/net/modificationstation/sltest/item/ItemListener.java +++ b/src/test/java/net/modificationstation/sltest/item/ItemListener.java @@ -6,6 +6,7 @@ import net.modificationstation.sltest.block.Blocks; import net.modificationstation.sltest.block.VariationBlock; import net.modificationstation.stationapi.api.event.registry.ItemRegistryEvent; +import net.modificationstation.stationapi.api.item.tool.MiningLevelManager; import net.modificationstation.stationapi.api.item.tool.ToolMaterialFactory; import net.modificationstation.stationapi.api.registry.BlockRegistry; import net.modificationstation.stationapi.api.registry.ItemRegistry; @@ -19,8 +20,13 @@ public class ItemListener { @EventListener public void registerItems(ItemRegistryEvent event) { + MiningLevelManager.LevelNode moddedNode = new MiningLevelManager.LevelNode(TagKey.of(BlockRegistry.KEY, NAMESPACE.id("needs_tool_level_modded"))); + MiningLevelManager.GRAPH.putEdge(ToolMaterial.STONE.getMiningLevelNode(), moddedNode); + MiningLevelManager.GRAPH.putEdge(moddedNode, ToolMaterial.IRON.getMiningLevelNode()); + MiningLevelManager.invalidateCache(); + testItem = new ModdedItem(NAMESPACE.id("test_item")).setTranslationKey(NAMESPACE, "testItem"); //8475 - testMaterial = ToolMaterialFactory.create("testMaterial", 3, Integer.MAX_VALUE, Float.MAX_VALUE, Integer.MAX_VALUE - 2).miningLevelTag(TagKey.of(BlockRegistry.KEY, NAMESPACE.id("needs_tool_level_modded"))); + testMaterial = ToolMaterialFactory.create("testMaterial", 3, Integer.MAX_VALUE, Float.MAX_VALUE, Integer.MAX_VALUE - 2).miningLevelNode(moddedNode); testPickaxe = new ModdedPickaxeItem(NAMESPACE.id("test_pickaxe"), testMaterial).setTranslationKey(NAMESPACE, "testPickaxe"); //8476 testNBTItem = new NBTItem(NAMESPACE.id("nbt_item")).setTranslationKey(NAMESPACE, "nbt_item"); //8477 testModelItem = new ModelItem(NAMESPACE.id("model_item")).setMaxCount(1).setTranslationKey(NAMESPACE, "idkSomething"); @@ -32,6 +38,8 @@ public void registerItems(ItemRegistryEvent event) { testShears = new TestShearsItem(NAMESPACE.id("test_shears")).setTranslationKey(NAMESPACE, "test_shears"); pacifistSword = new PacifistSwordItem(NAMESPACE.id("pacifist_sword")).setTranslationKey(NAMESPACE, "pacifist_sword"); dullPickaxe = new DullPickaxeItem(NAMESPACE.id("dull_pickaxe")).setTranslationKey(NAMESPACE, "dull_pickaxe"); + + } public static Item testItem; diff --git a/src/test/resources/data/minecraft/stationapi/tags/blocks/needs_iron_tool.json b/src/test/resources/data/minecraft/stationapi/tags/blocks/needs_iron_tool.json deleted file mode 100644 index 2dd664728..000000000 --- a/src/test/resources/data/minecraft/stationapi/tags/blocks/needs_iron_tool.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "values": [ - "#sltest:needs_tool_level_modded" - ] -} \ No newline at end of file diff --git a/src/test/resources/data/sltest/stationapi/tags/blocks/needs_tool_level_modded.json b/src/test/resources/data/sltest/stationapi/tags/blocks/needs_tool_level_modded.json index b15b2bb24..04f9bde83 100644 --- a/src/test/resources/data/sltest/stationapi/tags/blocks/needs_tool_level_modded.json +++ b/src/test/resources/data/sltest/stationapi/tags/blocks/needs_tool_level_modded.json @@ -1,6 +1,5 @@ { "values": [ - "#needs_stone_tool", "sltest:test_block" ] } \ No newline at end of file diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/MiningLevelManager.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/MiningLevelManager.java new file mode 100644 index 000000000..205f3b7db --- /dev/null +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/MiningLevelManager.java @@ -0,0 +1,33 @@ +package net.modificationstation.stationapi.api.item.tool; + +import com.google.common.graph.GraphBuilder; +import com.google.common.graph.MutableGraph; +import it.unimi.dsi.fastutil.objects.Object2BooleanMap; +import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap; +import lombok.val; +import net.minecraft.block.Block; +import net.modificationstation.stationapi.api.block.BlockState; +import net.modificationstation.stationapi.api.tag.TagKey; + +import java.util.stream.Collectors; + +public final class MiningLevelManager { + public record LevelNode(TagKey blockTag) {} + private record CacheKey(LevelNode levelNode, BlockState state) {} + + public static final MutableGraph GRAPH = GraphBuilder.directed().build(); + private static final Object2BooleanMap CACHE = new Object2BooleanOpenHashMap<>(); + + public static boolean isSuitable(LevelNode levelNode, BlockState state) { + return CACHE.computeIfAbsent(new CacheKey(levelNode, state), (CacheKey key) -> { + val nodes = GRAPH.nodes().stream().filter(node -> key.state.isIn(node.blockTag)).collect(Collectors.toSet()); + if (nodes.isEmpty()) return true; + val pred = GRAPH.predecessors(key.levelNode); + return nodes.stream().anyMatch(node -> key.levelNode.equals(node) || pred.contains(node)); + }); + } + + public static void invalidateCache() { + CACHE.clear(); + } +} diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationToolMaterial.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationToolMaterial.java index e404b21bb..a8aa7d932 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationToolMaterial.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationToolMaterial.java @@ -1,16 +1,14 @@ package net.modificationstation.stationapi.api.item.tool; -import net.minecraft.block.Block; import net.minecraft.item.ToolMaterial; -import net.modificationstation.stationapi.api.tag.TagKey; import net.modificationstation.stationapi.api.util.Util; public interface StationToolMaterial { - default ToolMaterial miningLevelTag(TagKey tag) { + default ToolMaterial miningLevelNode(MiningLevelManager.LevelNode levelNode) { return Util.assertImpl(); } - default TagKey getMiningLevelTag() { + default MiningLevelManager.LevelNode getMiningLevelNode() { return Util.assertImpl(); } } diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/ToolEffectivenessImplV1.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/ToolEffectivenessImplV1.java index 791131f69..9f4d161d6 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/ToolEffectivenessImplV1.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/ToolEffectivenessImplV1.java @@ -1,14 +1,15 @@ package net.modificationstation.stationapi.impl.item; +import com.google.common.graph.GraphBuilder; import net.mine_diver.unsafeevents.listener.EventListener; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.item.ToolMaterial; import net.modificationstation.stationapi.api.StationAPI; import net.modificationstation.stationapi.api.block.BlockState; import net.modificationstation.stationapi.api.event.item.IsItemSuitableForStateEvent; import net.modificationstation.stationapi.api.event.item.ItemMiningSpeedMultiplierOnStateEvent; import net.modificationstation.stationapi.api.event.registry.ItemRegistryEvent; +import net.modificationstation.stationapi.api.item.tool.MiningLevelManager; import net.modificationstation.stationapi.api.item.tool.ToolLevel; import net.modificationstation.stationapi.api.mod.entrypoint.Entrypoint; import net.modificationstation.stationapi.api.mod.entrypoint.EventBusPolicy; @@ -18,7 +19,6 @@ import net.modificationstation.stationapi.api.util.Namespace; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -73,19 +73,13 @@ private static void getStrength(ItemMiningSpeedMultiplierOnStateEvent event) { if (!isSuitable(event.itemStack, event.state)) return; + GraphBuilder.directed().allowsSelfLoops(true).build(); event.miningSpeedMultiplier = ((ToolLevel) event.itemStack.getItem()).getMaterial(event.itemStack).getMiningSpeedMultiplier(); } private static boolean isSuitable(ItemStack item, BlockState state) { return item.getItem() instanceof ToolLevel toolLevel && state.isIn(toolLevel.getEffectiveBlocks(item)) - && - ( - state.isIn(toolLevel.getMaterial(item).getMiningLevelTag()) - || Arrays - .stream(ToolMaterial.values()) - .filter(toolMaterial -> toolMaterial.getMiningLevelTag() != null) - .noneMatch(toolMaterial -> state.isIn(toolMaterial.getMiningLevelTag())) - ); + && MiningLevelManager.isSuitable(toolLevel.getMaterial(item).getMiningLevelNode(), state); } } diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/ToolMaterialMixin.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/ToolMaterialMixin.java index 820859da2..aa4265349 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/ToolMaterialMixin.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/ToolMaterialMixin.java @@ -1,27 +1,26 @@ package net.modificationstation.stationapi.mixin.tools; -import net.minecraft.block.Block; import net.minecraft.item.ToolMaterial; +import net.modificationstation.stationapi.api.item.tool.MiningLevelManager; import net.modificationstation.stationapi.api.item.tool.StationToolMaterial; -import net.modificationstation.stationapi.api.tag.TagKey; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; @Mixin(ToolMaterial.class) class ToolMaterialMixin implements StationToolMaterial { @Unique - private TagKey stationapi_miningLevelTag; + private MiningLevelManager.LevelNode stationapi_levelNode; @Override @Unique - public ToolMaterial miningLevelTag(TagKey tag) { - stationapi_miningLevelTag = tag; + public ToolMaterial miningLevelNode(MiningLevelManager.LevelNode levelNode) { + stationapi_levelNode = levelNode; return ToolMaterial.class.cast(this); } @Override @Unique - public TagKey getMiningLevelTag() { - return stationapi_miningLevelTag; + public MiningLevelManager.LevelNode getMiningLevelNode() { + return stationapi_levelNode; } } diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/impl/vanillafix/item/tool/VanillaToolFixImpl.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/impl/vanillafix/item/tool/VanillaToolFixImpl.java index 0c9cedfa7..f51cceb4c 100644 --- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/impl/vanillafix/item/tool/VanillaToolFixImpl.java +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/impl/vanillafix/item/tool/VanillaToolFixImpl.java @@ -4,6 +4,7 @@ import net.minecraft.item.ToolMaterial; import net.modificationstation.stationapi.api.StationAPI; import net.modificationstation.stationapi.api.event.registry.ItemRegistryEvent; +import net.modificationstation.stationapi.api.item.tool.MiningLevelManager; import net.modificationstation.stationapi.api.mod.entrypoint.Entrypoint; import net.modificationstation.stationapi.api.mod.entrypoint.EventBusPolicy; import net.modificationstation.stationapi.api.registry.BlockRegistry; @@ -16,11 +17,14 @@ public final class VanillaToolFixImpl { @EventListener private static void fixToolMaterials(ItemRegistryEvent event) { - ToolMaterial stone = ToolMaterial.STONE; - ToolMaterial iron = ToolMaterial.IRON; - ToolMaterial diamond = ToolMaterial.DIAMOND; - stone.miningLevelTag(TagKey.of(BlockRegistry.KEY, of("needs_stone_tool"))); - iron.miningLevelTag(TagKey.of(BlockRegistry.KEY, of("needs_iron_tool"))); - diamond.miningLevelTag(TagKey.of(BlockRegistry.KEY, of("needs_diamond_tool"))); + MiningLevelManager.LevelNode stoneNode = new MiningLevelManager.LevelNode(TagKey.of(BlockRegistry.KEY, of("needs_stone_tool"))); + MiningLevelManager.LevelNode ironNode = new MiningLevelManager.LevelNode(TagKey.of(BlockRegistry.KEY, of("needs_iron_tool"))); + MiningLevelManager.LevelNode diamondNode = new MiningLevelManager.LevelNode(TagKey.of(BlockRegistry.KEY, of("needs_diamond_tool"))); + MiningLevelManager.GRAPH.putEdge(stoneNode, ironNode); + MiningLevelManager.GRAPH.putEdge(ironNode, diamondNode); + MiningLevelManager.invalidateCache(); + ToolMaterial.STONE.miningLevelNode(stoneNode); + ToolMaterial.IRON.miningLevelNode(ironNode); + ToolMaterial.DIAMOND.miningLevelNode(diamondNode); } } diff --git a/station-vanilla-fix-v0/src/main/resources/data/minecraft/stationapi/tags/blocks/needs_diamond_tool.json b/station-vanilla-fix-v0/src/main/resources/data/minecraft/stationapi/tags/blocks/needs_diamond_tool.json index 7e914dc50..54d961641 100644 --- a/station-vanilla-fix-v0/src/main/resources/data/minecraft/stationapi/tags/blocks/needs_diamond_tool.json +++ b/station-vanilla-fix-v0/src/main/resources/data/minecraft/stationapi/tags/blocks/needs_diamond_tool.json @@ -1,6 +1,5 @@ { "values": [ - "#needs_iron_tool", "obsidian" ] } \ No newline at end of file diff --git a/station-vanilla-fix-v0/src/main/resources/data/minecraft/stationapi/tags/blocks/needs_iron_tool.json b/station-vanilla-fix-v0/src/main/resources/data/minecraft/stationapi/tags/blocks/needs_iron_tool.json index d0bdd018c..58f40dc96 100644 --- a/station-vanilla-fix-v0/src/main/resources/data/minecraft/stationapi/tags/blocks/needs_iron_tool.json +++ b/station-vanilla-fix-v0/src/main/resources/data/minecraft/stationapi/tags/blocks/needs_iron_tool.json @@ -1,6 +1,5 @@ { "values": [ - "#needs_stone_tool", "diamond_block", "diamond_ore", "gold_block", From a6dfbdcecfb32bb4b57c2ad1bf44dae91639b732 Mon Sep 17 00:00:00 2001 From: calmilamsy Date: Mon, 8 Jul 2024 17:52:06 +0100 Subject: [PATCH 03/25] Fix a bad mixin declaration in lifecycle events --- .../main/resources/station-lifecycle-events-v0.mixins.json | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/station-lifecycle-events-v0/src/main/resources/station-lifecycle-events-v0.mixins.json b/station-lifecycle-events-v0/src/main/resources/station-lifecycle-events-v0.mixins.json index bdfda5905..93d37150f 100644 --- a/station-lifecycle-events-v0/src/main/resources/station-lifecycle-events-v0.mixins.json +++ b/station-lifecycle-events-v0/src/main/resources/station-lifecycle-events-v0.mixins.json @@ -3,12 +3,10 @@ "minVersion": "0.8", "package": "net.modificationstation.stationapi.mixin.lifecycle", "compatibilityLevel": "JAVA_17", - "mixins": [ - "server.ServerPlayNetworkHandlerMixin" - ], "server": [ "server.MinecraftServerMixin", - "server.ServerLoginNetworkHandlerMixin" + "server.ServerLoginNetworkHandlerMixin", + "server.ServerPlayNetworkHandlerMixin" ], "client": [ "client.ClientNetworkHandlerMixin", From 6a63f392ef631fa6e8b9366833d35177a7f9b60f Mon Sep 17 00:00:00 2001 From: calmilamsy Date: Tue, 9 Jul 2024 17:39:05 +0100 Subject: [PATCH 04/25] Add RegistriesFrozenEvent --- .../event/registry/RegistriesFrozenEvent.java | 16 ++++++++++++++++ .../mixin/registry/client/MinecraftMixin.java | 3 +++ 2 files changed, 19 insertions(+) create mode 100644 station-registry-api-v0/src/main/java/net/modificationstation/stationapi/api/event/registry/RegistriesFrozenEvent.java diff --git a/station-registry-api-v0/src/main/java/net/modificationstation/stationapi/api/event/registry/RegistriesFrozenEvent.java b/station-registry-api-v0/src/main/java/net/modificationstation/stationapi/api/event/registry/RegistriesFrozenEvent.java new file mode 100644 index 000000000..d9a13dcd5 --- /dev/null +++ b/station-registry-api-v0/src/main/java/net/modificationstation/stationapi/api/event/registry/RegistriesFrozenEvent.java @@ -0,0 +1,16 @@ +package net.modificationstation.stationapi.api.event.registry; + +import net.mine_diver.unsafeevents.Event; +import net.mine_diver.unsafeevents.event.EventPhases; +import net.modificationstation.stationapi.api.StationAPI; + +/** + * This is the last init event called by StAPI. + * Called after registries are frozen. + * {@link net.modificationstation.stationapi.mixin.registry.client.MinecraftMixin} + */ +@SuppressWarnings("JavadocReference") // Shut, I know. +@EventPhases(StationAPI.INTERNAL_PHASE) +public class RegistriesFrozenEvent extends Event { + +} diff --git a/station-registry-api-v0/src/main/java/net/modificationstation/stationapi/mixin/registry/client/MinecraftMixin.java b/station-registry-api-v0/src/main/java/net/modificationstation/stationapi/mixin/registry/client/MinecraftMixin.java index e31a1526f..4bb983462 100644 --- a/station-registry-api-v0/src/main/java/net/modificationstation/stationapi/mixin/registry/client/MinecraftMixin.java +++ b/station-registry-api-v0/src/main/java/net/modificationstation/stationapi/mixin/registry/client/MinecraftMixin.java @@ -1,6 +1,8 @@ package net.modificationstation.stationapi.mixin.registry.client; import net.minecraft.client.Minecraft; +import net.modificationstation.stationapi.api.StationAPI; +import net.modificationstation.stationapi.api.event.registry.RegistriesFrozenEvent; import net.modificationstation.stationapi.api.registry.Registries; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -16,5 +18,6 @@ class MinecraftMixin { ) private void stationapi_freeze(CallbackInfo ci) { Registries.bootstrap(); + StationAPI.EVENT_BUS.post(new RegistriesFrozenEvent()); } } From 8f1edb957bf66a3b98f7b2bd5e641991970af9ff Mon Sep 17 00:00:00 2001 From: calmilamsy Date: Wed, 10 Jul 2024 21:39:11 +0100 Subject: [PATCH 05/25] Add station-api-config module # Conflicts: # glass-config-api-v3/src/main/resources/fabric.mod.json # settings.gradle.kts --- settings.gradle.kts | 1 + station-api-configuration/build.gradle.kts | 9 +++++ station-api-configuration/readme.md | 3 ++ .../stationapi/StationConfig.java | 12 ++++++ .../stationapi/StationConfigData.java | 4 ++ .../assets/station-api-configuration/icon.png | Bin 0 -> 213950 bytes .../stationapi/lang/en_US.lang | 2 + .../src/main/resources/fabric.mod.json | 35 ++++++++++++++++++ 8 files changed, 66 insertions(+) create mode 100644 station-api-configuration/build.gradle.kts create mode 100644 station-api-configuration/readme.md create mode 100644 station-api-configuration/src/main/java/net/modificationstation/stationapi/StationConfig.java create mode 100644 station-api-configuration/src/main/java/net/modificationstation/stationapi/StationConfigData.java create mode 100644 station-api-configuration/src/main/resources/assets/station-api-configuration/icon.png create mode 100644 station-api-configuration/src/main/resources/assets/station-api-configuration/stationapi/lang/en_US.lang create mode 100644 station-api-configuration/src/main/resources/fabric.mod.json diff --git a/settings.gradle.kts b/settings.gradle.kts index 737ddf9bb..36b8b1b46 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -46,3 +46,4 @@ include(":station-gui-api-v0") include(":station-transitive-access-wideners-v0") include(":station-maths-v0") include(":station-worldgen-api-v0") +include(":station-api-configuration") diff --git a/station-api-configuration/build.gradle.kts b/station-api-configuration/build.gradle.kts new file mode 100644 index 000000000..c431db4a2 --- /dev/null +++ b/station-api-configuration/build.gradle.kts @@ -0,0 +1,9 @@ +import net.modificationstation.stationapi.gradle.SubprojectHelpers.getSubprojectVersion +import net.modificationstation.stationapi.gradle.SubprojectHelpers.addModuleDependencies + +base.archivesName.set("station-api-config") +version = getSubprojectVersion(project, "1.0.0") + +addModuleDependencies(project, + "glass-config-api-v3" +) diff --git a/station-api-configuration/readme.md b/station-api-configuration/readme.md new file mode 100644 index 000000000..d92a32a69 --- /dev/null +++ b/station-api-configuration/readme.md @@ -0,0 +1,3 @@ +# This is a specialized module that appears in ModMenu for easy config editing. +# !!DO NOT USE THIS MODULE FOR ANYTHING OTHER THAN CONFIG!! +Also don't refer to values from this for your mods, changes here will not be as thoroughly documented as the rest of the API. diff --git a/station-api-configuration/src/main/java/net/modificationstation/stationapi/StationConfig.java b/station-api-configuration/src/main/java/net/modificationstation/stationapi/StationConfig.java new file mode 100644 index 000000000..3de042934 --- /dev/null +++ b/station-api-configuration/src/main/java/net/modificationstation/stationapi/StationConfig.java @@ -0,0 +1,12 @@ +package net.modificationstation.stationapi; + +import net.modificationstation.stationapi.api.config.ConfigRoot; + +public class StationConfig { + + @ConfigRoot( + value = "config", + visibleName = "gui.config.stationapi.main" + ) + public static StationConfigData stationConfigData = new StationConfigData(); +} diff --git a/station-api-configuration/src/main/java/net/modificationstation/stationapi/StationConfigData.java b/station-api-configuration/src/main/java/net/modificationstation/stationapi/StationConfigData.java new file mode 100644 index 000000000..4922a954e --- /dev/null +++ b/station-api-configuration/src/main/java/net/modificationstation/stationapi/StationConfigData.java @@ -0,0 +1,4 @@ +package net.modificationstation.stationapi; + +public class StationConfigData { +} diff --git a/station-api-configuration/src/main/resources/assets/station-api-configuration/icon.png b/station-api-configuration/src/main/resources/assets/station-api-configuration/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..30667fbf3e6c39cd0e8a65e818e60ad402325362 GIT binary patch literal 213950 zcmV)lK%c*fP)004&&004{<008|>004nL003F*009yY002DZ000@zy2&Ck0003Y zX+uL$Nkc;*P;zf(X>4Tx04UF6U|=$Eba8TJ5@2A+%_}Jia(7aQh>TKTKhMC%z{~&! ziOIzUjsXEaAa-7UUMd3y_;!tf5kz0s1)0S_8sJJUC@KNce}LF1CAB!2fq~Hg$j&Y= zDFBKy&H=JTlCr_<4Ip+=NRTs-eFVtnONX$pfY?b8_7f1h2CFd6v zfq~@@Ld>L>fnk9T0|Wn5gqWHk1A~A*1H-;K0Kmpi{cn=x1ONa432;bRa{vGf6951U z69E94oEQKA{#i*xK~#8N?EPnx97(bz3OeT`I7teiNcWw7GqbxQ`~Cg@4^L!eMBd)H z_jVTnkUTS}bN0?LkIalr09h#7jc(UM0TJQmM$}Y~s+yar%YXUHU!;yY>ZqfR{`E-N z{o7GT9d*>vzZi7}prejD>gZpTIs?#AM;&$aFG`&O=%}NPI{Fu-&H!}OQAZv9i_*sp zfUL->t|*;#=%}NPI{N3Ok72wl>w#ep4b|u@Kt~;Q)X_gJeE{)|r0A;IHw{~n>PA)- z!_&2UOQ4#X;cKcYw_iKzsH2WL`f^E~OeVXJEh)0mGwo0-S9w{;MrgVdQ&pv=mK0O7 zhNjck<+`cL8ozYZQAZth^ySiX10WlkJ+{=kN*0CUnZcn0#8*@qaBqZ$H@8hslbfbY zsw!`G_jJ@zM;&$a1=6!6AX)cx!;wiijZF3Pm3vMRkvqU$u@mQ~T=e@7j4)X|qs zPnLj;&~$owu}af*1%Pjwri{vTT_75$%cd@CLZqeHm>welSyeP! zZL%_3)BOk4SyjYki9cyo$*ykFL`qtEFzAXGa}% z)X_gXJsN7pDY1CvK2cMb%{#{iycg!mlUv zgnxG5@O}61M+lepuF9ICYO?e>2ODIz(vEjG{I)^-uHJJ4gaY{Gg%12C^mG(25PGHR z?AcF4-+s4$)(}+1>RV1-8Zt+)0v~vkWPe)F8ABx(KUir*sZX^C=4zUbKOzmu z&$9x1Vj-)jMgt_vpHYRZ877)+n)<`CPetvMq?npBu?$PDvR`^~9<6*vLoX14Lx?vg zh1|OrU?H&&Uw?vH32((4-}ZG4v-^MpDAxWiD*iRpA_hhFbGr9;Bn;gkV?JkoA7$oe z@rTLTOm}2JY^%Ixi)c^W{(KTK6;Lkx@&TGr3E}O3z|5aA0K$bq3(s@_T`&ihJGHDp zS5&FaE1nv|_#Q?jdbRs1%bKkjt|pZY_m5J~S+>2Tdxq(2O;y)b`wM;(A6j~-1Vr)L zeSAW)q}sYYGMzp~FM&tQS`o6}bt(GYRwC*F+?#=6SV~<85Kv^@)y3C)6@A*`<5yKN zfpI;p$?IBCoQds?O~cm&R~38W_;cH|QBPHulICzw^8KJVqK7)4k>JMe^M|z0jkXf; zm7@p^-B2(S7Ja#Lo4-RuwlB~}iZbfhZk=VB_W z-e7ik@_IZPyN+4rXs&~x-6ODmu!3+{wZ(Trd)2|TOJb1;<+KHPTSrQP3q!@+e@kp}Qj!fPkKBZ1m|=iuxZI zwfnsH_3^XNO5MRM)qEt`UfL`9SjjW`pyWrsJ`ifzzqF4nZOO;0pKMYwRKtTyApt=6 zegCd~l7R_2&=N=rrs1+@#;KcI>TE2#b(Y(2(YZ4Sg zH{>FzG~ebSrUPz2Z33p(HK4ABDHRbWMmBq3sX^vL z5cf+0{X;W+<@+N8l{B?%O&kwX&*qv2GsDinaAFpP72hYBC}8_qz5vWC{*g!12rCQw z!Fn(?T5*?UNsZ2UbI1185}YYz2qgw+`SkQ;+XxOFwg$|CVS_!sZv^hc_~^}a+$+;K zOXCuCS`Gw6vwhFCaNP;UnjQ{^1Ith$d+uO9n@u3u+x1og@5cw@$<#5`s%pH^ z(Kr9?e;iJSz|Op=?O-&TPH9x6TGlMra}~&i8(6xGY9ai(E@i8NAik&J&`Gceb80}m z@l{tXN`leiCe+I6o6g9#`&ylpMS8Eb^mQ~QYHR=^ng*wEr!r7Ix`CXC2bF!$5!93P!r3TCu23-^0m~4+M z)6sO^2z54kr<7gQ(qLMOSiq1V;j);JJ@yTA3mo9^F<#C!R2bv6d-q1gr^5>wMGcZp zR@fn(HppHps8$cLAp7|UN@xP`2UheTcq$x98aeS*piqM@QP`kCXrC?`91&r+And>v zF?_*%mb64kUGz|Tn*xEt%)y^bPF2?9DtNn`KH8p{R0=0tzy2iouS?lyKVbZn=-1SN0JGB zfJP%Ea#dirGq%y9=`uWm*1^D_GZ5|yO6aiLRO~I;3(wA>PQu_-Pnv+20O^@nhAyRx zynzina_m4iJjh|4M+hHw1yPb(H-&&UZ?~8@2rc452<<*vX&&Pw*na$h+RIStDdrauiwdtrL&y&&$tUx(Te5C<8@vQy zdQZnE6MzL51e!QDDYWqKD#?P(^f15hT8N%tIFPhS+QU6ER0(3)S|g_YMYNX|8L-3B zX_$NL44oke)m~RY)N@^>uM<_Or|YT&UCScgXt_!zDwm^a1{SbD? zpzQg&<`RJsMnLg}F9MKlG!OlRQ>Z~^5TL-2xKmRpt8`VWp%on9J0dbVZDiEU0z|+g z259V?RR}PA2&g%RFT+OxAOcJR`r2e^XhGO?OV=&%K!WPQWrRB=%#Vh-U}szvD5v^F zRo&Kf8WPFqvv05sXdRY#pELBhM;83BVwJ;cdk4f{#xA-9=kL);g&Ja-rhs7fxyU%b zkP6jMfh|CMb6`WA(N!=XOnYnsH^NW>+$=d?=C!T?E?`;VVH1>=Sr#`2`Jcf6Ahrgy zdhk#eX_iUeX%NCk$DnL6UbvFF0;><0$~MJA-#)sevLiYvz7D1!z(Jq(x`mnMvNDW} zX-oOC0Lk!Rk!DTieILuy2(^^U@znU;wf)5HJ z4O0acqqiEJyBt!8XbFDd2q7=p-FdMRhKe~d>z@8E?YD-Q+Ol?VB5(*+ml5_LU-a2br&G zT<@Tn%z(-Ymnj~K*9}Z{w#v5W(e@%m7$Mhna+9Vpd`0-GbpN?{uChP7TUug}!38&f zKBP*u#c;UD&r~9aCD206DWjuRZu4YGc402i0RT$A&M>(e++<6GM+_K(*F}VSgbs9D zH%zeFuw2*B>4O6d2BT@uv&t;D!|`Z51SYY7s&0xRUM+98QCz?jLfv%3fC;Vg zB#F{A+N>9g>$7)%{r7io-vRjyU0z?md;j)boR*e_9x4i)R@;)m5t&Q0P!`RE9PIH8 zzX9yj1`Ox1O3XZho~#6OD0>c~YPE{%BzRUQr6rMQd7efYo%O-eAb=a?m>a0lVEz~(HORB2f(-b0x3~d5p)Nu|F zNH!&vG|J(+K}b-6hDe~Spq22DG`m$9U;&?PJX;Xv@^@3g(J2df@iYTcS*DaF#tj<0 zz9`>bCMnF4cq#@YrB=dohpUR<1BxcJRRbs|B}$?*@NZcyc-d6kyIpyoUII8O#_%5V|d;ii>Ou!=RyZm?c^uSPKZ%9!h-L0C0(* z1}Ff>aZkQ)mmoaw_tFxcF9y%&5?o58v?X_0ks{zAgrOhkTwT?eC$Iy&V+CamIV&L~ z0i#{kMNB7ixyY)?2&N#x$$}VI`}#rWv{`B2dOXKr2iGEVjU6$Sa_*0jO?^ z_$rC-=!8IMP@bxT`WvblnxML3yijsP0vIoX^gY5PLE!Gko1-m;qCL3M4dNJbj4aKQ z+l&&U$W;u7A44EZ(F!^VzM<#vE-^=7Y1_o!G?6$!R>hyud3HO7Z$b#(_4a|F>g`-G zs30pa`!tQv7X}QBnJ~YQ`28jtpv*ewkBofCLo|oq5vCv(VWXy4DS&uWD-c+cP3V?t z&>Mx!uoxXoaT{D90178=N8~Nwv&pW{zI*rf$JKgUq+D|M8^P&Jx3UsC}@-%^wml6EOtE=0)yDUv$0#!{blJ)BL^6K(32ViPSkuj1l zaulvr1~A|jN0mpbyPI3d@caF~rjk*J+tW13@)A%7mt(!WzC8Q>{Ne_jgWSMg8LC|5 znFMJuOEVU6T$|bg1!6$wm=fZ{0i=XH(~)DmYah5K+sA$Lj;97t)Ods0w=6H z%G08Qdl6@i^`Ih{9~x%XfJuZd&`uE3iF6zxQ5(O*8i-pUR8OD5z;#7i@V<3S0=kM> zf>m1PTyKHHBxVhN1EGWxNst*jc@XSp<0U3wy5Sfl$qK*+wpIBW5(NxF--MDvFu?%` zgK$pRZGZw$f@|gE5`q{=5iBLVt{6ZMAbSvC2p5_FC&Vb=6`@XOAI6KnF(ODIBtN;M z1%f|{8sKrlvjI4AofB4PowGA(E#{)g?y~4I1%N`l^Q6`g_W+|GnrjKdj(Q2d5L03t z5d$3%eb|)&iI3!P4%voVfMJR0COo!-ZRl$*GMKA&vUbE|Ji-sa6qC>3BhZbm9!wWF zrJ4Xu+z!`~YR=Ax#-Lp24bTHVF69THh)d`^xCl%7&_a91r>M@$=ptJE7{l?ztn7XT zu|Z4&yll<^W(e$SyNLON_TrNsn9h)(2vFuy1|ksz6P^YePOK#OfN4ZoKmw)#;SW9% z(eS%~Ht-3u&le8}X@*IspNo5N-@b%G$W1<#LI6w5;*I=~k6ik&oRoMzatRS`QL1>2 zIq$g4qWgx2I22Ad<$%(|NUd)`#Oc)FKe+Zn5Mg8LBwxRc;w8*0cufPoIg8_4Iwp+D z5n(||o{0$f1aHU$X6&ToNylNsIT;);bL|y$d7vkd3!DOC$vOuOCc32Whd zd*B8-3M_nUe#n~r`cZ~!lor>Kd>wzN|7?YFz^5aRFndqHD{uxL7F2>-N0~t5}_d;Pl%Q5}AZ4XWFkk5M%zvDC4ABcCXfwK&s=sH@T z!F^zOyQ>@oX6q&*P1o!9dVR~#fW0LGb5lr242rfX7>#$X0+NRuc_Gbl}edNLmM!D`DN9Ui|L4M)AfFz^G{ z^G!nosF1(J9LPMM81zDzT&*rr^r0%UEKQ5DGThFMP_@m;94M#UG914#xmp+^|3W(%-{ zX{c#s$yFih3_V$r(2U<<%m7*FJms7JKN4IPgd^@)EE)$0`VfB5qT><;`{}Hq2Cx7# z0@m@#4ImEPK#SB7NQ#gwKFcL5_DSeFV?+oEjcAMK+;0KFB^1b(hPc@oneN;T4jel) zxE{`JHEaScbEO@|Z0f+?lxiy!3Q`)dCjF5*h4S{PBB-|7(f(}m~RvT zDDhE5nbHY;&L+6hkX+bmgbv(pfvcEuFch5^aLK$z0M^~2Atw~<15d#YOdI&ls|guR zhx!gSzvAt*=ZLTfWRQN?XBZfK#xIaCX3R!qd{oZ0ONcdkOVic%Nf4S~3|rS+Grdo; zM8Y`HP4ShSyic$S?*^P{!*AU_>xL^7kz`I zw=M&`8-$|x8`Yx!`;p*|Sg8msprtu@0y*ZakuxBwH&@J_F(29mO+$!{ySO(=ENe>O zA5>IKw+5Nx!wuE+aTN^^{@4}~m2o%tz=mOWp%p5hygjr+S>xW#UEG_-nB$u}HS- z#a)tRs^NIyz%k|J^?97jwqpU=lXx3#w-tE;e z;ROYNBwWja2LOOWWzajsZ7|$)X6cdx7C5281%@cH^_EbXfMZSN6D(p2bPYUg6(1u4 zd+`CWk(daADa{0zj^W*sGpJNNQA3>s1ZYQF5@L&zvXmoCUy3LB_XKwbfe{~QP_u-S zgui1#Keg=1qd4(5M=XRq6UZi3o`H3FBp%7aXvW13?)K>(OPiwBJ>B$R`B@d(stPU# zwTsoLnSKBb!wywIgi}U&qR%xv9)v}-QteEMB9i=S-HoueK#o&4-+U;e@?MF?@!W zp`OQD+95rmU5h9u3Zabn&a(TRc~0P>jpzp!w{d6O4hvnPv4noMt?ed`eJ1zto2Zk- z>*7O8;%gBV(RIq`p(O%$GKI>{_k0Om`?p5ZV5Kh4nmI0xV zoYpR)n?ku*PJG`Vml!*`Ee6%r31*{C!6n{*U-q6$Etu>PMubc4XgLbeMB6a?zAN=e z?2ov@7KL)PED7}2!@VCRq0BGd2%j??j$PY8V6j~AA=N|UyB44666nKUWX1M+ zy}?ke)79P0Hcp<5;O{~&Gv*(hz+hcL2#c`zi9`J{Vl?k?gCjia-A{iE{b3vykE6{V zH=Z#1Aw$}RKP6-z?-tC4Skc+t_1hZ&(lcw{(Z44B8UgsDVT+y|@SN`1ujqDL3yjrM z>(x<5za0@3IclaSw@;Bs~H-x1{O7ytRA35Z>D&FI(3ZCgu+{vG{})C$)#efe2` z_UQL90ADgGGXHc$f;ZbP4S&%jM)6GUcl6=_dFk^+0ag6NGV1e3@h?pfkUxM?kP$vM z*nRs)pqF+5we%^bFpWWAh+HMyFT~vfEw#lTe4zcW4>j$7eRk=W5~_KqLs2ACBcJO= zQWe>^RQxfN_UYHI%sxHbi+e0xF`1=f*RRKFWy#cKkyfky{@J7`ng!wF6DO`|@&Gj- z7e99Qv5gPtg-f9Qt8K5uS8-T@&x1bhiSCsoJ!@j`>+b0j_h0XRc_7UGj-hRB&+7bq zdZ9D;tjOH{%RQ-WxgBxA*A@@d9y+#v<5S`TYB7o(&mT%QlB}t^r}43<*b>9GRQdkt zqO9RYQ|68B5AENoth?OI$Ne+AlYO#kt6~9quL=Gv{suj?_#wS;3ABH8uTEKm6ruU& z^9!~ZP)VPg?%K_77?kF46zv`d(nFn0*ue3ATqQscC0pA6+TOAMb-&~Tk)@hAA|Q@p zS>i<1!xH^Nvp-o6=)Ofo=RR@>o_Jg=e%vRqX9l3e9fOz-+;v|kH)P|-eL=dflf>*p zJPp@w6C&N;_z`+`Y5yyQ>I30y2|O@V!&UL&*%NG1`@>#6FSQQZF9{M~q4;DD#@+t- ztmHEiP5gubU`~=9#J8302){dXH#~Bkk!9LE^~cl6Hn-eTo)m?f;vJrx5`~%Erk#E; zMKv|@+Eid#xVh8eK_8+Cy8V=8z;0W|-RLWQEc64NfXHg%VYi{SscS4LHr&&J z4_$5UqgJV?B*Rc9ffksGhZgH5s~g;CwdO(8h8wwkpFW~&8A<@KZlp|X_csm2(Pgof zKz1#47HYmBm)y&=Yf*2nL3)Il1eTCjd#plVt$`IDx=_NZs8z@CW<0^qrDl|ayowX& zxcRvr!W}WiCQjNMT8?(t1Q;bFYy*c0Ph{FdC91A~g*#>*4AHn(i@k|8#R8*;@B*P^7W^Xy*D9T)E0@h2v?GZ#FhO_UL5AW$n$ z6@itQ?GLOa1e8DGB2PyP9QQN`1}!40HP8fQM!+a{7MUK?cxX!Vuze7OyTH=m$YI~a z7INq|N6}*0euJ!p=a@82=H^%NjGBx>6PSAq9t?My^SpvMsTUl(mM_vP)s1+X&4dcv zPl;)?b{xjg^uP=b&|WRJBa`{NvzjUQv0(^2@3PZFBB0T3B!51?d*j9YYJxKu3(uWW z7Evwts<-powk|9#jFvNX{TaE&{fm3mg1y$r#wBh&ig+4B_jtkv0xgCwS~bt~ z4_znRrITtWktZBcA?+(Cv}LIf3?ZdNHPLPAEP9F7g+%Q}f${EoLPG1l5gfU;&-5_R zG-qa8t|C>fJ>dTO$GLcDf>KE#Cl6W?5^e0V1sx{CaU&Xk)&x{uaHbVt)+3xGhy^uB z@X!iPXQ%^u9us)rMj9BMNp7GtJjx&p^L-Q0IPwsk0rLThf)!NfXDmfM&`w(Pr-C7d zB?FUZj!=A>F@zeNCV{%(A!ZGoL^r@v{0-aRGXK*CfYM{wBg>r_I!}=D5XbHk_z+sb zAu6Cj=HU^5&cybZ_DgT_3RoMya)Y@8bwXFHi4z{X%noEJ5GPuWV~6QApi3bpjF;@5 zq14=<`Y>S3ap z9C+G6i00(HY${nE1=`R-V8NYcy3Qt`#euD8Y_uH#3F_e;GJg{!w#sU5Ya3gpI8|8X zwPLr4Giee^9)sB31ri(JY-TY6LRB@7kidFx-6KvW#)Ke z3$hMLP;4Do*(TI0^IGp&0d%{~x&0n~`#Fr7?t>&?)d z1{)6U*<%N~4Lw9>5W$f%D9_As%vbYRjg3)w!JG&rFqf$S(Kpjk>a=>Y>rCXc3g*m` zldcNIHDNX!k$!_sC<+E;yGp*wt6H|FaA+I@b~-D|T+;g%ES!{=Xqri)=8nkLqH)K4 zCP7{0s!Z3+eBGX4QmQ&zml6~K5Paae109`Vs;enj%EUE1`ME#8%oJ^75>1$#iaDt; z(cs=L!;fXSGus`Q0BZme`ia(Iu4MSVs>XDCBYXy|^YHM4$`DBr1c>6Y*Zd%zrp z3DfdGgnZ0zAIK-yFnGYqV+Sh9?e^j;Mqvk-aONiS5A8OoTrH%Ooq?1>z6z!r@}^9( zCJc!J=Cg0iG|8g|yRKj)Ows6o;T(I;t-B5+&DRY_#Mip!ABwpE>@vfT?#-F`N}N!W ztpOljVm1_9g+z^Q3N7>dG2a}TCqSh!fg>* zfnAZS2V;ku=|L-preR9iBHuRviq5og-rU0YASWuU@7%W0Iwl{???Dlm#EG7e&ctnK z-Sjk`NZsH5q(E_~GT<9cv#i1oV`rfF5DZ;|R$>$||G0~}j}EAnOrqDI=Zsk~v*3mb z9KZmDB7E8aK(c!#s<4^nh3Csr=}y$3z(dP{tcaaSFn+>ipq!I^Y+Ry~LF{ zvJF^7FbI9nne$7Au@oV*;us=PnySH@gVe4b5097zJ#NpC;cLTX$Q#)=VPa*QxxysN z1pb1nT$2HI!Mlgx0G9#Qn~a$Z!04Mzxy~EQQULde70R++WsT>+qM$);7l-8tZ05y; zcMU~brOfk;7PGvLO4^2jtss<6iaMr6MW7%px8-eI!^3N*2EASAUL39O=vgUcH{gN0nQ#=u@mnBrf4h5r3%t4uLd5RU083&s-bZjjty-s3r zz8x~b#T_J>soQic(287im%zGM7L2tn2!+T*=3b40;%AyG`fVi@hc+i@-hf&~X34U&Jn{m1y`$kED?*d+>n+iUY+tcHu1eXzmMH845`qUpME+g_hDx&OMB=&n)2xbJ)o?lmFI7A#LhMyM6vfvBl#X3~E z%~K#+&QqG`Y;qGX|GHVcOKT`J9MfgagK&(@qzd8)=}AS7fj#*FxN|MOYGU}~1&_p| z#Sqa(4K?R74!WM@O_Y=4kezK>Cndxc?nP6IyH*J}jIPmVN0Fjv@YP^Y*`(q|4n%5j zBmDimgbMQy8p0n?RzPte7_d4#HUws5MZHeys9-`ADBdEfFV^KUC77aqge>S1M09Tu zRNor$I8P_SnPhZXMFlv+l@kQG4tP@+aRCljP`n2c5iwnrjM;K{k_f%En5+?lhxj70 zqk|vu5&}DBM*&O03IGBo3RAX%HGPux3B)t;RlUn1N1dd=i6+DeZQ5X_6+;w^spmOx zk?09yuf>T?;t8F59`t``0#bpW@^!X7k2jZaCL!}|6cH9!^yvP#{1J;i489;;sDUTR zxq!pK7GX7jT8tMCI2yu8A^rG;r>}N(kSLQdy@I81#^HhpJwY(?bo~d!o?{5@@oWaa zOklMtO0mcTPQh$&j1Uj}z_ZpR>dZvqLJS#3kvpap0U2%DFFMP$3|t1^cv68*H$Jc= zJ#mUC22v-*<~?(MF~*mgGQs?E#&^8}aczp@7&I88#M|MHbHJ-s>;xPV>VTo)UfJ=O3?2<6Gp9qD;coS4Bl6s1T zb+p2BxlBAIL9|2)8k#q*%%HfCQm_$omoBpHSsdL^i!q77=-rCYt{;M+2yGJ!W_BYA zWMUL>vl!4bB#N(+_4_1CDVb%=+Q3h-V#5x%Av;_~X8MBN1!8bLswpDx zm_T@o7MEZ-0dV3P)eob>oIThW5=6El3dcDjT1*h}+R@>j!!08s1J;4#+l)Rg z7zO-<3}WP{18N7Lw{&_Nn6hnBEmCNw#Cfl|z7MA!1^{!Us02^KL!>Ti=GStB;*Dd2Zlgg1aOEs#h@|p zvMDnrsDNAd1Ry}T$fNVX9Zoi`(p@zmC_?nXu9Uh5?Iq$uaxkxeBat=)Ja5NzT4;tapj}PCmY8=ofv@-g34mDB zoe_Wzh+!5Nn~O!LX^(KDgcw{bEC_!B{Uz}6Ec-*pzzSxbKxep|N>_&*+ph=JU}WtY zE;@^8MYjX7fJ>miCloVPIC||U&|4G+SfeT)3x}iP8HjGdC7>-Q7{> zFka3tTv3y!sp-`Muf_aQFhq87&acp6I1{*4FkjOV2f$%`O6(grbQGt3DO{y=ZxXyYpdkJ8<0 z5Nadp?b>Rog(G1jX{b~>2L^LEVg^M9-?j-pH-gh7J=$r{a*AROhEev)w9wD;S&|vKqhR4s@PcNl_PCiD-{$W@yOK zxAt{U6kynUhwmB!#J%(onBoif9PS~_-R?(_qHE5W@db1kOraTpI6{ly|H3g@GsNCK z5~N+?l*6F_G_I5bRaW}p; zFb}+h%2L#WXs$pUz$G9XdW-(BB$ssf5+sQpJsJ=zB~6rJF8G+&Gx_vo3pYVT7>rOW zuH(ZVxNuCWruF(UF%)t|g5kjg!UDl8v1u9x1y%%qU?vyw4&fiDg_U+baN}+*7?x7J zh=UF+laTDK4+w&=pj#M2>*iy!p+(g;kME#-tdssDW;dp}MQBrGD1yQa$SCU~c?ci< zJ=RKX1j{H8Vv!0GNt@I*AztZ25pgxTCs||lp#WST6YK00P_6*1nGgy5;iEq`K{F;P zA~9LJ;;AZ3l_0|qaD zl0yju4ds(3$`Bk22tGbTlo11^JA@L%>?lxUlOQJU;Wb)ER2S#MA*GXq$wDRcuTd240Z~%SRMxImv06T2dBzzam{`|> zroaPo`j}KPii{D4!ME~Nneh5C{U`~L#r(qLphdt3gcE=W!Ds_b@D0*JlgCXpBFt*7 zgRoK@f~~`2z<}v^t|=J%)OH4fiU@&n-$$jo;n za5@?lW=M#yh~k8+g?kt#bJD?D>Jn=aRk1)jKtTCz z7T=@~Rvm%@3x#=rJ%_Jdi?6s7pHT!FFS0p_OAsJ|$aHwQ1Vqp`HGURLP;E!({-P=f zH=|_Wps*8tj|=@U2z(v9(x_b!X_GKA&(Ptqb(%TZ|hnn0Th<>ZFwEsKy3PMlVu2{R^SMbxM0f1u&<{3THomhq~Cl^t4Q$U(o zp>UKa=wLTITR3R!0Kp5bz-??tK~F?zGGwEDkBwC1>mQp`Sf$^^^fR*IUqmR%|%e@Xom#2L7CZa1bAb zgRZJ|9o-5S_!p#t04rfL-5EmAn#*l4*n!67Ht|S@^e`ASF+Qj%7S1pMFi>se=CCP;*9aqS3rw2Ue^OdlBle)?IJeh$4{=g({rN{%_T zLR~80g$d97VHo!lMB1>KFAIzO|O{W_n~3zu5@%qBicKxeMT z5V^8DX72o$cHI{n7{bBlD~5KzgC1Icxu4IjzFc^p9_oLf4}MV$%^o34ltl_v@mvA) z;f*g6Q8$EzvuJ{FBdiZh53SX%v!u38VY}NO=yAfB!0omeD8u3+CV+WEs0Sm#0>3mH zD3{yNNb7U4D|GfBd-6pPxP$N&qksea)Ia-q1TUJ-Dj$ySO~#i+^ofLP3=<4q{NiDt z9(YL*Lc}6pnmly$4@mUfb%GqA<^_bIn}9`9d*=EM;(1B1QS7{@SI>7 zejWYencJ2ak?cPHW`qiVmpXrkuKp49j2+KDf00A#=o9pt%;qzx_(>tzFYv7J%QtrP zA$<(}K|hfS;srtkp&EP`g=k~{NyTqWZ3Z4iZl5uJCh6R-$sIeOpA5OUxsw};enO~J zMeG6PLsLTbZ$b)l7I8ZhBeb9D0Kz&;M}+rrR;Xev>u2{1A*HrkM8t$DT*(r@{}iDx zcbgf4#q9%C6OzDZhZGExkBC{7EVdq@XQ&)k#l63bAOyO|((yYA8;E`0ef&KLLMa|! ze?)}He~#~GldOsx#hs832-TH2g@PB#^8_w^SNI4n5!q5)`x)^WdG^Gxgb%y3`_C$2X!nUaN1`T3(j zGS)8h75m~VzlhIjiw{Byf#?u7v6v;6p6_pbN+@Dzifd2|_{2hN1bPrt2s%&?BpQ?; zjqN1>`Y6yQo)(xqC!C3=6e-CUA4lQ)ht|+6wql zhJ6n%E%BSFAETC!~s-|(4YDK63$isUmOe7!FzENs4jtb3zWrrHK3EpqlXh}vTBA)>(c{&QnD--M-I-1tByEfZ8 zDJ?y{-Tk#=)Q5(7Cqm>f1cv#eMn;=ygLx^AT-y`r9G-TDq_oLq9Mk63czpK6Mj!|$ zxVFpu!6WgFF|_@$j+S`(nwwtssuIk9oD2LQw&mP^x#tYNaWju<_&T(v-O2@C5tne0 zSB06m7ojJ_ODv2Jq8?#K#dvuU)$a=i%-P;1qE;~YrIq~Mbnm{>ZTeuYQNPMvcFf39 z?_N7hOZkzKptjq4oe`gK1OFI-;fze&_d+TNCL=R_!x_VHOHJ|Q35@2M!HL6c1l&@p z5lVWN%giklM4l`^blTGskT#}OIbg;Nm9NX^y#Oino!gy1+_GAvf^gD{lx$1IxN(b3&NPj} z1V>@Ju?#Ib9B(@)uw&q>0a%gM8OmE21)31!mE}>WABGw%Qwf<+l>A|TV9@vmQXpSCOKBf%c6p2Ue9o-cDEmtUw!bxWD=c1lW)HQrpxw7Y@;smKNFVNfd-*xE}6Q) z@V$`%{nTuwig`$4R{>srUCX+x^x~|fFe*V$$a|HiZvqBgx#WGu*HD^ z+fi36$rhmq_g~3Uk)dm!rL@yir~lfweTpS!5N4S3%VbA9+OjJLg0BoeY|0JU>>EZ; z^ClqO)l@_Ej=kO-A(bzKi9TBxLbkZ?o!-4IDXMALWs4-GF*+LzpH(=0BK5I{VOxIco9Qvj{zZ3YQ++L zWI&!1A|QiqP7#496H3D@()v3l4iA;4;Tv*X$)V3t;c%Tj)4k#XotRwjQ3QdiI1Rui zyK^xoyi?TJ#~HKV=a|SGwTAO*ZZbD|V#dGJk8cXP`s3(MkBk`MfEC_W0F%@Tg%6nE$|B7@mx#L+JevPlMuvP=ED z=7`rXSjXv)e%bX-V~S8ZX>68p2O%q=mQDyM#L5NmUHPKAzD|$~DMZN4i1Yda^!Cyt zf5R)8kns9HZhTUM4e1>9r{*p=CDjwKa6`;}dfC$*B_uvhbNeGd?RO%vrZCAZepw^J z=Li6XO(lC3vgIFvlKql{nwpp6RM26H@%BUUc=B64fos&+n2^X7g@OJ#V6a4l-?y_X z{3~BRB|%uQ4dB;B7mAIYULr0jzc$YrJbwyXG=>kPar?+sIjaPhK_x#S-~|N&#Gzz2 zoiz%B!}NeEe?#B2lY_$$V8K(r`?csh`0 zH8`{3ycU#ycDVVYdDp)5fKo&;v%mB&i!lX2@pf1A2>R|nr@5h)BduRi((_qcSuz`XXd98<4WuCkF@rVz zvuW*e0Lf(hygo>NrEC>jYW`?Pe({nL{k2GSMn*5<2serAXTw4fG_*u1CJTi8LqT25NheJje+&iLy-8Ct+wi+nW*ll7@DfJD!YH#5-(t4q;c(N*^W ztC$w{zyVYGgnnS3Pd?d9Kgf+}f!a<4?M$hSx=Bd{JO#G5Z7rm5Eb-9lg-O09Pk02N`!u1YH^;F3JE(#ul&y@x(A;_tMW@C%J=` zE-d6ga)kxvr;4mT0P#>g#rFDveqC3H#I3GKqu}`7-U;p$GEXr*c!%d+q3~A;b(q{| zo!%*wMt|PQZ0)1Oq0c_cZ2EYg152nkI};wMqnUP2!P4;SU}2F_M54|}&Cx}q(Imum z_?$lNa1#`1q<9n`$c|*QP;OA@u|8$L-+NSyxt zfU|IzwxVq+E#viX?TI8-<=bpcd&0W=U4hK~tPo%^0kmO~iDA|UY{&~9PHj+EIrhr6 z+YbZ`V@ph0ij!U&te|*<`EkRLO2vRr>BijztHm6B^ibVb@g(WXiU(v{T-Uv#>Qh+K z-9=cz*XPH(mq}RZ5N8HhEUF9W$Q;6HUpN{vobaO9PCtvGUSf;d&_c@eGbD=w;LhyqC79-ubIA0O2+<%ALzor6X5ek2u!9`ukh_s6{dfD4F8?xq zkztZh%s*U{5~*g9f1n^YT7VK-#Z+Ino0}G-f%646li-<7pWO=Y z&L%ZaMC@_E7JPd+wc8yog}<JLtto#7!jC5W2@){LjR! zY{NpNt{I{9b*cwck$XgOv?o}?=!(dBw92I>HM#J)l;Y5@#_}-Qpfqb@hhzg4pd3t3 zQ)x&eJH_^VCGC!@UVWbH7Y=UOaKQVX_m?xGG8RajUF4sVxr11 z8=MkYj?{-fiuLmjAri?aua<5%o!igRE+l&$6j`P%MPp1cy!8_Mh>N98maOP|%-{(( z5@$JOxkAWCiXM5qjHS9dK2#uCSKD*cNQ3MbJ~XOfqd&iC3E|fz@DQ@;1K}>Doj+1t zenPMa1NCbj3t{+_!i>eCPNbG*AEzCX43fQ3e;s2Tq2hqmbTEL2#^id9$M565jc>BH zDBzDT8950oR*sz5@9#oR2`$e#Ik}YTkPq1yE=Zp=9p!y2?NgZOaIvO1*9>I2)5+`* zuM(MDGazQ;5mcO5UbRtYzYLd}91(w))W<1md6hi#O}Y6==G@)YN^=((8In?PS&**y zf-cql3kn;CRB?5gKtNh??GUKjQJ~Wt{8PA?=oYdbLUtR0JcDS#?gw8hR|F=kqUa69 zeCD?Uzk?iBX}f^_WLCQDEFG~Im}>-TA*k!3+_5tyAn9e}(xgeS{O@=O1DQ8g6zrTY zomk#Xzlgr*f4YDOgjf~QxPWejd@`CBQ;~h|>?4%HTa0L6jAJ;uxVc1HwSzwJB#S`c zj_IfVGN^1%;dQ`McHZD)$^n-TiL})e7kNmTDpqwt05=pchb5WK@~k;&UBm%jgl;89 zvK(97T8g`E#g@tfk8VhmQ;RIef^I%OX;d6}ghbfx-N}lzVXW;(P1<~DCeG0PV=AH3 zwA<1pNbVQfAyoWw{cPsgpsx8S@sx$(tnF<{8#yn|kACDTDc=-7+#IaQTWA%p^7WGer1{Wxd-TFBf`tV;xfhO8z zkJKc!;U;)YA;El@OrZ;#om1k-0jVn&IJJ51p5>5~egUleu$E*3KF`PsPR5$3+A3T( z0kju2>+BdVd0b=}tw=AuZd4Hq3uFYzoKXddP9#9FmX;PNNW=$KK;Dits>+q{AY<<( zt7A_N7xMDSHxV3C|8AF0QTj|Hr)(g|?cO*2RWu=JIe`}h^vGg& zPn?Y15Kn&2Dl=$pxw4K$OC@e*>lO6?CTqrA`Ltm;i#U*8h>Rp}<1q&6cT(n$NZB0IYRa2RCtMXInl2gxsR&zf!rsJ-;$mZ&xTT;;3zBVs6&!0&J{94 zHmahSWDr>03}@`r)DjRd$nKFeojM9e@?YswgNwi{j_hbG-Ryem@&KqDwHVY90{dy9 ziSGTFtwkG&GI{KH>x{*EeRO=F7SYmSYI+{WK1~eBG zZvbPhD#DIUrWc6z9ul(-N-ZR9KPQ0h)aMtkm#$L|`VSx77u?XG*029*S!Sg*3W+Q7 z%6!k4R4=Vgw+Q7#hpbsTygOp196H0cq+GvKgB@r)8>Eyy#q<3WS1%5kMyhfGyl`?j z+P!$AYBg-gL}e)Q!|2;)>EUjr5t=?y{>~W~6cuZkz>kQ45P>6~4p>!V!cYvy3T1_2 zlV!R#=nC9W|1wVGn}!!^0Kn~3`s1qCr=tjLWLHFhM=Kzw-<;jOPw8+8c$8>CAma5j zPzW#$Yi-Pp&D}54pC8SD19wsJq$%Q#30vt=apNu2fG`>H*ui)Lbs1<=8UR+#y!}nx{9hoxkzis7-R2IG?GqK*WRLs&InZ@pi;x$f|J^>AO59Py|PqvxszK~ zG4N?6y?--e@J+32u~VoQIpONZ9u>M6zIvrHk;D2;?!1Ai_qukSG6kHv)wdJ0B^2ZIo z>GVT8%HbxNu9ac_`6}D3lO0TO-_el8N-io|M~1U!Gt}}?5u(Tiyu>GOODB|wrVbaq ziGh}T12_S#6O-mDvCm(>HZ7sTyQkD4iA4u6lejz^Ip!?$L6J6g9$Wnw8n9|XLYtk3 zdfFV8VDef#lsKaB+OduHfVZq_*WMZl6m&ih?$}8hXwlcrT(A9k3*(`7vh{t1FogLp ztF?lZ?F`L1>66AQALK@6BD4PTy=gaI+$Rgw)FrB4PFy;nvq=l3+t@7g!Pu0x7D zN%GtB3!C}Vp>JO!_w<6WF0&!mS=Fg^^Y4~EY1isx-GurPA=(%?w81F6Tc*>&nl)HQh86|2#%3{v5mY{JBeAG9{&<64<0-49DLE0g)6JNh0mWz~@P1*;$aI+{*xrPUkko?R0` zlCYAmead55Ru2om?@e4C7^~z1euok>28#DJqFDYlLZMInVnHfY9&)0~~<1cH6~0;n?1x0a(jV4@^>*W1vDpfjTy`t|Ug*tF#zjS((K zfdF8bek4caYSkHIrGT)u0-#R0Dk@w>KRzG{rf`&NyC4$Gu2}Y zqt-Qr1+C_U(5-9LMf~&iT!7lcu(L$N410df=%45#Mk|$!+q#@QXf99BlEmH2vRkV{ zrLt1-nUu?*ec>I{d*|_1K4m36>tn41D3v8jXF8c?N|5GtBZ8vJNzNEhO#m%{6R~|- zJf|lyPqK8Ml@(*-7%eZ?gPJjYi!~4f8GuF`)~W^U&9xv8jIntb#rCgSADx#wyJEVl zEtjkzPVM>~&J!vi5dEFuF68L9K3XT<824+aNl>%R;Obo(C%)%(?r@&8z1;g`y?qjo zy}w`!J*ycod}LOM50h+8Qx&h897>CGQ3_$-!1Pa0leXDW>8^!ebJ%#CvhvisVFGqR ze$RHfU}8|gKPx8XBxOQO3KskrXI#HYB1!aB{n%=EEB$7{TueQ2Yj)fk#7=|@plE_j zRRt4utK!;jV29$K%FBJi`;Wjtn*2V=6YX~w4- zEB~f1TlrNgnYCjun}(Dx$eU{JhZtE?&}VBKV+Duwq%Bdkr=VDxdV1Z;$iftN?VYmX zghDA><#rFODFET$x`?W2WGbTeWUNF$7rcV%b+2_?<<{wSHK%w|<<%i@Jw0!^4HJ(o zTF=M_=mL>MEG(s8%!a9d$x~P6|HnD#2S_U+H|RZct#C9afQ+4lPeJoqXmSS1R~Fkx z5h|}AP>VPNy%JZ^sf+NEZ*3G+kzS zHX?xo0tf>$$$NjeQn$_A*$+J-03Ml3EGan{1#-X+T-A9QYzRNt`u zY>P>aSnR(22UfL~zGQpqI`&}y-Vq{{gQv6Pj>iT@11@3?2xj0~gS;{Bg)kZOhlFAL zMb9ctO3Ai|b)kgOvAHhcO1Qw$e(f8KhDq#-#c9up@W-h7#9X%^9BZF!O|7^fB>W+f zF3zo;WZgyEbOgAI3PO5;f%@spkyec=tJ}hS_aZ`vYyu2GY?xx98)i94`U`s)$G+J>o`(S=qHPYrg;fJcgP$x;215@N0Q|~2p705cJcA3rZx`4=2smUM zd*~Gl1PJtn*U*tu_a{W4icaOpj4pLG>-Mfewv3OFMkyR=B8J(oABX((SYOl5LQO@5 z2Vz0;YI(LMW6;*yN^-=GntIpBMYax+GO-vvykysGMRt0|`h#!cyz_&1MWd$e zW&fE;Jr~Cj0^(UrE7{8&mdC%fxqu2UhHaX&vTd)Ujy^-g0JZhB zR?Q=%WXh2TqQLT;z7xF#_QLmg&qH2YGpd@fUjajphu^PP_2O86BjAW9r{R0)vo`c& znSNOfmtHK$hZem^$WiDQ^$CG$M1U(qonxCAqNvh9h*LPdDg!tg0I>qNKq>2Ct+9q! z-Agzn4#dr2p{#?Ig~omlPPIt^&|t`AO&Ta-C;y`(3$s*YY6BD`*t9M)F4>MauI7q* zVYH`C_7!6k_M#$&WW;4C{r4)~qU8@ztXI=bxC6wI<-;->D&s>19;w=XCJEh_6cAD} zDy|AZ7~ozxSeH$mNO~b9L>^bT%?)wT+Fu1|G)`f?y!R^hMSS@29LUK^-N}r7g7}T} za7dfefXWlM3)Y}kgH@eROuRwjrh|rBanF=8hBvlfNCP0if?mwrOh0_ue)V(3o^A??2uQDK^>NVp*)-PK2E4N$Z0uxTf#e%NhlW^8|Y z`#g5u+{I^L*X4Or(T0KJLS%&bFe{ErJM`lb;NyIjbn?%2%pKws`2C_DugYp9_zK>FFKRdc48Q|0Cz> z0bawjh3sr0sL?j3z0Kd>G-rMP@pWgXHvGN&W;&kth^BksvL7d2Xa4`kw|CKcn^%HG z8`+2kQ38LcHPw2NTEFi6EAT2aqp$}_u6-r|q_8gz8|YQ^QJ@R$c+g`+_U%QBzHgX( z5eApqz`WXjOdTEdn9`cf%;7fWmf*NA8iK%*T^!AMxdAqg%ob~`k<(iVqm3P;rjZ)2 zdkpU@38K77SjXp+7|h*?Km=m1_0ve zNPDy);-Tih!dB8c zp7vJ^1X-Lam}+yk=RFX>DX@l^nw*3S>~a|^SJ-PVz!iIEIbqJ`wXbfsr(IUP3niS( z4~NHbaTK@^8=P_GI?}1fFol(BK%R13u9NVxV?MrYd>0;{5|(QokstV#kG|IUhj>~a z7x{U4`RDiOCmc0srgAGTPki(7f`-@RQY*h3Zj9O>e{{h|@6fjWLXwxjLze9r~2k$w+#yyWitp?JLdn0P24eMVhC(WP;*Yc~o1VxHLO@Ji!)GWTXX2~1V1vSo_x7vOO} z{ehZ(PcNft#sW{&S--<~dF4?*mi{)VHqtUuwtSM&`nLQh->qf6a=~7US6E>v$xQIY z8XLRwy}b;ilzU|N%Gn{?(fmV1%Vi_Z+dBo#?83}3=(HIN)9?r zZWxoE-s@}mlh!!NL4+ZdX!GZIZ~KGF5K5JdH-ggLUU-#UzCnWW#6MCaJ2LNFA^XRC z3DqOYy0{dw$3&xr&j4`6D8F<2_l#*s8qD2hhx?Q{*rMjD5cqHT#GD~u4M;5v`-llO zv#5q@%-P}UpeOWTM(4p`HX6|{Y=3bxD~CVLwDo~e{gtLwLkP3#pzU4^2~}H$K7}rvm96?5(?f2Lh0NokkT!9VHjs9$@$?v^qz6t1xB9|b6pwG=q>kueU$F~CbcQ9{H5Yu zZZi^Pf6zEpL0|#=#k3@NXTpR;XU?kK3B5nNpX%G3Qvp+{)wli-gj~O`OnvNt0Tip1 z0M;QxeQ!#OLZh$F!~+(?)`FF`N0ym3Dtwzk+DYI%^HgnPbLHP{oosc$B{n=5D=AHj zpis&Da^sO(6tMJ;T%!8f=H|uj9I4Yh&d=Ak0i-@BSt#)W$!%+`*~A^Z)Cft6D5G|# z(K|vobP^h=N=ri{7GUytp;nxB z)~j2KMvv>p+T+89)uEGn}9opB{AbFvaa^K*%h)i>j`hxDX;&sJN%GiLkC!5XU~ zInv9i%rgv3!lj0#i-h*v-8iM<)Zqn<20cBi|49CaMMoegK!B3T*tE}u+%2^Art&wa z5kZI6&;kNwDpZ8oWRWHbXXZ$z`d*-s|O(<@J zV{8h0HkaNr;kS@FNK^_``F+RybiyP!vM5C9Lo{0(vC0a7WQ%Y4wD{ilcBHi#CCL(p^_(!E?zLe%% zW8twiW@K*K>(G|lB2MtxL)cTWQeBS;&J?daHr(33IOrzs#sZ3z9W$L6cYJYHwcW;U zhOTVXstfNwW0ssMR8@TwG~-mGC_(p{qV1qg1x@Kma1U zZOe_#CKjxP7ni3#Gt{ek%vg0|=V0f_cL?XKIanw-P;kU}F`7%eHnrsxvO&dsA_Y>F zo57JnXEBXR3)>_g3`G(L&fW+^HgWe zrPrga%NSjnvb`FmjI9?pZ#O~@HJwB?+qW^jw~c{dl?(0>M5pJ?3u6vqykz{P!`tU- zvci>n!aPZXNZ0cJBp^I|KfLa&4il+sagPCZ)z^*z8~w4)D_Gc81sGy_a%fF^>V`dt zz>4mFv0j%VttuBS7i)38y!~2ZeI;WsVgZR29j9$TT~ZCRm-< zim!R37;HI6Zre^zLE4tr+&}T}y?QQ*M2DnJ99~R6T%6Nmt(L3E#OmrAXKJW`xf%~H zs&>c0ibwkHYtKSnW)WTk%nVuDNATmbU--e-MRnyI&r*`0O?r3X2_1> zZ_DOJZ168EC-O?ym4=y$cWxiwNn_N(26cnIFI%7|)i_}uP&nYW)gR&#kJzdx`;eX2 zrm(=J*K8ZRta0y>VXN6f?O07d#14p3v1ib6Ju{bX_z%9y2fQ=YL!eqMd@l^*mK604I zVOW2Fi0_kd)H`?j#!S>K+NKtrS@d}$6GzEi?K81C!>CvGuJ%u^w%MxotQ=8V67t=3 zx}50UTXom9wKK9nQYBD>Y4~!gCTg7Z21|uGGs*Op88qQ(Wv#4mJHM^FcO8aEU{S~0 z3h_%-`&y_gYhr_Ds|iQ)8wNMp^DpQEBec<0J|OQ@b7rw*P!~ z`K?i)2|2QT*Dt(z2~m}MspObwIBTx`$4l_Sx7$5&TY*r*1cjIuCN~1HBlp@ur_0Kq z&Kc6k-X7&;fs=5f?rqG>y(g5o3xKLPQ z)8>(-Y&TV8jk)9T&XsCYpDW5QU46$Ldr&;+4=xdJ8I#O0d{ObWD-uT-Cz5?_YPX)L z@yHX7T-r<~;@n!oavK@-rMa{dq}il639Akk|32+|Hc4TFhYYcFcU+L+UCl7I!)kA- z{aA%Du`4z|gSTv5f~b?frZ`0~T;ro@&MDzHXhMk^4?39YeIq&g*a60`}sX zKI5}4TjwNO=`#0zX(rK_I(_~l_=4-~9`-MhHIb*6j41L?y~T*RYtL-oOkX)%8kz;d zz2*Gly2VdX;3SfHLr3aOaIDp0WhIvd;dzzVYg@>W;_GDnmtOcZF2jcpAmPTPecJq+kvSTMe1agazY`-&;^$6M*}zXboK!6t z7D!e5FTDMDJ?P`>j|Djr~_cRJ*nZ9i*b%7;)-n z74NXMt5QQ)atkyx*z@846TJ$YE4 z(or1(w|*e-zZW{Ocy7H_g_ric|L;F!>4pJ@i$khr4(Vm)1Feef-Wg(+tkwS$2m5Ga z%E!;iv4vKDOHJDqK$Y9%nxCD6-~ZdOdB?hmg;*?NW6CY#2yb4?`rkv!nw{=XH>zkR%+Lkif-oDRA!Es)!FXR z1zo*RUtCmat95^ZM;{1Y`z{|~z4(soaRuHdswp0r-mCG#M7B|<8j0lql`dPJpZ{OK zq23QYN#Rf z=pjs|fkKmdC%id^Pys)ZausWUZE~HZpqiP8h@+6)7IUbMav;_&=c~@@fAO%ybRNVn zP7Agq>Ne^Lla&OkJbUdW)_mFoVAA0U8JnW911l`L_Ks?&&Sr zzwXMK!&}9VPYE1EGEqz>fml%mGon)C1uX^Tykke-k9H+fQB%odl%@E1W1l0vAV{}ykcu(qmHnRsMDX2?E2_ZOqWmF$ocR|Im`sh;n z_o3s2)zYDjcN5}N6zO+w3G@0 zcM4i8cUs%x)2$7kuMhux)zuaA^sa7?d%w$gdHw26Fp^f#sv!fT?uM`P{jY3uYy4*d zCb*nWJ-@EBrPs3=NsDy)K~uqH_}CsZtgW>=G!m(u7p65#e)Oakg*0@Bzp=*`%K(W4vh7A^ z5)?cr!LlycQ*PE7v>2cNzlm&gxDFT$uzD$>7ig$wY<}V9W@Bk0>268l`bM`bSyo@C zIdU9A)_t47SQ1+@a&cd)>gR4Q3W4j-lh}Z8EF4(M6gi+QxJeN(Bw4D=J6uprV-brb zF@0Lm8u|#pdlj1bzcFn<`M$^ebID7&;L-ltk_lVry57l^rV4Y&0beF5_KN{N>FHza z^5kWeKBYFDU0U<61%d$NRo>J>!!602S3ovRH>`Q{F4Sw_d6w9xzf%?czw-;@^CX8Y zhps8VNvL*FE4Kg74G9JjqW}i)^7Hcg+4IZTkFMmI1RIz!(O=WbXMtsKIijvu|C9QQ z&Zjv5l!`2OV(N`3k@qCM)4ra;q|R?4fyMxy0VLi8baZYOd=SM6T{Tjb`IgL%69k?)eBy z!SedoJ({g=GpY+}L@F2-^qI91VC;!0ClEco?zF1XN&Bzdlu8nZA{CvoAdA$7%HtYj z>i38`>>59DELl{6vQz`Dh8%xKADbil*ir|H{{@SGH1&?R_AUkbQCJ}-L8ShtGQ$ue0jZLgMl3RH zoHv*My`&mgXHHcO#&>=0HXRG5xp*)P(gNx$z@9dUpwrqeNaSiM-Q5r{Y34+7J?BC^ z_JK+Y!zKawoPZ#3Qm8xP2q z-=Mc7kUjNBGU*EnRKo_k3z_6}mKNO7-Lf`t1)ycrS&Ukhu=SL%LlVkr*2%*e(Spa{ z4-{VC-M6)rYa^sp!({-*+E&I(juAaEIdjhO^Q9#j<7=XNBW&%@LducryAS#TaU+ef zqmN~_XsD?Eohqs1a_p=Fq~=tDcFn53(OP6Crzo+?#2}z#V0aK#t3r8QzVUtKd8Q$c+ zHpu)!d%KDkL-ONfl(GyLh=OFaMhcVGguC599)Rm?13Fmhh>qN* zE0O2n^|-w)J}|wcW-e_ARfFT9u2H4^^n<#&KaOes;h}72W~M9K*3u!75*?YkMkM_pfCT>Zl~zl9YW?)d@4a}d znTWXc?e5~R8V6chrBDjdM99`|M0aT|^5T=<+a%WdB;DpyR1Mps(w(K6(pY zE9Ykg050Pcd2jX(RT$~65V;vkeUmpkg4+$K=*s%`4>o=#(fWmZB z&YRmgU)O1siOTI2)$Yijd}2~j=*y2!ln<7My-M~;9M}Gv?=L?i-v)ePzG(M>O>R)5 z6mBdXo!zNc{PSj1>Lb)fKy*6wIM+Ymyt}IaYty~qFV?$ zy(_Binc2z?mWe$h^1j~aczj|||4^m`BilOIv1Q8huM`t3p}@f}Q_h{;K0D~tecr|t zE26{wNX{{@Gf~#UiQhhxor$QwVwB%u@IX-*HTo}YeMla`PI5$Y@ws91NLOgF{B^Gb zm#?2(6vKUkQTc+0+jp|r2@{3Ww1uivWJ|ZQmm5E}g`A#p|3n60t=iS+NgL}@&ZAGW zb6~??bXRL`^Hnn|Fpff%7w>5wzP`eL;L0EgFvwN~MSAQP)h>-fkRPOo?2|-`i<&d5 zG82;gW^c=+UkDP+B$3@Mt$XpM!;w-G4x^qyfHbLw$@Y(Z72XIUfWi>@Q~ z=wa@~m6eAuXu|XJy6AnUL*ZFi#}uad3uVp*60ckk$sKSr9urmj2F|i}=gZUv!6;g^ z0$fgww&m+I~ zX64~CZVsaE|6#|MA&-phq4c8%>esq)+AXZ306#F$f2V~DnV8y~=WD;)7c!2W9`(#Q ztVq<2VriqfBZV&7jgm0!pk(4q5e(o$<*;_W$RM%4PEr}L%F29li?yz%Go zsfneJfqkd25rk@Nx?nws@C!00Z10}`TM`!kA(|r31WCO^mcAG@%|^S2<2GO0kd=19 zalYczwi^c^YZC7#PZm)YF=2*VP@OiTGunpP-rc?p-fdw~4{^EQe)Hivo4kG&wC->z zW_A`$-W114pgB>h3|hF7z>H&a1CY(6(HgGZ&zz+C?3m4T8Js^- zJcPX*YO-36^e}tXnPAq?DxW4tM|2ynPJG>RR8u#ek44s92_y0nI^Z3tz2xg}J6r@& znxNaf^+WuwTElw=KVbDd4T`R4a(u$Si_CTb6H7> zZEY=h>uFvcPCk3~fP1K~^cT^gQFXJ&53d%st@80g=>!|@V;=dFbt^XHt;^d16_(k* zq7nW8U3=?WpH;>xr?fp?Z+Svm&|Oh7;QwTyDlb1z9I3~U#{l!dpA#J# zTL;Irp99i^dstSOayeQ^J|I?OgOqa)I_!}~ww@j=1m6+0>u~RGH*cJA-6{{t~Ze^^Y!~8W1c(#LAs{sva&bAheyXN$I6%T z?QiV+eJ+rzI@0|oyT?Orl8K3(r20BhTgkelI2Hw+(P?NwMk~LrwK6k2q1Y`nP@$pJ zt}kxn00zY@c}?7W`~tkN*HcuzC_Q<$)c%TpCZQf6gEo*%O8ho5B#!$JNiw^;Z@2ug z+_w~>igwyhA)!9ftyJH(jQJA6$JPu@?mxtqZ#liqFr^^%i4^)R6Buo6Ys5vxzW#-q z#N!~NyR-9ipX$aST(oLi2R26A0j46exdTch|F~LM6aTzDu%AduLqu)dibRW!)}Dac zp9f=(>&Xr9kK7T;_z&GZQ*3_q+{Fi$k1ZkO^>^Nv0(+b$(99AIgm9-RW1Y-+(!M!( zySA|WfU9cv@Ske(1~8y*96#J}Mj)p8d^Kv+jjNcKI`xoG=@sgna+)VWuA?rKdw)n! zgkAubP9qme3=9+&s=9|&+c{j_dI})?_%;0r{pZC~8v0rEsR$-`=Gp*^j}WEa8ksI! z2G1{(M2Z-~^qg}510_?!r35)7CX`iaGjGq!_qM;gJ2;D-lTd&eMOJB2r_J;^c1_Uh zl@r&1kI7iU6%Lngduz*0mFCzw9{6aeNIYbHsCgM!N7MxOJ-S>gc0 zOr-y`qiBC|YkxIR;`6Dlc{#KC(Zqy-Fb{UNCwd=vK7D^PxbA3=wlNBT+mul0uEMM! zH)jJ7H^3Az%3$^(!tT)VAq)&41!sOI8)j=Pj6i2;X?fYQ!9Feo_l}fZ->Vw(qXKpnt|7D7<*O0!ky9lj5o;nSjC0I&%^+P2J*f%Gy<=P158hY>cZsi^zC+y{b;f9PNntj{Z%*7Y)9AI=8O)zjd!E!^$+ zdOUyN960dcE(u`>;MuVt%ATC=eH9Wk9Dwfp=?qbnkUk*RxwH}q+2CaFMaOg9Qj-F<xK($a}6atKjY9+XVFm;-agvHsG4GV_2c#JQbiyb3`4RM;B0^t4YA0<{9rEUTQEw|O-;pL zZUD1tno?cdUHg)&1n&tL_{sX)QpvNP3j$Ren3E+x=hxK)#7Fi1XoPD^Xqf46v4C~^i8c^Tz-FfeUpP( zm<%zu>;URx7KXA!oWM2tC;Eb~WuC^{ZIIFc;5}*uz=2eB|+l6=#e|%D$#3VwsH1!mK`x-7k+7b8eNZbNr1Cz76SNy`t z#kU6%+P?c0Ov5Z-=6*Qa{_nG7Thv)rUfm{tJCAO*6%YcDXK46?4oX#7M`;;lbxl>q zA55zZXwVh7uXT4`8&(Hc ztVs2Cd3}3(2dguhOe{meG^6B>MUZhc7%i{Pe!RZES}*V5;PeMQbQo%IUr10xXL-B2 zy}7zrtya-`RVvnSGL{QSXoila(faQC{Py-XFZd4VEX62be92(gA5_pzMO~)Lt9P(H zC74KwE#mF+_Ui2JZUMkyGp)FY5nv2lDAjb>-p%3)Sg$!f1m?nT0%ur=;s!y6(+-32 z{>Ph}>(z46=w81cz~@bKSV2UY%t^I37?Psfy~!awCdalZrFn)5?hsG7gVA^lTyCXA zbeqhD8gStl(LPY7i0>}n-7Hp>ur76(#~WDI^TlF?QE;3T5Ai^(9fry!d$IN{X!kGN z>nvK|;zl4olo1RDUi|Ra|6D{>FhDR@Byn6rrs!lK^4Xx#%gf8ndU1PwnN&)DG7EhV z)no~nczFX60(c3@SYDr9FSCD^?a2KEyIt*Ssu1(0-m zeUX+b;?%&i#T;UGSOf%5B1el??=H^HSBtv{vD#>&OWAfC?XTH_h@@o!K?X0;ONi?_ z&Jmu%nGh@7J4WCiGy$ARQ)mR5QSxL31Han9+ZAGxr(p2a<;7+jQ_$NElcDT3NYTJx za2UVu)IfX$OXKz8>iY5$Qi^IY`s;V!{qWrnnQZlXex1d@HKGsaB2S?zXFuHB-mX_S zcel5a;f^LVm`SjW48A&tlops^FgRY{od0-rbDQVc>h}Ed>KZ;S8l)n`RD>H`Dqtzm zS<#=po~qPJ37!FzMM4-dncAj?u#yjkS&aP_3|_&Dy1u@KRu+;q81>5(Q3S(T%Jcox z);+?_O|(4!{;&UWw~7PRCH(w9#>d2Dmh zf9lAGzS7qv#LTWO|JzVLbRbr=7xrZC{b_1dS-DB7EU$r|7+suIH>>PwUGiBv^Vv1Mo_Rd6 z=Og=cWWkuF1xmuNud}?dUGtk`?{s3nI&j~Nx#0$2?)B_{J8}EAg0Q*Zvfuz=9Gq8K zHNxS1dTp03 zM#B(|@}U!&EOQu!EQZ68LQmrD1~4u-)>56utMz&-(Hbg3JmLD~Dq?Wll597t1?&YQ z7$Gd6ief{lLG)CnnQHfEN5_F{0)aM*>ziwcz5^HsSR**aC}4=vcmrQ@eDHeM40l1|J{U0p;%LA$r`Rb*ZOTW*{pN;1@wr;LuXK)t{0a# zH+PB&xyUezs=+AKx&jMVP}lkCpO20Xxz;n7P0|0s1fu|wYKAkMy&4aCRl3=%Znzk#-k-ny{`PJG+eyIX>M3xE_7&~o7eEgP;$&GiJYuLKuxYcpOVSG7v2Yn6 zLhvI9Qbo==#l+oQoWX0c9Sfo1HqH>H!4~8hz@&5sN3;1H@}%1Vm(-`6G@K|dy z)IgaLBV^_HpEm4bxlVCQm900M2&2|i38og)syXA6um3!oj4aFTPYx&3*>8q|<8im_3GgzDj2S!p_gF2v=; zx&p5Ia#>W0&UD0(W)x_Z6!)PtgFG0RQl{)|S9fXAP%9fcc6qH1X0IpX5u#?>A5IUB zTCE%mLa-O|j5!oiNmrn3wBh`CJnF+~L%on^cB;$)6mYU2^3b!qs5MnS2$WO*Ll2yG z65bs613QZOjiT5LX4CNqmSekKWTo7nyn=G^QJ`3u?)8U*(ZsV2%#b&jPbZTm2Pi!( z{F3g+NzH;g5pCBJW^I0`H`$YC0KO%UEh);Rcbn!sYSy__Hhf9T#kRRgo2+KKw@oIU zZ5!xE3BZLTB};iF!JjptL#4bexahygq(aJg(*KHiFljAlkzGL7k#F z;-(9@Xh7r`fQx8*ynH;l6=(}F#&(kxB?P@d z9Di|6(HBqxk)vQGNtQxlwmZ02G(JUWV#Mt+mHAN)Coi(GA2L)*CuMoGuXh3^UVedObkM$ut4ZQnrx$O#Bo7q72WR-lwy5(b{1!4 z;40ttl%{B|(tUBFI}8+n5HbM2JVyZE$lR2XZs4b$A<6-MVodPKVRh3iV-r!7r)Y4E zNdnNL8yE$GAq*Lg9-@HN@(yLdVBWaAT`o6@W*NGi#Sv5ohSv*1x!T@conKvCz@myK zV11To4wFu63WhL1C%e%>c&v+?D{&QUScC1H6!^QEhPhuLv>EHuNx2q-mU;esUVWI&Oh~(BQSjWb4e9!Z01V6V6N!40>1vJAC0APzI&TuJ1 zSVsqtVGst0x+quhg9IlHC-fbCaryRcwcT^J0Q-t&*nWS~?|Jd^n(JCBOiG17=KAsq z0$jpPDAL6hBBv!>X-W%Z2?O13@K>~1LOdWQ+y#JvLkl)bI7}$RMUpaI-Cl2_%rLo( z3-&_M8rk%GH{aeu)Dh(%BB9l;3Ph)y^(N0ThwCIow=www$1Ab|GK|h(jyQL~CiI;C zF*FDU<7}~5B=FI8Qo4Y~0A!|4wX#I;3;z&gm+#+hlH9hGZ~C$! z_O^%+yCwe1a31Oqr!;n()n>Z^qY4BomuO<035iOeqSse&cHyo8b}*3bhL<2JLb=WW z5nR7`An0wn#T0Be%guVZf$k&12bx@;Kgk6&^_62+dcUeKp=RQKm`|7}j)|hc&*&rK zq_%Qg6+6BlqrBP`x>A+`3m7Hci1`yZbLpP!wpaoZfSig8q(8w$- zo)mBy1HPUY1acWcCTdBn263Sc*Z4dE1sNQ&Rjv=P1@2;|QGB4?RZ_bZ{=SQX1^BkR zQ7i<9#Q84?SovvBLJB2BAeTKYe4@>vuo= zm~dI?35mE-!CfHnmBc36e(pwrI@!So;#J;B2HZEu|G`#p5?>#N4p%-Fdodh#29Uh_%3hO$T=RPv5<9f}h%bTztcQ;iSQ6j(rCsvIjqIeDi@JvQ ze{gbKuHT)XUyBti(FAOcxNoNe?O<3lTgQ00NVEIx@glFGZ|xfH{V3SrJ@ea=_ua;4 zbdSG@I|UPK$?``Br>}=SFS>dA{rBI)b>$>+R>*+e@OMqz_eV5>Z=yEQ8Aa>QUQY+s z)sKI@Tem9@J5qI9>}s2-#p>;M|G8LkDV&ptI>e$-+i%frHYfV|Kx{(%OAd2t?pcc8 zD8LjaavM`7qy!z3{Nd4T8r+@z?Ph_XM6|%EppbxCZtS|X)cml;a0FMf20IT_t|^{dZATg|6~-C@nVi58G!5+4cpuwVy<1gzUA=?dJY|2E`>7 z<6N+9uxTgxqP880GNRtL%C;I&%M$}&>5`*LQ6Z&JWoKCJemm!1w}Cl%sz`}eOOI6MMfI}Lsmy0xiVf*Gw1h>=iye3Z)jDnIW+e!n;6fxf4jUWc9#wV|Jj>wD~?ROXc zZY1lL7xcM{4B;q($j?!SkC3b&j6e_%AG~#+9|+>)^@grvq?-jCa5}iZBcXCdHyzv3 z;r(V19wOJ@mlVqj!yaP3bS=V&U&vrpcU+JA%|y5iRy&#uYYn9R`_j$;JlLH-8Zdqx zq0?Vhhkt@vYmN`Ub{_tojM>T37bi?#D*gVt+luAC>~#K93p7GD62_?V#9%wpFNXfv zCIlh|A^YWW_Hg6hlQCitpxxJhaDwE67*~ISaCKMoAC!K7cK_P?zYtOQ6p7)3c3=Ow zX!j7fRfE6JAomokUB%*u_WMf&i^W6OpXf6x_9|X+r@IjUW z&2pItq1o-7|0tm$oktx}tj54S-{USqZqp`#Ex~X$nT+*aQkS0~o{pIw5Bq+VC$i~} z=O^RI*wo}AOUWErwcWsVtg_^8rB6wq!sX=9P$Y~95~Ap)7xGka!HpuaE_T2%#R50k zRk-FeHBI)==U+nT7?0Dzl@2cc7>QJdpvSL_3VpsMIz&@%x7hBuxck0%pI z5&GiwXOr0sg3)gF+}-dog1`g)q1VJHgEgUAsEJ`(_|i1uIE^6ujw#SgG|7WU=oX(2 zeuAKhh7F@4Ka}Awj;`UC-)#k5(KW;7qwimdhpM5OwkFjd!D~fVdFdyc09S2@cFU+n z)|}DoDD1L5rco6YlB-?+us$<^dX!EaD!R9ese;V&<3cd z(8|Vidy|8s;b3SPI`?|MI1p}{>M*Y1K{j9P!xrmuub&m(L%_wVMEN=H$!8K;`HFib9sUWUA5dW z?DZYXR#A^;_D1tw=oaxd%?lmZ`r|P0cxG3zhDYCg^X=E3$njEEl6imr76ySOMH9Lr zt5!HaIx?DEwg=Pcs7&HUcY1>X=8Y+R!s+3wSB_FF7u=t2yPg5BLe(wXMkA;P1LkhHSJ_?04XOn zNosHU>Z?Ef+rYC*Zfum?keS-#GL7O)clw84{kK2;x4#TSJKL`FS|3d3o~3~KFcuK_ za4>Xjt7aZ1v^NOCo^2ZS?&Q%UL2tcq*c16@&|)w;eDml3@%qgxODVVOjS)-_4kpF+ zZoN&>wIJ*}u4gh+U!_tKcxsx7V>tT^b6k~TGO7k1M0Dd+`}rDIq*uz#?Ao9R%iud+i^9yVop5O#3bmN zt~3C8=o?WFv&!<$(Dk5$u(aY%9cmgFFfVzAxq_XAhoEz(5?ElO2fRfy#J?&;9>$2t z9c4{?wqTv8Otis{ZaUo2hB|4D99-okNmaeEJD57Uurb`^!hY{aHKBhxY!b%VV1PPX zHw-u)ET&uRwr&XTQd4c;vMi;_xL*{;!18ocG|{jLum8{ldM8GK+t5{-4OfSGVBc!l z>e<1_;-Q0q}V^oO2fHFd?K-~9pS*CBucscgUB z>k+joblVMse&6#PYO!ifPQU&7o3C9>fgj=a4^Lj5xDMLsDa>nEx#1vyd5|FDHB3ba zWpo|r5l1nc4F|nCi{m82WC#5b1fG18lwflD^`HN3=+oUPfCe^(IJ8X-R)!^^jJ+Pz zzvA}jM^4GI-Vcvv;Yed>T-LJD_lCNJ;RKiyO*Q(#40-~wDC^30=BJ}0O_FSrsc0m{ zo%Byeu2%zJ@>Fws!_h#>Fcm5ME6zKKbfvCfNx*jMEIJr*Gbbj-E!_tX6u%pRl9fe`kV2dl+}U?9@BY5mFEHe@rH40~?6S!eB829Tom=Wkwr{mo#=ypL60I>V#m)6?N_s4Hb& ztJ9Nj=JRQ9FvNTTbOy82@xY5$w^3U455B@EdJu@FKuN&b$?<_MarbDcVnV*2&*vfY zRb}?z_|;cmqccoTmglfrA`6>m>-AeSWcB;F)hDe`m8G9V`CntkpUu%j=bC19Jx9M~egoqWM=sa{W93LIMdNrBOTuaTe zBAC8@_4-sRx7Qc%mfJL(99dHI{>L9O#XJ7$&!?|mjm8KLtg5I5XO5w)a-BDtd-(d> z>2w-~e!jisDR~19LwU*ZYJ<@rTVF1Jmnez-FscIVG6eTS*0o;RpdLzdTO~Zuo zZtQ^@3{3zujdvqE1Bbb4xQD!i2tMkuqTo`0;#jUBtUmh|jM!~rwFJy{&>0IY;%g(@ zeH*Zu$B6MHn6ci-Hld1yT*V#1%VAn?aoS1q0V*LoUzd#@*liOqBnUDUO~nT?DnTrl z<$2|VW7llf%LN_ZkIx33$ll~=G8rmm0;dP-!eiH=0g0xp4=F$FEKyoI0l28JvFo?Rw^LkhFJ@P~&p_;V55uh<(Mzxw){;h>L@GRG)JN2jk}VLp?1otDbz z@b%&G5gcc!N)>nb>gzv`35-FL$FLrcbEsMaf97e;YJ0tmSMWVTw})8FFnt6?_!`(= zkuL6{TLjL&H=Foz-WV_0~pSe@U!TO}JrRtULGC4;Aki8u&8d$sf>k~M!Y z9gpc9feS!kSu=ydbT}L{J2fKo*@5r7ZZH7w(SuS-XeNZ+we|Jg<>kfM<@+Db&(4xG zS2U|XIUe`iWV38^e*!ntb^YE5_yxxq^Riv95l+KH-!85e%Qb=wcpdQHY=>GR4r1h6 z9ydR~I)8ii_U$@K4a<@1^!EBXEybAw-R_SM+q8=nj1~2p|6>^Nu64Os++0Rk1rK{P zJ?MpjgHUrg4tgWsHPg*q0cYH{dAj80Dla8EasY7KwN0JQcv*-SrnI^} zTW`6e4&%)^UI0x&pyo+Ep1Q2zPJfUrR((;jh!Wl+WbZc^KSsmZq4>LOZR zM)9WLo@45uL;6!+!_# zQ=DyITvvF0~i??N)baephFC%Pz*7fFp3OHR7Ug|O@o*K^+#+X zj-zTf3KM}D>>TG=s_J;ndlks{I$d3ES65LI@!VO(*?}lRNR_>wJtZzVLLRLu%YfZb z`XC(IdUbp8cCn6NG%(HE<<)W>S+G~Cw7$KBYEw8xs>=ynPuGEp!F9t>+}?OFghevp z@(-r;AR+Pn5lof~kwshRF=E8Q_+UI90y-d3z8_e&3Dbk<6Mnv0r#F`mT6|a5h-3QG zgCk4Mwo&Sj=EEUOC1Tx4tJjFOlf1MXw<(i50!WFzG5jzczy&jT6=j)4%oYPZdiUMM z#T5W>%v_-^K(p8HTQ;Jr2GF&NGv*Ya6zy1}pu4(d>5d2aV7h;v__Xa1@n@WEcv@An z9V>7RgdmKO-~(s|qBAKg@(NbIsnTp47b)|IkR-xY=xO#;O}jh zJPW$rY`2l&58-ojGcVl*_ys%-x!y#;+&o^R82AMrBu^vm^o}-h#PfcD&+TT#6Ps~T zK{-?@gDJSX*(N!(t;jZ;^(yDlL!Qy*VM4Aj$W<2KU0;CdKv{U!JQ^2o5mIb7+)9j~ ziRl;KfA{u>@9u7I(FaUr&o!d;3huw6LNX!g-~*3yWPrMhAK!lWx78NnrPT#)y~>D8gA=(G(p z380EtKO$h5Yo?A^kq;>k6|v{y4-Z`PsAkGnCNQPGLg|7xlPWOzn%+Q8)_~jgtqlCH z9dJwNQ_HAUg~&+p`=>3Ir>&+@E5>M@O7`#;se^nUGWlaR`i&ArD|bPtD%lZb6&11oRmXVT2L?K~*5;8==MEDSRX7CSnMfIapDQAKJ0J zL!?OGF;7Q|@?_+>KvcP(QNTq;fml_D?Hi~!x3ymc( z{yeA*CdTXATSV}R74-V1&b+6nQ@|Y@eA-vAX?=H#=pU1Usf9oE_HX}neY?WQ_{f%) z05cD3pD#A&m#fPSrmcdXr+PMm08CMW0%>-4xqN>Yq36s4l;*LfA&hAg-W$52l=WUz zc+Yw?vHUFz0A!yP1jJ0@jWKz6)g*28GCf%>X)iO7x%fByLRt8XWR9`53dp(unrTBDpma5T*W z{8<(^iiOaj-|K07KL(tJNv}WXk0!9;&`qcX{8rcZ`TVe|;OPw}^IqsdZYeh$1XET~ zaT_M1VJZTcusDYO#w@3Cia>(v-Ee0`N(Phyn3_JSIbgnuys*RRXf#s5?0DU#3K5(E zif};@eR4#a9n*#x8v5ZN2m=fgHZB+)j)o)nwoEO;92Lw00GC;GW;Yd-SNeW>IGPRy z@JGCGIPDJ*VT^jcp25{kG1>S74=Wf9M`J`rgW=HB8Zj1j2AqO{XKhdzy5VspsR-Ur zzj_n!eLQexG`~L^4MG4ofL2GafJg@xoyM1|?uLa}ipvrFkAKLn5&%{!;png*`j8N` zqL{&Gb{zU1;1vFI&>IGP@BpV2_MGoL81zG6FhJbUosfF`k?3phkrqAIn7HIOL3i1BcXxDhiYW{g)v2^3}k5ttUh8bZ+i;W5~@EARpv zvsEDLg>7{UDH z+oR(n*V2U~kR2ez!{J~u7>uBVy*81l^)$>#R*>^&kb$1wmUxKZ2}XDK`|*&iH0#h}T| z&(kW-a1sQ8F7gy%iX9)3mw2O`r1^u{aM+W9ZyRR&pcZE^W};f+GYs7>1Ud-$od3 zx@8&};3kZ|DwRM(T!YPw;sU-7Ts)|~X_<8nN8mQi`2rJQuBA3G^#u5Sk4Z@iOhcks z9kSK6o{o z^_maXrbqceL;96|d5{c!Xb*B1-s8m#$VKHGvX zhjyVihH1blS}&JSff^n-nrQtj+IcnG-d5G9cWK+#|@1UN7=gTa{Y*WJ(EcU}3atn``t`<<++TlYSH@9XZ@AinqAdTCA` z^PTT}=H$umShgeO@pN#~>-CacF$GCc88jdIiP3wqY(5*qFoJ5c92*8IM4=1!wrs=q z7D0i$OqNS*!#K$lXeCan$};4vAL&m6Z|DI5NTUr|cP z-?p=GdU|x=g{4}n3)MF0orDobCRCtXZx~Q<0l#4eWihgSf6DKoqs+9+rD)naI^g7z zW}y{{AXFk5d@-Z2y-+!dZriq%1}tJc@mxoKvkq=54Z=bao&gwM*y9wE5X%q*&`FRH zpdrI6K_WwYiXnj?jL+h!0&tOUkYP>7DNJ(TgCnkJh5~IC!767Y8Ay3D5%SP%A(uHj z2Xh+898>!1a@}2<@fez~=bp-#!aKcQiNm>Sc9w@^Ccqpp*9M z(!M3Z_Vm`n4RE%^%%jQCgZtAtR1-LD0#-#=Ch#psV|ZhXCqoMD|P|l@fetPt92Fn`yRRkKE;Z_(6^A7pI(;baR<4n>ZTp>569BwFL z>IVr%1;%O^CgPi9BaP+^@hc`S;QYXAhOmI0fg#2@kMTIg=&LuYuA5^xPJP&>FjB?T zmj}MKDpfprQ3``*eO5hAAuqg#2x*O$=;qH(gl2)!Yxz1vYA*|X^ zq8dZ4$LTzXBiQvY^!w8zNH;@=jzDE#=|a^&jm7hD29}x62P1#R#aobIjEb15rrX)x zs~Fkf=;7E4V0T`tON%doF%kfU`6fE#1wjIpP0rzRr!>a8Qgv9_IgMHJ4Y$(;8)A&X zV}>NbaKiYZ-hk#%44r$%!aQN@d!gSr*};`RT%V_dk|3O{Ih~zro7-D@=H2=3Zx3b> z=P#k}@Emju%3w-(@UToWSgG8MR4zqOtqhKWafkuHw%PTq>o@j;(+}?6KSD_uwz{s- z`iv9s4Mqk{8VG-maPXuF{TT&8VMlW#jE#z|(9XJ$VLY6D82_fpP#nxSEZ&5;{_awMUzt(ch2_S|P z6ah<>Ry`gwNz$Ud(CpRLM#Yduy~BBw(@5h|Gl;a1UBUTu*cL?_K_`+l3L}!4a{y3^ z3XE7NNEJ4@xC_amiVnqt;*CPYL=qhx7=ox3lJQv>EcB*fB$^Ouu)-+aVD+4>|A9n< zR+G^8AS;Fq+#GZhRA!B@_3HEfy$AOn(he5FqTbrDwRG4!hRrWQtl)W?Vh|PFk{L|G z_U0J1G`2u|7|hVGMVwT0J}4}xt+HF-x#!tVL%wB~-s@%eeNmk?faoti0$7|s0l+n2 z9@b$UU|x%vAKd1u7?7Zt2!hv*`hhfj4#NToaI5Hc+J9)en8JhiK)(TL_#llmzV3lW z;yV{KSuhA0wmJF9`apKe20T#>ava5B;1_Zk&odGG18jw7iXtS# zH7hN+&?WEGn~vi}yerkqrq3BBE{_U+j4j1mhMG43YuWhI~iAq39UiFl8n`G=Nfq$p8(m!7iZSioksw zHS9Sg<_w}3jxyH{<+PbwtyUh4`n^6zT-oG~TQ5lg5EhRXCKXRf=S3G6_m;N`5ckEw z+JnoBxFk+jw-nvsI`oC#sC;3M$zC94~ zptyMU+{Lrig932ve754!3eG3St;PHUptyCRZp+*Rho(vfFPaGGE zlEg0nr;p7E)M5)nI|_JGO2CCY&jV`ll*$%&A;2ibMTr#q3xRSTiV8@wQPFKzmy%>Y z;%p+WFUl`U5vS`Vo~uBS$y0%BDa?z)h0@eg+lH#nPyGu)&>jcty?j;}57xV*xLaIU zb|p{Gx>ej<-CF#tr35@$L~*dZ%O4&sZ>>EhTa`w8i%Zf+#|Qnv5UP{61mJd&ut+Lk zy~M@ITHO|j2;$y)GQwk$E^o5WSC601Nu0!)-o2*%TNFxF2Md^{m}qn zj$OKz92`&>92qZ^hbSHr7W5O&#NzVr!lj^)3pA!c%*C}21qw+BhJS1+#b{cNsmBBQ z`V-mRsPfaAwE$`h;Ws?iet$`DRu%k54@30G?-+pRrDz(6$ag!hc*D@gOK!*id>j8s zQ2+!{xu*};4--D-;(w>X8ZUnA@T6Y-M2i03g^wHxKKUfdhO4gvdbt2fK6%iAz-uHH zXCEcS&zC38KFsoAwZ4e-IeVp9(D3S#i#c9w;WAs%_N%r2?CG_tBF{$)eHL77Fb|)r z`6vjENbx4%u~5W{xMD*;DIhqA)A`Q@>m+|}g1<~ap=*8q{2(5C(t}TFNbwZ!7KAFU z761qMN+=~=ev$9OL1tGs};9u8d{#E#iZf62Spj;Ipm-i zcEz#`zWOdQ6u;sw-x%tg5KlACzAoDJ#JZgW(aWop;>p#6>-SXMau~BHON!TnYbnLM z9e!y@f3Qf6o9FYysiNwrCLLnF(lx}i6q|yC62JU%86b!&IL^O*JOgC3s2Z1MR$H}d zrIbY=Ou1UGl*=mL*KsKc?(?M?BTR_Jg?!*#Wfr-}3cpPf^+2WYj9sqi>SF(4S=FqH zYdbbyeDj0*vTd7u2En4$9Sf*USg-lk*1w4A?Nw7*O zpR2j7@iQ*IqRvYUebQ)f%{gB@J_RH&f4N$799y9nRLrvL*p_%Zy5v>SK9KJGsjTUi zCgxGW=%A))ix^2b;;yI!KCpZW5AjeuSzHjmIA#SL*QKC9kry}+g8?E%ysYNwIgmBY za!l72-%KH?!VNofzIx|6OV!dVwox|3N?w_ZFL5BLT$rWmn&X&dOGAY<-KkV-RRyAF zIf1#V*(VNOk^-O{7u&s(7T_?Ah6D!_nH~LWST<}ah!(Nz#l%1G911ha&8=%U8x@Ni z=jxSh5z(PmZy4O0VxG&IDPr&7!9qMiuwuxgKvn0?;*OyN{ya%@3ImJGgeHI=ySq0w z+Vz~vk~8$H&aFGeKCzHvsFDOx!*O5m8K zY7+uCi{@bzqk+05wxUIjvRY~H?CtHDau$iN@)hpX%q`0?=12-r8ORrnvF|puJeJH_ zr_;*0QcpH5i{B&3YPGY!f8(0XucoIMRj3-8hT=q#cD22|cgs{h zjs07n-rL(!vS2owrCbqPX>RN^st#AIf}|{>SkeHBvb|^#B)nDY?p(X(8fq*SBpMJ0 z&6dVk6QQJ;jm>K}-~7}@tCj{{n3T$mR>juCxfg@NAe)7Otx~9n^)Y*T1cXy{+b>&R##{OiEh7kw(PMa5mFbuA*;bITfDMJbXQ5-ngJek5ObF+d`oS587R{RVBF+KSj0)aeJcw+$e3L>Sw`8Mix@}Zdf_`Kx z8kSQB7bqF*DA^KxVn_2C7Xm*CB&FKjzjo`jRKwKC{zmXoh6 zL)UQ(LEYZIvAwrj7yGn;KPmDHLBYsNwaxt-E!Rn-kjrD&s3XfptG2gQ-z*z8Lp7;Z z)viEM=w`iPgYlhqV+RMOs-fQH^44axDVG$-azSaw?(Q_NwaQg$7DcUfHmhab_h#Hw zQZDIYhj%=6p(|c}cqs}1Be}7$dwp|r10yHpH#=QRD@l5}*=m68oW|Dn-hQK6fy&hE z=Fat--EOy1HZk7H?fuu^DuTg-WH?d_dihKh^=*{nlVbh=%) zQqI#@E4PrRrEo{`R5m+1H+FXS+=`tgv0mxicsWy^@8$gFlDRokrwgUT_&&-Lx?ZJ0aN0T|ErCn{6O}Te?e=<*M-M!uYYu(LlTg@i3x!c;^-rcP-z)oz{ zHd*aX+c7otT7B!*Yj3>SsF(@zj5D{hyS2T+rOgxHs&C$W^K<(<8&c#A2ZKzjZ0%mF zn5D^Z7-b4Z_4e+5vr&`M2;*<_+G|@|+t7|6|G6EMBw1`)eq(EEi!nFSQgi3^H{O1` zUe>+w>2N$lmsYL(_`zK-(YyOMclWNf+FiG7!q7r{clNJ0>MrukWNTyZCR7EqW)_SG zgE7nq*HL;8@695my|D?U8J7%DnA_Y(-1POa0EVaZClqD@DyZ3x<5uAJNL+^m`31nZ zz(EF{flg#RgEUN1Nr4!(90qJCCE$--cXTKte+IPy#y6^Mr|d$_!$&F^Rg2+w90t{q z4fs_W#+eQwELLtWY6Aw;)N%{DS_J>$XSpS_YP(IEK&7mNJW(RVl=zwqjI33fIORvM z;xpq#CIH3MiU>ctE~RlMBPD|fK_Qf&-^v|W1CF8L7VUL|p9?_bmg0Gg5eM#Vv^or< z$B${A0AdMmtKmRLT23XN4<|uZZ8W72>@dz11F~Ru|9X?LzrdS12F?yfv15urJ(Qc7 zq*iMURn}X3uWhs{Fg^@jgCGY(qFZZl0ka%qVfXsYc6*~UHssno3RZ@M+q#L%=L7|mhySk*ippNx*D^BK&JM!T7Z+UDcg>O)m7eZ8y@K#E6o8~QHgD`-+jRi86@{VUHeK6L%?d_uno4cT%Bo$is3q`& z+wL^-EHNE73uj)G!C}wl!=r}}gH)+^w%iIvk{Up;CferS^_p9D%H=$XRHxZ)x-fmp zZZ-CX6EAdX?TS$v_D(akymS4vs-s7t?|V~-PPpv>keFuX4Nh!hGQG^@hC^Gt~q%4?!7yA z=W(gg*_5Nv;o)(vSGV@TGj-Fn4H&1XOM)70tcr^Dk1gIVObRf&5hjuoo`v&qpR)NKM%vnebg%TPjZG9HiB za%b;OaA!y@L)3Ypb{3<=Cpy^sck~v#dK>u^kUg^b-3@UG7rZ5 zMAxq5SrnjSGO6l-h#Fd(XTe~4>SvN;n7(&>>J1~1ThgiXlF4W^1t(Q4Ny$s2kUPA8 zvVg39HGqYrn0A@d@ggWe47=Bd4rn#&)ijtVnTpW`(>RVeA%h1(Z*Y2a0K*w3i8t;K z`ltQlgVU3fAc|pXakfpx^-)rSIcC$oVMH1Q!!!2!y^|w9g1wXZlfek)r`Ys7jroPD z_~rs;4hG=}c@BCS?BL{JJf)M%s2%;&nIAwZKuq|viRb(9v^7o5qWNfW zio2(W4+f)&qS>}>O5)ot`onqZPkN}#{rmT)lgWJU8!lWU1{%y|ILaochI9*ZX!$ly zNFGiX;Es@1EXIO9DM(8G7GkUrQsN2zD^3*EfH67lKj`&(pf2ZJZ3|W@NXp6TJOgEp zkD)fe2iauQ8}@s>oX@77H-(1QVO=Zv`1HYWGSgt$TXr5ZWYdV%6HQ)FsW>j0&l^vW{1<^!Cj4;F zgyaYFLT8{)<2YWt-w?SX#~3nW;7^B~bi`>ICG)W#1pI(V%*rqse$i8kD#de3Sac0! zw4&s}*q@yGd{9JSc3eYZ;Dkl(SCFMyFbVw`zbjS^RfDg}sUD089ORVLK>{O&%MMMI z-z24cA9Fqvn9B??go`pi4PyoPaW4&nZ1LUl6g(QhSxJ*LoCdSLKO2Q$Pf|;GJ>;`z z&<>^W6MV3TTFm$25`p}H%8q*v`ooE$L!XwVbbfMh8w@}50=PL0gwSvkesdco;oS52 zi90`)H0*-y1^?R;)#}WfP6B>CYrvl}bnyV7KwrO67~>-a{lf>NX;^MsV0DN-4n1_iy%t1AErgh0o@^q!3R zgFz32c0Qe|cCA*kF$nxHjL^-~5yKlyrw~}2YURsG@p=~j!Su1qkoAfzqx()Ce$XF! zs$s&;31Co9AZmILI_NG1oZ*xW5dc(#*|QBiX4y(9pU+0#JhUp!M!m)<#H_?wc}Q># zBL_^KhV$|8^kgy_&saCt)+HP;0H6QP+@p;F-Q^&!Qtug zWC{g9cfq#d{|2xOD`hJQW`b)eF+p35jdG=;(eLH16f~V+8uBZ`Irm&ANoNqdwA`S5 z7H>yr$Px`xqRlCrcC`prouXbWkMhtR+$E|?O3KM zB%A=UzpS$(SOh?oa|liJ@2Gz|9#0s+0J1#}r_h4Kaaxi=;LheILo-T{S(Qw%W(3Wgsi`QYU^a31)M2aaretJP}qJ&0mp_{`@0@q8RG?p;ED z*Uc!LhMAI{`k7z63qnaHOOxPdLqmMx z;AKn!;VD@$p~ejzR^4PY2;x$?+R*a((fxZfKT@gNZ6!}|4}GS}DO5YGn%JLArgPnP zx%NQHpxjkW@yES+RMO!DOeeX*kUDT>(Yvs;+d)F=7jA{@ia2{RP zK?lL298G32cUEcf6>;E$+2MgQLJ{m!h-TTSw>!DtJGg%kB)MJdZtZT%$qWuDm{OBd zWFEp=Eg{Wz7& z)h4$wh-u)k`IgDRqMY8h z2h5{HD%V<$rFnzn(_UYMNuh1xjR!N&SGZqFUCtQt%5Z{sdJsxLr zt-Z6gyH~4l<2J~CzPq-|urlE_gmDgIZazV7J{u@&wa)HFw;oQ0ev}w!ZN08Z$>8{4 zIPoiuPT9x@{gWVsEhcFu7gtD$A11lM;8D;GVM2vGjB>47Z|X`qJUJLmeROxVT0`xj zX2O!u-MUtH9T>N8J?&~6rU$Az?i~&WBg>FpuS;s4kD@|!odFoWm;w@K8DmO=I~ju{ z3Q!?PLCyeC7*hfjYtjVZ0fx{K0$ncU0gP0iLGX)nG$J4p0 z%GYaB%P5TlPHiuR8()=}BDyjRg*@`ax7?xbRBPNYONo3hQ_O0;Wvcn;^k6ui=}sNP z*3_i=bOM7Q@rQ%K6b1$;j_lxSCYe%7yuomc;STi+oe4oP4oP z2{HQSQMu8jOvh;L9}Y%SFsEf&uo$Pq0k}uEDjbhW?#(#Szp;D0YRgl&CWCj}nr&*)9CqzA<(^G74AH*dZ1S~9r% z-urjq_3Csk?PNan=CHxh{S4X4sVd4Nm={$H6nG(im{&VH+k3l>YI$_9LIrIu6)#*y+jfX)Zk)(3Q;A=t5olD#bOdlu}v{$ui-R(VF4Nng41-b6l zn$SiNoZ~Sl!z}?|m13lMb6>Swx8kG>p*5wE$)!pu%-%Hg!Tn7U zLS#4@Be4mI2FC;9-mcVL?*0bp<4wlHq@<$@l{|tE7^jk98hoF~kWg%)>A29@piCHN z5FC|CITsP=GzThtNAgea-uYl2!g)qb>l-_}M(&*+9YGXBn1M!cVjz#9x1b%N;U;5H zTXHHjE<%Msn@wSZx;1Va7kVSOHJVc;wb8)Q$d96}n*4UPbf=fSH@m0+!0@VA=8r-a zS^%<*?nf~Ogk3D8zt9EeR>g476SzqX2$~gB@Z2%chQQ|ARCtz}#VsZoVJ*sK9g>Yn z87B@DQ8;M;2Lgp^7VIB}e}f#K4;e2L0-hEobbDG-3{KqRN(xy;_e_}Dpoq{hkmGQ6 zV^}eg;?zw>Jj=3hf|kd!&Q)X3CE+}V$)j7G1xipENH4mT=x{mZ1PnZaMT^jO%k6A# zZI;5p;lqdXFsWG5=R0yZ&%V*igL85XqYcB0)=$8pIgZm3nB1*Zl`I6=!2;YZ702Td zbh%Yt^auukq{2l4F>}-)PhuF3aOq&KgAc**$X0Cn7IT&j<3Ysjfn5rhH%VpNtx}7? zw(ub|Trd)g7!89shrnM9F$f&7MI9<5C&73;6xLY5oHJRrDqPZo8o<#W2We*M6uUrb@Z7wYkxbCdWrd$3dLBj`W4L zG@It%9OU6Yo(kZ@22@Hj%I%%~PP>uJdJpb?FrEdAdoKo(Rqb@U4X=058;lp7Rg9{q z0TO6#duwZF$CBfd`|lr}4lo24H(v>0oJ~VlF{YokfbW$7A?x?cT6X&IE=)h64bccm zGi>O7=#Tg*dq+JtpjSH;xuxX~#`*XWszB;5mVrLC_hE5!N@UFgcxg~9&}39SDw`za z_*>k15s(yF(-lUh6M@?}zkR7}RJdKb7Kd}V)Mzafz+PDzd)dSJMcw&|0&00xmU#{k zTxzI%T@*ppmrAZJ?K-9YEI;-?A%t3kPlf^j$TFNe})C}JWvdXmnQ+?m*{X!veLN^B7PSh0aY$(GO0wh`ALIMi~=AOm3z`) z{qW)AF8_BFygI~uN*!M5;qc)D8vnbz{yQ74z6$6i!_$TwM(W2ZFh1h)FE4%Y&C9FL4Qps&Suq@y>AZY(bD`RjH`<0#GNNyIwHbgg9rF z_%c!S6@w?}8XJE#BBMx^`)80`Tr*@kwq=&YN}5HACj-bwu0;-PZ?Om#{et{7+<0ci z#G`xOo<7ElxN7hBO;pxD~i)F4?1{NxMV{yI?t6Dw_ z7A=w>>-ieVvKlt$yVx(g5iKs^0S4Uq4rFeS7$mrz5MKTFJ$8UGImg<>vx)|@^ zI1w}Ik(32{zc?!j?&Ibv%K%TJ56Krikh-!d>*Z_**Oq z71@50;H4=5_Q6toh|JFY4_e|7`3n*fNa>QK7u~*ZhVEqX;z5yzfZ~5~WesqN zB@}fl$`j*X6kpt1JSB03j##r8@mq72uq=Y{8tUzKOU=_*gi#aOEb?TjixMQwa+@tA zi%WXBF5)OKu8wFgno#fV?(FUuays`I(1s7Ls?Dd*NQyEwyV}{g)^M%RpQ%=T`}*tK z+na`xEdnK}pjE3{vEwMf&@PJLb9kPVDOx0HcBR?wSc)V<7%|#Xm0K<5=m_)!!wv1< zXt(N89ENdbSL*y~A@aFmiqUjdgen@i=nLk29tvs{hmiNR*4ED6wHkv#1tqQA-Mv;T zYk@Z<>1bryP1U(}e+etbEN{ERvAAlV2Ez?#GQaH@?;+2oFR zco>;t#Bo1%&|fPzI`wKLkE5d6d~i(`u`&gdp9e*?Th;BZ+o_mkYH-bQG!1pIta_P2 zva0RcR>Q7a;^S<$+;$CYc!ih+(F3rjje4<$+*96NvSqByPI2X*~+p^ zciT7K{@k_g4T|76)|^^(5&JB#>*`l1btRMYHiY(pr6t&=F$ ztSTO?)m$lqIFc&$jZU{)sgyC!ORCx4+-ufse>M)n#H=*hn>$VJET3`R@r}1$f8!0; z(uAm#z@6>xhNW}ESRE&u+h~Oe>p`_UTicox%M2@0jplRJX>>L=99z$l7;M$v+Oeg0 z*zc#3=GO5D>=l!%KLtrU8=Do7GzsGrBXEDSQ}qT%!_gEnrnSZB7qj8H`=9WKK1x*!L>I& z``YWTl}%|r9;LF?-r98x$>TELlI^xgDAxhKL77Hpr`73{9Sb6u-y@v?SNb=)+nsis zJLl(eWAplJpZeVHR#%FV)5L0QbsObL?{Mm;ZhI3%t5zGfsikR(s-l0P!!q!Rtkv3E z8{4~E+uKU!&*o9RyWee9(cXC^!-jBeRW-^MzxCsyz$XnwAtfLS0T3pIEiJ*VtGKSI zNsNoI6rVx?NM_Znv`o{4V9hc~t+Z{^h9xXR%9d2cu0a_w6a>#q4X1Wl!;{bunq@e3 z)8q$>xoYW-tHHz;TX~llA7TkqBxS>?na~izvt;BryUNIcOr~%{cDt-=1|4L@(2%F5 zlo*$y1e=3J7^qvG%cfr6a_cRIx8Wy(7*AExDKqpCq$5+Z2-Xb`+D(QD(lt5pAzD*d z65KT~nu*Uio&b_s-?+B5)m9;tT{n&9sp5dCsf3Ev(c`G~Y%+;6 zxzg-*S%eMxV$@uF^K;ktclg;{7^404&Q`0*u%<9hASb}&HRu@Fl(@TW75+E$`bK@r zkWxRIhZqiKqh=auCezkWh7|cqZD0Xvaf4@?8%9TnM2f0?kz&7QCpI;?%t<`~?Hoi;4Ha=B8i)skQmm2@Z)N6&}-UZz#{Zob)V)?ryj!8})Nh-24MyzyW<58Upx zz1?k#L3a#{4rl}0P%XDztLU@w5I({}Tgysg>&CU~`?lrSj-97zxwX5!vt6s#VM@oj z2FcQ>yOmnYkdxUwEH^e=b(dR923c$8wY}XPOXo)nL7Y{fjoS6ppN_|)Tz9vx-RiW_ zigFqUMq_(#Zx4>PYH5_hVXv2~<;}h8 zWg{zTZqZ*Hfg4@Mq)mMt<=b=bP1y&COOYK74rp-o%eFZnb1`aQ`4x-QAmS?riVW8sI1+OLDip(`q%)`KpwH z8r%E)(hXf2PJ1WEr;wDUk{lh}oyTgeQ42;7r=jH7#&pzwu2?{*naOCTx@o(xJ!}|y zywCOjG!VoG0gO*cX9*TJm-9=I`21!V7Cof6KZ|9Zp&1wqPKH8D3rxmLG*Vnj*d#&cY-P&kSu@Qz{)aQCD@&v_a)Kl+KWokX@OiYi`rjEtRJUH{!Kx zw7-LCoU2Nui;=-eFb4Hx-Aq&G!v8SHv@*t_WtBBelTv8whEsMmQA8=>-tJUKAwp2x#^bUHHxm~H2L@Xc}E?fJzx}9d(t+GH` zb=PZE@s(&2>vr9B84$H%=}{Ov^|q;%QmDQ>_JgdseGME~t-A1rC9A%(x93*MZmph2 zUXUsYYM}?A&;3v(p4c;}Bw2Z*K0?%LdAy%;r{oYwy}Vzo0ZVcm$2@TbrGh zVL6r|dy_GP$1M0kvaD98(#T_P8jNS5uWDt~QkHZ}Q|6&(m~}@f&3qV9lU%V{ZpRSw zv}rQyPkXVXn`&t=x_|18f-sb|O1)kQXZ@KU*}AmvN^({jM$fVB<;M*RN9hW{IY7on zu7Ryo19pxA{wz7QPP0*$GH{p)SKTtf*0>2DOH0Ga>CwY5gApT7`bWn{2S@imczAH& ziM`#yTXol(jRp`UwPu6Uemb1;ic_iN(YSYd5{pgVXMZwkG|)p{7ONi-Xs zAkX86_a5B6GoH>d$RlrfaQB1$aKcU7VK29~nst}a2vAY+sK|lyd1){`y#M~m=@148 zstqwsv0#<$a@EkX(dof-9x9p^`;*h-LobLRJr>2&WCLIzjeExrPYw?r-bFqm)vVSV zbsYoVuuKakn-b4Q5AVHy+8?1Zz89L6X0>cZ3=<=Z`B2q%>u$9IQ6r)V5a6A_+h=S7 z3|o?sfttBy8;+`FbNX75;WQLG2M97S*arR-&4T|l?H`<+oP1AfZ^%GlcR@+_ufA|JZ5Z%(}%90>3KE%X%&KdMCX>iQijBlVPua{NV1p z-@5WRIK?EME?blB*iefy90y-IuLYZKC9Oo;s^Ogvv6`eA0N->Gw>bv=k|se`?;!f z)&jLI63Tpc0=>*{fVr8s4F;CN2}p?MP#bEF;WqizR>V1vH2|?d6c5VZ4+0Jkv&?CB zC?3_|cW012{v;HWnx%M-{J8--PRJn02-VG4YnZbTN~qfeC5D;qFdziRi~{E3_r@g{ z0+aq6x4gqRS$mk*I{}jS~ha5rAxxVA?-E7*A&6eF`Ihc#}boVRPo_GBM5>q=5yJ+tG`l zIqdU*(R=2RQ)}1jF25X%8COm)BooHr9Gd3v!M(wtKbg+VTDxMav&lG4FnUd=QZ*UM zADJ@b2qfR({X3(HhtY)RhP}i7V8G9kaCf=+40EMFjlm96E%QdF{r*rk-DbOE!1m_% z>&2L0qf!Q_8bE?hXLAg>1S5BFba)@~YdH7kdbw69>w)j9Rt?5c8iMyy&RT+5pX@(q%kp_7cn~kF+&YXyei~!yiDl-^Set?Lx z;R$?&(>{8OJHAvZ8ta4VYbX;nD*7GfCkB!4&5MRm4555Z#nFwc^_X^;{;#^!2aw}tLYzXf%iMYjP#qe)~*)ZVyqcn$=G9QPbU#NCG zTO<^DvTR|2q**WxA;C2p+{_oVf>gZE#OSRU9mE)LBK#+GT;h+RAs7HIL$9JmF`1Rw zifJ+NB+o!MUA%=^195{f4NozmW>F5^Dc&haDmT($oGv^dI!kCLoKQhfLyMZ{2`qm& z8uX`Rm`j6`gW*_&2qT4K3^)pk$xPH7qz0|UAv+Tpva{i5k57-r)4;B_nvEKn2!=h# zDjJQX7-EybN$>R3hgp$gNP!(62op2rGJ{Ih;_?l?xemj@(eU2stk3XpS*mFj$57|N zG|3q~w?DamIDR;dLPgdX29}|rVIstk^{{85g%gI8L!-!qqR-hvG{ui|e%t;@fU7G2 zv^$y4hBGKwIKk*NcxAIG1LexO?@j0abUGgM?It>ka)eR_Jw<^6cE*2k>NGbtwl-mf zLQ;=<4+q1UZaXEIJChlFW{5m!7vG<2c57pMANDeoHmvw=ccb3o^m?W2=(HTTwGgBq z7%2`T)oyI;>{J}?S|wt-KuHI29L%San8gN+8$G7Z*A?h8r3+Q zPNyE^D24)?PYO@~FmfRyvw4i=&aF%QrBHyvfNW$Hp-A*fYkU8C)zL!VH{Fd+yP1X4 z*<>(*+|O7R>=xt|1Oe()t&|}MVIwzMoob`qXf#wt9?RU;F83-ZrNMj*{RdS-p#i#! zf-r1EUu2*%24=Op-RZV%_;lUvcB|cJZ?@YlQ*5xsT0!P0I=r-QceCE?v^O^_EuHd% zd#GX=X&C-XXmr#nq8YAndho{0YFU_0X$h5S)hodi#&gU#ViZRd@#vo*2z49QTbW_& zShoVuZ?hoEYMs4?Ylq%=Hl1WjxwCZ*oB)0^%5~JF)_^Q%!l#r}z24bt)+!JJP%@?_ zU8_o6^J$FEDG+wW+z%6mP{?8Iu|36`%SVB78+1@rPQsWH2$`Y9@L(*h(z0|zf-q5S zQ*8VKWeB}mGHQ0MV>7aU4%?Tuc`7T0Ln~7=6-@;GWN-52Ftr7QOdRrkXAUI^&P)oP z(wv56n&dL0Y?N!JRpCnlI2^QA!D52{C@i@Rfa)|%!;m9zJ#1IzLXCpVDJRKa_;1mo z0^qthZr#*N;C{ZOl}j5Hd9NbTJYFOLkS555XrKUlcqSK2m zn9auUFE{qy*xTE+Ee)c%fB3KBm2ESP{BiH7*B@(^BQtcwBt@~pEP!1g8MTdV zMtOqi;5Ih98(_I^ySwQ+aB4s@PzFurtBp7eWwW}mv*(s|Z_0?jkVR-D85_zCLyPRl zNKA&)*tz+7x6M(k$nX%HiruW3jAWJO31|R8KMm(O*hn=UvtH#)AK$t}5uE=yxG_#6 z8d;JAVM2q6Z??)Vx2C}`XflnqAD&!=ZjeGsx z0G0`Q0c;#IeBcm+Jc8_u6AnV9>t8OEzB=di?2PmcY0fR3l_mnXhAgK!MzGa>G2*C?7@t-9gp z=;-(q)`i08(-Ml9i?53#n4>e8#;}@bfFctJ=gDvY<2{!($E`Y+5sdreSpb!TI`gyO z*_3-ys46VC-qGQBJj1A`^;5(tnsV9^logSAAd-aC_dEEY+Ea*=spbQ3FR)V{2n+kMqNr6A3!?d5z zCh&6n5d2yat_&=62B8CCAV$ZdQ5Z(-3k(--WH14tppn7bNr;Cs!*-}MK+XAV?s>En zMa|P(ww#KotI&#Q%WOQHc|IOXLB!!;9)vLQJkkWiiB>V}amMkaOzt@Anr5Mg7yHc}sDezbsAN8M(X5gpMU^e%`qrr4=dVDxtc93AOK8!Uq zm>+0+6K^(yV+m1*B4D7-=0T$@zh0Aqpfq@LFgOq$jRP^bYzU;7LlrQHEiD!C48{fR z*>#|y$&0Zc`{Rfmj--^pjOruib{IQ&J_>?4?Hrt?Q5wz|6g;Ip&IMw~QnU1O({fx0 zafa@J=7>Z7vII(MWC?YIu|XjYk!5hdI4PL%)fK$2)gveXl92O4U^i3-qy!mC+!HTG zWzdR@uP(Uy2Br{-c+A(m+@P(yxv50slcS?~m{_LtdP8zbrQ1kPmFiSZqRs6`v5Fjum^@M z2^V-%E>B_;P)AMElyDBiG$`aa8U!aHfPoKsr_sdg!8_t|B%xox8d2;=5bn{;!0=Z{5Z%Jm^j<*hBNCQ_WL7f>{eO2;Yu?SD z1PF@4$LE8%BRYZPW>2s$P*uhhgC&Xrin=ZHVKU@UWXNP}1nx1wWKjg`CX(SH0NW>0 z7foP6%v3>+3VL(c&=} zKB78IDoD)Y*rDtSaNt%=-Ze_^53&=6o;(MrC#Nig4p>}TmbG>PHD~()i}NK=*oz7l ztW{ir)+hV0Qp{t)O4Ng(3GxD|7Omp{iipc*3i>Rx0_iNC5x{QdDe?g;!2B;a3^_^0 z5PI`;Q3QY$AZM{a_JDX)Gz&Gs{pB$mS2XRch%*pj11nDKjj3YuQq`8;s7d2l_THp) zq4BI2G*Q8S3*JDVh`GuYKM3w;i8x_rF(qp$xB~}*3_RxJ6dfX|7>r0N!{6W9-`d&I zQt#gF@AQTBu7s)D4rDXPk+MPimG>W^bM#N}$kRC8EDG+3q5c1_+g^7jXM?-7=J1>xm} zf*@rUhc5^a}ko$FU9A8|baYwdVmz zvE6#DUV~LX9`xokC`c$)U{S;)O*mKjBX^$&7g7ptyx5Az!;&e5b$V8@N8#y}S=}v~ z`1pJl_nubDlYkA<4T$;%yaomjKNr1@BUChEk^ggnNPSilmcV2DIJ#s=`Q!;(H5F{X zco6?xC>7T!8wf8}pXUcrO>wjoGEV>qGNa5*`_q7t@P*WU$v`>?JyD#(^e*d?ALaA) z{y77ZHOZ#)8vl(M4pqk)PQdGP-SAsk9%UeKs0blJ;i@aUCiL($kL zJ@q`*KF6_0?HDCpDuLzT4ZQmBNs0wT0S5w8A%7fDj1SS(iz~kiSAa+5?Z*P=McCuv zRq62s|1Hjb$Ajpa-yLxuF38b#Si>vz1 zwQ$ut#VmYrd}Sc-EskWy8ZPxX|9`CLEf8P6XZfPUCTa1kXDzkdE`)A0n^> zPV|46@UmNhLCSq|#5<)rrqOPsPQ1H6(n_`Yeu~0c@q{nit~Q zXM^DDC)MHEw+iB47{V9eWhwwX{v?tW6P$~2%5;lkNztrw#ZaX*P9)WE8{KBRQ*rDP zS3y29Z7b@>BJiKA*xa(pNV(`fM`lH0v;nsayKEZ_sIc%C_@JoS<7>AD=TnNO&*nA7 zP4TZ((hR5KR%9-FT)ZJ;-Nb>SbJKP?=f+Lq!r3i?Xaz2)hE*>wtt>XFYt-E=@g=?7>@f6&uF71sjyf=MQQ0<)j7w1Y7FYZu zuqx7`fwHP|dw0}Bd><#PM!8x?*CbJdXVBhSt6Qs9xI{Ba4X0WzTU?yT{6$u)HWp+O z-`W%xF2GqzZirZIv^%IAIxAQ7dS|Czb&|+KuP$4?$Yw#c;z^K+d(6AK#?EfEx0)@k z0Y!J)wRW@B61xX;k*i4kctE~F^b>W)0wNDV{%N|QF>Zo5St>acuIQ?6ahWLFmU0U) z?)r*kS-f>DPR#IxJprk!cE6;Dkec?iJQxz$}iO=F4`!q zd)oM4(43o~t+n?eER*3sZf9Q*3e^-5TwGh{n%1YhxR4~>avSZ9W~<}6t}5qo6e~K0 zn2RBnNqV)>J@Mt+i2 zlUoNW>6$d-gNq}P`fNC!fufjIr&)9Aj?T|4RK);)B0E!e_#LNSsg;`*v!W{sDr=h+ zjkbzzsJgC|YkaU~qa$^r((Ke+D~SRw!4_~-)=f)+Sdsa` zDGDo=b6L8E5kaxy)*$#aRfa6G>YLYJf2&h3gLWmYvUB5&PN(5iYqp{Ip2zrPE(bZ6 zd7%hA=#&`&w3IWFTBmDkrTNT5=TI8g>K3<|&NQdKbL*|0%{H_OWPngHHEvgpLCtSI zO;8fmFbo|ccdg0X=m&LkST`;wAg{P}$2Pd~CX)=iQmMKoA19B4BWu-i?9YNQK?BQ- zRAp0a$a-`8=8ao7%bLu^{@g7Ojc_qovoym91}RV(bf;?7Hn(>)DU!{`Mz@s)^ISIF zTFuZDRX47^`TEU+~T&8Z8~zb5FJi1kRdvRg4wH|m>n z93^xN_=Hd&- zS;ioP71uVUBHRF!#hX*C9(HEXupvTO&;nZ}W1xvfqIgOOia zoNxUaNV0Cbo$YJ;*KbyAHSi`;T!JA}cb&-R=I`~*YrDJKQZ$=PJTyW#9Sl{=R53K2 z`u6o(ue%QSrf2L6Ndr4NWt%jW)Y`_io3Fp-8Y;OOEC>6b*(fEx2zJukyY<#~7pMHV z7t)F!3_@d=rd4U~-h89gtilE|)!g^y3gng;#b9dgfXhuNZFsAwJ58fbSC>=Bq6|Z| zTm^8y*eo|H?Y-CD+G^LSnBo|%1m`-o34H|l2&qwV`4y^APwU!IvaHT_a~Hiq3YR3? zYLrzuE$L0SYpPn=>9)!>O{}ewl*(@V2Bf5_z#i6fNo!X3wyJHh%X(1K?dHaYF2%Fi z47_NlrK(<%^RpM!FGT^!cCEW}?bhbTM%mIJE355I$B-n$ZMU1q)a~r;?Cm$|HArOD zY46>9t=(>OXWAsOYFpQDy;d)qkw1@9rPgX;*v1g=x*P;at-HUqyIrl6vnWvQ*6xj4 zco4+RV;@|$y}R#d>2T1`6np#n8#_DOF#ExAirv`1`Q}EemdD&A-D&OZ-?#x`=2&`O z(i)u&Shc7cv}6ETCO$|OjZkWv*RS7vz1eEJjs;7@u5ayJyT-kz!62F1-Mh85wOMbp z7#b*(n_Jh~^@>04dtm}CwtxLbz2+(Q*lgi9pr?mlrXYwU7F42<@U}tgCn~9CdTv4a=nNJl&Ma4XTNO1V6L<~ZFCoe z_3rLoyZ6y@ z->xZ*2fZlQ+uJvG_xCZb7@ATm@7{b1oPcgZ-R5(KGF^bAx=>WtZge-n9ts3(ZIhbP zCQ1eU9b>8w*fV_uD`aqx!I`IVsCJI z+7krKk00FeBBjx8CElr@D2`=J#S$Yh_M!sk0oRKe9{jJvUWH25%rf*&+0nQZwpakf z+VejM2#Z0RAe$4=xFlCPa9;S0R2*_wUb}8Xlg54&`do{u+iEFF0xv0HTsCdD$!I)M zMwjVqkYR{a;JPv3kETKcND#7>CLBW@!Yjkb?l^AUfIZHY{<4gGY+H%u;8_{P)ix4 zRR*eyJt3gM6M`5@+37TG$Dj9x-T)nLSq&I~Ff$StD;5KhHwjgd{ z$7IQD=#AhK7;@4Z-tW&ALA|PF)f*3jIBPiaYc*IprAbUz0Pr%Vab?wQY;?LExLS=C z%n}p!K(*P0Bn1_8v(nz&sk)U)z13*8U}GCv36`T`xn*0QjZS-~$ESx6PL7ZLD2BsS zYi&1c<#2{>u5`Ax@LUasK(keCv@JD*K+)}rp)2!Ae>C-=in)+mn4pF#LilF!TttuP z9UmM$Wau84^)LouM{{?0SV#s8i|ux+rNhj}Kp`3M2bAHrqi)mjFv?`7TyJmefWyje zquK6O>n*opNB%T}4lg@NFhgfEdXEa*Nrgem7^N6@X%+|5LGQSKdUSknzdxKX{O87I z89qpJqgJa~P8k+0D#OS(rOX#*2nYdBB8Gl9Ox>{R?X6~`igCs-vxESG;cvsS12s(t zEk%_WZ4uT(z1?7-A%$vqzS=0SqItySG}6sXc^%*I}jpgCMvEf@{91uV~cyK6|1=ZBUH`z4!=N8{eZ zJKy=n2Or#>$C)8Eq~(`uuu5&1SB#TK_pRQk*K0{Ij&c>uP;0cymO2}s&gKCGUD4ja zpNAo1yTV2Az42`3K`6^ys{U+%0gbL_z=}#4h8ri^=@Zba#@(e=Bw_&_c_YRGisK;m zCk)cy4FX8{7`B!N_a8;l%%&e8<{jeQxd}af z76Bb*!*8_Vh_Nz;!!Clz&e2|oa!~|Kc;OXEs1-kp24p4p1pbtj@rIyu3Ioll8Snt; zF);Qj2%QD6+&IHtil)K%*c+Y98Q==uOE?dMh~GLttvlc@M#0?kVYAJ>FhG}1hQmIG z7<40)16Z09EKI6%_j>YwrPgjVn~d3Sz?9?)Tf)!i* z=DgZy!M(?LGaXk~^4YjI@qFK>7G@ily&^604U_&~13j7c!A-dVr zv?SqY*(oev`02q6$0F`dfNF7%j8Y!PdC$*1bc-N5;OYt>m*C^_YxF$ur<2JT;{!4U zYNuJRMDtmgNRUq%SZmBr1Ti{7$d2`a$$dV!E6GCxKfV;o0da}4N{gAeZA zxicJ%!0<3%sud&jId@;FIH&_B)L^ZFI`ry=yg+~9kndf24ymi@D(WCeDgunbdlS4v z;1e`!DPa^E4a$(n~oS0%|AZRHor^6wvcm}s&+zwWIGMd3tfMLTh9&9Wm z3hF;6NpW|~FRRf#-b~CYLgb;cdM>^Lo_TY4vY`Lq^uhfP-aY9J(N*F_6hGTnHJiG@ z8z39T#DJ3(hd$cS?@gz8aK)1ZvI3|x_u!l>5Ta~FZ|3=uYM}8sW5)C#Ey&39;6!_u zqE%S-Am4%_BqaZTB7lLZ$sjx+ydbN{Gn{PZcSMUMR0ByELkRj)@yT|QMggP}gq!%d zH=$j;KH){`i&9Y+h4VyE(42&TFkOJ?QZaSIoI@WZfpd{X9()Ko=ZlT=gHkrLv; zP&5qL1gusNjKe@2KC z8Aa)gmRiqCNzZPvPZh_B>2{jUCiGAM z| z7+&zYT=>V=u0b>7aXeeD!kn*S@M5gOF2Q)mR;mu;AHph6m$KDmjL<;gl>+o}UNN>P4TI&=D?&SdBxh>{xt( zR+1gKyfFFY400UIh7m-TEA%wQ9VD~LECde{kRhMbtIc-Rg|`CZyHx{M*PE_ef%DEe zu`+J#3Uw5zcUMx20;MUaz|t z4poK-&nSvg!*LzQ^at}90095=Nkl8B; zPU8$>u)A~ZX5B5rsL~j04(&h!roo@C*%E{P1+vT+!kld=xoELHj zZ5R*wx$d@_P3nx80fAJAe#c7uN&n=S!PiQvU3N`f2CcyW;C=2JBV-fUyxM3avy+Dh zM^LPy`|BVqJOdcs&}CCb38iAsA@UjUHuuK;$;^`t3Vj&q;dD3)^LndOwhRv8xd#ut zQmrZsSA9GXp+g~sZO4LHJe|$>Qrs}$4#EmRC%{5R5hBVVXeaBs7I}k{qhkm;%`_o( zkmI<2G9FJ*0gM9M(qZ7t{RrYjSJKhRLBBuX_DvQTA_Pfc1m&{99b?26V44jFvukP! z3>Fjw6M>=mrF1qt?e+Rxa%5T{DcmEPZZVkAN4E#F5u6FW&90QW@+c`)TN|}%1tJjj zfu@19194{KagwWUv)jU$f%nT+4dF}ZmaUW$So3o@cBK-=k{|Fxc-Z~rTD#_&{sgxo zhNmt&c{J-C9!!I**4(g_m=+T(87}OxpmKC6g^vMlgnf(Q4ch{3^wIlex0K9Jj~4-5vGnfqAZgH2Pu5B3*{ox$qo)#EXJtQ@EVTyC`zf7kbB1Lj4 zHQRAuI>2w>^jic8i~i0EK2!}(x6seZ)H>fPl|e+(^Y3LjQ!$FuzU@N&KchVG?tqNy0P7)V?f0G^V?Hg8~5#=j@MttAVcO zd~K4#wh`(f#)Du1t|Xx*=Mo+m4_vE*UJU|Cb2>ZMHn+Eo+`s$IH~Z6=Z=hi8CsY6^ z(1fa>%%CsLDNW0UC5L-30MOsGOxQNbu5Dhwc`fYSxqI&+U*4&j4!c`~sDk^-edO#ycV0!>w67NUy_ z)=+iMtHVQrG{rHyiL=g9rMcbhHp9XFd-o48G?7%{zF%9m8V^s8F~WsK0uq5EaDx7Y zEFcR(ZwW$a==&%PGrCT&QK2xAhZdZ!W5{2FSno0$_1o zfGBl+4B!mL+Oj!ofX>q(yGt;WVa=#IwF&KDF(V{FJ_@xt}Y$b|X|x?xd-N`@`LpNuojF{^DO8qTNVSmlN* z7>iuVh9W|-5{bEqR>=xXdR7#fz-TsHvCWww&re}-VZ@16h$7G>4-OhU3VgI1)R6Dsl!kF6q_%TW{#$$@}kr0L=&^9D{0zX#ALrrX_P zTrxQvz5mX)CqWJ|1)T~p0u~f23^fcJBxOTjB+xu!Tt)QoLM}mQK%uHdklkXMi!;9% z{%8Y6il$nI$~{M+VWT7@e<@m)F}ObTvI#xRz(<_?!-KG?!OLh>M18=X0nw5yQS@@N zyJaa+|Kw;k4`rovt0i}p{I^f@!OK+ugvFDEMFm)K^7CYgB+KV6!19g?>9Dcgs8zyg z@8s~I7eEs6KHXg0M?(1Z?9UhIC?sW zG8RW7^;wB)u*zw1SDZgK;92ayFO0EDBM4O$qJ%u!@pl(^O+ z7Kq~lK)4kxm{IYVRBG5#MJb(nv^OsRZiDA(Ydp2uu>CPE9_InPD6kxfFPM3NO6J1P zToUr~fb2AzGc(bQ(}!zCKqj$>MY<)dibVUlLu3_>uLxWUTmJbfv!d8CeevJwasljz zf-Q3)({V{tOI-)HU4AmZ7+?3qPA zEx}DoSmwKWkn6)+n>+Ap=Y!+pqa%MUm=&^Jq!WNb*3K5NR+%$+Y{~)_iI??Q)C9-t z(%>8{k`~m5;Zev0*cly1QuF-SI}45V;l=_&o{OU=z+-9g7+{NFQo)g4hRZLS_&9ic zo{NSFuV2_W#gKk%=}22Zakn^tBG&{pV_4%)qY~~tvq{Sgp4|9V>CXh_g_KB-leI^1 zy#VBcUtD3^pPc8@>U~D;BERDJX;74Sp@q0uke!UFYLHLp%Hq};oUg~~5w=2{a6|imLi{cl@MZ3Z+)LLN2}EDO$`vzaqESLJKBW!IjK#_0pvY%&@&tIEG#7vsUI=ee ze%0_ID=<)GIaMN&zLC;(t;%Jdm8T100CG4d zXGo((H3|WGq0n_GD!fckoDtBpqJfXr`3ywzM_W`}DF)hwi|32G2&=p62lxf`KtoP4 zKA|F4gqN%UR<*|{eemGE?+3`cxb=yGT+`I;?d@{8jFZ`Hc5rY2!yhdxZht}`$3WWI z*|BX4hW5jU4=0n!$K4$ngJj6^bT;Fh&9i}g-xdJY!h`*O|M>X0cuBKJ^2q=;92})- z8l(f*36k#R^+jH*Rkyab7H3Zd6g?h;4X#2xj*i{kT@3Sk_wGG)TtM?FwOXy!YC%g; zM$_F`nD&LhdGO%DZ04=ya3=A=x=;g8k;1qR(T^NJ(wEBEoYP0?Py-j`;aOFLq7-+F zA90a@fi@nGA-xypSAsMCC(&3YvVD{ui&{QTd7m`^k5MU}Z_!JN1tgxt4~t+uN)HYW zpwEkYpFkv!LR@0dLX+RUdl#Jg32X}uGzgkntmq9;zq$t?9zn61iX24zHRSWoJMW}vqB@)QYk#7Y@m2LA z^{WkVRb|cgAN>932~pZa(s+mz4HZY=f|>m4hCh?R~hn5Qmy$1|5H4A7nFbd zGoQVG_wIBul2x<(=096fbR@WHkG$y9Fb-sO_Re2T=O;Lm4Y&OI&y-{aKzMvsNUs>l z^qzP7uj8!QY~8qd^WedK3^1Hp`#+&KKb0o|#)3%wii14+&R@>L5uEw`y}kE8_#jO% zG&Y>q|76aE+m~$uNGB_K+TzG-tZ<72+ApOh)@X2<;*^0226nuKDYx8 z2Vubml4`s#8{k=tj(fit^}Z>jHm_)nH|=Xbbzxj^9H~~+|7|2@O4L-&8;!=!jkmj- zo70oKw{O2U98Y4tKFwsKR(|78qat}4mf!p{s=IgiSAHy+9YAFL(Leqt4Jm&A{r4it z?rdzx!MJzY3&cV@P1mEq|Mqvji?*xoHT&it&C@`-njcV9+k5Y?CzHF9ti1W=o2H>d zbL)(CvtO&&(X4-TaDO_FAX=e~(lq8gp2C&9ij>2ZxqbUKT^2=m-uTn9=AcQJ8)%%o zQuJhU&wuad(1SbMw|?-mKb*&Y7*EGxps9M~4}+3kvmIC!w%x4gdK}Nk-XLZ?5qsth zQc26Ru%uMl)s89Wvw3e62X-6B!QuT6##0~JLXBKi0Tj|-Eb7>-*!p~YI-dBT;#Ys= z%UPOOyFa%5=l)(6!1X)7*zQ#YFq2{^qwoIw>3{o^ICZNv{7%MH={tY^o95=HvKS8O ztEB)Q<*z(T6kC1xSAJ&poxg(9@A-k>^TF+RhW%5;YV7|@_hj9n@$%7%PN7+4@4dh8 zefO`(M!oW>Kc}}|Tikmbup=zRd+(PH{_>CF)UDQk{HK2U+rRZ2-}%;WpZ{_erm*G~DPIsU^dx@Y zadP)Rx|YR$wO;wm=UyM4_^NFr$Sk-aCK&^ymNiEF23p zkim$CEf2v>xxp)to<{eN{k8I&f4CS~SsWqTlfUt&X5am9kj?M=@t^24%I~~?P}_R_ zjkjLcg2CPQ-Z?z(sZMiavvdFb@BG?7`bS8nZGLIz&whno1B<;pV{_nG>cL|FWt0@Bi|_U;bg7?(e+*BVYJEy}^MO&*PHOuC|i-Ae3x4 zQ?oFxRhoG;9zp&`ky~YWuhIB0%5rahG>(HBx@AA&8q z75PdEV3Al-n>(*xzrM@Ozy0ya@#$fI@|(Z%4{+by`qI|V{QWGNEbN6>AM#vQjOpOp zy}$7@`S^X(+ZD%?ZJQXMbT4v_fPz7XZQDJ7jxq+=r-7fSui^N+ker! z{c~dAQ0OmGXf{}}{Zs#mbL)?!UVrg;o+(aq{G0!u-Y@)baQ1y){JvJba_^vD+rIVs zo3Cl}{+;)3k3(r=|F!LI{qOza-}?49zm80`xBqPS_x}5;%s9c!OTd+E2rK zMg@QRpZuqq-L2`#1247eu6%g+_KcquDXrZ%cDi+b9hnBF2M;o{(b?$KD&@cRbARRT z-Mgrd`Ne;&`$PXm=_(#73?`%M-}!~ZzxIc5)@p40)DQmT#OwEGCw``HG2DvjOR^I-6Sc zdhLt(Ilru9*Eeua@l{$y~%bgNZjx8FB#xNzzPmteT-@ zvv8I}ab{7FGR_nRy)0!x?5mosNu?;Ei>xV9l7@>k<&*h8A&9D?&%l6SDba%EBq?vuUw#GJ0x$RMbWyMK z2y0E? zOcbDM#%ggjAHPtUj{}RoxNz|tt~CdMN{iROLT+yUfVlBobbAE(6bDuotF~iwKC{SP zF2O{>T?}*a-W0qH0VKY5Q{+|Avf%R~BfTjS_oO=YNEaZ~T!2jhU zlBFc6mR)fi3)(-4!~W^fpx;LtrM#t-H>8{kTT!v~tX>p__9;0x{*WlV)E^9}+7w>Z z%}TSoySsnAQLB)^ka)9E|K!L|LTe<4Im@-)ubpGFSB?el{*T#XYnBp{`B^zWCLcS_y+&wV?m;qgA_Cz z^NX6}SJBJ9HxtL~j-pH)eT+zB?df$`w1w^?6LPQ==}T(kmXLI3O@0w92o59-VDK~R zQm&esRfgpV@x)yUM!nIXKbZ%96bG;hqgX^|k`-hB$Me*u7j>4;3!o@7cR%yz@gKyK zTCQ=Ghv={;AWf1inka@_`{Msvt!(631eK6QGu}O44Q5WnAHkdZo*%|hI34yL-oH2C z6ihxF9S=@V##4qCMjFX(D^5F&ru%HCtl3pfK@C0l3KM_ogz8T^b#OSdr_pg zcsf%0FNY97DjnRv)9?3isMsBQ|Hrr~kT69*9;EbF=A-vvF5sZhRZqmF^v8c!;{_0nM<2%3ojj#OA|I^og{T~%i$W{|>L^OLyLcR=91Leum z6@5IK{K`N0JHPzpFMsXVe&z4~{NMQb|MBO3@fUvKt6%-~U;E16y>sVooPdmZG=SfAm5vn%ro#UOsDZo3_veh8n7Y46-B`_m2(_?hS_HFp7b=rqyoPyFZf0-p4smUkquf3F(?kMg@$;7K+iORdy9d zmQEgdkHts;Vd0% z4j2!6Fu8D`m^HPsooDeP(*MVVaPYI#A0GZn4v(t%#Qs7W0x3^#r8vpiCyNt7yVb4L zLobG+E0-jaU=jM$c+eZ&dH)`#s(BqkYJp$|2yVXr=WI#QeV5_{PQiFa`|bUo{q^#V zKa?lWKfs}YRPx}(>t_hY&f>ti`A1~K&6CwK0g7620N}ygoApmm_yGLc{of}lz-&R3 zRaTe4)#EIN0q`EbR$@9C-+uSqSVS?&l6XGp-?{xRA}=fV94Gd~0oAt$`x#TCH1`M)~m0shu*0Ti>LIGk~2Awnv>@(7Bf zw}7yq1AYI;L_5HI;0ErYKwWV0k&hA?=gaMUWc@ptuW`Bg8W>~n;FoYhvAB>^t2CnW z#b6d@1bj>J&8lb;8^~u21z{}l04 z|4ikLKVJXRzixFuC()ECo;}O$1yGjq)HgbxmUXK{7vQq_Jc>~2d8Ab~-B10ql{f!{ z`*W?mN`Cs!st&&m z@|WQ>3c=@ba*`dYc0MENHYx_!u&@^|O&m5yE@`!WWD8(13qVOMYX!wM{yY_u$e)cz zejucOsT9Wfy>a%!%RpBN9(w?ac%FCv!2w7B{@efAuTqT{>g*E%+#@0!Vn{1`I=nsp z`F}-{xxJ42nSXBUkNszfHz;O=K1PsbZFKZ&(fqW&^@FNWMcrUmo$oXBf|5p)aqqX{ zlW&ZF@n6MQ!4;%ze(7KD{P_PZ@%p9pCEKqkz&MuEEWGz${7BsU4h1N8IO4BXzj^(i z|N6(VlJx=zIw$_%{+AWasc(G|PJyU4hVMCmsJinXe?A)CUbF&|D@$8{@c-WWzJCQS z1nyo){{p~8nT@0W;a?nm?Jt2dp&Dzon(s3tJ8tg$>@U05e<%w@Ky(0#!9avr7zbd6 z%NHsDIpypTinqn3mkGISRH##nIxhiAS1oI&|MS0d@^}7KNip&?R2#2Xf9n60`hC;g zuXetWUFE~N0wBZ`RW_UpMFZeJDVB2gKluaR2fv73ySBf#3UhS#?%iUMmHQL_zS4Xn zk3Cs2n!7*7&ZQT=meKQ9k84uv({KN`5C6MAiN_qr+1c4H?$APA{;nSY){mbD1ZO-q ztYrP8fLp~~200N2=GOO1{BZfaS@cRHS4oE6L)!b`t@=%^^BGPxfUJtnMqW(+F<_R* zmG-B=QNzPu$r4ZDXT7PIOIRUp(jee3w}>kM&z`|r;+KJiwes>2++4K!B8XcbJEG}{ zW>jjM-vfVt+W(fSS-iNYIZ(8slyalkt?v`n7K2kXD2=@=^`V*8R7RFj7Fo7 zkv8CfYp@K`=`5Z1Q%|5c$ov665MA%SOCfU*?J165HkP0oVW}kZK7W^(&IgIdsSGwy zBvTtV1^=TK8Doqt80HGdoZ?4|27-XeEGk~PqcmvQLgLNma}f}!q_*Bv8aGM_KZ-^s zQP6{#!WFLS0*e(Kq#G%RK?>RUWbufaB!S+14K5B&gK!Zt4^Wg_{9X}WOaVL!>s7f> zt@4c@mxTgYj)zwr0eo|_n5N~fHrnQ5DShqpe<4pJI7t^C`4~_PJVn(pj3==1qmiWQ zQ zTOdnUHGA(zSb8ZJ;rv*Q)%sd(;|sECpo0Zj^6~L+4jz1YHuw&VgIWLE)803O>3ukD zSsE0t2Nd1pCmm0!vn=Q7-0XfvZ}6LWh*gNz0;oUO`imm>nE=Tlc5+j>1*m{aDu8oE z7L{P`3@5izQ&~J;GKVl&J_*Qn6cr|6Qmw=JF~F){*Ass%2*v_0y6sOZiV@9E;0MGZ zT7asY9BiqKmG?w(T;%+en5HxX#ez2hSh4e2EX_4g4{z3u3uiMz(ExXluK%W4h z!(Pm}@)F6|TX6HjA*{4n|69}kZ$lHnL^!?ocY62#UhnST89w}#@zJjbvx6j_&`Mss zF1~ z>Xkfzh5ixp(XDs8o744*R%) zSX29Xw1Q%#|!RBBT2PtpZ?RO&=boRi3*Ajocn3vLW^EJ2imZF)Ff8tN>!cGK1 z&L>;6VgXqK?gF1-_&tRPk08lQIxlICYmDc0!Hh#v2&0Y9%2rK6K}fXhvJVMAQs7S6 zjL=2b%4(?f{ZbZ@lB@~{LKNvc zk=;tgaB7>^-g^D*&+hH*yA@kwAhs>2qDIZtbls_UHg~UY@9o!XuK0p&33*9X%MG_% zF-#%2Wy@?dEA1Ch0Ozd!Gr&dJuA0x5CcU~2g(lj*78%DVc(M}O51VnMSIG|t5gtEE&rJ|p3S|oTm z$S)+%2PfbszS?q5JdYxO0wbWvWdVXpYW?y+utWHgEHrmeW)l@4X0TBx%c4S-Qi$RXm@?*2gG|9-et;Cs@XNGwr|(3H+O$e zWA}%EIB4$uFmd;XTl+uOzW(FQy&u7;(|nDyb7;u2lm)^wQ1$BPf0lV-%*l%DmQ_tR zZQChVY}?i}qukuwxpr$8xPPr)t95p6?%#NAbN9y1?v7(>1#JLi9n~~7JxjuQFqsB3 z?$NE7m+=4=hX3Lh6;*Aw?p7-*Od#9Qb*_^Md*AUNd_}bz@L`IPdo|>U`tVVLI~mRo z7w@jo0kE}qe}HXf-&{!iOuW#9tKfy4`5k|rConUL1e8RghN}Z1gK$fNAQ1HzfRyO) zg14@K7y}SG;rs{&Z!}+`e-h4*<8Z_g^2j64#AQoY$icvaMb$6B!q$5cTorY7ypVG) z2W&I=+leb2a%qFMb7#{xW=;*7%!+(T> z{)2xIdJI>7(LRGk$rVR}f*&##ZTZNMV^e@y+lR9y=*()+4`u=i;SUEdAE4k`v`I+8xLf$G4&(GaiH;+X+%MJo+hzB9rjL+ zPLB@`@826u1KVxF*oWZ;2kQ) zWfZ`pfJ$abG@JBilX2N`ii^W<|J67+h1P;e^kgi62cpf3VY807rKq|Bljp-kVNwxM z7qXM+09=#|*WUU*d*ibb90Jw2@YIu#uZ$jP$fXgvUCf_V1x-}J961hnW$l)b!hE)r zEzLvGqJ_XZpZ^PD2ID^s`@@4@9zOil;lp29;;#-Kd>PKH;AUv13r{@*m!fcm&{aG@ zoi76VrC3w3TwL)?n_mYv4{er`BDGg|J=X-_r2je!R)}F-V0{;)5If-7Bmt+X8`YyW9sVN{R$$aS14(w z*8NnLcvNx}W3X%wC{tdX_nsGJ$bgx(^*uNK;#c2Etu31x15ZCsfhTL#=&gd@ArFt z5N0@;Px?pq4<0<21rS+q7s{rg!xYpMEsjRVqX)g&AV{J#OEuNG`i@|D28zT)8PEYS z4Z9{NZ5&j3zK( zkQkRlNluelG(VL%=L3zYEKn+GX4R~0!BP_&z6a<41CLxy+iWSoQbS`hu*hD9^O`(H^0 z?+fQnj9-pOx%LD9qUv-svo2IVvN_*_FB?BH01Yv?2EY3MlvJzyxu1d0E~p3Dm8zO! zmN&!)A|G0fKu9Ot)^~6y23=eWPM0m z8e8M>H~veG@ig1r+MLbilJ3+SO+%I9ILu|3^hPO5BY)=2eY5OJ$$U8ILq~uS^m23e z`gL1N=d;MMJ2lJBvIMq&oCGD+s#iKM@FCdhR&jve;vma&%_!HJZPSp$>G1aL+s7w8 z&IRXL?I-@vYUfi~>~T~eEvSbd#@vV5!p+JJrz1mqRJI^WR7gzHSCp{;M(3aPzdb(r zEm+@0aUUvx;;L%!zg1C^JpR@H(E9YB6dxR(|EA+{fWek!v0-$lJ&ngIp`*(KdR{qO&kxc9ECJFoq(zOI%#SFRQ0 zksi$+43B<8d{Bmph|3s+X>3+D>ziNX_c+2Ty96w2hD_zG6rX(c|Iz=&|0~Y-_xJmQ z!E8EJDjT&w{O|EAq~`!ZjSOr@Yj=gCMs~btT-s#)~CQ8 zoIJTa`{nTdp!UA|@9x`g{j~f2|3Vgs4Hd|HkyX7`ZgXpdE9CzifV}yh6LeUWQWz`Z zRFa1W{}3h`L*B|tW9LWldo}v!vgW+|AATV`{f?#^pMCp{ndgI}I-6ULmJNGH^F(cS zHY&F6jZTN-sa0txnLiv3Ad`itw3_?h?h|4PwJXhNrP%Wc11X}#&T-m0|TXl#F}eeL(R zul?To))#AhOWxECmwFsk7L+WI6c*+WGJ*Kxq{oMh6tV@27p22G(=EMuGoKy7c2=IF z4)7T8YnD5-yw=)sX#|LzjrG!5iejLOe9ydZm6)QzK|!bG zb#@lZ5w~P?oEV!gh*TUvWWrxgr;5rKtAG~A&(92;wG%W!-G~5Dy~`onNLdWsdagSJ z8hno@l5xuJ+%0`Ijmth@T<#x4Vw&~^=^i1%c_bxEd7NcImPHGMdnZYnQGvbE{nGyq zd9I{C0mCwjF>shU3%xvoXpm)w-GG;qB_2HW%V7rnQA(KQ`TSoHxhzt5H|wAM(-;+U z@d5xO5_j1(S8MEZA&Q{2EaGf00PZj6dJ2GNKKmNkV7n4G3VjQP~(F8_% z988Yy-@beI&X_?z$H({I`{4F>kB(3Mxj#BR?Dq@lPlCk$=;57rk5Bt?8c)5$yC?75 zIeqVVavG*-oXmQoyWp(nf|apz-s&NUD||Zm=urf%NKlWWQX-B(F%7eNwcD z*$K*C1=%Tzg35`RN`ZxH!Ci4*6iC^9Srob?_8y4U5d;`DVI&q@i_*`v_sIx>A$~y( zQ7iFY;cAEqpl<0!nlDNbL|DHrgM+-_-CtnMml`bRH^72)qNR%_KM@6RB&-3y{J_<$ zlqFp4a|XOBDSEMxVbSU(uH$AQxNoqR1c4v10%+w+p2Rwg-D%Bu;S`z`L?yZhsEP&h8It<+hYZ z$Z9?Di=rrtJS|4FI9Og6rwevprN1092Sv`}skQq(dXsx%%>Cu3@UVswU-ZRVPdx#P z%CJ^~R$%w5AiF~p`q(z&3RAF0&R^#+qy+~M-GY>hw2#f_`H_!iF|1UjXw|G0TnbU91ExhCm^2$wW&b%;V+nQ=#b3Ga$RX zBoHb=)CX2u9(&2;IQ0jpBXkejA}YKZL$TaNfOzH^NI*T-@sTu7 zLXm#ai~@4-t{U9=<#cu|A_7sDJ`D?Y7r!_?Ys-rxAD5*xo~6-H7`^9;Mgqtc5|hJ9 zaM;={(7YHPNRTHH?pd3kSM6%yORiF00v8oq5Nz#M(QsT8V_q=*<*~?tGKf-xT&k){ zrCdh#sn-i1d{x#gjE%F>pMgup6FFZEpG-Ybgpk0G+&T};W7$k#ar|t&nCGG|iaZNo z&Hx(R(9cB&0T$^mfr}afp3?AVV}|;~{t3Gb8H$=;67iP==I-}EEW)=ET8cG9bJJ*& z37v-$&pq-{VbL_cDHMDQs~1(G+IuABi=wPtjNV9TyOjQb;&}babHYng0HAvmMMcDR z3MLq6j6-tn8>JUV_BTIg%^|`Px)EZ1#Zxh2eD?KBz#ygckz|j@#Ut#?wHy?g({J-0 zEh0AcSqPD}5I2w9dJz<3PtLP2OXiAtwh`C`d{S9Z0*i~H+QU4_~;;8){6N2uzF+- z7x|nAaY4|Hch58PrLZXF(I!7XLO!JNM9k&lm zTR*K>RkXk8j4PpBs&0I~w)Oq>tuHpVzyDeI#pdqsDc7&VND#arXqQF0Q8CM1!)cr4 zr(g%a!fryj=cveO1w|)ok*UP{<_^ffMxWnOq(VuIBN@vI;Cr&I=cTOA0Im zs2CpN^yOeN-(3_TibD~_shHhSRf^k<@wgIAFY#p4SUjlGEC z7HWrTpSvzt;yf&Foone;aFOj9pwq>z;#K_l#FxXzHu*V`tVc(V((yvJFN}(uCtmf< zKcqTM+J$Fb!-HkAE0=Ofgd~i0yV2PG!P@5cHnzV6k#a>bNbbpFwZg^vkSakCtWWV5 z@ciQbQ9$-r0+x-^CB?AIy2(%B0Y>wt%)KkcTgt0qNw-^u)6pruA)}v$2Bmz}An_GN(u{O+D0VkvFFz6S2M#dn zU;?54L5!;qK`=MyE9A$yf&`NM8Q-HInW*YH%(z6F*I5U`vPCZeIhgrkLQuFs)`3Ml zsi1`{cp*gYLTZpp&-1v*b6NCLu}BOK1)YkT6sqe*aaAkQ`|&-pN__r$k$4?={al`p z;#zJ`LqVdm{JAC=|2emQgkOiSe?%QFKJ_9f9v9q5ep_Vtf`|v{hvRsa)#VYK9UIN- zif)Q117}qwH}da7`i~Y%8H5kaO(Cx~6s>qs@kp}gM(}?cO{#DFq+VlG$CPh<&ku#G z!HX$?qU;MbKo1*EwYzh}t%|LX@h3h(Vqd%r;i%gRSs%kp5Jx=@NF_b~2 z`8t?`<6)W4W0CTjo2$@bBI(JjqH(I0Ob+rmh>pLNMKexn$wDnZ4#ng6OTn5LeGrnW zW^$Dn8T4GEo)4GIjl5|?31jkHaf@G}1J2zdidNvd%)P?|utnncidf1rhTc6_A5j^> zvP|&EBjn}_SDuA=2D2h~__gr#Hu5tKecb~P89uQi)(|!$xLfIstUTj zAc~@aY~~|u!0UuZuhXO`?iH}gO`JT6&rd6|2h*Pck2SYbxT=q&zZBw!6&5{vzG=^i z905fRVpv@f>GBE*bKyGVP8v^zf_@35TpBSt7P5$6Xg*`Y;5iVA4Q-9Y_af+BNZ)h3 zbVYptT0R?|UWO#8POV*U)F&f;0L&|50Ww%;tr=H9A^V;iK-I7%z3A_FIG%H zMX8y^13bnuuK(rNRexU;%TPxhk)9BN4(Y09;oRVB?)->CGG35nZ z*6R6C5K~(2{!yye>&1Qm1msq<`urnLK+q;09{%d-y}#Rg@JrLdx3gri6U$|gI`u;S z3lt0w$LqX@0TG~T`~>Vgpi&~A$2Os8+H)YdJ@&2cTh+H1G#jTy=A|@RM;3jiGfE{{eVFW)LWG3v`S%Mj|PaeSCN(RUWzZ!iYbS zp$Ivbid{ud)Mm@_e!v#3B<8W+4sF-<2fWg`+C0 zp0kUq8m{B&`cqI;6@LN@!#MK*3d$4-o{cC@PPtE0YS@h|o|WLD75Sel?sT8pwH?`&Na}<;BM;m`M_$>hF7w3?eNQ|KvoVW{ zVfdVcdMvU?La;Nz6A;;DZtJbq z?vJ>gPuI7;C}QIj>x(WH`fQZt&^zEKl&A_DvR=><$?nBF=Zm*Q6L5gPk}Q-oo3oHL zmqTWT0~CtxRURP))ZY2@g~)hxK(4Mo6-A2+pgLQzySO3x=3J&vKvXvcGqm@9tk(HV zee-)YO~gs&%|}Xn28u`6HDU~&M{$c)Tf3M`njR1C=5ZjLfJOa_lxf68(n~C!Se-6$ zosy47Je3yn17dQdRKD>8Mr$9AUtWsRXtZRiFaCHR$&nxj~qoc!QFYde_2!^bT=K8k6Mk0wKJuwPnV{4@L< zzp&h|iVG(f3IO?2!qDhMiMRn(B)IhABkNcscqSrik^V6t8u-LsSVtsFRn4rn-xfwF zdL&ppeo4e1e%Xri1u@T}ffuhoGRQ<62q=J&5RI$$7R0#(ipQ4#1DVSfSTy?O<#cyZ zJ<5DrrScAYO&3%2=qkZ*k{AjI+cTaQEhoe6~n z#i=}SD~IRGsV$5vnE$~C|A>o07xv?$xRBbVY&n|*SX^IE_I$`XEQcRe6h;uQoF(8z z7B~Ivzg0-&MV-YhV3zT_8$1l47cVZZJ$`9~)`?4bL^HGaw0rRzKyMZa&ZS=vc7=kx z&qij#=a(R8DGrK;hy>3BiYC8MhT_3hi`ZW)Tu=6#$eAcbHB`;Y z<9XtXolw^X2uk6?P`-m%J@PvN(VcnhRj&V#`0gPKg2ih4b$C(3e+8FU02qy{QnM^c zA{bVvZOPgGoMKk^H5T&zI1%>ag)2`+a16!_%_VS;U|BYh7a{3p-~GFym27M}@6*4b zv@IT4N7{Nsc3RPOSHq%K_$>@En!`mYX9(I$x{=OKy>I`btQE1bmM9)P6PnCKD2YXF zuYgj?uD|ZIKIe8n-`M`X`quX@aQpiguL>`e!kSz_RP3oJ#&dB{)E}_oH-2NtY}Xq5 zWaL61AhUgra-WGT9}Q%WtcsAN45EoMp9@oWbsf#;Q+z1PT-PmLV@$sFix5?dCa|R< zOt$!q{oPU??2QHd@f&zz;X5+Z-{^IFrM7ndy}3T7;7yJGU^M36{P{OP^H zgD;Oye)Hs=pBsJaf6%O|v^LoQ^$^XEV6TaR{74R;V1(xy*;}7dZSIAMQLq{aD-e{u z3?TdGg$tz?r>oy&wHJKkafFC2`2-^c5J^=xlEE;un%rvW| zmp6^drsZz0(5~(%swQTEE~LLCF6l`?Ggq6!d$+&Lm==&O&jHKkzm)DkMzQI16xBqH zii~j})(W4DzWQHlnog^91yt}^{4Ijw5f$OaB zg_M`Uf_g=3&NbI=5{gdnP$C6RZ?2(H2+ z6K%q;7^THf7Y)y%c``ZTi>$}d0a+o5RoN1}h-c52^1{d>L{`F|5h$v+xJVSI#ahY9 zZ~ZOQjn?rpO({=H&{e|fEHV^W9A61J1;kG)B7X9|hK0U)8m?FVsmR$aYAh5+NYk{@ zXz)gTZ+D&(MV~HZ+2s-Au#`g#@!O771@cVMjOg^e(O3WK^qYTEF&(~PE^ZYa zQSc8%Vc}a676}$3e0h4lwC6%T#XemJ3c*E3i+P*N<$Q*MdW-h1)%JOjk1!+90jHO* zPiELHxAW=d)(>ue_D^X>EuJ1p43ScFYtg@`Cx4gC{~dt~Ccz;gNz!5=P$7!(`y`qC zJn#Y@zzQBM4_8uZr(7}0jnDj%m-n*qqeH=|_*)!vq=Mi%TzhWpz&4^MWF?FI==fd5 zxcC*~Izm9;mrtzae<@rH9@a!4k7?kn6{pB~JU6%B)@vKdtj`zD%F-snh!vJ;;tknJ zt4CfAipo45FQhz=9GMqz$>{5dKk@mE86O9+=_a_;o#82)%9mT z(Flto(%g3QbN?hs2@*sRh1C+)k6#onqX3>-9#laQgciv@Nw`jK{L+O4->XVII-p?1 zHPJf!g(vTE76?z#+C7Jy{a~6DIj(1ZNmP_H@go03Xdvdy6?CZEdZDOr9xJA;Fgh-) z1Xl*`A~5GB#!7JXT_^xar3_;2nXhQfD}*b`KZ>GFOArE7NID!82}qWwBHv1jWQz=6 z3bM}mqOY^%0V~FxXHYqQSPuGgmkSKt@PuD70~AGJA_45UMOIfw!7gjCy!Nv4huOi; zS_*zUDCfZQl`-qwPiieu7BbY%~VuF zuWl~8w-^iOejj@($*Sd4EXx%339lhLZho#TB>&6t021ywAm*n~Btg{sjDKEzgsCE! ztKcVG!JjP2rX3CLr}Ht+HLds-rsO~T7C8(6oj_v0p24H2h+lg8%X}`6Fq-h2(x@-! ziL1DBp=d?nho*dhb(`J(hk9dEv0c@v5z95H*e!$~uPu$%MgAW*E*te^1PzI-|9L=1 z@q7ue=zA`=embzuH1LgXy!y#C0GA|DsIfxXFZYwY(dPfWGFGJO70kX@W*Vm&t?NfMPpoX$ROf(cbkBWW=% zz?sGWJdichaT~2Nw~{YXYIdc*v9n*VR*;^W;L@AIue1$H3gdJv;y_gPzi;D*{v2P< zpaY7IfAx`;wF1K-nBEn%E>O-RKTo2lf8TrWt7ux;t)aC^5|`50+I(F$tSt2MBwWW* z8l}P1a<_F0iI+hdE{8%_L;8o_{pA%@O3LCO4QA)cjk#mo_*;KB^(UxsJUX1;`3?X6 zH~f2F_wV8Nx6p+0_GdPK^e+l#dL{dX6}x~Kz*3eB{p0VBzw;H)ztL#4+wI%$-iCp# zn3eKt-=9Yw7ojG>Q?Nw(_)?ygo43f~7fX3@WFG14PYjCzw zZ{#2Rwtx3)MHkHPenXcB?UJtni(afJGZ}$o7+GBzrFD%{_SY=P0Nxkk*?oCd< z#+|>=JPc9WJ^1hc-RZl(BB=)W7^(Jd-12AB)01P009g^!GJKZ50&s*8h@t-W|MI`7 zzx|VmKVGD{B*4s3(s({P{D;d6s8wzF^}l`ixBo+KhlHUndWN^4yptI976aj|N&xtP zd6sPa(9gd9XaA#Dw_nKO=K+M3lyLrj|7$;Y_rLphaN)*{8=w2!=YH`Qe-XS4o1?V+ zI`0A$%(((|R+dCYZR-pF+LzIl;Md2L_52`wY7Cy={I`B6_6Fy+>BvL~u#zl#;T)h2 zsMY4?=I1~E`JexVUr3Y0>Rh|^=l*S3ah>Mp`IYz;>O^&DIMX}7{*C|O4^mW!=D+qA z{sW`2lg7THl`EYu7AY?c;2*8rzW)pV-kqQOH)O-k)8v`eUG>5BKl5*CwGD1b1d9s! zn2qYj_w!p(A=NGkc_tfrfJ&8Z5)f+$d<3CANJnDxfyVY&L{x2oLX>VZH+j2M#N>9UnYU+@0$;_U6a$ zzVq%qr+eeZwQcwZmZ=@zf6td|+neozaL)^?(N!Ga2PjFZhylSrt^qA#Y8EqqA36&6 z_N5>lC(#O?qFt%IN7cv;2umfXT(?rL*IZpU(e^w|vp6Is(F#jx0_ksWyjg$a$Fgt& zg?h1w7eY#f)p2nESr$xh|0B|QQTnn1akwUT*7zPR5o05ZeTpY$$_Bo2Nai_@;vyO@ zP6?p8rfGY7du$Hu(1HSwAY{!tvR^I$T(e;2AE>V9KkMLiPjEIeE3B>eF#W|KiyN zk`oiuijxx(B_6?UXIk#6{hJe{YG5z~wR#8D7x?MbGfJ$VyZU z8K!a6d%#kl#%s}})R9H+cUEf`aP=oCJVtiPlGTfLbkb6+mgl zh44HC+c4!7H-ZN5;XgpmEzfilEDyfdROn<4V?mrQFY1O486fI`Do}W_v84=>AqhwD zv-2#H7x7eB{})E|L>B9A+u3{*-Z=_cTo(oA8T|FLm(N$kLe3Bs?ZT~(8cVsNTdLCl zUH!Q~?4Qhry}@u4fvIFgQCU40BJ-K2R~j|f^u1}6qO(--g23P_OcGo{e}Qj7D>zBP zd~*4B00gF|a+yrVMIfNct?w(94S)DS=pBZ$haV;$0Cl@1;uNlt>BSKM)=cABCk>Pkf z{H6aGgUu;BKmPlF|DyE$eW)eJaZra9KsVqQ7f}ZcF8B-|eDDE&HK*44!cWMGsoPzQ z#H&;Z8ACipljEbW{O1MV0NUUGPw;buG=bPM$~zYyc~Q(W)pW-1etGoWzmIdD4X995pN37&~hhFOSpH-|{DSg4u&O=o?Pw!rhM$ zCCF>Dz7_QDOz-?!o=cUA4LP19{5Y;sYg8)bJe>7=CqW|Dnr*E#KYDNwm(2FgwXLm9 z+f?Jgi;~=_wkmGbP)p?!(3T2mjtK)^rB@g_5vGz_wP|U&yPay;fINb!R#Q3 z#*}8X%fwvJWl>mmN#s2g{sfK%+mp$1&25Qh<+JI?^JXcW0oWdKoTZSZ(^3C)>Ul|$ zgg$OgggT_y5@zO=szj7vF-g(<5Dp(JCTfM^Q33v!XOr=GHXYCXFijJGHlEER)i4!B zPLpUh?)6Sj=DweZ?ckSyJRd3LRmGC9j)m2E-nNw_&_5BY&Mp8hKDt}p859}v_a)#W z&zzs96-5J3F+lVP;NnHo3Z|uCT~Vw2Lfc;qFH}h|ZZtR$i$TP!#f9{jKxpD{+Whn% zC^q5`gDCRjU>+y2V8twtaq2~(Cxi?JM_9Zhpg}qQ&X*NUUwt%_=P6&DHug^+x%-hK z{jfYOhCd)qQZezK&PKeyZ7FE_w@91aCGnB{@oW=0O&)&;zSHcoSKG)e#EKw-fsj4?`T$8tc_cr zu6fA_rZg*CV#l@BYOqTqDh@3+7pzloPr+eX^{pQ&S{Vj@5=D?N@R|aD9>LQZ_XoY> z(QxPoVI2CCVJ|EC2E+j+u39BjfH|O%R`Ta^Yfedg0;)SoDcVba_Ny@b_FvJbeyW zq+UXi+l9`(3NEtc)M07-?pN2=$e&Ag2^4)1n~g0vQbj3T3KW9ZmfVxA|xEl&(Z0_!-IQ+;Ur;P@Njf;aB_Sa!Xk-gy@z)`c;}n%zx&;jUf=hogX8=6 z@4k0%@L)Qdhu-A$;KdaH0NlK;1HcHnu9wSY(mT(*d%q>?+*xNbl>)L#tDy+w1p%wl1>{K-1il|9sM+Ec;G9K_O!@nXK(tiJQZI|)WFqo8YxNcIJP7_N2Fv+mmqiYTlz}#j?9nMS-tl)H#6=#cs=8<#xemR# zU}?BaR%Od9ccBBQRl;E$^rHE3G(QQwqa+*$-ofbTt55?1e|>cP8>6FN8y@^JRE0PE zF4!Cy3P$F8@7V`m%hQOHJw^USq*o%7EG}LeQG}w}+{}Z)AG0h>6OUfXg=8Nc^38{{ z`3A{a%6#7!2Y_OrL;8R-i&H{zhsz}dP-GSNaJ-NkJh|%VLLTUE&-03n%5Y`;?XSd> z9+xF>s4N)hax(eyHC^^qU|zr{d)Ik0Fu z>3Ib#awufm)!o&Dci>wK=h@deXv zvnGOKki&T#Z2j<`RZNG=92Q!6fiH{I(PXjGm#?q0WS#^AXg6m5NXm}@MU(y3r~iN~ zzUqfe7vy~gJaYs+mjWm>#!_$a0Quq<0O^m;K0ZE%0)RdN!Q%1h0Y(cwLWr58_E5WK@M=gLITh0t!+*3j98(n0tMslovzM zG_bWeK)IQs>+|Cepj=Uk7zr1F*OyQnr|DwSaO;Qv*<5Udd$E*D;@Yh3c@)&Ukod)s z(+c$#cnpxJ2vToHDFE&^uG%(YwiZI>KHKKn-ad|S2=7+G}7AY@{ zMU$yZ*heUsOPdyS_&AV*g1f2}>-r#jg$@u?0?W?F#l_JQ9=&n_o~8hv^6>gCD14lP zOnRlISG$^BiwDP`m#W*UW_}o`Xa;z~s_w!&Bd1>pKwLHUducc#uTs4e+0(qWNCTI4 z`Qh~fU=;9cY_d11Ag&9NfCYJU#YzbfIWJ-u&D3+9gTnm*4As2kulgO)owJ z2d@_6ZgI0zQaO9eKEkD|W1jy1+5696%a$xX3_IJq1p57@AZ4HpDkb4 zAMdu``o7G4>@{`kR?YMq1XpF9n>%-!l`B^+lRI~AKTRfSGCdoF>$99$kP+;$9Ax78 zL6j2WjF;z$w(9}st^6fbR|C_}i_gO%F{j~k16WJR;!&1NC>`e=zedOr%j=aONhf}B z3qQ|MKZ4*u)*?j@51WDzzdR&z$9k4VY08fUA*8Wi$oyz}gi4tn!%JWTh@`lSJebaK zFt}Q=9FkeU-5E2GDq#x{mF#K5&yye?XP<~uczTOOA_jT ziqA!DFB&A*KX?6*Fsc!Z5Bi7S6>rJTDoj&&m&3bn-Tga!4b^d+*+DLnwV>WC%QE9& z8iWz%@L2*`8~-$pBX{%GXaDS9NW!t({3+e6QKViQ zt2EOrclhXs-~PY+^K1kraGJD!@=JIA$N#fv)KLw$*!lzcNL{-L!Hp2;$KU&Jl4!~? zy$XOIqR`#C?cIDMi}+qH3B}`eZOh%{K#QS~IYk@K0vrg~ZJqApuZg$fXT=2*mKvXN zt1m;Nh?=hp;(&lj|KZ@|P532g9F$t0bE~i9yuCtA5{L!381?LZxiUbmn&sx(|M8za z_{QJC<>z1jV!2rKm8?{&q<+8M=|nLFGH?JA^J#L?e35Y3SYBRo&iC^OKZ?ZTv3TGI zKbbESkXwS5ZrAn<-F59+cn6_7{7CjH$1(j6Y zjACIH!PfT5d{iY|w(AEL2VuiB9#V+Po`SJN6Ck;+o23dj{~9_ErLc>Ya=ECaagv}r znp>*YYIWOO98>_YAS;30`8;7>0|XEKq**{ZCWc{`O{=67BJzM?6|x`+dz0=5{lo7J zj=$GGVn8JJPm{2pgx%H9i-UF{^)cD#=}T7(Z7ucUc_4S9pD(Zm@lsx1=`|pqQW(ut zu9<-Ymz#LjkTWnxVO}|bci|%@<0LpiL{VTAU$-H_Jeb-ye&tv1{0o2n)<5@WZ~gOE z2!Hh7y7MpnJFU|sP!7;8&s^tvP%!}`yR>PTF6swM`@;v3e;NnfI7H|y1+Z>MeDD5638jky zDhDU$LfbWMOVi@ek21Z|+NzdZc3&yfoWiDCFt5g?mnnd&m^O0nbACbbBm-ag{@o8! zOg~ouzszgn{8Q1T3g$)eJ#_iVU z|48Bw#1iD9m1hq*N}R)TJKC(j5^UFNY-}}Jo0W1=r^0o$EEJ`)2L8a*N(H%`4j4=Yk|Dmk!Q!>gqvu z|G8GBL{TVdae!zpES_gvXdOgTZ|BwW?Jr`+O6eemg9C&NXbO~6H3OPe+_-jI;IPwh zcoL0HBK$rzFxzqB_aR2JG?3p5N>d+~0=?%8=yg2xwqCBi`Ulc*ES?R>TcoE@ctm)X zc_&O@sT%-ATyCtzQYZe=UvGQq9j5$lr{Jg%paCmB2Mw zMVa(I?(TmB@#@x3Hg5cUV6FIBwuG0-?3nc>jh{Mp_rc~P#7=!)#FmHvddl$E0c^xVz_b{2P5iof81`m@;I z`l)|e4smzX50WV3_y=(e7mbH+V~QM)(?`S1pDlLE-;3bc6o7)x$}UV=w_Y+7I&5g>_zITcuD3=A(F&CE!f*uTD7a6%; z5Yh^xKF5b~I3oE+adDZ%;dCN z+J)B5KU8UbMr`uCD6|;ddb#zP`tHv_85FB`1h$-Ppl>)iiGvceWxJ!IE_61t`wDqBqXz}Z&4VM5E z)@|1hlFb$!7=P54}A9uD#$B ziO=(o3z>v0vVg_7z&(YEZQc2m=FMNUOIukX5_)XChO2~Gou7yRx{1k4GOo=ynm%$_ zlJ*3=(reB~a3H8>m$rG_0113iJt+iQ91h~J3#Gn9{HFwR__N?9hXBG#jxnb{oqo-9 zi-xX5L70%o3L8cBMp3b}r-*(DPgejE=F?9`Cp1hW^rw)) z%*QwDP!EW3F&(ZHC~1ZF%u11hafLALfBZHRh@Ud`187}1A{h*i$tW)9rAp1V3|%*9 z8Ud0t62~CBt($hG3744@f2EaY4tygf94P5j)AX6-qClK;ClMB}jBN`KvyzvW`x0NQ5sD?0)Tmy&+kbmy(%MM--4~hSL9*Nps5LS5&1TI1r z3Y~Yp<+l$s(}aF4HC}VeyN1ChnKaQ}Ky#mnfC-^#+UfVd3}&ZSD%o!q*wZW)d!wD) z>3R0RIjATa4=)m0Uog33_|<^HWljbbS+D1Ukm{QLOt`Uf1bTdg0M>UHS#G&nt7gHl z-ycB;nR;QTq_ixW7FU6*Du87G6VGSkd|7tm3%@cO2|26J4JkM>kE2VA^cNehQ*-`Q zQv{5SX6QlpXnOnvT|-xsB<68IJn$B^VI7P z1n!0EOF!vt-pXQ_?PRxW2O@w`LnSn?z>(Ba#4Zmx0hwX7;1vQH2V_QnVc?*C%dHpd zFEa(nF9L}C(hy%S02j$8F91kD$t2H=g?D_|1r;kE(D{_@xlIZ z;-eM=hJTuMgKWM8bU9o{0h|lss9_+mrW+Rlh^A=}P7dKNF(r3?Uwjb6x_af9Fp%8| zDZx^5R5RHAQU5gP@wHp=78tmSr+yAPCxgKViXaZD3Bn+dXKiqN3WesUeqMu*&j%sT z+dD;5;;@s!_XK;)7>JgL09gI-KcXm>1|=@1qu!w33nH!uMFKIn03t8MfzPEXR5~9ng4L2^1q)a`Q`n8n&8(o^m&>4Cpwf z#~5=bfwu~=lT794uT^`6AlB$8A1GBMtFHygv1C-*UZ;FY%m>Bih9znjQdLu-0K(}p z@-Nb#64*7>&@?MQeHnuuO^2P6!+w7VLBz|b@Ti~dPsF0t%-y^ME>r+>U-ev&cVlq` zu1o>Pkrp(O&I!1M0gI+5OZyPk^Sq#diZNg@d1n3AdH`0MrpG}C0SrYQo(HON&QSqW z0ICv9hP~6nPP;SZV-L|?vgHZ^sRb|Qm5Tz}I+MagGL66l6*9u%Uw}kl7QtV>8jfKR zmsA=6k#XsR{ zLA`m+&rPv)jAVse!Ul`RK|hH`Ni4!2k^)TfxP0KAj(cA*(hF_IF|_X3l+dwSgQqek7)@L zmD1kp#hsVZ(3gVdY!IDP!E>;VX?Td9tmSzj0djnF`c5j&y;-|;Hi$VRBS265ijezs zd>F6<6tD!An8EUD7=X+uM|Y`}rv^=Mv54md7hFX(xwsS=2%;f2BO}Wo5=EvJU=6bJ zyou`sBEwK97`iy|6m7{s^yDw^u9mt+U~Piqc_};aRG4@FTwsNH&GS~C62PW>pu$S$ zDYAoCMd>m?RqWj}V|9MuY+42KjFLo?_CvmA(Rute@w*7^hrc;G{yr^*StZNt@ren1 zzB+3EsQvKEoyR;AbSZqT`}nK(fAc>P){dAUGNA8iSgOBl*i{(B+>9VTJ9DPyrw3F8 zS!+~knm|?Ia0on?k(A-GZ;FI(;gz(Rj3DoJ@ z-4_y|TB4xs4`7E2D=W_=3mxr;>I&meK_kA65N#%|cGH;HDS3YXZ5Ej?T~qQ8433|06ySzNiD ze_t9xKbQM!B7YSwxqBT2AR1+jT>lXfK6DbR%xmZ_1;~A$+wC{dAnm>8j$l4@Gwg#DA5Dnr=E?(KHNDV7?a?w2|X_r65{? zSLBZ#Px>DTb+y1*c$dOhKsu1r)M(g^$D_QRRe+1?lpD21!?6s*a!S=kt==qp`R6+b z^G2U1%oM5=TSRXrzeFN_bDKTS|9nA?NRIz=LypxIaTDq`81Ij}?}_C>XaL#w83m{a zp9_Sj5@Fux1p$o<4$YfBCy+@HRsaPsA~Y(*(5!_#@sc_}Nr6_gjLd`FrqMe&`0al( zIeM&_21Kd2mGWgt&ZDOj_9}rBQ2a8Sr>)sgK9uXXmICO^cesR!%$%%KK^GhhZ8$lc zCq6Y0A5|PVEP#tYvu!wYSd&zj!&4N1tZQDQj7U2Rzi>d1gm`i54pS}<91>coNj%~U zDcoE|u6<#FL-{%XY zFn_@`q>@;altIR!e%Xr5_FRG33WO2K*dS*zhybkcXN^!ob0kTOCg#I556Ca335vbYIryT3_%9JY z!*8mRMt+uZ?S+Jz-{P988jcU367o@do`C;E;2avtAP|$|cwrs}9@4-^aiUK41x#fZ zw=_+o&B`aE$aSXmvjHWO$SOBXuL{Iqdd4w^7Ll+q@WaIWbSt<^VxUOqC-{Xxr6^y!dnO1emVsCDskk7s%pl0B6dJWE zWPi1_y}fsHYxhRIUbS4WT;HfwtEQ=8ilSG@s9BC(Z5Gm)+Gp0pC4pQ8JV^vFLy#up zIYIbnIh{t-4dRVCp_Y)J_+**wy0zB!*3QlCo!xTD({-pG9tAq=cl{s={jopw6F8im z4)c>~z=A0LG*Yvnrw#{^p+eGyS)2=KQXapCRbn1N)#nTn+a#u5d?6qzyh;Z}0J)QC zG(7;z3XYnU5?v!-<+WZP?`rQjNwilFN#y?9m(`>)}UG$W)6`5ywKrwVJO_oOOc|w-Z@+)rg z2qV&U2?rtZ=Q-DItp$-syd*TsFK~{bz2dN!a5E^z;^_#ZvoLZiH(#s2_EQ3z^_7Wd zg=;PW<*^w6C(M+Kf}$koUK$Ouj1LK*pOdiT_wQ)F-YNJ{$0|^r@a1{7K zh#W~22Eioor=#&$=D+zB4!)5_eKBR?^=zo5kUG^yUbO&$e~e)|lQ|FKfzx{8CoPcK5RtuD;x|oKK$5|| z_t8^KK4ud$1?(>})BBlcex4v&=RQDqQ_BdEC{RLg38>Vh$-TVV0k4z5W9dH=naG$Unc9k8~MjT zL+ltA<{|4?&J6UZ%gONwGZB_w0);Hhv#pf6Mi4X<^8qG~=tSQ4ivUBAEw5dNHA3S1T zW1oB|M6hH?K@eH?xdST^oFj-P5y%6Ej{$ku;>xYHAadfD6C_8BgU(I~%QYB3@(1@} z*j;5TkO$HLVn>d2x7(ew{WAYwG8dNNd3zga zbtEN8fW&e4-AVU7%rTaIz94Hzf;MW_p=>7mFsR|XE$2BKPzpilB+ z{;II7^VR@2a;jb>aA=+kj=sxrAu|-h@e?33&wzUJdY=O*HK2N7TcW4)rq2f42cNlh zi(yf&s4LHUVRa1eLloIF^j0|D0avnhv`osHAVFnRU5Ekg`|ARl{Hg_PG!!U}U z<1xVbUj$oIDfnHE03dRZ|LEvwI27cT1s#bD8Qwsc3qV#Eb77p>q(X%USzl>g?3R%^K zAZQYdj|wVWOG27LFY0!QBPw&ic8jLR_(dG#Haze6tslJkpZ|5-tJa&ZeCqQ>*DfSM zzkS#r`d(vavsIgP4%+Rm>ee=QZq|y%Z~x{$Jvv4WgAirVB%s%ks*bj!QHz&(eEe!%|E;I6F(jJx}uu6Df65I ziW&!l(C-R5(<2Zc-l>{SbKV!!4BMo4|ATM*d;c3|gG5P_+kfbfzWP7#K{6(2< z8Bhd*1ml=#Wz8tQpdtI+0bv~ZPH$MM`Xfj!&kpReIRSFketl~imW=Rb3mnS?IWL&6OB43(>K$Wdr z2JnT=WwcQQ3Se}&|E<5oFA+lM?Cxv_QR-Ei&5ezcXOG(Z$L+pm+6K>u;P+SV-n$=1 zk?uG@_2>U>s|;@)-FZr*f+jTC z8H9Ev-9!X*gTX^_10!pJ5^m`_yde0h|Mt;ueNAvO zbSD(Rmp=7B`Jaxvo%5z7k%47{TmEz`M)Go+{CHt8S;SQaX_ZFN_y5LU9UmSbp?dqJ zKk(=OoygD6$P^NWtP5^@LH)v@YeKLr0Nf6wrN}azD-l*;j^A28aS0xh@yB2P8s>}6 z-7ZiKm)Rui033E%N|ha<<+Ai32AKorQRg z<8Ub$5v??FHb|Pt=EPcx2+MR37AWuH z7q{Rl?tk}N5+&q{g2}Mo9S(+3%ve|IlNsa< zI308jA0Iw>G8j(a@XZ0#=OOQcGSl`+mINHpGfk|86`Jr;aKLf~L7dqygB)d8ZDI8UR%6(@@Hvq4Afdci!ST)KkP36h07|KQ$L`hKOL#FTXKF;>lv>p~{`a!!xV1UVcz1u%g{B)=t4LL{&CIe>~^ zR*Rm_n!YG-p&4RM1cA?b28LB3AohUrX`#gb+`t2q*DCp>h9#U6!_rUQelv;q>1p&7 zVw9$i$TQ#d#LF|4Tr0#71%_=vxXl6tG)w}459iAQx3ht=h{Wk{0FgL#zNCF)ok(sSf zIDPkBC5x`us0=v;)MQC7=7C4r%{qdBreuqR{?Yib*{B?VOXcYyhnK? zuk<+pGK=_J1*?3T%);7T268OVb;v=C3%ob@r8Bv6Ca|6i3SiN--!}oI3y1x@pM^sA z{{6wjdyva7gz;7a1xVosfAc^2=3o4a-~KCquSNv&7@^stOGsBEYwKYEwFmDc?X&Xv3% z0u-S%M#AyfZ=cXWcq$R*fe7RG96VP<1HGcF0#JfcAQlGrXej21Q3;KsGfm_{HZhOL z_ywWB!{yOCXadT?G>UHCxFH*wbUNXnqr(okdiO5~!W~xqUVADYW1LI*s{=~UI(0R~ zmZ>qn%pxbwgxE$T(;%qR@yCZ^-s*57m3`&A&Jv!X) ze0+C!aL|ABc<}hi;L+pB>FMeFAH?GUoZwu)t`%GkT*8%MC8yN=`G78^Umnme2-t(~ zeUA)OD1etBdFG;6CIaU1v$xK|bv%IO1|Vf9B4HEy!IN))*A%Nj3$N$=0FAd$daKs= zYFICLl>pZ-UK5>94@=pE3RyVR^T+G*at^9ym^QpY>4d73fQk}Lr%=v@33Vox5v~$M z(`4B**wS0d=6y*(Z`t%Yps0pjESAcap~*d}mhIS@`g9i`!2`>_7rHMtDw?22NB9qhhSxkI*;U-k&rfaI?8D*OZoaD}P%A3PYh^S9h3h(+V2x8B(0=i@+BNDkD8Pada9 z!gsJ?)Cp%7zk~gQ$>|ASVS)<3xFLa$lywrHrJQom<*c74J|$2gVSYXQ=67VTVSHaM z+^+)HTmqT{2qIR2h)3t{{WP3H&@5}Mvq37u`8o+AjLTm+e)FKM6uerP83LjPR(^#_ zh|+6 z!+fd!vtfQ0k&B2Xu#z(krkAW7Iufp^j4L_)uiX8M0{Y7b0QqV=q(4lJ=VA9*%~wNg znNX5f^MK;4A+PjV03!wbxmqYZW(elo_kSvXBF}PIyDRVk1It#TC=v&>a5;`DpZQn1 zEIEojqDcXszZyY483ElfZ3Ff=<{D4No$&*DDtS`$OHSwK?H678H0(Wii2BnwF1qg4 zM#}&b3M*tL+>!HwhO~S}%ODc-oGTLPoB=&QU^H z1VuQyQtW40wOTC|T}?Aewbtg&-saX$rBbrpVzseRtyXAaE2`<1w{~yK7q6npBny2G z_R|~91F$8_<||jTQpB7#8r@7a%aSmieS62WEVo?W*uJr`x#`-bqUv6yQSwZGH1Pc} zjUz=f-~gZu-x-k_0(dO<{{yP5{p0L_uO@kXTp<9xLG(o{g8Wz!8|azq)8#r zxjwuA1)v*NwXrELKl;iy(qO7<5bhwsMS)yMiqPohvk^^SK3E2HSp??i1JY*;vPN@Jr|t-$gwsD|SfEz?j{1M+uk zdmA1Z@{f+&?T_!;E+0vqY31TT{$T5?s0yqKvE}HeAAZz(%;(a!ZI#OPT5GG(+GuX= zH0o8ugt&JK(R4T(#Yr0aw|No^VA(d0r(-c*PbK(Mf(~|%{MMcA`pq3w3+W#}=c$K+m{&(k(m|Bs?<|ou zU}W>vxaYtJC51G9I(yG>U|73_0AviKaQveWSf{FR#Zu}QIHp{TMF#vX2T@AYxm?dD zGpu2bfKK(FaIp)dL+<%^R0jqpKHT& zF9A^p6gKzn*sh1m{*zF6lw=9WcRnsa}9?%L1 z`h(mAUTfl_0FlZFDRAZ%H6?w<*}AhhnXck^p2_c2auYWfreI_6eLDF%A{ZmZPnsl- zTeigKLq{j=XfonT=0)R@6KWQ@2zlP3aRk#+DkOHiQkgFS-T%h#z}2|0l`9AInriQ( zd!2{-sMhm5jK#I>9Z+Sh{-*?XAC%`VEWwj`cM!+OlD*~Lr021}XdC8JKvsTXki0Yx zt9OO{R2T@Es3>Z)*`)C2xD;&9fYdk}bYTbZc+00Y{o@YcfjQckm|o56-hVjl4bVY2 z-zC?f6)gIj3mlT@d3g^3<~BzE;D^%0$t=^1lEU#gOJ_&_KK#y`ZrL`M&|40o2Gj#g za;dUZxiEGS2V6%1tf(D$l4)vLcD>QURT{@1 z{pPn#8@~D~*PaRJ5`|h8yCwUTs&e22T2Nj7F10Ajd}nz>6>N5-S8CXqcvM@MS#_S7@FrYJT1z*#L%^<2cos^5drF zWz~EAu+r-n@eo*I^$fTvS^k(bSLaNLEn7Q!_rqY!g9rFB?ebiB7Cs;@8AtdEKK$vm8_WdVl2s7QZOt2oN+5FX4e=s`!;O-iE^YHO~A+_^o z`*Y^W19i5T@5_mo1_%TwztPdr{cpXArXhgjUb5#m{{h;@#s>bNF2Ge(%DmNiW{iNQ zTb}2h9`7Sv*Ky~dbU{r;nq?v z3v8N4IkJ>)U?4b2o)$3JJS8!lOh5eU@1Tc{!6Tfle#^&bcxv!&d`|bPR`r$l0_|7}`zxB3Z z>bHOTjbJ>!IyHWe1L^FUAAa@wzx_A=8{mBJn*#rDzy0xV{h)LIKvH|><{i_rj*pKJ zZ`|H~{SSRH;dW;-=Wd{CbCkfLlz90JLPJ-^GfN=>e)#|Wt<#U6pgPBPq?!jE&V~6c z8Cm;XgXdiW0-!VF{wb`pa+zje62(XF--GWaJ?P7VSWGA+VK5vIPrBoiHWZzz@b!xG z!kOZi2D--3y&{g9xgmOXd1098YSU6BtuT?s!~SG4^{1mjuNS8<{CUs{O>lqMJv|;x zrhHiGPsYPRabe(sgYB7z?|$@yzxQRYB40D%ExvUnup&bI z22eDD>EAx;^?IXGAE+fsJnpqee&UsD4)`=nrh|6-^aRpBj;5B_#tNAB`9 zEkrKETo^U^{+u$h&*%3GL$yd;RYc!0?zpr>y@`Y{FY4{h)vKY%JXP0azE0Dx;ANAYBupKl1w zub?|9`yv<*bjG+m{O*rrgJR>BV(SG*FBqC8AN5@X65DCFuj|qk76ElC30!d@g(MR` z1D=?+5HU~QqU!@=KtBEztu0_VWgb79?JPW-0+`phHX+kE81_z#*%>MKzWt+UJl4Ty z!U?)4KrwD@aXY_j}P|uhoiAS8MKcNI;SVP z*a!sZK0M03yfaOlAM$P{?|u3E`|sQj$7AlM71#>%0m>{Vc$}ob${+Pk51yPH9Z#n` z@GhM8PYxb+dxJPhf=T~)|H0!2_uHLb7=(OpOAH!@4)v3aYfaC>oWh7ao!T?eEP;$6 zcw=3nvpY4BLn+4AVK#zUxPyaN$6QoEC z<(5G{HWXZq={fCoO}PrRTH7ZhB!-~`{lSCpaS0wc!>*ED0630Q29!#ZVGlOhoVTe; z#gt#I>KcKqPukt~1Nm4*F=op?m}=8F^SmPbQK*3&p&0-%;3+qWqSS1pB!!{RSSM5( zU(cqLlXssU#HyqIpcG&}&(@u@7-GJ2eDs8JRvf{fpvwpt3<6>a%tlLcla>Vc6fP@4}Y1Q$XuTn7P!2?#!f^#8&azQD;S93u!U3Gx9_F!r-VnE#g#@sBHj_b~Kv zC?B){=b8ZEkKanAA{{TVx!`Q}eE&xe+7I?k2i?2sjJqh%1hmx7!-Gk0gu2DSY_Pzy zNmytHg^%juNdNA`!%2@H zFU0S6f9r2IVh)k%S>eZC9ek?{R>(vt8}M z_dbZGA;<*oMUQ|#x+ZNJfan%=o8)bFKZ;NmCi8Mt*9ai8p=Wo$Dc64rT>lY#5GI9S zw)SQ6l*8-RigaA2u`=?3FZ{?uW z`(JzK@cl<#)#6J)Id@7nWss%jH9S4Q^U|{Yclo^T^xo03SEWHilT&*y9dHUC+U#RHO_$Z84ZEL`2-M+ zUOq0!2Lo!3UK)i$mXXWP1~h~b0rx}P5EJfkCN<7>fvkDKGXMY=Oe7_rFNo1!5d3*S z(Nr-OoOo-koDC#`sT_awWIC9j><7Q~4kWBT>y#L*7l0MUL?~l&_;Twjf%9Ma%HR0M z_rCLfv1U_huVsMUV5uK|U7TB0SZo2ph_5k5ekl>>Rxvq{K%8$PMRuu3h(77>p7Jz`n;aTCT3Sb$|Z3&4GF+dR#3YSR~ zzx^9;qN^YTNN_g5yGLKp&uO2JdSngI1pnYK{(lbNe_XCRFp9Z;&EJ(EH|Jd?@Z~@~ zlQ#9ZH|{>6L`LFTw&j2pskG3d9AxtkHeHq{af({2CJeHM&(;()k0%d{AyUkO(Vz_})`2zl;bFF9DnbGe#hv2;e(ng4GvQeR2ZmA5JD8 zeM`LBRuHeYT?Nt?&?B%MXx@H!By~URAbHB6%C9!?Fn-RhGa#BL%rC_sF$KuRv8JUD z-{c#`-Tlrxzwsux>!Lwl4iF3A*v`Y_55FN^M_Ah9D?zlD!*a?zE+Z1wF6VImHqf=) z%a?1n=0)ZJD|jkC&lUyo=f3p1Q?lU2n6_@(5GAuej+2^1#LMPsr>)o?0}&1%_A zB407RdTYB{tr%J%3`4jNNs>h=01SgirF&9{M; z8s1O*_dX*xo35jQ04{ZOQ1Ux}@4HXlI{+GYzkAoK+8cN3@XzKG3Xx*fzWe?A$9GRq z|E*iMAR|(7Mkapm-Mc5_^vhum6ckKMq^P>~)Bp14y|NAYvOY0?+yV35_KaXW{lPzc z8=?TLE~Oq{#&jG52IJD#1JO14ia6pw@h^V1zEi%Co>vRHp?Vej>;KPh^bRO7nzfB) zb(1Ik8m3b$+m@ch5ns1l1)w1T@##cRSXKYP|L_ZN+B99^E2L`SoB#E9#=QyrgGcW? zM&ipqeG|Wz6Ca}kWbS?M-pAj$2U%oWc3B*`2$0s@MSu*;5m90hS%dRG2?;CDH) z2Jo>>+ck70^v7YCU>*hmwz->)$D=68EW7A9R+jN2ka4D!s!i8YdZ$Oj@s!Nzx^Sq2$=Hw5CyyV;5x1l4eQMiu zFK$i%`VPnO@b1Z|GsY00T_l1gH$JnYn|%6&OVDcngTv{-2P@vWeFsCSXqH!Wl{A`+ z$5B!!HFh>P8$s{z_@u4cmF-)vR2}8`@y7>;Ck5Sx8hCJ*zC~@T(zsEJqcZ|abR2#w zIxa?&DRY4I0WxxpZW$iGdjRs5N~K@^x>2rhW8!!Jv&GW|7?kMy%uT=7^N&mDz z7=sN=NOra0N11pmoCAtr7GQ8OWH&y|`778`osNS2_Yd=Fg-lA}=4W@GPJd1T<;e#} z{*bbC{*aj!JPnY4`FA<82G5`X=34mv*R37vxT-E^N2YQxk zjn91M)05HIDm5GRvYN%c<432xX?^$Qs-5gVxHp^xs%|!RUTT!I{RbZpCTVSR*Rizk zee<`b^h<#LQw9YML7Ky=0+(N&SE2+7``OQa7Wr}c+rRzWm;f?8&-8-e=YHG%7vfUd$wR{_*) zSr(eu+uOTD`UB7+@Pz9L1m@Y0_~}o7x?ZnCEy;y~s{o37p7-jjuYUgXpNC`G>-At5 z<@W@jA!PW%7rs!fROl3WaKACyRtE{re}Kp&i0;U= zwfnNGj33>7wL86ns>AQ@cKDI0+qZAO^2#f8Y*%>*R*Bq{2EZkLF>)XzjG#4%d2K+8 zuw*d-o?0PB7IW{-H{V?L003Y5(w8vnAZ_LHw@kboFcD;3MYo*qqNt+BBQL2-K8(cJpx?hecv%+2X!5GfXH zq5jF?goiUq;Y*i4O%qVDXjjzCpM-wQB|O!&t3}IB4|M$Ky!l3{N$jI&hL?E1!zqfJkajssYKvVWvZP9H(19Oe|Br(^gqK)A#J zEz$pckb@`z1z~9+We!NpV^9z?pFmzpkeBn{<;YohHVVV8FDrjhXz>?xK6R66%w9ZW5ZlF(M`2trbtO|E zg-fO(kGf0@r&unRY>5A2ksF_NtJd7CmWxUTb4GJLz60rbMU6XXVt9zvN*Q%zJggsy z$z;g4WPt;}ozmKLjBGp{CYfRvtBqE}(iDtHvD$-y7$9D` z3c28VWf7Jb6adlmxXVUZqj5R!~&ab*ET$Jr_-=SvVO_HPeRw z8$qQ`hEqSZy&9_ZM}shm4Y$l1C^vV^@ES8G4 zX<<$nx~_3j>u^3S2RNiErm^QCRaJm+0rn3rol?cM4NNo>t~95E0p^4WqJzUs%QTJ1 zANg^?EixNla)j}Li2(HyM?gEt;E>sA#=uo>MD3E@%d9G{Y`AFz|KPt(s~wm<}=(Ld}7yfU*M3AmYlEGLJhSO@Khr zQYsdPMp^a%0D{1|xL*d`noC#2^VIVI1Gg5DMXmxe=i2XbL-sW+47x%p$Ukc%DORp^%|e7$=1+g^h}O zV4o*YEYmS$vTpK)Yh6jF<8h{%m_0xl{w&N63?N#MLk!OlrUm+;!DCblkltuLLsKDI zMDHNhRLikre>i{wfF;AT^lhLPpb|ypBVI~pp}o1)2dV+~!*DVQ6qxH}@T(KyGRTUR zDwGpc8l-s&_t0^aG#d6hBUB5t$-Fvy$lB=1!3h9B?k6$Cwl7ZbL@zFozKCyadd0)UjidGn@BMkfJ@z@{Wo~H7vX_~5`o|tdWCt*xSA&Mq&*r@`6 zXB5b)%@(O=T1oLK?se;xETRA{mjeeCr}u%OEdBxg6Fm&%$yk z{7P7kufdg;fB-T+|6K#LplY<$A&fykNG?IWOvEwbn43DCGd@}*GO`H%katz;It(FN zmx&T#c?-bdiDN~xij^9au$G3MlcPxh_neZju@N+MrWnqGu{$TEovj? zupOLoy-|xsogO?{;E5(+AYkz6W$Uy|GR{DfgL{9;;!rWrXhnVzY^Us6{i6p5#~oNG zV(kbb6ikEpW?*_^azyAOdkn6FMu@ zhqXYBpcQUD16xaEk_cT9yZ%jBQ8|S*Q|wAA47;a3d@h5p8z%I!L(~Gbf;wYh#>Gdp z0A(zQMn9e11-;QGdYuzo>`m!(JL0)<;q}*F2a}v#0{TP&m5kDT8q^Jd&5_iN55> zUJ|g#fT4wgg)qto0VKtwqsu9(rNCLbMOh<3B=Gifq6B$I-a=e(AVuDEJdjVrP^aJx zxC?;gCIBosyG4+x5O}l(Qu-9&Re`_2N8V=ch0TRaHbJF`6nK^}#vlS@<+KHHoz!~(z?f^+6JqU2U-bc2<^H(*o|KLhjBSuwF! zL0CL+)U!B%uNeRh&S;qFwBcAK>nGplIEzN|>4P|@elAjE&9Ywv@fdb?3(SrwBrj!( z$Svw%6S&0`@go{RWL8yP2!w)L&UFhG#o+MnI8s0;wkk4QjJFuR+>+U3;&13n#gyQjy4!4O=B=4ARg zP0rxFTLpNhE#ne|5)w0cffbVT*bI=ME+ID0z#0gQ<92=}u2)+5@8CrP1bwYm%P(Fi zNUoFdr6FDbBpn6dj0Yh1Mqyzb^AP%TVa8TVu#$An{YwEJLon*KJEte(@f31BPX;W- z&y^|!+*rMZ9_2B>$}L=6h#Nm*J%g1RW>}yV&Mw+dxMrJBNqt`##XQtsg2d!Z@x>+L z67uT{V4gunmh-dldBtTqU^zaAa}$^0DRcYsN)eGDFXxb_iuC1Q8F^Na1;rT9%D_P6 z3D*N^dKwYSmCJ}s0j$Nvr4+CMj3B`W^E-K28If?&<=Mn#$Zv={d331=Q)h7YQl`u! z^Eg0W0`lvn4D;XRh=lni&7$8Yu-1j&F8~UIt@Dc)4d)IY2(=7(ssQBvy&Z2F`3aXC zbI5TLSj{6cK2Mp$a>{yq_3~WE@6PV$mm(s6*A&b$;5JRERXA4-0M=4)c^2|}v%C4l z4AxTQrO244&*L(3b$Dju?%c+R!V;XDxJ)jY;fj!#IRhZ~B_s4yxTx}Z;&KN36;auo zOwU_i%9BSVTynW~O9B$->5R-S@qeBU5Xno~7AZhSo&X&MG9ke9Q9ISyw*W)ryUp9K#Fq3wk(WLUM`2(#S${y&QWPLS}n&m4BIW&TJ>hDRPuCw zv6!H<1q*yBFIlBTVpbV1F#v{1H1f3H_wf73efeDiIpUHIV!#Pv+-IQjwZ~;PSh}|k zYx75NVjf?qb2-Yms+oN9D^r++M)@RIUM|U^)HfLcupoI}JYCQTHT z0-qFu{58}#3{$b`)3j`EcPV6=;Z&MiwMwzTS3kH5MyLaW^dP&7;em^`?a0zO>s2QBrRyB<5e0PWzPC@zopKP~nwh&?b{fBHo;kTj{UJ8$T`}ZOTe4VoQ7P)sAvO0oHcv%o6C(x4F|w!MInad%bT2*_`N zHD^+daad-Zx9@+T?i z)s4N4Mm6?FKDWcdiY*mO9=8NWF=Q5G3gik22P7%kY3~X-VHB&aMx(CtH772DQNTe^ zP`nw{jor=7%~H9{cch{axlP-qED}p}x?x+eefdTqx5EmGQOp5JG+%AB98>Wzf4R-w za!QqrottIXz>LOVIM9V+(;tPh?L60uU;vilJ5#mR_KjAnX`5P-DaC3XBVK?Yu2eu; zyVPiIY?eF+MA7YXb8EX=tD<9Q&H-+_H!DS#!dlUx^wca!RnxHy(9bD1V99!}mBx{3 z73&+@Rep@k$f5fzN=)32GO*!jakg*VMaCTY8JwJ zGGJ9|cBx#1`Bkhni?$72r`p3 z4^J+Fh|{c6y|r1bmieIz&8lzR*xK5FITlADgkH6=*=RN#6LYQLR_dl2O{TG1<_oP( zrL`%A4^PS0>svQ>cK2Y?L6E!ER;6fVidk)KSh`}BTDyBUY&Gn6d#Ubj-FRj1)-C7~ zEuBI(Ks4>_?s~Q!#c^@t=B+y~T}c55+OB|1$$wSoz#BWe+t4j=SU_~ct$I)eJSo6P zQl;A3E|)ypbs>=px>teNN)yZW3W@JWnd5l{Zm#S`saCExi=GP&$@hU%9nL|~<-3l^ zkAbX~9JFS;UJ{I_LBw}lO=U71K;*YJcOXL(zF`|hAf1sFf z5sTrd3n5$IzPVAa@;w)SJe`0EprrJ1_oUk!=q{{YIb?Am-2Q&nL|B$_0t?Lgy3;P`UU#ywa9aX5`q6>dy4 z84UV;C{8MXgbDygG`s{k+`mWg>`kH9%L;%zS}2su<-NT<+>&`dfdC{y+fJv0u>+qk zA1;k_n$p*$I_5I$$ws3ACxEqCdTXbiz>?KrOTvPLkXPa`;cin+i6#+5knTV_Q|9Vm z^a$n(hMZeuXkFTdTQ(t!6=`m2n&TO?{l&7phC&t`Z1|~K0am9C*Hl$uuVUhae6!tj zXhg+P!Gici9MVtd7~O%sp@|G+phxVIC2Uz*%L#0=Gy@uOAPf@75s1%fr4WtBVjJFk z;UxbfBCxQF)n=t!#QaitY(+0h6t`5dG`{(-*_Gx-16CT$WO(72UzKtN%n!RCXglR5 ztUZVqIKgPJSZ#O?D5Zy!L691?debs3nB>BWg~;k1?>`w1Cqdvtb{C6YBoqK}(O`3z z%NgA7Ag#2vYLyD?dbs^5UoN9N;uR~lsZ7UXPJc_A^g6@w#NwF%n-q2w6cL)RfD|lE z%S_|gtu|p$!nWo@is99pbr9O}N?H~xR=HX!X}S%)5{+Wt-7tfTYGv6 zHwe;Z8mq;f8+%2bnBYXg)UIwfE5&DC0+NKDNAO=!;jrvA>ZJq*Z{QDly+|>+dSw~W zWEg~MZDRxGXB_fHz!*-68jt!t)pRr5hM05gWYTM&b}~rES{;s#uBOAzX_(pdRs*U# z26OrW^6QyD7>!NagLoVcM=*zBD~yMO2om3REl6!8gXVy8&@2}k53|aTQ?F7(!PArD zDbx+H0h8D3wy91BozZ9lLql|(jw^E7T5@`HFdR+5=}@|!ttKIrN|YHzM<28gV{sT< z`{X#xRE&Bs>WwB-uo470m^cw%=0zVJQyU!bcl%?wIL#JMi~vk07;+422+=&5@^m1& znpGgfGczy&#hDovrbrr&!CFqKYAZ1+%wW0H>smGqGsANoutmAvvh*Yhqv;q31Ymlj z5I~8>m?w(rl^f7n{a!m$-CC{e_m3thsjG3Smupou13^Q7LeEJ}rx5hOKlb4~MDVx6 zVW-z0VDiDhkxM{7`?Eg_!33^>ZbFxf&jjaXhYo{lSm7e-JXEUSVsZF^DB{5mV8la2 z2A3t5FBfqSPE3+wpkj#84YjXp&B4uZ13ms`T;YKb3dgOpnY#T$e zUabfmD%XWN{75JOjBKr05o;-w?>deCEEvaJ_<++r45PSUl`O~AAqwFrL_P#IY$MJN zOmWTBA>t!H;!FMFJ8j_hfTy(ag(|3%LXw0L{0uGOOOud+P%LT+%Uvwka0w`ZJ6u^)S- zvY~Pb2^rx5X$EXB2r8(U6w@L<3=*IK>)_KCbO6syI)D&V*Ofmm0?UgOMW@Civ`&(u z6?*!7x*+mux=^JSgamGKe8pOX1Ps^=ICxKo3v!_Hfr$%XPOh=?@sC6pAWfME4<1e?69`DSe4=&%qC9FxkkOT%Jv#_&iHJZ4fC%U( zYo0-#Z57ZN@r&V>XfK1T8Uhk31o)o?(YUNLUp$`&k3~@&(B>;a= zz`%g>*%n2A5`tk9?v&HDj!9$Ch!aN0POULZ>eK)U`}vC7bwjOhRfA# z9x0-#Xi)~fo3Apb1;d)lMa&HO4jUi-hro|42LwVte^oxqhyfb}?tFMA52oeoyq=|c zJY`PYTmbRHWak%(plC5tg#61eg@mrAC;>@+Q(%fy- zs+ew0kxw;>C8*xbTD1%>63PY?2KE%k!8DArQggFjD?yvUV1bEk@_aigg9xLWBa;D7 zXgGA5M(1i9FOseTrwMv`2H_D!gkyEX5x#$Mt9^^h40UonZFc`#eJi^@) zEJNGksU zm2aZvejz6pfolff@?6#l5L|v<5GvqofS^X55>PWI2PX;VE~}bnBX_aooLXY4%f!5} z0I;!mC6w=WtU)T@RTTkonfWZpj$I!pw(_bZ5MlNVfUb&r%(0qj31rq~K&|-AaXt@V zx8fIhWCg5$DG1=eVX)){^6(517}`8e0rIhs29x0kWQDB(U5jDo8Erv? zKEo@AEdi|!YXsy>3oxEQqfq4mlos4k=;Q*Nq76R4fqS?A;Nzj62^Cj}dHfu71J}+V zP$4Lxt6_D(`2w#(oziJlG7JEO1hBP=&AnSU;=$pQCxF2w+a` zC*w{`^a7qu5M|}o&i3AoTG{I#eEjg>6q*BOWf}$JK_3me#UfnZ$*?cpY1ABA8Aixu z!O(z3V4Df>oJ=_(vZCl%Wt`?piKJrtuSgxWJFoQ>?zyWYwMS)i0c*6h!NijD@;|a_m zo>#;V?-|gr&;{Hs26rTwz^r@xeFQFGmM-7{sT$?pX9)lH~0ePN>1WaCdMrcFEX>9RxiNXE*5B~n& z|NCgvcI@4~ZRh}uxlZxR;<0#`YKX0EG3+r&f7Y51 zeEaXDk(mBmLvZ2EKrr&TsaJ6w3&t(1Qq8orLVA4#0GMCOi1;sm7QYhK z3SJ$+`Y;FZ2hy;*u~V;=lS%hz|H;S?&zlr$0Pb1Kq}Zi;y;kx2M?HSpZDqnQ&wm-8 zr$ADd8(UkuJC+ii?mswbccDDwy|dk%r{t0II)6?Y`?-n_|BEz{cNwMpmH?3g6%4M^ z;t$LfK^QG70GSO6KnS>VEbc3UI7x|KEo$Q_ z+T!5*v*6P}n|%#`2~dh#gl7OGAv}h|5$Zg97~H@1ul)(QLQnvbZgW7pNRYWOySO4e zD{?WM$$$h{vS|iacR?Rm!ZhOK_{_!#0yoRx-mkSH6~H&X@vX0YZAAgVuWGfLz*+iO zD7AvUtasicAtOYitQ_JNS{yb!ERKf{AOG5~{TkBYEpBdYu^x%mncw9I0B#M$F(f;P zL@BRowyQ<(R3}T~`ME(hFXMAqK|{uAjXAJe`5^(G15>Cv%7#@q8D$+(Yk`sE;AIe3 z>xmMU84 z%cTNK(UtgB;JLPe&M##I|MQ4|c?7T=e^x+Q4hMZk7_PlRug7OJSE}%A9>*r) zmA?XKtDLt21W?e2h2J?D4tWBtK#P!Pn8lY<)*^E_n?g8~HY?8`sAqAJm&O0(`T<;2 zgB3%IOeU{nSi4+Kng7lrc@1#oU=Tn7eBldUkTOUDZqZriQCt^8%ms=IKpfPSa~c~0 z$P_;M6Du3c1YcJ)ff>ZGiX>vvWPyZ2f~IRhz{BrOPfvTj-aID&$aCNDx^>Ux0$H)R zrJ?~?p0epV5Tym+5(V>%9A=kjI`0oOu~>YUIa!6M20y4B=CR1N0Nes?A3b^u$EDF| z$cMm4M`ER1Qn{25F)Y?;f&Wri=??e5lRZRz++c%I!%wHv`3L{tA3_Zv3)CzeZRWii zASaNPOGaGn!O(<^i{@S!JhiI4wVb_q1~sn>3Y?!&SeT@I9L)?fIEx)qE@$iJ&qn63oPxS!ok*Ui$Oz#~Q}cw& zkjQ~`F1ID)YrkhNC7}L;g9BKjkVL=wtG@~{1c5kj6B+W@1ps+L(PePC|16wEUbcuo zeA+(~)@Vd##9auq`SVQN<%1b6V-Rpx%FxG;pZwqlKR7u#nH6W-f9B8p8}h@A04Nku z;+X)mPy7|@=@9Nu?fV>n1{&q_r+I&u$^vHyX=FI-0f5xCYW35f{uClUZQh0ZA}hcZ z(BMNX0r@>-63EHS!1eI(@W1}Gzbg@LHk-=|Kt}Rk`A>jM{Jnz<+B-LSIq}?4IFop8 zt~FR`YKann)m!Idn!~)MwI(mWJPT{BEMLy!=O#*6ySxfK*F#_l7hx%3IerGHb>{hH zM8f>81bHPAm*JAC=apOtvf8z5%a^P|T*?SQU?gwmu*5C|rpzMe0&cMm0rFBNi{Bij z9B^-mUFK;rE+cc0cLj)RFdAg=S}FNEgXK6t++?2lrTm52b$omb#Bx(sfXJJJ=*j|U zc?ttGe+oQ<{I&p8Em~q5E0xT$NgVK3-j$fhUkT#wf>uaD6Ta`a+ik>g3zs6}3M^wT zJ8~BC+Y6Yv3HhzF87>2qf)Iy36k(;T>-3%YLkE(#FKVMAaNw1_8;@4snr(ATNi*VW-oD7l1r`%~Vx!3yps9 zi(i<3Sw&D%iUTSPw7UkR7zcEr>X>x~$bd^!a&cfQ^CBX%tR!!A8PFPjk%$c6``-6K z>Q<{&uh)S#QXJcc%`UtaUdkeC06ayt1T-MG6-vNej1Z{t;fEhFuIt<~umniVV<<*I z3U@ttMNh?y0!j1R=Yz^aY$Si?WaT3$?q49Td8Vg>IHZL;bjfuhtdzy21VovcdtXh? zH<2yBCxEA0fW6l!HLFDYJr7iFi#2pi6>cVC8~7)buONzM=#~LDR*aO&jhm8MU=!Rj zb?#o``55x#AFh|>Q&r$5n-CzcF2iIASavn%{8HWmtX%@uF0T&PQ2>Cm?a46^HOR`C zMxGScxJ&lLUDA)UPh{YJ)>><;XzMXw(JF4-xU;jnD?aDT{ZpVPMWoEiaS^O4tLB$K z>z-rAA-9u?o4AcTxMh_ao3*l+ipPVTxB}+Y5T(WS0+!ogMMRsIvuwO#HeRbX_gR*C z5`*}(fX+u|qWid2syACLy^!*Qm!d7v3t0|z;2#?^-Ab+5(6SgEuhnYkF*?E>5&+$* zZtU&e*t6ASI+=o|s6!w)1M;pQq9C~GRyX%`ks)S+5QqYA!!A~8byLg4s)Y(}o{UGhwYRtTna_L%`JkI;z`ZG$jlgy= z7(xdm+`Pf)GQQAm)@NstLBR;+FA-g>De4mgRz zDZk2Fu9b>T9Qxu_L^*L-mJJFnlU1>T**(>8TDy04Z|qiURYT1}e?H&yw!~bKk^*s^ z^WC)*u8E0_Mqg@Q+*ib%QLF^zSc{lA#6XG$QM1GXplfcUva?a%DA}HY ze1_+lCMs~Po?+Pa^6qwZx8fFogvnQlFyHz1 z0cH*Q#_qDQMSF`@uLkpi667Ud?NY+ol&ixv6##&(&KlNv#?4Nv)r1kiuP0Wj+-0Xb zmU)Ef=YbufJ_uPzTcfPhH~dZoF&DVl(cu}T}a-}v0koh@B_lhLG# zVL{8_SwN*qRaXm!Qz{kRboneGRrAV?jqSaLU~72Lrc-Tg@7Ahi1rtA2Dvj;d)>gS( zLUDAhwSBW*ariOSAa+X4jh($ly{0J;xAxYZPrdrut7XT4a*9#~+}YaLbZx$5XrV{j zyFkV^G(~e-Ticcrt2}q45>6+k2SRNZ9TS97OddsKt5LtxNfonFZ`dYWB&S?1LmY}@ zOaw`zFiMo_*3HdUWz;_C^@frRr#Qgz?$Y|7l1|~3Q@e* z>pgn(2xvgABRvRw{Ql%mei8CeqAPv{-h8ceaf~Z#0iZ=qgC_!HaD~kHT~Yw&gS;!N zl{68Kkw{wtorN(Jkt_L+~$BHkofqOmk@%$n*uYc~&%{|l^@+D(7fr3yfkmjZO*2Wgk5Ti5*B6Mm-QN^-rTh(n-iKgKM zb_6afmIZlGEjDdUHLXh7wt{f%M}Dd}yRDZSwhaN|7`h)$b+gtiRSVIuKkiM#$f>oe zC2KP52T|gf%5F)q)xvb?i!o~;F_=T1dIs{_0?wvLI5+X?aD4>;K+9}i(aIY)Z{5BF z2e!x;j*?=1vt;YAE*kY}mKN&Uceb`R%8e#TOeew1>DH~A zHgbASmSm;YjosayO0_P|tui-nyi}{A`G%#&s=Z|vldub?yZ->j%D;W4y@|V9_)IUX`U1NQ_U_qmZ^(VE{5Z2skz(Q+=Mq! z;DHPSU}+VCUb~&@#jTrnidI@MOD&9-qSUr-gQS&eRZFMiXie;FS&8!29QF<^e)RKOh;4*Jl6nN;TD_+;>;$Lzz-m^pX~3$`#L#2 zg(n1cc=zsI+%+w8@1-5vMfF_Za;lD7GAE@|wEbACZ|s&meb7FQ6np#j%Pkln#j>euMzOwg^H!tYDpgAw&v2}5 z-?&+?)jiLO!^EvN9254Gra~43S!3t+#%2riT}?v8LBSg(uT-wqvuNZeYOS?XakYNC zooLSPOK)toYM^xFPh-WXZ|+t+bK36=##5)ZbK};{8k%qn__CPPn2jc8zp3%S6m1I$Xm9>)1=jC(nAyNc8~7}`XNlNYRLf~^PooL(+zmjG?(O(rqIZcMW7yJ z9GWIMTxg{RTqvN%cXbRtMuF3i?e_8P6DtB+#$n0Js_ev)vGf z3C{t#1eHsWOJr*xi_5sgSt5?65y36Fq_Z4EiVGU``+al_YH$C^{)2~)9zT9Ers2+> zkl?ci7|?hYWR+S_4e$}!HJXH@ZV-mxuGAm+!_&#I>xWT>TNnmVU5t2+)mgv|%oW|_ ziNqK~B}=D+HUJE!a;3iL+2*kGq&uA2MVQn)%{Z9)&{krNvBi_xz%$TDa6F+PY8&-x z(I0hV#jG_NU{^4>E#|u#joK%NAtr{Zjxnj*?U2V4!A{LbSnx=U)=!QOP7fbHdHA3| z3X4^kj3v>8!v_p%Vbnc(^6()<0Vpa49Kd?Gj!z~uEZx%hq3JJ{QqtTQHf7W5c7EtT# zH7()?*$4(ZKHPuY>vo32iCt-xJcDm3^L$#jRN*UstPcDi2jc;x_ruhVU3C;Y3Jk^bO13E7+&HXX@MsvKl>%77-~Tjmmh!p@dWO< zc;q`bNJTa_hw+qxTLLWodaVYJy9y(g0UC#Azo8g1%fhH+4$@wRN3y-Wxw#3W0hR=T zrK%Nlfiqoj13;8!Ph=thE#e2aa#blI&$a?Amcu+EjP_Yh)FyvrM^=HnDzizDm#kqG zSm|oZ0?qS5Rt@6iS!X!N>SbKiDXYyvwj)^)d2mrGd9T0r>T9pQ`l&bGxP9}+#%6PS zXIrR{oF*9AXbLWb5~S=*<1`q-P=T+*coL<2(ky0{m{GaQg;otsv2=Oj=K_!oRr;eg zX4Et)Kw5Lzo<)TLAc-JqAhO^q@hBTCBGY+bVi$tq#D}*E1LS1CHyBG#iPjtE`(b}L z5-gj-(PDEml5)og+`A;~pB@fIQ;+BAS79lk{-xnB#ONHFI6XxZ5F$}9>7DK$!Nd$> z&E)4|phq>;Ff}s@ddI!Tr=yO~L+nz^EEi2<8VqA7okG|dJU-|hK!hPPP>o<57#2?` zEvV2L3iNx*llutb5gllY)-jv>IOAf|1&|k6h5X*rAkTf}{7;4FR{)re@pRZ5j{}G+ zAeQhbAQ)TdwX{qo)<*a?Zex4zcBSM&XIEOgn_Jtp*7nBMcB$w&HV@k&^Md72X%L!TeP{1R znTt8XszG~U5Q*cEAf7XxATh~g){+N{+#nvI5Dh=MRJw{EtY4KAxq`a>vJ%xg*zzT}gS1s`DY01|jq z#rj6AUbif_wawKq3^3Y)nK>NdFVCWyPNy)Ur8SM;Vv#3U^I!@AAj!_|&d$y@e;KwJ z-`Pe1n5R7+PBH3sd#41NjVC9ks1&_+UFZ%M#B4OsJ_7*uBl<`c$Xz`VHwkfxCPLfH z&C~c?Y0=9(a$-OZ0R(gM0RsTi5FH)C8Q^gMi!c(uAR29cv9Besc?O8H3Co(v(j27Z zh5nWgz4_8TVFb5G3UryD3`swSoC!39Yq0>dC6Q;=707TGIBTi~*8~JdL(2iIivg3} zM76+?-epb(1L}5rYin5zx-V5XDPFm9O9 zy@?-dh6N*od>;A3_ED!ZFx;Y=g~P!pQ+YfCk1d-{RJ*pdcc%)Efgk+fL%upJtSz1` z59=Pz7WE6412CII)vj#cxLNj0sE~;t!O5k?Cfdax&L(h9nps|B@8#FGT6G=rNrORE zta#0`Q{)+oDZhi1K$!W{f?}AM zSX=JGKMj4(K2Qtl0ql%10;!-iFdumq+z7g45T z^8*UH0x6CXJh&JZu#%0tCnv{8)2VQQ!R~21K@))=a2;R*eg^^h@x&@mNQNU%F6Uw7 zJpE(p2N1!bsEyJP#&N`>Qc_qGz4mA{P8HoNSDQK^!gM)+n_wVB_QX#R>IZ*hEU-*L9O2j(Rci<1^6oJ4kt5M|e z5Jw(q2at7g-BAPpWHCyCbf}HYJ_9r)N^m1T*Ifu)7sD@N;@LP4x{w4xH>g^8?jzUA z=75gl=6AmPJ%}gd6wd&ln^UOHO1T6>pg$OJH!U>ZQUDD>9^eMr!b`OIAyB@l2b2WS z*b9v5_rCXiB%<|FxdL?K5Vis=p@KMLIrnMsJB#p>OPkwUY6KVf2*$Ewsjt;lw~!r8 z3NWx2ou?+DsRFs%KRsx-`>NqshJwk9=`iN;#Z%<+NANR`Fx5HF2mSG=KLX?S`w<02 zOe1DA!U#-|J|3e_<3SH|Q1B|46LEfwrBtq3dSTExo<@pksG%?C`v`LZcHtC;#L?jx z>X0rB_&VWHl6-?5ZhwS%#F`__!XX9)q77&ZpIQwj!^xD-oX~ZoCz#1_k)SA&U^qVQ z2bkTKm z%Tam(K$`!q!FApQJ{Q1tpr>?e1v^3i@d~$iA=V11B*Zn15b-NmR@@c#aefPbSeT2& zxJO42d~6jrcJFNMY$`$T!AI|P20jpGZ4{#L6N$gDWyNx{qCoPX5?r$dMnuyE#jS4d z-PoR-+}}TH3n`2?h_=9lfJ$;2h)VDm#&TBBG0eNSZj~(cXz>LC9AOfP4AR92?KY;*OZ$(jgh$BflBO0F)hz^4K zx?8Hcwmuznra=s$0A?5TPUP4MdBw6hp>PYB5`nz8yvG(v5TeRc>D9-NA3-od9{#C6 z^(P^%Bn?r#QmL?#StmeV`FGK+8Ibg-yuc6gJ%0QIPQ+?K3cGT-R1;?nAr*oQ8RT7n zL=D*>3WuX1>Oxr{wz;tZtd{Emp5Oca?|kJeUqL-U6)BLy`27=q;*VFV6=-Bh=OxI? zqI9)VhEzCrq6%wv&}|*I2xnZNSW6;2R0+-5XeRk%yZFk(ns8aE`fvf z*Z;W*2c_hr7s3w27*m5n_Ugdtxf) z#X%+}2!wHof^hD=O5M@ZQNN3+hveO=vTYUacCu5r3bNQI7+#16Kp>4l)p-rPp4Y}( zQqah&#V_2QrElWN`u#$YM;G)kfec zPN6@9aU8``B`n|NMIIBt%H_@tuqN!#G#s>#+HI~avi6i)#q%cE1=$Ay%lHUXW<0do z0Ivy)3t4KBz)sGqS>)u^(q)#yvzShJ`k<&IhJc^lWdi=oOU4DN@Z z9S(>1g*5s6=f8mY#mpi*ZRZ)l)P;LALF1D#WG=>q2C57~=))<4;os@Baf!0Bk~zqU z#L`n(j}z4Fx-L?H4Ii9~2g?v)u%a;=O>uG@Bq>Tk?4m7rn*8C{NTQRIQ|SRyD z%Rl?GKLd9GCOy)HR^tpu`ZC}et^sZ9m`ja3j1evo#u)BCtB+x04u>O&sszMA8M(TH zYGsQOaBB{z2bG`({31Un%T{Ip3PEhW{SM$=6htNP0KnwP2`3f&PN#55yDWpGgCU3m zyy(=R6;cAMMm~i1_vV{#3M4gXh{c9PAh?7hs+vdO^n!%~9+S>%2)9XC=mZ7%pmP-@ zqbxX+7jP@`0mh#Nb23rD>=H=fZhj&DFpvDhnIhss$Ea~I#(eMg2Iw96lJY&ziE2bg za}Y&yM0t-hF29g}=deJ9QDIxn5;zBBOjbhagOo)L%kdn<)SJN75b^|s!-)0$!XP@E z^^*uMOac6E!EDlDe0dOezXxG~VG;O}+?T+)H&X~G%Bl0`)x`i0ddd^JhodlJS+*{J zt^!xfbsnJPH3~lkG16}KJC9)SWrAb_BuWJU3G&&`eg@(Oaha1dQ2-)xN05+lAyUw; zyamABqvK;J2h2vuyLs_7Kv@Y8V#ol8fT{e%jbZXT*Hpa_2f&JkrU1lc{W*X+k^~Ci z-o1M$D)JKz{QmMU{US69icto0$13Yy1JN`kD1M*-ra}S8PGSB_tpHd?9&zA+1fU0M z+4eaHnj*uPOAr*ztV$4#t;_;6BCnKrCAkvE@dW0W#gOZ48QS zSx}xJGAhJS@aYjnSK90Kp;!B^pge)ul5rUWNZ=g>+8d{ zs^Gk&J@CoXkuMC`wdD>%B;glw>VpqHgshQ?0M0`(9}$PJg@}ROO0f$oovU^PWRQut zC+;&v7GDG05{*Js(dP!_)f1l_8C;U|Gr%Ql6d*FQEl53?8IYIHvX4H#3lwO~&1#c1 zpuzmFkS!9HYm*=^0ixCwU_s)=H*)i&RhU&T8l4gCTtEi21s&7vb`inlS&E@1YC7?Y zOWY8(%S678AghwaF#P}abwWr0HB6JAjLr)R$nOCV zy}T|;RpywNLf7OjAOI4@YK(Y5YFc3!!Rmy-!Y{;o8AdyyT=Yt?+F`kKVZ!8j5&3$K zn8ZX#h|IGfL>VJ6>+=VlVT{Uq{eGX1tNVi?pP$ce@jF8DEd+#l{yFA|%+=MSM~{$Y zG?@USYNc8(m8+Es&=uJ6i7awT!yhI;esPKJ6vfsi$Kh)$NTCWjM+{}9a%p>e%kzpk z_5?)o03lwl*IWF8Z==;{fE0o-%OS5E#U%3Z7!W}^65xoSR+3R<#aNKe#UhXgdY}dd zfH(&M6fEkIwV@JFL;}$fi$$n&_B!>IK~Xf;XMmsbl*@r_TrKActP~M-5c2CQ!gb1A z1!TQqLggt75Vr*6U07tv(*SVA`Og-?$MPR#NvnpvuCwpvY|krISY9Tm-RY8!ivYAK2M70Kq- z9;A+G@XK=~j-uLb*>&uMud~v8&IvoCuMoeAqMMHEX$p5$!|u{e8?N_gI6#IQH*Va% zeH(&O&Ih@yAsGhpONtmM449$F%sC+fE+L>NlZg5YZAW0p{L3IS zUj*nxyWN&+DYk9bYPG?Dm~U-u-MMoIf)c{a;^9U7q$L`X_!DELfV}ju(P~0ZaBpwERg zN(E&-kH=RK8NOLYq62-$&Yy_j5^|p_N`f+?LRN=gTp}4w-@pH0aS%|+qoKlCLO`PU zOPI%ru%Vl-Ve$n*bWrmI2dWu$?MlbiK{3RKwQJRi1`-xDaKBD&#=Ky)=K=|+TVARjmpY9==!?Lu98j>Ro_;xn#K1D+b-RhtkRwxPfrIO{K{rc*4H^#aD|nO1#O+p5${ z8&#)b(}mJZou3s`RnrBHG}Ch%HLp>$T+mfRj~x#~iaaJJkzK17TNM`tEz>R5h+6^1 z#aY}w3GiYRfT|fT-(M|@k2b6P`X>p)UDaR#NV;;Z?pOvyq6%iIR55J~U4wA;>N_vJ z{^`wHF$sf$S=_zzTB}*%SBx!fI^t*6%hj4?sE}M3f?~M_+Xto&2Htcl&5bR`C`?Af zI92RorBbW&e4#Woz1odeKXY?uL!}ZCuYOeOC`jBOoE-;ZN;9|vkFUWjx(q%BL)KyY z8M>0h3BMOytruNe?84!9*UFWO%~!D?psi|it6K5G=?K;+Il0#0hlRyyC(XTAUwQTA zqN#>llg-fkvN#+GGm|@6tLQ~ZS9##u*4~~`2vw)Px!FwoNv7H8g>7gM$8K$F@77DM z7WTSbeqz%ra^JJYS9sBVwpb-e#S6e{sj<7ew^IlPu$48Zx_9S|y`7DC0>gQva+5-9 zbN5!g;(%5>f{r9*2T=)>m{)W)fp@XKy?g5pk1&b?(8Vp)AxwH59FWLlyM=^ z79dm34MO~#p5_VwYOLO9wNFnF-`w1M_0?A(PS6VSNeqF!5KlRvUm~3y0&=Krxg$uG z54w>EZlM&HkuU^0_=vO{Vkl!m|FykKtZ-maE;924dZ zj|mmur{pKSFa{PTV^vN@MRzy%ZntC#kyH`Kb%atFS%qXC4AD zpi)}hc?H&1(KVrHE3IwM0u9UjtX-i{*|@oP<3_z+QIg2;TDM+?ly8>HAW&>owr;)r zO4YN%$v8;0YNM$n6P~kSsD6-Cw{Gw5?NyL7^feFs@p7}(s#Ytoa|>o==jJWXNV=U) zs(ZUHy|KHy1KR<@OLOZtUV3e#!LLG3roPv_dFQ2<#3^!CR?zDkTehxP<&8$wn~nzJ z*}Y(GRjX~?dFhqc8jU7g5a?7jE9NhY~6f$XLqMka*`-;>U(!yeig_RJ)jyn z<+`O~;+0%88;vHV7Ef)f)yj!K=np4mv1(;O_w*DU+`4hQWET{(%(H+BSs5g~d4sP# zgUP}a$dt`^|Ka`N#D`=z-IArohmY@%17+jpE3n_|ji!->gGt!f=6S0ieilV`b^FGx zTUDVrqbPA|+dDfu5EKEwm=?nxgPb`zIsk2M-MY2Cz2*BnDFN~Y@)mO$06_x@C9F>T z@UQ#>KsL`S;&(6@q7>%*>#x67t5sVqe)r08U?%cdr*gRjnTz5u!%-FDo0}URJUjWG zl-MbshYJCwF<*k(f3kmHC;*^kI!?dKgN(p|w{G18=J3?GL0_!%1U#5w0cclt2OvAR z3{u+xe^8)VuQ%$ohWM@5Yn}@+q>2|9%;O0nZxcmxOX}T$1EwBs|7{G2ouOa34 z_Ya`AP>)mqu%aO9TdfxCaA+Bc1O7y?Cd7h|#2;A6Tg!k%`SM!PE8f5NV1Iuf?Uw5m zC;*;)$NgUgt7Mnzw&RJj@N~Vj=@l!MjZ1o5isABmW?7W@<1m=`iczdVc=3pvAfF~{ z07Kp^ZtUJL)4|cfA-^kKFq*r!8nBOr-K|=c)7#%$h;B zlcA_l=(kU%apu-Gc5mL<+}ieR9bQCr6Ta(BM^mPgVU!sgH(%c6dBdeN@{MBa_A9S9 z>Bf06zsWxT&S<7;Zlk>As&RL8(x3FBOs{x+SJbxP+(c2qEZfd>+U|}!<0!6_b~Z{? z&`(p9>9o@i0?TsapmWgOAE41hg{^92lYV~)65gz-d#*C{v*~541HX5W+Z4|Qs?H<# zHd?OdRT~?Svrw&-#ultF$I=a})Y{&yl#9hmqgIDrEJ6E@hJD2>d5$sc9`h`q{fCE# zhf_aPb-T8)*W}qC{S4;F_BQ<2a;*iiTd6lJEgp|Xuv;x%9rsUq{UI!3n9`V8Zn0!) zd|5P2qA?iZ`0(`b@xkLq!*O6bo>mCE?RJ>*X(YV2`o?an*)TOuFQM}AA3=c?0Wq1mkXuIpVp{=biRxhzY|(%`_V>pzvEcQT<{2 zcPsI*Qs5`P9bZNhCT4E2=?s11b0Dz^#3a2A1M$*6#If8 zJppq8#c^F)KoIsithiiCNnUQ@ zM+9zQmssUQ$a4q~_;B@1)+rFoffSrUp0obemPf;1*VWkPG2to?WQ#^8lm5|o&<#i-z5ve;mxH~|c5eX+pF4$T)vi=Z_GEY(BUVS9AVD_3d=D|i^z2DN(4793ZW*?1qM5Qq9_I1bt^;>S znFPZOa>{UvcEvMogRcvuK^z&Dr>lh^3dR2P2-zl)&kyhW6R1Ul?{#A|3;k(!ILZ7^ zhV%zKzXHg>t}wYk1%Eu~_qyZp2>;AdQ=SDB#PD-99sttojK&kp!(h_ybxx*X42lQS z5%N!leTX6QcjS*pLkh6TB!wE*R3yNZoA?oCI=C1Oz;eR$iTufUJQ0hBN*qkOCr9HT zhOU5>5yP7p4=1Q`FyI+iDNm|6dUEg4gL{zLgW<%hZ&iyHki}S`4RDNbuK6w+T01>> z@aW#%!6<^IiwGI!gNE-pP~u5AWUUbi0$uRGbB51ydgeP?^WuLUNIw3Rjx=BWTRo z4NZdtTxqI~N_nV{AgN&dB?-hB#RvYvw1vw&8Fq%F5he&fVF3ds7y+5_G=P~7WDo}( z!2AJUvz$!F!|8Mi5$R9Iu)5_Imj@3XN()^yum*CQCKqi8`JxPv<(WvZ&*4?TIfHEr z8yvPW5_9=0bO8E>Y8{8?*F!VaY852HRF|(2L`$0{m&3C4JHHYFPypmnlv{Je2&f2< z2uhH5&jM}>Xp)V0KA17OYG8DkfvQ*X6NpoZhN#Ii9I2uy(+o zkh+#-OnZk1`v)-BAVmlL4zR`)g_NI+dg25WBF>HweIZkM0U-p`Fip8oY@0gzrRpZ8 zG&%-H92`F$PoW*)-HiHe$`cJ*E#uLRhmRiK{kYQ~Vum3R8kEPqt8j_J&hX%5cmk5p zc2V@AQ&CZ0=!2@0>FH5_zdISF$XiIJ;nXl3y-1D;<2aE%Od970zfQxZaWkA^Umi$%*H54lxjGy+HBFAsjeIFnWR!=b~JNL9Dm ztT!5_p@RY22MA>zHf;lP==%2UDtsK|!~`a&RX2@SxP(yYos@93>5`h!7MAUr$Gm zAjhZT#h?i+;(}&X8#}d1g}%H~t~FYfTD?+l!U%zo1qag^E>|r>%eeGu!-J?)JWK{O z#7>OIkfFeY$UuJ#2jU!r336J7;!ojj+c1=XCu9tX138goR;k|H+;SZaV$LaVG@A`I zg-J2Y>zsn5T-<<2(k&Mr0%n5cl=$d^%b;bA+iKKuW2aHC8_+{kTReUP^yE`1%yKab zaws6Kz~x?rheh*IgIC(v+ChY4e4)go`3$`RDF&q_esh2wDxVcYDMGlTYuwPoJv{@c zX512Tl-qY4*F^?+kUKkDaFtF@PLGdHcv45Z-9HQBK%y~bvm6-m2Rg*x93!z@9?mW+ zm8vv~h17TofDFi-cVG!n9O-O`0d2vZCmQk>*XYXG;QPMBmM|EMG1z?HZ8DyWArDa} z05b6Sm@D^i1S zO-Ggz(=PNg&8=_jVAjG(r5?;DKO2jK;ql{pol#V*)-6Mw4o~;*zklzekJ_Csi~yMF zt&JUsRa64WUaoI8n=RlI_@gM(D$U($$%SPJ69C>Fyx7LZHip{;&Kf@q0Opf86jZa) z+^kkh5L9Wws+aYI` zsU{~)I_|dz!?9|WDz#>*=mn$B$j@rcmS;n|BydGi1){$UuIruVM~CWAMckn@=I5nU z9tDj~4|;tV5^!GN$jA*p;1Gz-VB9`AJc8>C6AA_toSt6ic+lqwdTyx%xgJ5{PXp5_ znJSN@K5g@{u;sXLJ>dk5C({DY@~_)khW_eMlg*Z;t2`-ah!%CnEkYB(O*w6!CYfei zPDb0R$Dx3JnoQAGe%WRkz-WRoo+V)z7rasxO+UK#F(fsF$mc%yIe{<%5pWAfUYItJ zMR2E+XRtS*`If%L;%b@%q$Yd$}F4a5(QA}FpdCClqk5BSlKtgFj z7~=OAe&H9mN+1w`wa$EJV7aPuYhD8O9cY6lw9vSaZilEG*Uo6a8(=zB+gzt>Au({r6**giQriBe2Ps3)H+HyJ_yk9sHl;S`b) zA{!cF&^;Z)Q5JMFtfFh1lipFgGjwX3)smA&)85HG_!wO6dc`apogVHFhSLlaz~z~c zkQGxuz(hv3xaM$r0=HW?UGf0@lHoAbEEpNdq<3<7FogrpBZKm#PDqAwqve^(u-{J# zX3;L%P@8;(a1tc3s#!`pX%CJkNx|VmJ7_vg{|LlGKPUbeT4+3N_opMse5i!6KY&U# zK*Zgft{wu<;W*F@^_7OwGL#ds3Umpd{hq;#ISUAijw@z{9tV6v1ulZj(;%OM0Nf#V z16i<=VWq%<(^N(1Ne#w!5~nK9|8^i3!L?v%B*Kx?RRxBv*g{~6cXtED@LGGfcXoHI zY;ynocRHg`F54wgOhjg8jgwt3upE#B42^mPY6cWlhz`Oe6EE&la7enrh{L4dPCNJju1Niv$l@zYkaZ6~cXxMyt<1#VWdORc?s!-s0cAlPOays(2Ij?CikA|Jv(?UFp5Y9_642Iv@n8I{ zPN#ziX#2(+Z}1UimHrTrf!lGe8sJ;neK0TX zyz!ETK{ch}PTHD|!H>YmBSN`ar|^Vhh~QC}z`hj##w<6uQaWrO!e>je!gf`Cqg;5{ z&hC%p=_m`}J1CX|&IY5#;*?s<3rrw%8Ei!cv^d2u7gQdykCyp_96}zg(|SYN{j zOcQVes~1y)AN`K~X`(teUiq}A_V*t>hIvQ+=XN*?OfBXnI>HYO@JU!O4Iy?Re8B&F zaRfrRfVm=lYw)~4hWroWKQZP~gc!tjFW_=_walJy-c$Qwhh}yS;z56aZmX zGUs#{MvKM6{O0_YxRL*vmt3AAND`Og7VCjp^%`5d^=dH~oE{$R!|fJ@2*^2Wd{N0t ziwjV!VhxqR0vL?=tzDwQCf2g$FslUrjZ%GcV{1cC{nLX--5#by-Xf6`buc=wCr4<} ziP^25uh*B<0KnIo z_Y1JxojEed;5lB-yjKIXGMVPfGWl2wKvn;E#m$vz@nnP8%vwAV4KQ@ zU6=$Jyr{hLA2(cN>^wVw76N9ME5um4wftvZGQScqyOcK=hxgYxd~olBcON}|;tMvN z!z>>`lp?HM&L9gXz2k!?gK_@JQ)EQeJbDIZm4K&`N&n>W$M42I1(LoW*A-_DY8W9D^t3^(DPU18kX+7m2?&NX6{9@i9KwK_v(J0H42_nvo z|1hX$x2T)vw+Vt2omt` z0&;{AgX)?XfD6ATFW_gib*;1Fbahr%AO3fPWVZY{(w*XVQ>q8 zh$B2Nk|=+z8rZzp_>o`#vk0KeGI78Xko)K|pj0YtZEeca&A`;FOB0mW0{HBNyWsd( zPOPhnIU;{C4P;etQu2*Egc#{CTDdZnpNqg(k#U31QG)>U=Nu3NkvGY|Z1v>iR6YYh zC1?>D@cZhkuOdZyMX^}9nuDl@^`If-5g;*@Paseyb&&X_SCroq09i0Y0Kb=qeE%sT zd0{A2fe>*j6yAF4E%^)p>F_^xc6O@O3U?KYoWM|U{Q_`}MAU}T_~D|1AQygQqG=j$ zzx|FRg=Jf=?E;G|0sr!J%f+t<{18?mf7#%2AJ>4qkwJo|vd*j3iaf~mB3lpW|1^ z(>ch@fVE3emJ%PZoGw6K;&&bhqAC2(gMdX@vB8{NAy8#=h~O9EQz{P>fn*nAkbpe8 zI3P%7mY4uomB=HNlc+TZT+9JwFM>RWfb$CC=llsMyTZ251Cb>M;3<1Fql3ghCj|io zFeK24`SmLOmoj41Gy}XVo{eg{Gvlb0_Raum=iv+WCO2e@gHi}<R@0P2b#d-Rd>6I$>0@dZo$bA-^T#GI*S90bu2Svve zbgC7%R$eppZSD$PpC9(Ilf!wH}Dm|~Lvx}Pb<#`adLI&B}GcDi9CJ}azivQBp5|Iglk zHA|Ld>0zKBt%Ym9?pH=ciV|o51jf(Y;y1b&>94q-Bn$cm6@TgcI`(C_xZkk{NA`BGb=NyD{D|IBmEw+&z5U_Yps3u zUI&%oCooIJ4hMryI=@O=b|-Y!w--@bp%7S{bxZAxPR9qm_~z-eXDmY3(xcV_qa(dTVPzJ2+t7cX9BiY5`t9EDxKat8V z1qcy=stP9LP6xC0+Ep~4&E~MYWz7uR!PSeWFJ1tcKxe<6qjUcD-~QWw_=kU(Bz#*7 zfWa6vod$x9iAI5QaBH*ScXojv03w*)FlHZe6tRf*zRG1r!i~UPuFw#(L;FMz1RDkI zkKZK7)2nPD?r7AX{p{!e{eS;I;M8Y09ci^(;`i_W{lDMqbx~i8EUE;=#l`(oqGI?( zDc9H6?RFc(&9;cpbx5{ctzcZklK5Z$*MD<L5 zl>XQM`d>djKJvv!5l~yE{UBio?|TC{k3Xhq{_B7JumA18{dc&+m+Jkl>1bfwB7tiK zyMw!bQD@P$-~hfH#?xG-ZfIWD($rR+meH!RLU<#?a&>k7@;tlS6aF?Snms!CY%~ma zRUR*=moHz$Sp{*F#7hLAfWn;>lw#=I_VCbFi`(lf1w~>GEc|-0+^x00ErZ z+wQDzcrff0tDD=~8T>v8g2WaIETX^*c?TA8Vcxz)AW72N!Qs&FNZT^aR%@_2`oGcKZPE)DFB|RjPJpa{6dE z9D0rkE6nYmeEQ>`3_3mrw%+O8;eop2sxQ~p(&3E`jNatz@aQP;Y#@{F4IcmK501w}rNv2P6Kr+zs6QCkh6*NwM%L99 zz^)y-WeSsaaOmy&cJLHi|G^{(i@H)li^a(rN9;R_vGlf9eUu;qLSL< z)2^q_E}k#fF~hpG2c9L*u3oN_Di|Cc9-oa4Cfr!RNnM7GJM?UmmGOt;qmyp0XBld> zZ3V-V)3dXH@syxaw{|e-cRTAjwAd2e^W@3n!^1;}O@pBip&76R(7|;;WS;YLxVQ*V z!xcDlKztm4AhA#_&!0d4+0TCd<(FSRdxk^)|K*oo1%VG$fv2b*_XMR$1$Wq0&Y=+Gz#5jqW?AAkvU5S47a z2iEqE_E%tOxsC%3x({s44pH#z)2Gj#zj%QR9T$d52v~PqZhVE3)ojCSTZ{$7Ju!;g zv)#5~IVu%`q}XlKuwZ0uxgR($HLKn2_(imc)8gHVPQ(K0kB=-lUB{*0?zGBGGQ)%8 z({4ME>Y{3Cy)h$t`Hs1*wr*z}dRh(03_}=VIwXf8)=}VFYu@1}KYe_5Y^g2S2WBwn z1ZI{OcF>l~tZZ4MqtijZugO~&S>fP#a(D!t4V;0s)IB&I_JTZGY~tJs2Ztw+;(@NT z&|Cn_r=NWmhyVeoO)xydg8+)U%r&QbNO>Oti^?qF=9fJ|iCEoW?5WZ^p02Z~lJvIQ zQE1bI4wP9-3oNh57Rz{2=zxsHn(t^;svy1HJ)>q;`({ee<*OAuVK z!$6+ct)yt>@3U?GV(DWj07-2hoSmGUcrLin0^^uL-?w$u^cewdEAi(9Ez|Nk zj=o(j7L0<>Ft)684$j60eHaJ2VZtT~2FJrem-9Tz4rX+JJTcXl;e@(WE|)9C3Ob>e zt!GhI_l};7hdr=6iciu^vwhz+GL*H{mmqLm5x*q%r%XW%%lW!S` zv)Ihw0;E|1C)^LhXg#~VouYeyFpnQU0!oU`dS#n~XMmPq9$djOGz35s;DlSa-fSHJ zK_39HuCH(4l>G4@|M9bD&j8k-i;D~Vf_VUZcoqbFTr8HCmsiUL|HJX!zXeS4gkJ!M zS-Fj)m~W)35}1dw;BEZuXMcWq$Ygp0zu$G=zgXXOOpSXEwyVg=y}8vAem-M^d97dUoY+j49b z+N9p*3^%2?9ou%nag2CSON!G0-eagZUse^NWdYo;Re2)Ev|2FZd*qC=7#cdZXn&0 ztU0~lz}K|`{8&UetTD^i86XHI&Z?4~juW)DMP9&At6it(8Wx6Vw=0<XeH+K%k~K z>)RZ5EezsLPiv(B4LD$-C7BYx8TkWI0PmiH{B;PzF5OSb{u}*fV0o+EdciP{Od1XzBmWR zCrM^_9cYU@P2ho>mIAGBaH#0Fid(Sf_`Xs+at{#P z=B6pT_4LK<^j2&o!*e#LxHuKg_NJTZ?d?@wOK`)Z)qJ&>q2`Ol3Wj_Pl@ukg?nOOX zz*a!Bc-P1`k<48XicZsn=)7EVM9R{(Y|}9D3*#IRz5;B6_i=YN2X@0hKpLW-ARHi* zqM%NNI(Yi@`Et2N<}_wC4e5~>wPm?g701bHwL(c37f=vamsi&>UYtLD_Tu@Am+&VV z&jZxt*%0cy7S!1C;u>`oP8%Y3iG{6KS64XRL=juELdBOrYA7(MmInJ!tB}!5`@J6g zvC;99$@pkAIU66H9gL3;j-DKzeRlNtM@NUJ*7K6tRy*f#c>SFsg)K9JAu0w{ZcTz(7~)HH=Dz z^=N{MG(TCoTCbZg0iYj%$VFNJ(6hKmV+?vrrK?6}A?Ls;sOoeH`QTR8x~!6A8qK(k zcfW{~b4FmW_bAUhk~Jgfjk}>6FK*UJX;?PgG6j6>`p`CVom{{C6$U9vawHA92mNkP zrkkv4A%O_RT%aJBAdso~^!obZ<#NSuk-{S}EgQB`6s3mao2CkIfhDJEwklVP+n38V z1Nc;VvYg#)VzI4fyJc7!a02Ig)NPe6=eP6e&F$sO>2%prEyr^?i(HCbMAEK^mzU2W z@6S*-3IsbCeq+wh`1?&k+4Fiz3}V7*#zfDU4&6`~~UZoW}Q-7FxNkXwG& zz@kiYRu)4ML3d8CH*t(!;#&~$9eKf>C{WS)pbjR6$qy*B$4<*W7smB zvzcH4MMFe#o%HIngh0gW`avpzV8x}FQ%qx{399PV$QPaUlfS;y<_!ZajhNaWs2aevd)rZ3?2#u?X&HVDkS3mputEbsk_X59FKp$ny z1}%pXgiAqS>RM}8MvL3kI?+)xO)iTxfvtBZVkj9_6nK?e_I7nNr+Zjz`F6D~vm{!t zU|KEaS;0;0y5Sg{C_|T%;TaSh59%5NIxZK@#0$SIBVL#p7A2QE=LMw9rq}CDEEX+S zB@9Li7%&J}5j!RRT;bk2a!4C=X)b;odEYNjx06%~HKJi1+FFb6e=WSS?a z1|F$l!pa7ms}l>m^t^^qp)oTP<#3O>g;?Ms%r&bGL!t?ExbpW0uzr z+g-7vw2gX~_=>z>O zmy`G$WD&H7)681)Z%?>#kG5|R5M-a0|F}C>d=_!PtO#z70moSo1QCs~ZJxr^&vT3f zgRY@*;w}j=iatbfAlGq%!0Y$BLxzx}&S{{a&BcK~|^3!qko?F=koF|hVf2rSwbAjA?5DatJXN_<-{Q3uoB z-8*d{RH)iYFd}Jy&}J8%3Krvw6a1li;ad(d!zMugVfB!n=XXRfZ++IF~-&V;C*}0lca~#3T6m2V$2yovW zA9dPp4Pb`VcyooqVF1A>gN@FwIkmQVvX0Zz?;Q<#U38V{wg(3jD44K+(CxNq7}{_V zb{T!mswN**UT-`YbgF!{m@iw3W$2m+xI%dcKM17>=SYViGdvhTIwba`?z^KwFmf5` zq$(iQ`DUH2(0!cqFx!J*(s2Ul{i2B0$zsj9*qC8d;aHS$Ugqde)v%$5Or?%C5rbqX zt>aMoB#>aVKJ4t@B7K}-aKIAuGecZ1W)XB`$tccXiq$%T$C@+tB!+XoUar{XF|-0~ z-w5ncz&{`iF@j+n!*$p|&%-vyUBDt)4^X|DuUDJAC}D!zuBYq@a9f;YMaF1PoAnA$ zaW!<7ET-f_`pr4(!$71giv__EXFZbM~0F&8654hVEj>lHwZca zIF4L4oPLID4Y4sD7i^m>Zsv;>nz&g`8UC8VpHs9lT1}@{S8<#{#PcM^vk4<(ZwT&a z^J2DMN9YG!ftG4|8eGV5*KlAr48n_>Ovs4*bEHAfAQN`qW(AKQU4$ZLx3>`kud++w z)vQ+QLd2ewVL2Hp)M?4xJq)S^cZYR@-+?}z-%f9D&{yaYR)#UI*CJ3WtCuB6lb{JG zi(w_Hn_-UCkTg7UeRTzp08akRzxg*CyIXvqWlzm4KlBIqhfTU8bRjTIyw5b749E%Ab60o$vK@b2MMZ=}z+s=mgm){)5W!H6v zgTb?>&o0C}000WOsSxh~PEL-4zy~NJ6OJnIwyFTJVGxLh@YSjB`#=BlKcCMRKmIW{ z4FD1D+k(G9f?xdNmv9_$5fxxQG_IkG7-!US%>)0OEfGC&FUP;8~K@Q6o5LiPwJ>1pzs^N+TTn!v`d2>Ertf4d8 zj(p~|qLjhlUcm&?@6b#_ea^`=*ucR3I8EVa-oWc6%Yj{C=g)4J%N1n;%)DA8u)ld%$e_p{y;8v*OYtu)Qq-*A zCu8PoezyZdkmpqj07}awE0Z(_PNBL$w^hcujf%TX;5W1+)9rM+VXcp;DUZ_9v%M<8?H9`SiB={k6aLpZ#C|FaH(PKj(@>9dNLsw%&h_0h$1MqTv)& z2GryOzX4he`f0V^{Ih@d|HO#kcruybDdhhSY6`yli{FO_DAh0>T@iM44Xd^_aHXLk zov*j^{nzGybHt|Y58pvxCe>|^#>dC5-kP0%b#ZkA2aFZ}02F*fp6{g(KK6}yN~+1A zkYb5Z3AT1j>C}^=WcxCH5K;BFO1~SSAOu^&gel_HY<_zaCHIkherqhN^ znE8i^lc&H!&fVW$!|0|+{J;n%CEO{%+5Y_f^o~(}Apfu36{-RF4g~<*84ictZWkaf zOwoIS-OBg0c(!>6FwLn55}9hBN)R6W>Z`p6pzA8%Wr)R^-EI#a0GtmL4x_#?`QIQq zWn2KX&uULNg+(hu)P3>A7mWwd*y*Szj)8zb{pn9}s`Jy{s1gqOKMG>SE3N{7?f?Jz zSO1gaxTj|)@Br>K92&w_;P>Z0|HZurfSTYIXDnd9i;15%h;4qI_BY-|&0UlNjn%j; zBYwsH6vybSrh(iTEryjHD)R#`sHE_K=)q{*M6GfTOH)x9RZ)KN%U}NKpZ*!rLpMM# zHg$MK7?is@-dCXceRzO@2Sb6jcTEIojFV+5P#qB+h8A7q>Ud z<+Av7pZ$T+D;Tyq(5Cy$P`vebYf8%x9-@CiJKM@({=mqxM ztA9wqZ4l^JP3v_#_=iT}2PVJgI{4@N9=eEA9eJ@{Z{ryrgI_z<`^qVgd&{Y?@}7Zv#76HWL1 z;fIKAdC;Q0`G0?N zg$df93))|L58?JcouK{I*Dng%U#Gc$_YYUmF}MhK;LER`LM5QNP*3#=zl`<`{H;e1C0!9_ z3CD5lJJPw@Q4zB>d^wz@!rBILbJlAnHtN$9hhN*anm5d=)q1fII|o(|{wP;roEawp_|VvX|bRckyM^N}|Hv5nN@lTKvHHVjg3KLQV0cVj657E?b z=x+98e=2HzPtCcwd`J6hTo?*8z8h_lxcv@7KQz_5Z`ysW#p}xL7hnA9zx{9j*?JSX zuG`cT{VW>Dt_H#D+UIpYxOdv8DfbOf#m)T@j!{Fw0;sEQxwhkgiT3y2PkWa8cI-;7 zqTqZ(N(z7mw+BwlH;WQj)i5o1Ywt*j*1REH-;OwFT!5;p{5%!1XsW^N#CSryblknu z(aq3`W8Ttmm*0*xY)43?$nu9sAMG80X#L%w-uL(ZK=h0_x+`iwB(iRY-M(WekWZQ4 z{5qQ)9)^L>?^)$JYV+X1=E?nolA^moho6AYGe!ep31R_UbF0$}U3*({_Dwtm!h^gC zy3b4;JS1McODRrKI+E?Bs42XW7ukT@9dNUINhg#kMa@_f!wI|HuDZiLG1tcj-)sdk z(Ja5+=_tEe(wv|ZN+LKCSPLn^&*9*3d^j=WI^}XzKGi&pqvqgYo~r2&CZ`?WF0x3m z+LO~y#^VD+$~2>`vBH>Yrl z6*XUd_4Rbht;OQ4tezw>j>9ng8-L?(=sHxoj?PB1w+WeuY~DdYe8Bh9r%#)mz@vi+ zAZEGXR@jr1^-V1t9f*{2%|{&@M>uSO4l?IX*r@LAZ`&4I!Pb z8$bW~&(R62XD={qoeZ&M*CBD!d!iTj%+j2RWArnx;6yV}Nr|h2IFurVNZ6zXoN&@d z0QV=Ke1baTpeg+!p_$xND7F6hkN^FzzW5dDd3Cws;VK6sI$q96#z0dX~xW z_mRPpdBi^N_@`d;5NagobMyKV?;%g`NIUXI-xhKD^D4#P zSF70W9zFT&Q=?cu|LRw(T%J7s%+;!LD{qt8voF7{R0dV3xZHDI%SPDg8aluF7C{=# zU^E`f+2ZB%XK5vQVLu2wZtPnwT4wjrkABiMcUND3aejTh#h3-Y$|dp3C@Bq7FSB^7 z7+}_Ty?QmFFUkDoaM*?oU2rSOvZcFWr>(Zi^?VvWq#9t9AY2 z>-j1M;)mUiq3oi?EH0$s+2?1+qxkyS^JiZ#H<{_RJ=aF-L9)r9H$c@iTIO5x;Aou9 zUdAoA-?naFJk48{58240)oNpeB!NI98I`n?{5kZrezM@OAb=TH9RPyX!B_=+-Ycf!u#`O`0eTd@5< z`Q%B%d(9iOUyFoJQeVD2Z&b_YKlv%D@aKQ_f8ZGQ&7((W+`r8Ia<5eqHNU*Py1l){ z0nF&b!-;4eUkg7Zv;|75S>|;1`LSi`c?4@5BLPfijL9meXsbL0%y3mDver#*%fqdz z+Nq{ySW2CjX;exu9SyOrA1QM}vZBMzl;^jL`HXsKJRXY`v2RwRAy_%<_3G)dno~)zuXe4~9KPSkl#S;ApK~vdpril2p}npyhWtxTz(ZF0>tx zZJR}9OVfjqt!q*p=ZmXUGQ!E(6IV%J{OT8rO|$6kE!v@V;mPNJFlg&}UMsr{iPwb; z8JFvPy|_(^og4HZIF#bWyrp@=$+4{z7tg+0r(3VngJ?**Dq2i|8>ZKRZrJ6~av24a zPfw3}aDU(d%%1<^YMMChj;ZdV<&0ZCkiWe>>N#x&U_Ka4ktA4361N-#V)G|ii(C#q z`AdJLZ@13B{Mn0(YrB7TIPUYSyUA*LyR_TwI+~ZNXDiu@ufK}2a&M~0>frQ8k4_G` zMmmeGU!KeU=wQ@UTlMn#+2u4D96j=F1p*t-Uz}epJ4c@$wDp(2{FC$BXmI-DC>Q`SxwJ|<93tXelHW$yo-Z=-yha-SQnXPWFrcQUHLE3hP zDW?|~*G}(vIDqSrUp@Wvi$yVh{9}K+{MDcTd7*emkDti-&8E;hp|_mR?9OD+@uh8X z^Wv8;uUCV!A9s!7t6%&aI4-H?_|cCKy2jIA{OKxF4j+HsZ@X|s>-hTX=hxxzB=pT~ z9$&q9S{c3ZL6-{^lGWw;h2oD-&yKdMtLI;TdAooHV%VZ&_VUZGp1n9f-@8HIn~1i^ zYPTB>NA1DU%V%Fi>m|YEBjv9f`lGY6t*k%$>I=Zf{_6V)F#0Wd-Y|`$M-v6Gp21a< z?Y1d`!|tjS&?^ZfC10oOq6JghQE{)zU~E(}EJI(bvwXA26$`E-&=@)sn48xUY(zQ- z(K34WtMgx{3s7-pvp;)_VAnqW^jMX3RHk#_>aA@w&(d^j2A1n{e{a6d(n9iwHcp_P z(`A|@J1c}+#%Q3MIV^O!J$`a}*quK6v-9gEl*~TshXe&+wa_5(9G^Fq{^acJScYwMdwxA#w~s#m?30sX_TsBAe!0w~(aB>t$~%D1i(jR3cye+A zA*zb_>g!)#-pubzkDa0g$HUJ%+IG6WTEvS=au3?0RvEQayH#(}oi*}1NpwApXK}e5 z_C7xe+nab^RO#*F>7rD|y)(U9yqLdCtJ?I2XPR!oj51_G!6Q z&7wBq5%rj&!Zd(dx}C3N&2D!Gu4AdXiP9Y}H1*bMdKu@Xs%b^Kn%-O{a0J9;4xLIa zVCR}Ws+sGH+pBZfI5*RUY6Y;rxqZoYEF0dWT7hR@KAkT&44;wYhSv=|t4LyWnyzc8 z16++D2)F|uI71PK=!p+xYbvK&4a>4&)3Zw%HORJ`*?}5XF7!7V!-a$Rj|Q)T0kQOG zehxdgsCK5)Zuh!)&ahA!N7J=3UCnN9;Fjs?b~(SE-Co~ZzPz2zU@OAZiV^}S3hs1z zsF)b-SA;fW#5p{kKRg&e`SkO%)05HU=wNc>IJOQKORSiDgJ5f;w|(D(YoBN7;qkFy z5D@pbzaPnpIypY$^s*!$9iKE4%`}xsO_DbW3dwOi_$&MK_Ym3=1Ywbs$)+fBn9k(5 zI;-*oHj|{87z&M3zlMkaVXCbP8o#LcLV=7{mN5RnB`A&7MwwNxIQXW<(vTQT>;`tX z-+pf`UnkVoa?Jh7yGT~#!_yHsj&Y7tU~iGE^LPc{L?|i){e;pLMPszNbd_yZ4E_To zjHmJHDuJRREA3zl<&4hoP459DS+N87E$uQ|q(v+24ICRx2Ep+hKQxtU`tr+*%c~qd z5WMM|>%7`=HV4g6TJiF7wpgi_?}fciuWOp<5F0f|Pw7_B9}d+zUPqbJ9{9ckc4MAi zXdCKgeg#(m!U&n2-CS%^I-{tk=wqlfus>rG;MUF6`Q`Jkudb((?sWyE=oaLL{J$;Z z>+@$f(FS+fWt=3?O`E*{jw6NdTARVIG z@NQk#NTa2!yYO@8qPFdJP{xb(CIR!vss_snf{*%?iWLTKw!B@g6Yy}i>t!2cGUpVK z0b{7Re)()RUu0>H+y;|FN8jFFo>yux9Q9jufhv{pe7cOCuTghr28J3HS8@S}Yhpu0)*4!ka=&m0s+kCxRtGYEfesnPCXo>{Hw;i`Lm>eG; zI;L*Knsvad>pFZNEvu$wp&ntke|R`9vaFUg&$Uc( z553nvIP8WV9|3gQ9xX$Hynp>O+LqVx+dW{P?Yg$>yJ0`%$G#jp?0OcSv4N0b z7-B%6kG;X9ANG8pJp7Cb++%6Lusr4bkL8OfTS-~KI^9YJy!K5VFAMHx=4%A}gDf;S z0BwQ(_Ta2S+;G~&vVQ|4WX%fN9jS)>#(g@QxbV9@xrPY`o?lii!*SGTG0jTGohXWm zQXV)E@U)b}9+4rhRZCZkqP9J^PFG-fupn%0T`7|^tBY*8Serr5(yH}>+kMk~*Rb(c zf%{U=r?)k%%x-6wZ5Txkqr+(~#tn@c7=fIwry{~=4_dZLAT@Kq3hW+7Z%r?rPp8wA zulmtZjsa7s-s-v^+D;r_UT>yJkplgFZ`gI*Je|(s*f!g8y}nwWFSDej*uLdLSz4yI zD^|Cg+m`CJZ8y&ro1EK~6vOTG`%<|^nH7znR#|gX#dm<(-voVs1wi9Kr76mQ9%YuS zmor$#-4SrDx_bWgI;|kv01ohYvROd^z?4qnM7P{J1F)w~(C@SZIM3ylc1^mxNoz<@ zD@{_Mi6X&($~Nm|Et~Cj7m(!IM!cMFH6ONKr|s2w%HZ{02ziAq3AR`)Bbe{KZdV6- z6{X<>x?C-0w`mFOPp0tQee7idyJU_ z6DnRNS?NNg{J;;wZMKQBZTH~hU^LViWI0z2V2EcLmb}e~!Y#ei9|C}?B88+weBorH z715dsz=UR+?kgjyR(~`xTJgn;7f>;sZYb}zvaF<=>1@8%`7*h~aEWy(>$czS!m_SY zXwn5vb%kLR1Jv?T+huaA2V?6x~v#9h{GN zy>2m+DoG3Iz&u*UY3%||9CHg`+oCo=V1Czuu{!dSA8YgMI?q}%9lri}(hh?izbjMn z#kJI`8Gr*;5BE67un2&QzI$8ns32Xs}+(inWllwmLM zomO4JaeZ>eC^8ULydm`=@7;xsHJL(ZZOC( zXZ!(zu>H{zh{Cp270_#nVKd~i0?UFS_%V`(q04|*n7yW>HPPze2LOWU&mwPT#qDgm zi30foShoyD^`=;IL5yKD_5pH1)Asq;I@$^kPlDQYtf1#QuA$Nrf`!XZCqW}`;e1pr zoQe+sz^QD>Yz^O})_H|&ptmZRuc_G7@cJZ=sym(G#J5_Do69IEbX`95Ie(p0ukB)m zTK9sWP8aK_FfAjGqa7VeGH0?`rbX=pJ-^+CLWQX8H0R*x(XihYt0#7TcNB)cX_z(N z53bN_Fe2(ACv&Q>rcx*o&2k`}1uaK?$H=?uD9ymtLD2TYP%0CY8xD^r;{!w4MR29=ID&%;7>A$Vdc7$akETl2vl%B7a?Y5_as>cf zKzqZ3X6OJI18KB|h}JdzBY2xh9Ekv&i#Sdyeh6qOOnWI$;4t99QZrrPuOZhMSD0Dg zGC&UF2*oiBDovG=&fKzR~D<%p^07Qn?1{d{?SeSHIktm@Dj z3b+ck2AVHoh;LA(oe0c=Ot#_;Q53}t2k5sQ+l2qI=8JBNteP>jQC@8U7x4L~R~M_* zx)SgEA^Z&Iwq6rWrB)U#*XvbLGTKNS#V7&NhEnRf*es@t**wn+cK@z|?F4m&5^Gd| z(ZKNRYO{$U^qf7rx>zik4_sYzDQuaPTXShO+lG>*QA?$nO;sE-k`MY2pe16XT+iq8 zykLMGbna@os-a_+!Iy7m!cn5J{Upz-cr4$+`HJ z8o=m1Iq^;9_Qfw>p5IW&P|2op;-e@ijsh((j!(j}L(Nb(0u+h>$lzGuji`(u)*EHs zcbZ7KCsqL20t>j}o_E%1oBicHZPD57bFctyb_ zmZ%N;47Vt~c$&S?6uR#Xb|a4|+PHyM2`CgN>>TzJ3urE|F#_+JR*12Cuqjtufar=Q zvy1t*MuKDPw{1&H*Youz+II)8aw;7fB6)p(e^Vx<5vAdr*))|G1)|Q)NmDtTHT6Qu zz>?ZpYnJRb@7giS)}nv!NaWej{t$oIL4umo<_7Vn_l)+WY$TrMDRGlPAfc}Q50sRa@j1(dVX0X?sga@3U>lkvhnkOk2WRF7m%x*njY%kKL-S@-+ zK%K=-wPxrUjQ^fF$*KxJK>!s;UKDR;z=4VZkMOjWTwR=B(Ku&EF=g{$Qz2dy-O7A~ zh*1`HGR*49$!Xg)78hSWdwx;TH$$quG;$%nNZD8+dtqd*$d)Huw$`X#_9w@oX$U)w ztO}{Y5xPkh97jxHuL-si9EMS1N=OuOLo8zD*dR4w1b5gENNKqI{8AY&p}>Gdt|fim zmg0E#<$5O;rT+HmqXvT$e6&A)lSCK2k65Z0@ORMuL0azJzULVEX1);L+HG#|S3D_r zDuMqICpoz0VdazWz!eWi=r{C|Jcq!-WaNt}|~ADq4-an@YJFX`3Mx1;9O3#_&*jo*mn zBC7rC=J#$wPP!s#QY)>59sCxdEDCvZB(5~noHf6wN>dx0-d}&?pgDfy;GXUqgFi4! z03P%V1U5CdLH;eU6x@cZzfA>^W&1oCac$x~cu%4LNFF%9AD0pX@l3i~thgg7AG zAKVjRo%Pz6>lmE>S?9ZN_bDqp^)SO%r^paTI9F77^xm$77neS0+#3(RlVte2?QTce z<`70a{-!XB-g>P?;(UMnt%@LV7?|{(iCN|M+iB#x^H!A%!^LvAFq)n!6vM*Hi2tc=+6h zGx-)JyqB69-qYJxK0pr>H^<*H!~2U5Z@xSu8#QBm7pX+&Ba%9vW$X>9di*U;S+ar7XU`-6s>w%nQZcc*v14c#BJO#HdyDqguiXbQi-^j3-ZC5cIQ z(TR6g?&v8AHrdT9U|ec$-W7e93&Xcr zOvX2&+?dj&7rB6mbvNjBI&DSTmc_fjIr3VGsu6S#y4>BCNt)B{A9UJnU6renVdZgO zHythw;w!RO^Ti}&A}WVNNzqKp=DJ(%kK3URmh1A1*Cm53DVkyXzGGu(=m?>S{KhBW zPB+zHo(+k7Ne`|)pu3wqk|gd)^L*3LkSm&Di*;69=_01c8+z~*XnzKUXBd{MaF3kh z1^jX{U!S&EY0uYnm3wXZ$(IiifKpgKipl`iqDHc;iI2E8mB&4ikZ<`E4Mi~_uF0BW zI)<*veAOrV4{7$5dstaPydwTXcB%osZ9cU7kSj>y7+k>@|6*`OhWr%=cv?XP@F=mJ zS+OR3p-#l-R|3!qR$DRbpxv`|wGyj^gofke4c#B(fMe=7T&i00)g`VpT(v)biyD?g zZ`ppg)9s-3CBLpNn{L=09JCqZq*aM888qqdO0nD^V3>@uMEgv~)m23-tPl-*MY3u5 zfz$O(58aGnFc1)3hSlKOFwL>rfgReqh2BwA%hnCFTvJU9i*1I1)A9JAZa99s*Vkq4 z{ckjm_<5tO-_xExjslQm42bV=zYoJ?>4r&R1h@0MjkFxS~|qmahZ~fly{OH z4o^P$d=R=-o=dtvdHngou;==1OPA6(Zh>_m%t#54MG=ngINWfF5>?CV^oKT+@%1{y z-t$oeaAd36?a8Ch4o5w%HLfbaF(3v|t5OgY-DH(y@hw>KQ4i4o5)oOXbhv8)Rb@1^ zz%~sCD>#YB;(8+fC{>K#8G`A!04y)jK*tYV$EIeG_4fGe(c?3eS5O#s0+KxDxvdGR z`^reF6&@TO>bpX++M{8=&XTRHyMDm9T`k$|PL3ZvvgK;ET-H0;;0Nx3SX|_dy1wdC z3X#)n6TN}a4%YsGFKJ^u00;b>cIHk+uWKs>o^s}tBs6rofv@VSSeW@T*Gw{43n zt#&AJj1mJ&E1@=aEyE2#^0r8`LgA9|!^7jV(6cH=`;u)xGXQs%xg zOV{|VaDbm?07k-gw~IpRmev^@_Ie$u&dOQ}`;!iUf|_hwWI1ZEFZwMK&`%U5yL)rvt;sWyP@fGN=~=p?S!VqO?^5du#$ zSpx2Xp7<1Rm0{g8Gcb59HJ?zcxlX=imY3jrgLu>dReoe=g}dJ zs*q7P+efcJUBl2;?4a9ehf{z zDF*BMJ_a2%bJ_=oXOBI7w_YwvNO3SY`Q#^u2ZK6WMM(y^aa|~N9fAXE2!e_cAs^+H z84ix0d_L;>+cIZ#raM)^9+j7rSYSJl>QZz2$B#bg4+g$x!wRrElSiL?+5xQOX|Yw? zy`EG>WlI-J+N*GQJU%=WA2iQor+f712_6iCU|Z#~)t(%mI%>U~&$fznaQZ0_&~wbX zEL5j^`pJ(D1|12Rrn%EQJbCoE+v~$AfZ%lcBZ#-*^}C^yCs9#x6_;p)5{^#K9)Hs7 z_dVCDiqdY6k512ey{_7-%B?aydNP@e+nt`FY>S=J8=no@ZnB;wS&auz&YpBT0pzc0 zX@iqb&rXjmb(cXoNygyt@pv-vT`qsNI!C9ESOnvkR<#p!4F#5u=bCa9C2sF^leK!2$Hynf{r*6g%5_|{N2iBJM}cp{9<##n@!6vQ%Rn^0Zl6*7U;}!+1DY;jNTFzj@I_*K1gI|n1~-=X5-p0%K7Db;d5ty+3#IO+F?e$YnU zfW?;A?e+(r>u~M8VswTWh>quZyF7-HgHeGD*Yn%FQv86s!Hb=08EVD=8?bFz_}c_r zh6f-R9|}N&A^_Z4blxmgrISgMSBM6Wz&a)jW@_PW0W_<*8Q74kg#MCh>t4@hxDbAK zovK3Dq?W2Wo{oog*97QWHjH3?C0I64SgVNPxgvMgq$vVgM7MQ2Fi?1r)v~TRp=r7r zOnb35TDCkBm|W4Q00Tp>8#>^a`!04+Kk!cE7Hl3^zQ|c}!mg!llQ@Qk7HuTGDht26 z7OFKI4yt6i*~AzfCmd3WM?>3$6wB};Dj1$T{^YY>$Y`K(6oEb1eiGN6 z_WThTe!jU`rR%L^h7LUJooR+ztE$ndrWq&GMZC!BUE4qGy8*2|MNX30x~MJFsq^XO z;%c3MC$)CJFPAic;NzXOrJ>PUXRRN|()%A2(JJ}ABm)8t2BRTt((Ygk^n`gD_J*C_ zfS+x)y#Dww2>qZl=mBdy-!j!aO*A|793x&$XVcr+^~LSYEz~uvji5j71PRN`vjUkfe`kns4VW$&%VYfFJ1|3Elt&7Gf zadEI*E-G4Vs-!5k&v>8IpZq{}v=E=ezP&u>?sKO*JUC#0fj)g?+x1LcLS?piRN7`) z!MKL5U8cZ;7K~oqwA+J8w-eUFDgs^s zH~1gv{SeUK0$?p9W zj4Dr{>HwOYEaa9n?&1;xzAK9qz8CHAJA8ke#PvPVd^foV*kPfty73%6Ev_ElCn0K9 zd6_KocmZF9lS_9SPKc(uYk(_Zq1)h1lcC^EnB=Y@;_aw*$o;1@(mkk!ZGFFL6aO`N ziv!f0Q(tiR#Jm)$!7XDrg{FZmzTK7O7JdLdiS2$nSeaGLb^!+bS)nf(eF%me<0o@- zBAjPYKW0v94(@*OPfP%U*bpJb!+{HqABe2~5>)+b_~h0UH?3U`;?t zQhpaOiKso+^q7VhBy?A6EcHw3Y;yH zO%(A9{is1zFe-8iE5PyKy^CtBqV;06SO8&n+bY@2uU>rl;@Pvs9BLzVJEPDuk`4FM z(h7t~iFs1UChB%`{`K>(zg{P$4$pUoXIF8ON|Gk+^3_7@8Yjr2IjcP9W{zE5N6YDI z9Vxo)x~>f6uvtdYYQ308Q7SP^j8YbCMFv#dR%tZ9e);8#r%#v5C34oG06Y^KQPSZ! z^GyJd3q^x>DWiL)MLA%40bF}g(RUTJxLnpzv0Ox=!s989LBOVpqb9aO>ZO~unp9jPSH63(E zOs#TGP-6fCzC~x{xNGiVvKAl*W;^sw6aL}uGJmKupwBDr-U4vJ%vUVk_S7A0@hzwI zVH`A}q50f{3hnc0GTTXY1@%BMZm3nmo`6)q#8NQ4&>TYL@F|gUTNhh~zt{mi;Z>@R#eL(bsbS}-2l zA;b?1HobfXH&3@6X;&uEhP(ZvHNzED6@xf*`i`X&OT2avwp~BOFW>=YFW?ydv*&wa z6X1@qb2=S(Adnoc8Ou|!T|$7{NR05ejWM3V*s_fQ5)fquQ)D zYLFKxELuMt_?`!bWl)NC7uGl`L4i3TS&InG_DZS~_6MT_$K7$1&vSDwQ9Yr%4XzhxGz(s2O(OR%p@V6t{9P0)A`sF&JLaHPfSW#fS~812e=i z>?p(5bW7JQ;eOoJ62I^yc#EGFV9jLI0&TZclz!Kgrh3dy)!~Tf;AKjeB*As=T9P3G zo-);*n3!*jyTjgaSBu(MB=h+36X$B}<@j8#ab8@)d5q(;V=4-*s#g zjxCtM3t;<0*9(Rce8qr5wjW|R0uQd6>+rqMRx-UdI9W$46tg=%olFk+%1CD5BlH(= z9NoFymJlLS)v|np?$i_=Iuy6K4_MJ!+dL@}bQ%0T^eIdt+8wnJ9CVdw>x{U^6$)UV zjx7zW*1NtI_Ivs$?*KU37-vmrJTtrAP^Lbv=)>3Lb9^qqU_%Aa`Z9rs2P{{Z82FSz2o~n@fh@>vtin zBCbfTJHG2$b+(zq@Z^N121Een0PyM^R7twttbrUt_>8dAsp8v<^UJbku#VoK!}xAd z3dVtFi3Y&*Bmhf_Y1*p1g*~&1V$}rN_k7POqD7RqI{lHyki6R>O}2phAP}F9xtY)A zU_9WQ!(hB{aAJNg$28!xtXE4Ib1((hXc~PNbhm66Mwu*buCC$7>ZZ+5k$JM3-!7MM zdx3gf=>)GK$x71+3}puoWjdSJ>=~dTYCBKj6n;0<9X}tICYsak4TcO*B_a`RTN?0D zm3Ptdb~>GH@t|d~LsmOD{{w} zvtFXd2xyuC5TPYqRj}z{+?EAYO9n_Pw=D8J2O7N@ypI+kTga5Xk7c$h)E%V}%A zt}cN8qKKRkoZ{3mr4wJ4x2+Ao`|u{w_H1C2=tAQkT>%?DM_pm606%cfb*bX7NGYBZ zAj-%Mz+YISjIqO2D;fiWGRh`8L04dgB#gHNmyW@Op)nYKhu(w4kkJO;-$I309)?}l zbm%!rvo#CamP;u(v(H+=>W5%bH!08=2J(^6L0c37w*dM8HNh!yZ%<%1yEB}GuC|%q ztfNd)q{C32SkfwQ(a+k~oqwS`9nM~QmJKPR!GoF^;2f~(YFU&!!?d>9>iY5`&KTE> zA$Mx99ESiZSwvtoAb>K=sNN9b1_ppjDoeYJvr!C)DqhQvV2t1*d<)nfFr>KB0Tx)a zE_YgIFmm)37_}vtzU>?68d)x@1gcZhY^jQF*H`IQwoTt*P*d1*@T1T>MUul8-^THD zl_#)ClvWwRb=YooI~-1qY_*tPT}EkX=+b9hDO6fFX^YMk8vlEGKp$rx0OTB8+qkQbI+Rg_>* z!!&@Ha4KYeF!FRfndrOZ*)RWW9u)=`lK=#eE4UmQ2Pq5qACO%JRkR(A6-XG0it#TC z+9a)(9gZJ8KFelbKYM;r!aav1nmSB!h&&nr`vsP)5PZ(Wh-Hz$HDH|N_a~F%la6oA zU;gsh%Nts23@}omh^lTG7E}fJKF;%kbM~eKe5{Hj%}Rg-qzd%};SL@Gu-##c0vQ9w zicW*U!*BP&)rUV*lqFwopcRTlkgaws0;0v(3G6h}rZl4Q;*>J)8r%8Jd0NUMT^Qg$WER3v_UaGgEYFmSz9|Sy<7}c38MsSMSWKg%TU17%oKO5FS2dnh$_~lNOpK;dFK)#URI@hq=++1DV z6k<&v{JNmqGh{~nEx3S|RyI6LF6R|%Q2=$#x+Bei$*6KV9fO7H7$!iIra)exXV8ae zPM)E}df>~)R_lDZy?pE2Fv!1|FJeJ=Bnl;(-k*YNpa~!vO|tvMG_*BE)uGXw3UYQ{ z%xYn1xqt_X10Dd4P?gEx=>YvXB_xYUAzY|;iU~&nqX5n=(-pgc(;=L=5W#Ao0+<<# zgBn2ocovtC4~%>26|oMLONNA{&veuxu#Nh16)&a?!fY7wk9v|`wtl|Y#dmMS_iaIs zGsGwq`4&8eL5BkZuk2omf%xDMj6bCqCnlU-c##RlPcSEgx$+y3U|lk2i{S$KkvJ8i z4Jk&?qV|mMq%oowo}{R9A()L`gC`2X(Jc#j02_{Kk)dj3z9|=Lq~Kqv(3rj#Tm^{95x9Wx^Ln1*MD%EL%IxCwki0KZ{^xu%L$4e+AjtbgZfifLt7l{C%vm%bIDc!r3Fxdr+) zpZ!788zX*y`hf$GIELuGy7G`7rhF$g@80=Z@Oup9Hz+gE;1|4GpgOaa^# z|6abt<@*XU&AsvTTcL-w`A&qV_YHk@w5O&kejNc7-Z7qfHHP2v>9+@ce+7@@=EQ9M~nr;O1`&#$oavoS1GyngF8F8=8>;%9ounqjbD@C>o1Y?-4C`T-Lg&bmAGc! zT2y|2Q!Fm#msNN|;?4Kg?KOHM<%0r2_mvT`aV*E;o4ozo&Q}j|wu((4HR<2XMWp2F zb6spXm1I@p3$BKkQoKe+`xqE)pZ{BQUl~!N$xlzX(vGXA`DV{DHSXx&zYpNtx>!rz z^wj->539}DF;(SyOn%dYl`=6Fii{RAjjR}!Z5RyCf{{V%Ez4+$&d1|mH_`cmM6UN| zZxTz|-^5>TBS1!C#KDcG8+eZ0+TOoIMw0u);_U8(uVuhF3jdh4V=`0*7t(M!EVuG< z>COjg(Gb53iGIQV{QRTb>?mliH6~F*C>PC>74#3zSo*6@dq8hrc}O2l&*QsO9KUf3 zr79YjiZ6)o8>NWP3!`SZvQH`Q@Ib5}Z7w#1TLh^G)TI245Z6a>W5iyBUnka$P_sXM zAEA1jti|}Eni9hefxXEXTrco`LeV082zePYMI1p%`1h)@jS$>5{{jE+&t5yl$^IC$ zKNaFFB9!c}OER#)TR)O#TaS_ra-f)3?bs!1z7jjDp!wr49DZKA#HQ6nPI0hhKpcE^5woVE!}AkMniR1N=DG{_gZCI)h*Fp za&c#La&mfV%2l-4F#OGa!J@=!iwcNE^deKf+3t={&H_tGqK)cwPd@p{@zJ3!l`+4z zNU&yjxX{hhgd0nB7J)ViwA)t(St64Wzfdo8#T2Rsnd@{kw1V3^^`JLCe*EdM-`0G15u@Jc!uHPRXSZIpoPR>3P?XAjM>P{XV9vy`~!2&gZy9W0} zR7Isp01X43xrJaz3e=}%Fj|=?i7DAVFgRS(>6n%S&~0(48ubMeG}uD*Ah?~pg3GA5 z7#>l1avk|rn6S<1zI#|Yx{QS|8}^>K*L3AQDY6w$9e$ePu+oQ4Vjh+M*Q?i4w!Ryw_aVKPY5FJjhmv zTM!h(;b7HVc_&hGYX_So>#EbXxh9-%yji69x?gFrqnd2YuSNr=rX^vZ+AwM zBk~4W`n@_pR_)=@li{Fan8Dy+*y7sq63l|C?uP>WcLx+0ULl$qOWdFFL(t7q2qYC- zLH14Nt97Aocd{Dv588oSq_GIZ1#M>sot|aLd6L3b5~3+Uf7en?7jo0}?JCbJ@u4w7 zidbC7EFpWylPPgZ5aEcnxPgTgZDez|Q_W!V=<}naNf?Hj#HHR_n$3Gi+2_*$BMnp2 z@Ahm%%?XVBQlZBECTt;qv3qdb@A$OxE9TUZi>Dv`3SZvwp9u0z+i;;L%S${p?fEQjvdIEA8PS9&}BuDhmVp zP84CWgS5_Yq|23Jg`L0wXXEbp@Q5FiG(&>NYpVm_TA&(2_En+ypNhHX?%{MJ06(PWz!Xzk0D;M>|Okx}(6;=Ql4`Q32I3IX*p@971^3o7m|bj1SqRby1rB zaD04%%Gjn-@09lV$!9aA$CEVt;lA%MFRdQx3Nr4J`(!_k57JG+|N5rQR%J#4t4;FF<2bdoybC!c=)(|*S* zlhtYyIh{$zQ|DLbaVbNgp`z_hPkf}lviv^Uiy_+qRAd7}b#Qn*8V;l~T5S@$J!t#p za(WRLa(_HA2@KQWVqmI`!16+Ydev67piC{>qa^_**FDH2{1UM>ttDHb<+d3$ z2-q#@n%A){A419nor8is>8B$61UU67uvq7C)Z}F>gsMy=!ta z1`06s_Sg$MP-!h_F~FMBwj5vJ1yZ(cPpC1fyPaePXp{-{w}T=#Ayqao7ubTjq2^8V zL9(X0UD!P6p2n~jtq9?{5y}-)M`bLZ4+6?`$M8CayxnGL$Er$ACBdlAc8nmamr1a1Us6-A*tkoS{*zoWE}v=xB= zCleT>@Y3t85<-d(#*V30W##n_yMeh{%poVhP^6q39%{RMwOa2~t3Npvs0F^Q(b`Xb z@&|{b9=a*ZGSv=8ho}8sTZH(q28XAkgK-G1=GH;8cW`oWaDXC8#_57c3DiRIiq$_j zP+K{-^jK;VXLfhYA{Y=Q12B$I?E!$%hQen6ox>wTDpt!CB&93b`wAF;^p}svFgoij z&lHo!_s38GlFDdkr>8!I-n9UoRygo&9SqwJUC4QV@@UZOxPAacmd*CT_y9uVc;2>1 zime)Ux^fXsZ?4lyZudtp>Y=sjbe)yT@aU|AEIbcLt~&kUs1Lp81wolC<6;MV^o-VG zdb`!!t^gTXbt zBrBcqqoc_I@W9}DXGXs|7!6!6;D=Xt8X=GIQQC%5tv8Y8ki)X|bd%Qo<0q5xkbJ`s zDNs3`wr{7)+u3X(Tiv6xM{NwUN3hm|(Reg~tz(&Hk;Rhk*oL9$mH@I8CV02k2hZ*D z^=z?%d!+BO#cZ}!+|lu=qXAmnUcU$N>yA&GE>-F@O3Sc6Hh1ym`AcYnx~^ea8&Y|F z@gm<@lhY@mXTS)Ow^>rk!^1NOgX{SKYu$$j(nD`Mu3M%N6cOrK$IIFD7BZ#)QhH)J z`CQ7s*2zGA}1@S@x2=P#dQKr#AiwYj>w+UddM^zpFQcf7!|wQVK&y^-&l zhVAJJ%nffi85WLL9u7+tEiA1%h)XERF6XWh~GV*?@1^C z{#7*FVQ^;ySmfH4VG1vcK|ZJjgq=lz5{`V8RgBbT!fUe(3qwZ}5p8ojfOu7hDy_he zmfvO=IPL`ANp8=z9XRh$Ufd&Yd8Xy+NDRzXY{T(2*zCY=SnGyod4aBr87x2^tu#?* zR%Y8$En25}OvJ|{rVG|-<#D-FR3AnQzu^xP3ueD$xG+Im`KBoHt>Ig~&<(IPcU#Ho z*ibeMVg-F9$!^bqzCnpp$c7H226L*q0-L9N5IjM#v|xxXqS+5)T2fVLIFmb*m2I`t z;2U`=TLGzq&BML@j9`~-N@$~CXyZX3UI_$d^Ldi40G=%yx*_E1e>4n;=yYve1EatR z*_GUTKqQ7^Tx6&WEC~Y|V3#jp$3TXs26o}31p=yK3tqcb@e^uU_jwNtm80PF=|RLW$X)%wBlqjo!B zFhl^O+aHa3U|#6eB3VJ_hP|P!Zs*fmON~~GN@A1fEiw46X zt7k7?zKD`0l#qZhcul&Et|%hvMT}@`TgK6PJ-@zs{`Jkx3_b_ChZ~&m3^(6$k1_Z0 zZ6(w4EnQyEFQ6k0+qYd$u9Ml-i`53&r2zubWN}1fVCxBz_)na_o0=O`01Sfz@VC$k z#uVY?4-BSee=YwL^>39)5zW#y`-a9jEMF1%2SXrh&;;C-$V~BDSDZj%0rLqGN5*2M~!b5lxjQ$n_?0FF!x*vQo zvs2|5uQFX1(E@C_RZUehDdx-wW53Bqk5aJ z($#H}C5%+cJzFAy*a0V%DMQf-Z3!VNP&d>HB-EaG5rxECntaJRPZrr`kyo{(+oHW3 zInlJbPM0Vm%~FPhNao41O)!>t9}8UQ<;{fCV4g0{%BVH7}qPvp2Y}-$qXfU_^E5Xn8xIFSu8Z zELw{8ZiOTO7-8C7Pp?^-B-=WEXhW`=p8I};UV!NxuNMsM8AaQxFoLm!= zWWs9WA)bNUGFbVx+AOD=B;)4Nb^w(Dfnx&XDbTL2z@0$si`8ElekDe)uTnH#%XG6|3n3a6RCAyDcMos)LR0aiFOx&UfX`Wgf3?ujUJezOemHr`NL>VuvFJl;dV&lv~4nhMCA|I^@a%cBrb(xy)uT#5Dp3 z=QV)QKv|*%2sS&)M*Ywzz8o-Nj9Uf-ounDIYjdwD*Abw4t}bzdDKmW+30x&Uq46~3 z`TiF}j2@u1@(Kl6Kh9jEvqS`OA^oh4xP?)z^9blxz;K2YoW&)?*!CHtxrl-BHH>H& z{(yLNC$~b2*?9qcU?+hp7@vx9gz~5qVk?vzN2aMFe`J1?22}$C0(LP-Xg%k%0j%gn z%@&3V6$I>Pw1t9?YF8QSmPU-1D(VUuWWG2-O^O8CBF|GsSirwJuaYHBg+>wo1a~m; zwyN`ui1)z&M-_m+X)jwsL=(`+zT+`#2%n>_(G}3{hHJp-VOOzkly5W$H7T<)-2gn$ zBP;>BGh-3ZnW)@dhqD667Ca0N_3AOIM58^?bHq7;V@O`{{UMXr4vD zvDxi)6ldTy=n~kOH&+*%IE9UHbMb7kPEZ>CBD9IXNGV3Y2{__QIP^U#gR&SGfxuX7 z768WF4*TtPD1Z^R9`A!`YKEv>e}4r4wOB>V8PE+T4ThC!Ct7Do&OT#EHK6XImQbn& zDG>n)7#9(W5_*6E3X6T`^{43*O}T*mq1t z(Zl|@-|u_vUT=8dIkw3_6grBAn+YI8%UU|;{*f5nnB{;N@)qu(lk>blK{1pdyh?}f zBs!rF#;IWa!6E>LQIAKAbq-rcL?FoGRaQ!!;R*a2cw&~<8yt*7a1H&~=drZzw`%Gv*TPB?zA^^J6%J z;m{9zgVBMh))0)kB|EnSuKj4-WeX+h63ehx^2EHfST!a z!9p;|gWh52nhA`|qOwfsaa%sH-XHZ)==~fc!63Fd@C*H)q%cq#+`)xCPCp<>5}_0S zssh+h=LveJmYVl)BKCuLMJEjNRtqq#Fcbvf3{PReXsP25S`I@<)^#xp&yW(xhkh)V zFhS+Xx}#aXER54Nw^nUa6l5;?UAg7fMkAzQawS zuI2EcP>c)?P; z6~jO)_(oHa%>YiUu6u@sx}jpiX5)8ki0Qz&S~fMeV={C~RKO1q?G?8e;)3<(KQTD> zgsQZA3@#0)8LHFJrL(qtXmgX-L!w5@VOGUy5~cW?tb`P!c7|{Y71IJxXc#kwTH*RJ z2I7DuFbZ*&aheZa5EwCDrTI4K9}oIHP1z-z`Dzt6QVh@rXX{Sq`0?k*Cr5z~5E%Em zJ-o zfC92fFd8FXuo;1}`ib zg=;mto=#`T4Lv4u281$%VTuefx+K1r_kA~AT;ANyX@o&aiHy_=7zaGyKsatR+Si-)8aH9U%x-QX5v&pU zvjVF%BbQZ`Vz{=cptq_mWU|<-Q5@>FfiR#UU>`bC=zmlO%56PgGed^%PU8g9f`eu( zM73iK31k5V9v(p-A|bEG5o!f7f>{Ks5-p0@`Ku^Gg&~aAi-;aoOm1R7-Ar$9v$E>B@|h>C)7Jbw!QcRX^p*KN0TM?bNzn=b z1R#t0fv`f)t>JY+M5q!LP6CCFvE@89jAB44uZRHsOpt*i(HjC#YuGcim*EO9WsdF> zbCAWBfi7VgU{KbDu?(~@P^!u<@o&YCD0jahJlX-j6&-`P@#mH5YYT88K7Ad z!N|=p^8u!?oh#G%}-f}Ba zB_`r&tqRxSPLa@i;6e(nEki39|1Mn@R4{Zb0CCiCs4z}p*Tc+5mG~@-G$d&50wmGi z7)~u!X_LO`;8XrjzH8V272vXh&DVsHf1&mGR zT+A7D9Q{{7g0E)NX=4|{%%0s`&KGl-J>b5v_0W4}l2typf@bK|xbC~%!p-e%D0Te(g%2Bcwkdg=_giN8nYlspKDCK+)y7YS|GQ+7FlF{eGUUM@Hj6Qimn@NG4{x&ubk z1b?WYW;Xr%3zr=88CZ>Dr*749@NBd-W*?!KPs zYtOw+``b7WXX5b9)FRFOt>y}U?@QQU-IKVtZ{xl$FkFX|Q_pNoFP={4OVOFQDI1n+ zXfj|7Y%DJEiHEJYtI0keobHbr!p*xgajP}*<$=C?zT7SDzddzFcn}Hzv_F3jAs?uR z*A>8f2u0tuTh!{VvOMMQ!_($i)?laGj;GdXvAzWWy<$nY5h7kRlfw4rXF5ge?&V4x zfcB*@PoD9ZBvL-8!Gl|G5YxSRQ{rbV;Z@LaYHWN?5WYcoc`CZ*^eo3!t0-UHCe6w( zk>Ww!9zK2FhBuDiM|X??c;tk5tJU?SLrc0`ZEx}>#cQ;$*IlViW$wCSU$y(1y?sw~ zhT?S&#>ZTgJUjpL{NkE%=9urp$9T>&(*9W7f4zwNY{lv81@7rCBXRSMdkx{n{&JJ{ zRW_pv+bu@kc^_S~dyqIkAmAG86`a&#Knj@C5?@gYEYs z@g4&7LnwYjazUKs8kp8Ah<`}U>4$3f8>Vkp0a<*RK#}?W89vQl0EFmjOBcf`9FpGz zNjl}-k>J#AU{t+jKKx+l4j2_^M|c&#E-?Ns#RB?hgeHD>q557A|DGPu?|bt1^xf(E zaL+&er~h<+^d6ee=li1v^e_I!zt|tWhyKHV_z(M|-yQn?FM)pt>3hM>?=kCR(K~zc zFWUZSoPZC|hy8=!({GD@KPumwAZxqdz5;-N-HjzzkZ~QJSbz6T#6?vv&rHyVzkV<7AN(y6%Kw(#+;kfMVSK@*_O}~f z4(9&w+YukQqy42H9zCoayRZ?l{e^E!!?+)&7;c?Ay zEX(4u(XZ}}N= zF@yiUOg~5%M7KR0VZ=SV&hwpW4JM}@Zi|b`@*CdJfOAk=Q|FfwM@Nsw;{#Jf5D5B5 z2a^dJ3l3@;@;*Y9_xKKNW*C|*agzgA3R;H74IJVH8mV~$pqV;9DjSYrIk`9KeMmMX(+wDFt1jOAiU)L#y@@im^^0nIiy}$SO_DAm_egf|;`tr*!_ebxctE;Q#;9=DslC0Zd z2O`$u3ivw_(^ZJrgDsN}>0Q}?m3((N3=cv(Fkm^!x}}?~-B#6Hmme3kJN~HabzQ?m zV$)~`mIK^3b=)#NcQ6PJI!w7iQ#KRyAxplUs z+G0l^z|L_jirqaIO2D|V(;J{}00Wc=WWlNLJ1u^Sx&@`u?e-kUQRJPZTHWEK9oXFQ zQ1D~)o&G2kd(d`@IXLTBU5Y zhl5U;Mv~!o`+eKgw)GYb937q5a=8>=0CxRQ*8rHPx6S6W#DQyZ$9cV#gTc{w)GOB0 z#d0I-?&#>rXwc5q)72*7XBLMC2S=xEPmeYm#R_|UhDEBYO1FGe20g==Vl6d1c=XAS ze$w+S2v1eFyzXc?=(nmgiZgWS@uz?A>5o2dJ9@fVRV|}Cnz)7(Z`MVEomETRUp7sV5Lu+xh4R`_g;rTv;0q|`mlQnVyC^G`f@AGS$QVm9KS%6?$DPn3F zNd;f)3{)Yv0Pz55%jdo)KFQ_77z9QKG5~x@b-&CJW}N2Wx+&Ln&Imt5RXk{zP(M2u zYFz%0D(Ox1JV|#9o8RZh__uTy+-bD9Ui{71+emMDT)wGdSZg5T{uEfjQ$u4B(DN__ z#CL`*7yggD1I{v76HnnzA%5My$U52^MQ~)sEOA<9FO{Wyh{1~VE_zqqYXQ0 zS6B7U^4jEo+XVlEb-hl%KROy89zi8SntB~S*(|fXLJu1@kcn|}ps5&rkm9rbFaFE_ za$nGU=({O^c(VegHS*qw7{Es$L)+Ap?M?{}&OZI|kGp}*uO)9=US~8I^jhL;%rN4- z_Mp@47^+0@G2Bl7pxqA9r?7<|>Pl60hnb>34Pf*-c7R^7oqk}Ns^)dQjSLPDRy^q#IRz?W|db;(CI3>ylSbsRHyl_H#r?0 z90b0*D>LxX(dlWs-3i06Dw3_@3>lAXyO>RD%{_Yjql01J(1E$Br27ZQXI;t#S89!tSjg|2N_VKJVS zV>dG!+&4)p5=I68sfNn0(pKAoVHg;>LPsx0H0E><3}svJ4;V$KmQ9_(-~vMhT*7qd zI9@;`1pqh8jYiP6ethOwR{E?GF+l3RFmJgoWRfxxk_MJ z>==iqs4@|k;uT4f8QS5{0UR5qiYBOz6%K5aj@m*2n7-w8Ov7eiOG#7xfdjBzUP#IP3(@W-*P^9ClCV;Oyx57$zpS zi{_=*n;cAzzys)lt>#TmpY*yN-*fVKS)#)%bv5TQe^qw}$4`!qj=-E~6F6ru?4#j- z_=kVEFX=t>-4uXr=@=FO1q26p1Ju%jgVV=P;LE@i-qsZy^~vEO{6?q>iWuDAgHfwk zFBWS9sPX6tq}%uGs>sat7(fxYjPn67;$+Flf-Czt;1l%jPs#SCom0MFc;^^XXd6Q%*hWy)1#(kJDSgIHHyWKYI z3da|bHzYX7F!Z{b4C}z|2-_S+8Keu6)~b@l^tzS|%TU&{%j>K2tCvqN&M%UTBOUf9 zz0ir*i>+$IL$NKxas$tAdqG>-#>@G9C&NK+Z5G!v?uKn7xCxF5&@KUg(emcz>iqiR z`T6r_&;W|2Z}aul<@p-6;1FhR%egBlZf4P`@Av4lcJkGsuJK*e>$i zcd6%l%}jL-J3-7iZEMt{#ItCfqS;Vp>GEE3cyKz52=2qWg3Jut^rvt7Vi*A|^+&o}xupFTZ~Jt1qVW#d>)=oy}ld13=+c(l&=P zV!2)r7^a~}^=f)?J6mFO&^e7&fnQXn-RZXS<$SSHO&c7!Ud(1UFTVc8pFDf^A_K6i z3U|!_LKvM>ftd{i1}eK=7g7Oh z9ZmfA7?`gU1M`@+gW=%^7zp}!teH;5-8-Xbmq*$9I$mBU$)*x20YA;?NX-_}be*?U zMYq)^27?OIn|^=}$Sz`rH`qV$pi;nDUc^;8AGD)&Q)XlVn9nWYNqE8`*zH7^2OT-< zmc}p9b5Gc-$~`1mxFM(v`kxz1p|r{>USwImWiSq?$~ez+IFZN)&hR$d(LDahkj4O3(Hxv(xNXN}JPk!vp=Y}A(Swem zRP!5#!sS-w=0X02Rqen4hxsp<(?g};AGdp>eF-0%;HALb==S0M!cz|%4-S+8xVyc4 zx!lB%_r+Ae-Se+5FRv+Lw^yr8D$9(5%{h!-mk{cOj^jYmRYFS1xH7MI6U-1Dwufdr z2A#FKrU&ZUf!ZRM!CBHZ(=uF>Iq>WJd0j){(~$r^fcLnMJ1KyKK$s%?{t5sDN#k@& zyqN<{xI1(c>n=^SJl^Cb}Ii~X9w2J zU~R+R18c#uDbTU>a8XI_P@OL!zHJ7IXysxHagjrE7(s}wfGvuiiBq6e!JV)#U!pS0 zWt^m7NZ-{_VcGP3k6uv&fRrHuta#5up2kHYJ&px7?V2uKf$0SRA=8X0VxH&ZA*4Yyt8j#EfV#>mb_9Go)Zg?V|=E zH$04He}LGZ`wnYCn_yVUU>w~Ck_Xiy!sZky^i5;AvTFna@-NVi6N=lGqA{i$V;_h& zI+EDQg=fi%;<4tJv_D`DcdiI`UFA`pqj3xq&|(N^cs&e%fCp>HZVHj&1Ts={toi4j zm`F66@uEbJ;`Xiuo=Vr*W(v0CMl)25Q*+``)VL}{%ns2I8u&?((ygI>s~8t3+W@;! z8E*X*{~&+3iQih(f_z4Ai80`!5|2Qmh#@y@Ua~IN+=khm+4@P$|V=&c$MxY*uNp z3kL`L0zN*WScZ?>qgIrlTfpIfl$X!Gg2BqrCIq{zggm0xOK#%76LSSTo`|T6Q5&pK-UX0Y&eRzB|FhtI%Me8$_mtP!?GdZD3NEx}3(FB#odFI96;g zc@3#(Khe_K!rnr?oc3Ta9GJQShjxB_K3hb(&0Rv#X2a)12p#YseTmVb?^tlYz0R=L z9|r9{OaRA*7p;J~U@gK42R8zsGzSAcc5H*9jIzK!DR7Xx!@)z~o;Z%{mSlSUqeq|g zJ0YWHp(wVYVlabbv)QaN^eC(!XsHZ|_0Hf3t^*8J!)f=1BaBT4b$|^H`wuLQL4w!K z4u(!PI>Sjj^w@}X#4sw2#uBX-Mk=FRq)7y02(W`AnE4>6D|8c5q1tGL;dMrbN3N}c zYfNw0>veZ!l0?hRdJPRKSg1fU;I?YIu499bOo&IP?}r`nP69yN@_UDHkX3ohJ!~7e zli&r&b1o`FZHfb;1|1?f=pCRG`19@lLATp$rtEdb4n|t~p)fJraL^l|^Lud740Q_? zB0hJ)2qpqR(ORLbv%Hp6zt35(z%~Ku@I<}NxZC!jSYhhJj>AO}GMW4d*B(}=V_O&t zW+90Ekwfpcg5F`L_R8oT1g3`xg%P(yi=m#Or4-c(8Q%s#DR3Dr6F3Qe z2RHbPdQaqo1ZzYsu~G?%__A4Zbf;se3`NGcJroP@T|whb(b4l@mx?f&AwOYRlRbE> zyM`0e!+?rxvTasE0eqbh);QRl={UG}LIhfHL_Cp6yj0#j>2 zq{t0&tM5t^SJGb}9`O*I5`TDjc65B?S}M|;{&3LmNsKR1LsEnlMl%BT%}#ZD2giZS z`F*Gr6HIn|HaP=7a|(Zww8T} zSf5j7@J_njF5j88{kn)E+GOy1F%q?~N6-hdPA87D#G{i>#^VtkADI7KJY>Vhhx&xs z+>#h|GRihp3;cq+2Aq72O97R-V#Eo`dCdNmJHxNS%9&h5=mj$sdPP?USGki-qvuGpe?sR*j$9pjH5^h z0_yGSvJzFOw zgKt0>VWuV#zhz^YyCRugUoKZ`j310vO;<~z{{}#TArx_S_x)g2wH^7h5RPVRoj1Q-6 zI=*;iDkA)_+29XZs(`~1LAWo)U;E2{X&Uq zVC3^6hW&(&&9eDCUX(i-3ZR*Sgvr47z>w@L&Pv!#GYAz%u&&cMPwECO{DoS`-99)u zIZSV!zP!AlOabFr1ZvIYlH}<|QJ^Yd9LP6XfjnD^-y2U(P6At-KL6$O^J}u4@EYhF z@5G!YIF9opY=xMG5DP(TMmyvi0wm;|0BxeCGNRjH_G1Ew-dLFiC16AnX+#Uz!Lo$92HSrfmWCp#=95xY<;(0PT}j{8;=5fIRPeEi1~;f75syKjwwN#qyWU>Go* zpy8+>Mh{&eI!ipuexRmlPQ^MO2NFuo$v1EWIqu8{7liQ9jAEZRs)zi7$3(A-;_iyT zDNA8u@Q}=ip?s~o1#nBcX4!HwPxt{)Q96qjkMJpE$)`|UOZP3mt!2yoTMeY(;5}%? z!v{g40<1YMiGJfnG7fzq_SUQBb98VFr$9W}5EOvh34I6Zc@0e5wgOxFQCnI?yI-w# zZv`i%RAA(z{bnis0iP8$AoK_=2gU1b^@ihrK zUf>4K(Z3L4CX*T89FM_pf#`4s3HMM6?h%(Dw)EUM_&8z$k(m6=VPkz{7+YP>Ha=!3 z2t3=!%sWWr`(5thj<^orG3*U}*Ub2)0roPzn1-4Mna68cymf&jX}0G%Rvytb_~xdv zNi;{mH~iQ@uOn5-;`WBK`K&T&U&LEY;G=h^505`gZ>D@L+t+XM)`L^Zu26`LD2q$4 zo_kQYH;Z_K?z0t733@yETlZcs;zJ~g*SV^%uWqyDde3wH$1@~LYAx~|-xs|_D2tN`A0&1ttMgWUzALeAO~sMvN6EFxZ{K+87$6LM zh|Ky+W&l}?^&L0lC z5Y6W7t$X6{{(?BYzX|#W|KK0&kKRKV@%_;Q`ZxdP-|UaxL(iW--yey}?2q53`}*9~ zv#H!a{>T5gIeQ;%HkOXdXt2pecYYE54-qH!oBZy_wIUK zW{aB_&%gTO`dZ8wh({V~61+Ov(_0rvJHBU`-o)Pq{XxuvnZO%P*0&d5fARA93!r~9 zehoDVoAdp#pogb#-1-2$nUcBQUwQrJ!#f~AKaHVxRPFUl-pJ)Gx=+i4hQ#S>w7&s* zcwvA1VG`-8Jf2=WyAtyN`|AzSiWAoF+w^(?56@UO>D6g-fNVC|?k0UV`hy_nw9`IF z9~b>W$PH#S|9z}n;puR)sL68&K+hOfdVli+R2NmcDSi#~2fa21`@g>_YDV?dKtDVd zqx_%(Z{8F1@N|Ft7egN|?!G?afFv&e#S-xXy!|m1z;Bp@$MZgP_%(<^vOoNFNC2#W zgZ+iy(|0Ef0ebR#59K!#3ixmt-^dK#jaz=Z^gCGP-_vi0ewYg2Tk)@$uN3o?zYP*| z75CG}-2jwe%^__BWZ?ZnmRkADS_VeeZ}^TD9BHA`L`uWkqw6nR=J9F&oXb(8x?za+C1^_ z^nFcua0`X1I$!Ow?GjiN9gmu~-dll&Bm3lSjI4AP0KkR^?O8NtTWH3e*rYo_A@`7o~F z94iTK_L;hr#xeJNINVeNNCL+};DMNsS@5OGw}=CqpAU@D znHqO;aw|FnLbZZ}v(F~OE;qo`6%fL-T_Q3x0g%$*+957l5(|?awwR#+L=lXdvPD&O z+x1LCe0O)p1*0O|riOlkD0uCD5V#fhSd~Cdq_hFz7;jk%N2h0Jr&8L+OCwW_HfwW7D>&;ULp>Fq;UECqer$5fkxKM5?Y;@Ull;a0jmbyuWm4qebc`s9-z|8&^%D{d2#{qDfAv@DKFu~yY` zTtnw_c<2qm35-iB`t3E2qK@Gg+bse~OR|Ih;o~1ae)7aOxj& z0Kgpv5D^|M0_{N!yp<&2j&B)zwFheC0@XEr%kNuUYPsDOIkXj6xmnM{wx~Meok8aD z(B6mP5-(xhalbUwjIcx=^oOj<45HAtlR|E-2u^CW_D}Xx(Cr_S) zwk{U=a_4ZT+m*LPmZV!r{=0woLz)uw9Tb4N>yCrA)KWdm2SYga=&*azww>L!tYp>i z4L^zk09f?Kr;iWDW7|~gtsM48wk}DA*YEdWR=K^S!;_Ov+i%sS=JbvpeL5Nqeb zbb7~6KKoHWaQKDLo!0L4q%ta6hHI)>TKI$G$SyhpNMkk*f9Un8`WmW3#;L&G4nGAdKwoJ3!>KvXtdeR>dumBzH!O&1!hS%$c zZq6nA-1kqCm2hx;`sCC8aOB%&RTRMIqtml~x2x=ka)YBMlfwx{%use!OB)bIR_ zHH-5)7#^QIdfe-_xq?#CN2i}ZetZVyRHSja(*~1Alf&lo^tsiYoI>FZhpw$dki2$J zmv^%1d$yXy2>|f$=p+oiI*a10u>6i8VgYRxdoVt7ElD=~UcU$S^m<5m(g}kdnpp0@ zS8c0x{qpH5N}y)IShlvie)(*ZVf-H*pPUVbBSWq>Q5FnOkB*K5&)$}$)fqGV$Z&wl zK#7J2kDq+pH2=sb-bF-<~!XxI6m`@)_Ok6cWU?G z^yuWY*J*>5cbaqf2wHp`hC!>$(v&aE_arG!dpJ3Lg1cakqS|#PpMLV$=bo`!&8`;f z*zX^DT6y{WS-LgHXP=#%p7jQ!z%#3|cDsidi(Wh6*AW$GeEP}wh`ZbBWN|y4X?EZk z(#`qPs8G7YL7mRCT5~LYvzli`^-hQZ;d*1>!<^NiXQ-Z_9X-!?bq*v<+x=?_n%O(F zj0^3dhHGv`YS~@*t0v5F?g r|Y<|TNtDPj1O%{Jzxh0a7uH{pa;#N!UW(KclYIE z7=dAQ0`{?hB-si~zi-=~2Bjxys_nu?;chR(gz{J1uI;q}Wm1(9b>Rf;-i`&-;-<4; z=(r5W#=2>a84etNJ6?k+&0SznW6YUGjTQ_XH#7~KVVqj3=JiknP@l1YjF5`QtNeK!T*xn@x-eaJgd%eU(?GlJ2{Lj>Y#r#9*bB&t4Omuf9wDJf7)mC9{Mf{pw;WyE{0lHq&S|(Rm(A* zBE7v{U2T$hr+~4(KS`?B9ghwU{GdHJIP`tTu>E##*y%9{pTV!c9(CGb*gNPChHlXI zT%!j1_+8&Klg)g&m@TH)vl(Qygry`V0c=30Y~sPg5N^tF((4bx?$CEMNTtKDJZc&( z0g+I)TuG~2VW)4KI-~_=TpF(y^VxECGri%i5X%o8OU?3JH67E0d5Wq{`2Bw916ULL zfyN)n^a9s0iwwR9jOHG#=59CW4u%H@L8sqthtjrGEzkG8ZJDgs>mA(*?&);H9@LUx zWbT$)FJ{ZdbbfQST*uHfqsgHkg!t3#wjEZ6fgcojVag8RZF-%+wW};HtCnHfs9$e% z*zX4LE$+X3*(~$-J&Yatuj_?q!BHC(>Z410sDxn{bpZ{+$k-)6>W;zPBxx#ZXl+m7 z&MI!WvwT)22+^i76bbTjOtma)C+xeX60K0}+3fauF<&B&XtRXbWtd=*Z62?9>*Cqd zFMc_lE%+h$BxS%F*m?De3|b7a}=kJ{Zq7&v9J zf$xRPVLGs}_?IwlM9l%1Z`K={zTdROv!TX+bv-vg7dwW=X@AXt>qnzq;57MTSH}7J zCSKnrNnA-P7y;IDV>5{t7dn_1-3<;?U`LytVKJ}|uESQbEJw3E(*Z;Zqkd2P*e}<( zH)sPd-EI?_P1kS&WDXA$emcAz9Lokb{ThaiA}j;SoDaUzC9ep^9z*@gfPTe9R+?sO znhw;a%Yv+sA#@ZidY`%JLP@|M#&s)T5h&DY;}(1_^hB#FcM6<|-8PR3FloBZ`4#v= z7;Ln!sYR{8LWRN6jQVL|@EFmksSNxDQLSH-c3{~}npK)^ZcA<+g(b}}STHTe69>x0 z>vZ}o6i-u{Tqo;1U!UgfliWIbV3?M!D^-!EagwJ%n-nHNx8s*Efos|11UF2TC@(l)pGAx5 z?M0kb5HH~PayehlZWpsThMD`PX_9Y~&AM(W!0RnH(jgNVD_W5(X49LLTNAfgv=SR@ zxqSr8xL(e(VheW*Qd=ae)pEW91mE5yX|b!TWHr5b_Qmt(&zFn&CQjYXL7Tc~4JT1- zT4~<$al;1ccJ<=RXHTC-Sq(Ub8;5GASpip0f-ye3Tt_iD8tA-U&YPVC$RFdn-Xy?6 z)3VUeHNVzBXS|(N1b>_J(P(`fG0M-jPB+ub=U+U3_H?!6*ZmDB0ME>mq@^-eEye?I zg#M&gzBi6o2&)HCLv^8VRTCtlf6?j9(6b2HMOnpFR8PSJU|l5QRE7Jq$##Z6jMVDoe>FRVCOZTF$1Imy6}P zs<`tDBipnADg^SuPAh9h9+1(BODI%yGJs%PMDyE=)q_x@@1{5VV? zP^56P!4iyYf>i81_(ib&3)ppBsaGV7r7a^vjq%a<)%rClj~6$WFVkA-j3(`Nm$3`k z!;)@TJC;y;-BDoc0EZo8xpHqUxCw*SJWgQ%?}1$`3$4uK2!NZ$>#UMsHZ^HJKA|R- z13QM{$KtryBh?&`^8D+s7R$v3w*Cq#;Ci`$jg`gg#d<>#!;`vc?KAnPv}5qr63i%K zlx#KCP{5ztyOqE2rkaEAMJOak=WgQla2`xK zly?k%LM4mFEYUM@#d+ARs-dm))%lje6+OdOGRT8l*kG08CgUN+5ynD1m~t5E8fpMz zfd^Thq{8<>voxJ?LPP_75n|{bMa4w1<-#;a7hv49#=l@?mLkv)H-n=fJCY4FrgWmg!!UdYP16VCnn3;0U$syDhMN4vHhOQPdG4I zgQQtOyXP`$kR)bV(O%DXY&;4WbAqlPcm$-n#+9}u`Pzrn0E^-NOHOU*rm3m)TDY@a zycWJAAu%jdc zFaw|B8U@}1Ofx0NVasqpB5+%tK+mvdc&^T?EJ9OJB47%JEaQE`u0WGDQ)R=|7RCoE zDsLXFAZ$>dTN!SU1AVx!)vrff;t@EuUKKfm_`6^kPnGI4NdX_Q9FjP-g05|};s}ml z3M(y!lv2bp^owD^VeW_RkdYZ-lR}Eu0G~|`iAzhj-P@P)(TTFj%Ir}q;e0GQ4hm~M zpKc;b95~DNLeF)MYGOMb^jxaETNhrU*tCTqxd;nBV^$ z09cQ#0ZcS>t%ha3S^&W?Xss%`xp)a16>v>GysM%$XBFgD2^7K;=oT1xU_d_%fKC|< zZCOgzvjhf|wBy$mBpB5uZR+J5s@wIu?M~Oyr1gB>GK0ZzXbTsi$V)&!dJ-MIoL;Tg zF$^;=Xj__`WeIE>v(!*}Aj;9yr7g^P^{O)k{|7-8hVlB(ov`}o#zVBAw z>@J$@&Z(m6S_LjY*rqUYfrOzbOO{+b@Wun;wVo_Xen3X(UhDe7Pv}|*A@PQ&E0Au% z8=`Ru3J`FrI494^%;+ zi}@Tqtr>J+R*}&(4o3#NLXrM9Yg7j2$YxDJLYSBnU=`=l^8EBH$y=&Hr{$qVo5d7H zaoq}tPUyurDKyJfrPgMCI-4)x&ueu2K<=*>5ap-<^n?T>HG)gg=?^ESCTB6U?zSbW zmhH+S7j5R#*`lO%2rBIL?Rs56{g-hN#IQYMe+B1FW)oa|nWY8q_9xv=o0byQ(UxGH zRw>kBR*LYs2g8x6DJ*{BI>{@xwxNKIjZ?^69{y3Y(V7$CeN$XmcE$k2zhygI8PCs7 zHhzY_*QH`HyTDr{2W8!%LnG28%>_xMAbe2-ZAT%b3eI#~u}tUZFIL+~(J8hzSElR5 zG;Jx}!PwH(911&(870_!nV?UXtF586KJ_@hsFrCh!e0UeUw;E2aSkR;StM#$`cy2L z>$C}N^t!e97{bbRO? zn9t|QYxuMO`~U5){dd3o!_PkX!6%O%9!x&@>VBKJvtF*;w-;Ak^qT$KWtu?_N2WFZZi_A%z4-X! zj~~B=)oL}m7tf#kY`$25<7%k|Nm8^(t=I1I|M|Cn`;$ipJ%@s#A3b{X$tNE_Ivlr6 z*>T*X2M_i~?QXXVO1lTAr>Deh<*;4IJ zZ#aH8p&%eDVRpgH-WrqO}{ z5ha`e@&c2z{<0|;=rpsp+beMl^kd z=4-5oFp6lI1&<<{V=Os#MiHb4&C!D!O$$mCJpiRb>W~&pnG)ZMLB~Z4UWde2F`U_y zrbOv%BhoPB_KJ$x8Sa@ zL`M|m1x$N-N(+B-MK@Ii_5$vFrpCxLhiok2avK)h3%CWaS7BZiZ1xJRK!I7s$&%EB zl4dQG;cv-2eQ(bzTJ00f*5t4NpLKvXTCqb% zhT)ReEQ$$=!AdX!;3!LoS8&QHx*SdQaNxK`j$c&a zLBRkbuNbyJYcO>VTNFeUfU6{_B=M>F3F^mQNWh6fAUY7t2^+||Cj#-Ee4U-QVW%#K_adJzn8!L+rQnUy8}P?!4I0N zJMi@B)8^_L{`J59*Ui;!IC*hGZXP664xTOqc&vPtfxI}u>WsUd^$ueJ;l*o?=#5)s zd)-aFfxDkF5kNK$eA>=?d>apKC4ht8>$aU>dA3^nD3$&A zda^4tk3jrZXE+>>rB*yWeoC|3#24&olgEuF;1SUL(zN2usNVvvC4O1EmshWWramB# zAQBa8^|t}Cqi+vPk(Ko6Oj2MaZDLq{chU=kq{BGolPzrS zchkCC@prxh1@L$O?%!>$F2ShriU1hFy=*%XLvu-}{-^)x|Jz*Nfp4Y&e(!(&pX*{? zsmvvQE(+kQufA%oZh#D2D1&#o6Zl4hU%kDX#|U>nZTgXG6?wcmfBx0ye*}Xuh|~I& zdsvs@^`})5tj>?0ueZ@P=C~)5<`KmLTF+j5`QN_$=}+g&EeR|)G6i3ieJMg(Up}^vkuhDE-y@d-4IUmG|mk!MwBfq{WM7YWlUR(UT^cO$m0|#>6DoFAFq%fsNt2i-{^=p z^~*QKRlfJ}!Y>HmWx_Fu-_40&e-fb2QSj=wTQ))8{P+z3NlD8W-kPQ13&V-rP>kJo zCk{SXl+fp4z|JXqCo=F(K$T>#ob2@qpaVb&wTQn5P3m`xcP=6>Go*C}U(b{O`YCt# zzTy{50e~7An%f&7#r|_tt#$E#QWdzbBkn+5HTa*GVE6A1?=;VsLwPgXw;p4b0pa=$ zd-4XL4gv$40i}(>H?9F(H>q#no%94U`DXci;}^g8*!9dcG|X@}JN$_$fV*nI(V8;w z7^=wPc+e6?U8gTfZvX`g(Agn~%@5ZaNo)JR-X@^i@U_TCU>~n#I&0+;SMO1qSTul_ zIo-&UZdoci!s+Uweg@FmYHHo9`QHQDQ0ll|M^j}%k~PCJOpBslT;@q7i0qtU!d(rd ziqI>pC#ecX6GEdI9g5Dtb_db7O4{%KHHPUvpcs^*Xm$7vbcCRq6rV(43+J0eFLC1+ zj@Fq2BHC-#?Zq8c4A-i9ZRzUmsHH!;MUo_0p~FO}k3>3%3O97co+3@H1L&)?NPjpA z)j^+USzMqxvp0iYzmXgjsADz=Upto?^@}np_LeVx8^HFtR{y#O=u7u66fV2;u8LvM zMdgNrN8hO3L?i}NWRpvUv|M>tjly-BN=S&$93o3vQX zrg4%pLyoivotPu3ZhvTs<>KNzjMIwNpA)0Nm&dCZjJisw!wv7AEek{m9Mu$$s77l-1tuHT&prR$+ z>vWuWHH}-U>lpt0+>cVU5v^+pa(j3eW`a0@>HAfG9Uv=4e52TCo*P5|;%* zRM#HV0;0;xQZW_HqJ=MMkmnU|wpBjQ*VC|`Lnq-#L(|M@5ygRYh~n^!zWw5LS{JvW z6Cx=E(nzA=L5~XYGNe7BEahdZF{%C_-}sH+Xs+(Szx}uWwz;|kfA-J*+2-mt?CtF}S9jo+df)L4 z_B#IX5C5>ax(&bn>%ZPy-GTr7pZ{}nbqD^%zxWr;)iwO+zy1iafbkTGl+peJODWEt z{%p3`Dt3SW!9!CMvuHa%dqM2Ly1$XAjQ`(FFgVEZ?&x4J9HBg#==FN0p`!t^)gA90XhObOuX0ZE`g^#g5I033+k?kH{MEy~5$ckriDGs~ zdxxEVUz3E2lWeao@hu7VvTYVgOw06YaJ=dD$NNV;+Fl^$X(}6#c?X@g!xdRxa!!A5 zG@3ZBBSP>BYJYM>;niq)dk%?DFLpb$^M+SPkAC>cCm-9IoTpJ*a87SB8jlS{%JURm zfs|cTMiyJV(jAUuF5|U!w{6BjfB_p#_H08f(xea+uRl^->1sYJIK}Ptb%p1t-VVr9 zbj-)wx%9gHV?mM-U6 zM&mL$?De~?}dY#(wiI(M?*zu&T0<7u$sEj1ETQJ+Iw04H@#6`fcy9?U=O53jH=Z9Pb~FMk6lw z*PGDlj61Hro*f5?(BIqFM2f1X%lvk;Of%YGd@D#%k@$m<v1NxFJ#p-Bg zTZ3amo2n>=!et#~QFD|g77#ebfGXECgLW_SB0MmPdnjp=Ofld%&D9K-mKD-UX<0HH zxs~QIiz0U&k}jKV-EiQ>@X)iOCZlxSroa`jWJFCdJG8&0MQb@Fqs^i?s7)Y09Yr`Y zthKUeDX2CoW5LnjT7qB=tts;yfT4USHlG!+}Zs4lkH z`SMM*7z9N$+Pdjbq&oDBYO9}p^jY)l8Xi1&&|KYtH-_aoIy!2uZUct6xq2I12K&4d zCnqP()opmA);T{vZ?5jZt%nkC!=ydj9}M~sxoMigrs($CxxZL#LfsvWCxbHaLA#bN z6(x_9{o&Bm6-XFScL$TBccB0{!5thOJ~;AR*EBS6j_wU?O%zn8?OA2XbtVr7{jP00 zLRAQwH{RP*71^-tG7U3MZFhTO9xhHLCe{+l&ynDpLIP0WSc}m-jclD(2z>lr<)*hh7Ts=0UUizQ()%U z-Jz~Zn$vZ3VY^x+Bp?_&@5K0whQh^D`~KI$NQ5Z^a>9v`FhGS4N|kh%2i_*q;k;|CvgU>?gVMYTw|x=StF=JHf_pqTm) zX@+T_GL>X@YLkCH3!(%9raKr2d9YZlAeq|zp~fd?PrtmF&9av0bcc>6tY#NEr%xV! zIvn&cE);Tx*CvOLXqCQZ2xYw8uoY7TNHn!OelQ$#bkjC9IrM$WfXm_dvuDqrKG`Nk zyFU`LHN2KmcJ>~AJQ@xy$J2GG%%P3Oo@;8RO$LT!jrR93h^nf_+u8Z~6s86S<^097 zun=9(iI&IPnA0_RyPQJ>HRJml@O!NQc)SmNA&Clx*D`gQ^&-Jft{-_2%#x*}Zpkvt z;{s$$VpkAki6aG&SBj(BZB?X&`9euPC~O~9Gi4Dnu;lc%rh*+%)-)A~%qh|8QcNL574j&J6L`-QYT{-vIF3^t-RY`= z$Wwx%6b#k&6kcFE`5<#0+M+|t_63^9G`pH4aiU5wS2JGx5Szy(-{ii7@^IRUNV z^Nggt3WFQml(S%F?XTJBHm+RpbQ4nOB-;&?X!xgUc-o4R{_pjMOB}Q=-6@ z=IW34A2(00VW$9Y#jOgUlI+RBf#bp&RD;#UIxbDq$o=Jd6F~E~T|HROavtmg4uo;G zrzjXlohu7ib%R0YTg~AzfSN_!av`R{OoBi$mSI3@Zm->Tt2}|NVtX{J3rAaoO(FI{;o4j@y2&S?7$GP9kPuD)3?jLWa&%gTV*~Kgj{WvY1?ijWt2szE* z5>XS_9}*O4usDADv*XkAyd^tsTUTZLDuC&9P;|aHf4)J6oREc^+4-3tC3p*EqWHYF z7ppRhHnWS9+4=G5v#&0uOM&*`!f8M*&_ObsZ^$fE=Jb3@+xWr+#vzLZ6u?$f6eQp^ z(=knpd1}Nv^cQ=ZCcw~rG|LUik1iEy{WtQ&1K3mK)seMDZ;^jblMxgET;ey=XXob^ z3FH)MPjo5eLjl8hF4|7dPETONK{%~uXBTHDr_Z09on4@#mNN>`L*l#2(cJ0T$@KIE zx^%Hx`>WY(dJ#i+qAzIsZd;?ROcY8V)hx4cdi)hwG>B3psM#NlKuX)O((T3h#jNBZ z8nex6KEHVJ{EMHQoSZ|BuvSpycUa<(v=j&=2w9?;9fqV z|9Oc1R*?s*h<1Ic5^b>K*`8ad72IOb*HJC{k@|Y2E~`xW&@>U!%NQMWC0C*ljzYFk z6igD^d0cnaf3zkuqfuzWM&*OA63;i`s*1->mw=u{K>PsYZ9@VBD z0|M+2T~;(!b7EFxQ>A{qzMxsAJkEl360Tx@7D88L3GFe48$^9fry9^UG`v7>vE6WN z?&)Ubz)F$=rIn&Y3^vrjt@YpGt)QB&Z5d3!NPGbvT96HzY|p>F0w6#JrW9=F0&>CMZUQpy+GGU>AQK9P62h#!I9)E+w5~b> z=}_QC5D)ka)WYVXKzCe5yS$z**FNJC7M2GUzc|}$1LlR3xkl0s7ho3%L;8RxwTfiD zxYz~>h5GYcqQIPeY@m60^51jVw{QneUM!c3&1MVF*3x)?v&o7Is>Sv?6v`h3Qc4Qj zadGl|wb|yh@N>18o-O8!tWgzYE>cQjQOY0kSKwOVdQQf^Vs(21RTgQ+hzKrHWJS8EVsVT;Hm0>*TeltINF`X@F z$2o;F@>q;bg-k@UWzj`(nrECy8^2@PqF8Gz5>T*tsnQVRpp`2rOs!xQWAx3)0F9!0 z!sxhaFYb{{Ry8;W^r@sQ(T}RwQkqO}M_m9h3~M%H2^#2E-yy9EL5x3FiUDZ^2?err z^e!%F1FfpV8>Go9JdLwf}hqA_H~+DNJCCDIc#CLqZ?p`dc%Hloei&}pktSeIc%Trf&eN>n(jLqe;&QHmRUOn;qJQhJxJgxZfW*onCJ+q8Ps9f0DmV%vnMk zMS|)M_x3GAC4B?)lH>_g5vyAU?ur5m&BiHackzP zkl}Fz`%UPK9`w3xNf0%&I~eVGUZ*n{d!9qlBoqZy4dF)yD9y_Y?csi}>txXyDu;H2 z(>He3d>EJ{BvX_U!y`d|BvBMbC>?ST9EC^tkHjdng4v!NJ#-8yf=)GioiAF0HB7v*nx(=kEW}#j^%k8w=ZK0J$ab|WVbXXXLN?D>yX~vokgvlsi1BI)s z{ig!TAx$f*H|Y=hy6JX@d)-dg>kfOp9;{fD0ze2r=GpDxU`Qddd&7|?7VG7Lg271W zs2t-;u{6*^ilmcQoM?3?`-d1cwajDmi`gD~wg!TYlcN6gicx`7D4}}8h`w>Swun2Z zLHZM?7|U=SM48>$b4>+J*lbpLOY4pfOgiI?4nIJ9ZM3)3Q6vr}y1jkR)}iP?@tVRv z^7w)FsxW^Q6nP;E1E0dCK%J0IN>Y+kcfSOpFS3FH?a_pm1Unl2VmJ!OKZ9*UAK2+# zXbXz(mbDZMZnsFfQ{ZJ5`c2Vcyg*HmMiF({>T0qC2b5-4Km!z(FsHp;D2l~agE0b5 zp|}pnmt-+`Ijdw#wK^I+14+HilZ7OrNqJ9&E~Q`$7!0CHumuI1V_z>QbWY8Lql$X_$y{i%vdpMoj!C_AYMB3+=s zr8Hj#kF;s8F3CFhh5`pw68m}qN{PV`uY4ic;Tr%Zau6n>1o=ZBcS|~HpmO^Alf8*1 zwSv|3{N(95>4p^i2o|P^0+PDE?+2pMdnX@(NsL3TL7@1n1@eWQgN?skPFKrSni3~N z^g&ClSIan#Vcvv6NN0rv+a!)CULtt~QRr{+Q@CCGK|l<-*@Q7|ZG`uLH{&D&DH)ax zT3ya4f-zTRv@^@!27yn+S!S@^;eteQg7QJ#P>oUG$B-+bkJ6wU&^!tj>DbZo^kO;( z`N4uh^&=D=L-bS3YKqy3lq7&*gMkUR>*X>CLRueUTDmGn>*;C}P*~m24=7~u2J!-( zkoc(ADaCiCC`_mk$#?iecuF#Q1Ie{PZ!|@)u7>y~=VUQmuh)12;Ry>Jtys+GVFZq6 z^I9dUM_L4VCc$bBe`vFfsY~hA&58^{Fp{KMnkvEugJOW4j91V({+3P!Kz&g9VtT$_ ztzd3rEJ%#5*Dwg95cS7cK)qrtVj2t5UjeEtN@9_~{jZM}2=RypE)0u`gNZG)iV#Hv zTYs}cFMzfvWb|rD(Ud9VsE-b)iG!)Mm_=7<}kREJFixP?y9Zvx`Ymp6; zJWC+N=@t?h(iU{VuIW9J(JZDLod9Ey+=UL4Wj+hiU>#HG6j>V0qwR1^j*~5qOu|jt zqR2S(MIl^)UD0@!Ed_u>G<{`ITh046F2QMVr$}%L!Civ87MDVCrxYp0El80oOFKXw+b*BM8}J6JvWZVw)j6u@p1L@UDaJqgc}qvQ zT9e!A+a9a0mwe3W95H%Ze+T^{# zL2=-!T>c=|sk_mUy3diL%qoC2)Jk~*$)cN@0|k!k5dp?LaguH2{khREV-657df3r? z2muHoPUAPMr|_i{&24 z1;Ws67Hm5Tj*q_tSaKDV1OIjY+D6=GJx;OITok!HEVC2}V8$g8mc+pt!pBkRe9}EE zep>y@=~m+Ff-Vb8n0XxvOg!IPgQ-+mlNRI(>HkNCHL(;jb@rb{27o*QZ%m9%{8y?M<#!b~V!$2aU$=A{hp8P#}w z)+A@+rzN=Td53FU+-wqr-7(-QeoWKHcvX0| z=Sre&$CTe`Ms;)?WOr9x_Cld+6?#wd5R}Rv*yngoCNP@Gh=NN_bMtSric3p^bqpue*)C-(!(sd(%%T4pEWYLC(bvwH`PYxtdJx?M>Xt)~ zvj5e_RU|}ABe6bL@%VYw$nMx%afPRN)P%l3t%}d`r`^z6)ix_UL#`3i?51}<Bqbe`=~*b-#GmeHA&A-E$GH z!`JsCOD!;N)`3ckb6Gk&oSY9c3!1I&WWL=E3&8LreJPAQlGtGr=&$ zF;>mt#wf$Bwnm0p!#MJ6fMoFVhYQ92Y!uYr2hrd5BvBHaQzrW+cFvYzT5l*W17Pm- zh9&!keveo<_*EY6*aGF9k>V}l>$9$Bvq$IeBgA{qq3z#(Ki_Rs6gqB(aT|*9#QW; zw=NP01CQ~Eq6_QaeDxK$ezeIGgV#wRboSaOuSz!P!n7R0Lg^XOYj7H+3=Z#LcRxtDr`wPPOUs6rVAqh3z$!PJ%vKUMJXs2Im`R{TY2RX&gm4%5Uyk`qt% zV257=NY5(-=Yl3&3AESN5vG#MzM7^a+381{SJi9wzS-=EefXuWQO|_G8)QpQyf8CO zXv(o0;rD}iY*N11NApTR9Tw6ZKy(qleu-5W_r@8LmBGw&;wlkHK3y8Ln&V-3rYPnH zA;p+J(5A=7MmOA&#Wi}5PuhV0T|Q|)_(d?|tto1qg%?z@7k5G|yr5zzWB*SUPb?ol zS`%4@mUq-f{|h-dq?x_&&yk_$H&;-!vYDvktL@o010Lx2gc^f!lOvDs^(h0x=_r2N zN_J+j(h;fBM9+)EcUsifQW7Z6fPJ*C&{ywxgyR2-?yQr-x}LV`WGE>s!1UT#R)2fg z^FBH|`UM!DWfi)D0D5Ka38Ojwrfl zvrtH5BIR(lZ{Ka@J$pUyb-8me?{Tv3&6gsSsx$azQYBZiQ3d6_bnWY7E#-7fO5!!q zQq40KAOtI5q-~Za(V)DbaamofW%1a3bt=6A#M=1&a+r@n3(Hzs#X+Y&o`Q~smM~B; z9iv8G$X8rmpk1l^Th*dUT-$Kd4ISTsdnxv-!Hf?+S=&F3h3TSj+_)-^pXM5`z)MO_ zzoC9vgF~7gR9ahf!;L0Jdl;H}&yI3SPr2U48E0U9YEZPu?HQ(PURjwvhEw%T) z0kmd^IP?{QM83}76Twy%&*PzpFTligA0|~YpRw*RAX6kcD5><8bHV4(g8NH?!Uvqc zuagCRxIFWpQ+*hC`yv*4d=*{TS=d}$*MEQP*D^YDrEfn`?CRlJ>56-D+N+%R1bgEo z_A_u^pi{1PcH3JV{91S+h~e>^J?|0bR$1RYZ0ha6F94KYa@Uo-CrA`{NA^h2X%l2I z>*7+8ut*c#(Gv*Wi)8LS)p|zCm%7i__H@=8#{w%w`{8wI?mO9xa95(Ql+nc_q~^rB z-w)30M@b>zE{Sg%*MvacME#nOQ-6;o?FdMwcYoohe{{+st`lFni}`-P_u|pmS$K%q z#^}&ts+0l5mc zamao2RM}&(@x$RiKIwm{|H}0%7wi%s>Tsz-;e^g`9tl;9GoYx*2B}w6PdNQ*GB`~q z%_ll5c&pY#jDP&@>d)MyQ0h4)k1mPO1f!`Om{;QE=oyec2kW{Ji<2`jx=LT`!neJ0 zvQ7J*T34+NaZEIT+;t9Po;%Qh4*r|{%AZ{I1#QeIO)u66KV$-AE2q#J%2){`K4DME z4o@XC{3iP@;j5gb0~r?PRj(BE)%Z$y_(!eIPk9&IHK4WJh546-oYZFOIk0|ns-PO&fBv(V&qY38UCJA#A zIBualm)6LiTSqW`dy+|UTqp&Dbhxx9U5knW0H^W2(x3X99EphVUx@`=Ba7>6H;#I`wsxKju7H>S z?b*r-ZDFj|DmJh(}=%(dU}D^=`Aw0eB7J13#K1e z>z}*HTH4(matp&2*NqbWQ?&wLhf9B%pmO7q@w*4Y_XZkEzgnNjJRO~$mLX^s$Z5Y! zo*ZjmUz<||^y%`m6Um(1v?tjYKOH?hgol^m&hKB;_Gw%$SawLC>C-RRwrA-V%}Lyn zcPn7?_ff2&#sXJge|H@f@P%67^{U}H>jVo+7#bCf{8{4};YNc`cz+zSGAVSM-8uwBsB}2bYQB+Me~Uz58$4hiyUUYTr3>>88-%C5DddwJ|Y12ReL3 z%o-;8J?^M74Hc*?B#CnpI%NY4Ld%U7r%5qam=puX4z2@vSHiH}ocPaA`eVvbQmeb6 zGh(He%W)jTTLnh@-a#b2lIcIMb_V9(k}KK7_wkE5)kT6Qfa`_A*n%IZTHN2otoABf z&lNX|?DgA}&g17*xzZo(w#_^RqBB>v862UK_7yMEZ(gF9| z1HK%+`c#+i_>&Zv=IjjJw&9l#EU|(MB^HBd0^h-x9K2C1xCKW|*p%IXHVh?DB_+$} z3L4K~MH7ft8*a!OyR6nr+S%w=xImNCttQDh;V*D!AH6F(Lx zoX2M!jYdk%PdQ%))WqjYtOYgATp$LZeqL`poh#8o`k5jNdv>$8ozZvEHyqo)jgRMr zTx~v|PrneSuq2J5#R|4ugM|L%#q61IEj?UNYLdQ5n>-IpnuQnH26%O>V0rSZT}n`^ zoBam4V?_FmTzkVUS)0W+6H!nVBo*vrFA<8wm@2UMG|{C82$_9h%e=eF3;wxDX6vCY z;%oFhxtN~?b=U&`lMfqL{%ZR6=Q#j_1ALQTi2AFjmll2#)rjdPMHD-`Rn0?aE zx|{qU9bU409JHK#*-AkVEsgpfQsSlW4k!wO3qN}W&US%{IF@Y3#3gkyQ1{rnP#xd8 z*yctYKxio=n0CchP~Nb^NgN=A?Gh&NO4?cvaC7ebwKg2|(|a-5WQ<6n1EAk%=-JNr znYCKcz`h!dq;C2%;MPpf;i@@a~7s}^9cujaw*I#%k ze41~#L&xUa&74{>m+>Tz4Dznq-GdGI6PvTA(Gm!+)zbK({i1*Z5GOQM_;(F?tCsci zORGA-$4u?~5$l?5)zIHejIsYFL0ClfQa1slyu5!NL}zoFHD4f_Ml=0du$UADSmg0h z{q8UC5bPIsu8jn~wL}ygb5)GiOlu%YUWu(pzj4Uoz}>~JRWR-t>PMIg_2_=!cc%Vg zjfi9Mq&GNVoL!6z5lj?VOLKhuoi_o|d|1Awt_b>PdU#3<)j$BMNc7?M2kOXIKg9=z z#e%PohK=KqeJ_QtwqhKrKs>11Jlk>O&%J5o#ED(FDIl!6>`UBxGhhvN)s!pK3I+lD z>?G7;!tByM-K5nZFgVp7lHzy3n=|$hdL798Y0No&a?3S}9HL8!sBr=)r2W#BZ+spi zkxbw%Cg|TYSU9)%D+YpdB;%ElMTc@WntA|GB1C1776FZcwciz3_prOG*HTp?(6M+59U3v4eL&ToK47Ut_{&`488YL@sxOgRqa}x2)-ad2>dr8 zuG|3_#Tc1M<6gJYr*5Yqn=(;KiO&h>VtbiF!BdOh5ZOncoUb){{9?gD{cm9cx!ZQ} zCkosj`<@2Y@Lg^{tj2iw20)&Cf21R{V@0P&3L1urU9iHUadub}s=n~XoCO%hdnrQI zfEx9dgewJ;CO30836$3^zvBKfPIUpvznByD8h1CNb;4n;X{6DvY3SP3D?{6k^l z74wh;Vf|+jRya!iM}Iod$H05rABoxj=qv~3@9_)SPX#C`=xT?lN%Z6U*LnoU)Y-PI zj!lTCAv$B5GnI|Od}qgGC@JrO?r3?U5ttrveaFqDV1={-lqD^_Y~~dmjo3^#Cx;Tc zM*{cI4?7yQtB3E%aIvg$(mcB^ZIZoMqY50>(QQ+kxn)B<_?zDu65G8F&!JD~t(o0F zsF3%r;g&1PDoH`lrf68dj#kK#mwf@ish)_L12ks?GC014Gs>yG)hEYk#94jx{+AsFicyj!eep($*i16D{4 zYh}EV4$=KL!75}>SM)b=W2N#TQ|V!nZnzCB23|k~y^#i$Yu8_I^HQ2Xz;*MWUbWIX;rOOwR0C{cZI(iRF@R57z;`?Q-_Cd zM82WaM85J#l>4GB#nP6L+fycUjx0SJ>`~uE;n#HJp)8GSVomOGgE*{Cy#3w1j(Rru zL%6t%jBw~lt^*AO{}Jd-nj^EGiS^53ChJ-}DWWFw#lGL5+qe?JL>lyGB6m&UlJcIN zwp|gznwKMsQ&5gQwftSo2Fxly4r3V(Baod&a`QJ-c062ZPd~P((ro3FF!kmd2Y~SACk+r)FmAH%7cDwQp6DCU9J_Z1+(ELU*a`4mxU_RVqwo0ZH?Io=Ub|3Q ze?W4iqQnvwNqBt5DlUXP5;uxDdR^OP*T0^-SE&fazx8(s=C2s_1bR$@BZ&tc2euJ6 zeO&i2PHpOlp zli7^PEXcVs*Xwqz`Q*PO%NZMnmx_2?%QqS10_7gp!?j$pxya z)&vV}7q4vF2}Dg<5cL{T^M4-8>dduM{Mkm<_a{f5}^UO1N}z&_9-ZHm20^1Rr3ukYzn#7rE2^iaM%6v5QAt`g-1 z5P=q+{)q=^odJHR;Yt9aU#v~jWW@@vlVGYFrAwM>kN?@bjX9BBPrdt~w$8

_6x7Zz_j#wH0w47XA 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 z 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 i1>R|tU&$Aq-rz;G(cKF@r)FWGKOjI^rbfyn Date: Wed, 10 Jul 2024 21:40:10 +0100 Subject: [PATCH 06/25] Loading screen config entry (not implemented, still reverse engineering code) --- .../stationapi/StationConfigData.java | 4 --- .../stationapi/config/FactoryProvider.java | 25 +++++++++++++++++++ .../config/LoadingScreenOption.java | 20 +++++++++++++++ .../{ => config}/StationConfig.java | 2 +- .../stationapi/config/StationConfigData.java | 11 ++++++++ .../stationapi/lang/en_US.lang | 10 +++++++- .../src/main/resources/fabric.mod.json | 5 +++- .../api/client/resource/ReloadScreen.java | 1 + 8 files changed, 71 insertions(+), 7 deletions(-) delete mode 100644 station-api-configuration/src/main/java/net/modificationstation/stationapi/StationConfigData.java create mode 100644 station-api-configuration/src/main/java/net/modificationstation/stationapi/config/FactoryProvider.java create mode 100644 station-api-configuration/src/main/java/net/modificationstation/stationapi/config/LoadingScreenOption.java rename station-api-configuration/src/main/java/net/modificationstation/stationapi/{ => config}/StationConfig.java (84%) create mode 100644 station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfigData.java diff --git a/station-api-configuration/src/main/java/net/modificationstation/stationapi/StationConfigData.java b/station-api-configuration/src/main/java/net/modificationstation/stationapi/StationConfigData.java deleted file mode 100644 index 4922a954e..000000000 --- a/station-api-configuration/src/main/java/net/modificationstation/stationapi/StationConfigData.java +++ /dev/null @@ -1,4 +0,0 @@ -package net.modificationstation.stationapi; - -public class StationConfigData { -} diff --git a/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/FactoryProvider.java b/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/FactoryProvider.java new file mode 100644 index 000000000..b9cdc9e51 --- /dev/null +++ b/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/FactoryProvider.java @@ -0,0 +1,25 @@ +package net.modificationstation.stationapi.config; + +import com.google.common.collect.ImmutableMap; +import net.modificationstation.stationapi.api.config.ConfigEntry; +import net.modificationstation.stationapi.api.config.ConfigFactoryProvider; +import net.modificationstation.stationapi.impl.config.factory.DefaultFactoryProvider; +import net.modificationstation.stationapi.impl.config.object.ConfigEntryHandler; +import net.modificationstation.stationapi.impl.config.object.entry.EnumConfigEntryHandler; +import uk.co.benjiweber.expressions.function.SeptFunction; + +import java.lang.reflect.*; +import java.util.function.*; + +public class FactoryProvider implements ConfigFactoryProvider { + @Override + public void provideLoadFactories(ImmutableMap.Builder>> immutableBuilder) { + immutableBuilder.put(LoadingScreenOption.class, ((id, configEntry, parentField, parentObject, isMultiplayerSynced, enumOrOrdinal, defaultEnum) -> + new EnumConfigEntryHandler(id, configEntry, parentField, parentObject, isMultiplayerSynced, DefaultFactoryProvider.enumOrOrdinalToOrdinal(enumOrOrdinal), ((LoadingScreenOption) defaultEnum).ordinal(), LoadingScreenOption.class))); + } + + @Override + public void provideSaveFactories(ImmutableMap.Builder> immutableBuilder) { + immutableBuilder.put(LoadingScreenOption.class, enumEntry -> enumEntry); + } +} diff --git a/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/LoadingScreenOption.java b/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/LoadingScreenOption.java new file mode 100644 index 000000000..b78db3d3e --- /dev/null +++ b/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/LoadingScreenOption.java @@ -0,0 +1,20 @@ +package net.modificationstation.stationapi.config; + +public enum LoadingScreenOption { + SHOW("gui.config.stationapi.loadingscreen.show"), + NO_ANIMATE("gui.config.stationapi.loadingscreen.no_animate"), + NO_RECOLOR("gui.config.stationapi.loadingscreen.no_recolor"), + FORGE("gui.config.stationapi.loadingscreen.forge"), + HIDE("gui.config.stationapi.loadingscreen.hide"); + + public final String translationKey; + + LoadingScreenOption(String translationKey) { + this.translationKey = translationKey; + } + + @Override + public String toString() { + return translationKey; + } +} diff --git a/station-api-configuration/src/main/java/net/modificationstation/stationapi/StationConfig.java b/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfig.java similarity index 84% rename from station-api-configuration/src/main/java/net/modificationstation/stationapi/StationConfig.java rename to station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfig.java index 3de042934..f5e4be325 100644 --- a/station-api-configuration/src/main/java/net/modificationstation/stationapi/StationConfig.java +++ b/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfig.java @@ -1,4 +1,4 @@ -package net.modificationstation.stationapi; +package net.modificationstation.stationapi.config; import net.modificationstation.stationapi.api.config.ConfigRoot; diff --git a/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfigData.java b/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfigData.java new file mode 100644 index 000000000..4a837be6f --- /dev/null +++ b/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfigData.java @@ -0,0 +1,11 @@ +package net.modificationstation.stationapi.config; + +import net.modificationstation.stationapi.api.config.ConfigEntry; + +public class StationConfigData { + + @ConfigEntry( + name = "gui.config.stationapi.main.loading_screen_option" + ) + public LoadingScreenOption loadingScreenOption = LoadingScreenOption.SHOW; +} diff --git a/station-api-configuration/src/main/resources/assets/station-api-configuration/stationapi/lang/en_US.lang b/station-api-configuration/src/main/resources/assets/station-api-configuration/stationapi/lang/en_US.lang index d7f00896d..dd903399a 100644 --- a/station-api-configuration/src/main/resources/assets/station-api-configuration/stationapi/lang/en_US.lang +++ b/station-api-configuration/src/main/resources/assets/station-api-configuration/stationapi/lang/en_US.lang @@ -1,2 +1,10 @@ -# Achievement pages +# Config Entries gui.config.stationapi.main=StationAPI Configuration +gui.config.stationapi.main.loading_screen_option=Loading Screen Animation + + +gui.config.stationapi.loadingscreen.show=Show +gui.config.stationapi.loadingscreen.no_animate=Don't Animate +gui.config.stationapi.loadingscreen.no_recolor=Don't Recolor +gui.config.stationapi.loadingscreen.forge=Forge-Like +gui.config.stationapi.loadingscreen.hide=Hide (Vanilla) diff --git a/station-api-configuration/src/main/resources/fabric.mod.json b/station-api-configuration/src/main/resources/fabric.mod.json index 0e6a2812d..4c4afe942 100644 --- a/station-api-configuration/src/main/resources/fabric.mod.json +++ b/station-api-configuration/src/main/resources/fabric.mod.json @@ -20,7 +20,10 @@ "environment": "*", "entrypoints": { "gcapi": [ - "net.modificationstation.stationapi.StationConfig" + "net.modificationstation.stationapi.config.StationConfig" + ], + "gcapi:factory_provider": [ + "net.modificationstation.stationapi.config.FactoryProvider" ] }, diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java index c088afc31..710d8db81 100644 --- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java +++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java @@ -27,6 +27,7 @@ import static net.modificationstation.stationapi.api.util.math.MathHelper.lerp; import static org.lwjgl.opengl.GL11.*; +@SuppressWarnings("UnstableApiUsage") class ReloadScreen extends Screen { private static final long MAX_FPS = 60, From 7bbf1e496359550d96b20658b5164d6013050d81 Mon Sep 17 00:00:00 2001 From: calmilamsy Date: Wed, 10 Jul 2024 21:40:27 +0100 Subject: [PATCH 07/25] Update to GCAPI 3-beta.1 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 0944f1d17..efd2571ec 100644 --- a/gradle.properties +++ b/gradle.properties @@ -33,7 +33,7 @@ fabric.loom.multiProjectOptimisation=true archives_base_name = StationAPI # Test properties - gcapi_version = 1.3.1 + gcapi_version = 3.0.0-beta.1 hmi_version = 5.1.1 modmenu_version = v1.8.5-beta.3 mojangfix_version = 0.5.2 \ No newline at end of file From d2eb933cfa8e8dbd3d3a07c44a1fa95fce963e15 Mon Sep 17 00:00:00 2001 From: calmilamsy Date: Wed, 10 Jul 2024 22:30:37 +0100 Subject: [PATCH 08/25] Why --- build.gradle.kts | 8 +++---- gradle.properties | 2 +- station-api-configuration/build.gradle.kts | 5 ---- .../stationapi/config/FactoryProvider.java | 10 ++++---- .../stationapi/config/StationConfig.java | 2 +- .../stationapi/config/StationConfigData.java | 2 +- station-resource-loader-v0/build.gradle.kts | 3 ++- .../api/client/resource/ReloadScreen.java | 24 ++++++++++++++++++- 8 files changed, 36 insertions(+), 20 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 7f1299466..63535d4e2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -91,14 +91,12 @@ allprojects { // adds some useful annotations for miscellaneous uses. does not add any dependencies, though people without the lib will be missing some useful context hints. "implementationOnly"("org.jetbrains:annotations:23.0.0") - modLocalRuntime("com.github.calmilamsy:ModMenu:${project.properties["modmenu_version"]}") { + modLocalRuntime("net.glasslauncher.mods:ModMenu:${project.properties["modmenu_version"]}") { isTransitive = false } - implementation("blue.endless:jankson:1.2.1") - modLocalRuntime("net.glasslauncher.mods:GlassConfigAPI:${project.properties["gcapi_version"]}") { - isTransitive = false - } + + modImplementation("net.glasslauncher.mods:GlassConfigAPI:${project.properties["gcapi_version"]}") modLocalRuntime("net.glasslauncher:HowManyItems-Fabric-Unofficial:${project.properties["hmi_version"]}") { isTransitive = false } diff --git a/gradle.properties b/gradle.properties index efd2571ec..f6bcd498e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -35,5 +35,5 @@ fabric.loom.multiProjectOptimisation=true # Test properties gcapi_version = 3.0.0-beta.1 hmi_version = 5.1.1 - modmenu_version = v1.8.5-beta.3 + modmenu_version = 1.8.5-beta.8 mojangfix_version = 0.5.2 \ No newline at end of file diff --git a/station-api-configuration/build.gradle.kts b/station-api-configuration/build.gradle.kts index c431db4a2..a385be12b 100644 --- a/station-api-configuration/build.gradle.kts +++ b/station-api-configuration/build.gradle.kts @@ -1,9 +1,4 @@ import net.modificationstation.stationapi.gradle.SubprojectHelpers.getSubprojectVersion -import net.modificationstation.stationapi.gradle.SubprojectHelpers.addModuleDependencies base.archivesName.set("station-api-config") version = getSubprojectVersion(project, "1.0.0") - -addModuleDependencies(project, - "glass-config-api-v3" -) diff --git a/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/FactoryProvider.java b/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/FactoryProvider.java index b9cdc9e51..9df4eee87 100644 --- a/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/FactoryProvider.java +++ b/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/FactoryProvider.java @@ -1,11 +1,11 @@ package net.modificationstation.stationapi.config; import com.google.common.collect.ImmutableMap; -import net.modificationstation.stationapi.api.config.ConfigEntry; -import net.modificationstation.stationapi.api.config.ConfigFactoryProvider; -import net.modificationstation.stationapi.impl.config.factory.DefaultFactoryProvider; -import net.modificationstation.stationapi.impl.config.object.ConfigEntryHandler; -import net.modificationstation.stationapi.impl.config.object.entry.EnumConfigEntryHandler; +import net.glasslauncher.mods.gcapi.api.ConfigEntry; +import net.glasslauncher.mods.gcapi.api.ConfigFactoryProvider; +import net.glasslauncher.mods.gcapi.impl.factory.DefaultFactoryProvider; +import net.glasslauncher.mods.gcapi.impl.object.ConfigEntryHandler; +import net.glasslauncher.mods.gcapi.impl.object.entry.EnumConfigEntryHandler; import uk.co.benjiweber.expressions.function.SeptFunction; import java.lang.reflect.*; diff --git a/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfig.java b/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfig.java index f5e4be325..7f60edbd6 100644 --- a/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfig.java +++ b/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfig.java @@ -1,6 +1,6 @@ package net.modificationstation.stationapi.config; -import net.modificationstation.stationapi.api.config.ConfigRoot; +import net.glasslauncher.mods.gcapi.api.ConfigRoot; public class StationConfig { diff --git a/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfigData.java b/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfigData.java index 4a837be6f..648662267 100644 --- a/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfigData.java +++ b/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfigData.java @@ -1,6 +1,6 @@ package net.modificationstation.stationapi.config; -import net.modificationstation.stationapi.api.config.ConfigEntry; +import net.glasslauncher.mods.gcapi.api.ConfigEntry; public class StationConfigData { diff --git a/station-resource-loader-v0/build.gradle.kts b/station-resource-loader-v0/build.gradle.kts index d41afc0bb..70b9398eb 100644 --- a/station-resource-loader-v0/build.gradle.kts +++ b/station-resource-loader-v0/build.gradle.kts @@ -7,5 +7,6 @@ addModuleDependencies(project, "station-api-base", "station-maths-v0", "station-lifecycle-events-v0", - "station-world-events-v0" + "station-world-events-v0", + "station-api-configuration" ) \ No newline at end of file diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java index 710d8db81..20ccadc96 100644 --- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java +++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java @@ -14,6 +14,8 @@ import net.minecraft.util.math.MathHelper; import net.modificationstation.stationapi.api.resource.ResourceReload; import net.modificationstation.stationapi.api.util.math.ColorHelper; +import net.modificationstation.stationapi.config.LoadingScreenOption; +import net.modificationstation.stationapi.config.StationConfig; import net.modificationstation.stationapi.impl.client.resource.ReloadScreenManagerImpl; import java.util.Random; @@ -29,7 +31,7 @@ @SuppressWarnings("UnstableApiUsage") class ReloadScreen extends Screen { - private static final long + private static long MAX_FPS = 60, BACKGROUND_START = 0, BACKGROUND_FADE_IN = 1000, @@ -125,6 +127,26 @@ private static UnaryOperator when(BooleanSupplier condition expression(this::renderProgressBar) .before(this::renderLogo) .partiallyApply(deltaFunc)::get; + if(StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.NO_ANIMATE)) { + MAX_FPS = + BACKGROUND_START = + BACKGROUND_FADE_IN = + STAGE_0_START = + STAGE_0_FADE_IN = + GLOBAL_FADE_OUT = + RELOAD_START = + EXCEPTION_TRANSFORM = 0; + } + else { + MAX_FPS = 60; + BACKGROUND_START = 0; + BACKGROUND_FADE_IN = 1000; + STAGE_0_START = BACKGROUND_START + BACKGROUND_FADE_IN; + STAGE_0_FADE_IN = 2000; + GLOBAL_FADE_OUT = 1000; + RELOAD_START = STAGE_0_START + STAGE_0_FADE_IN; + EXCEPTION_TRANSFORM = 500; + } } private void renderBackground(ToDoubleFunction deltaFunc) { From ae72efbac7a75f7d29f9a9e6b6931b1b63b05fc9 Mon Sep 17 00:00:00 2001 From: calmilamsy Date: Thu, 11 Jul 2024 18:40:40 +0100 Subject: [PATCH 09/25] Changes --- .../station-api-configuration/stationapi/lang/en_US.lang | 2 +- station-api-configuration/src/main/resources/fabric.mod.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/station-api-configuration/src/main/resources/assets/station-api-configuration/stationapi/lang/en_US.lang b/station-api-configuration/src/main/resources/assets/station-api-configuration/stationapi/lang/en_US.lang index dd903399a..0c3664261 100644 --- a/station-api-configuration/src/main/resources/assets/station-api-configuration/stationapi/lang/en_US.lang +++ b/station-api-configuration/src/main/resources/assets/station-api-configuration/stationapi/lang/en_US.lang @@ -1,6 +1,6 @@ # Config Entries gui.config.stationapi.main=StationAPI Configuration -gui.config.stationapi.main.loading_screen_option=Loading Screen Animation +gui.config.stationapi.main.loading_screen_option=Loading Screen Style gui.config.stationapi.loadingscreen.show=Show diff --git a/station-api-configuration/src/main/resources/fabric.mod.json b/station-api-configuration/src/main/resources/fabric.mod.json index 4c4afe942..dde39c648 100644 --- a/station-api-configuration/src/main/resources/fabric.mod.json +++ b/station-api-configuration/src/main/resources/fabric.mod.json @@ -1,10 +1,10 @@ { "schemaVersion": 1, - "id": "station-achievements-v0", + "id": "station-api-configuration", "version": "${version}", "name": "Station API Configuration", - "description": "Provides systems for modded achievements, such as achievement pages.", + "description": "Configuration package for StationAPI.", "authors": [ "Modification Station" ], From ce4c7a789d3399fc14a5c14239e49d344629b451 Mon Sep 17 00:00:00 2001 From: calmilamsy Date: Thu, 11 Jul 2024 18:40:47 +0100 Subject: [PATCH 10/25] Fuck you reloadscreen --- .../api/client/resource/ReloadScreen.java | 362 +++++------------- .../client/resource/ReloadScreenManager.java | 2 +- 2 files changed, 88 insertions(+), 276 deletions(-) diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java index 20ccadc96..96ee466f2 100644 --- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java +++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java @@ -1,29 +1,22 @@ package net.modificationstation.stationapi.api.client.resource; import com.google.common.primitives.Floats; -import com.google.common.primitives.Longs; import cyclops.control.Option; -import cyclops.function.Effect; -import cyclops.function.FluentFunctions; -import it.unimi.dsi.fastutil.doubles.Double2DoubleFunction; import it.unimi.dsi.fastutil.longs.Long2DoubleFunction; -import lombok.val; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.render.Tessellator; -import net.minecraft.util.math.MathHelper; import net.modificationstation.stationapi.api.resource.ResourceReload; import net.modificationstation.stationapi.api.util.math.ColorHelper; -import net.modificationstation.stationapi.config.LoadingScreenOption; -import net.modificationstation.stationapi.config.StationConfig; -import net.modificationstation.stationapi.impl.client.resource.ReloadScreenManagerImpl; +import org.lwjgl.opengl.GL11; +import java.awt.*; +import java.text.*; +import java.util.List; import java.util.Random; import java.util.concurrent.CompletionException; import java.util.function.*; -import static cyclops.function.FluentFunctions.expression; -import static java.util.Map.of; import static net.modificationstation.stationapi.api.StationAPI.LOGGER; import static net.modificationstation.stationapi.api.util.math.MathHelper.ceil; import static net.modificationstation.stationapi.api.util.math.MathHelper.lerp; @@ -31,40 +24,15 @@ @SuppressWarnings("UnstableApiUsage") class ReloadScreen extends Screen { - private static long - MAX_FPS = 60, - BACKGROUND_START = 0, - BACKGROUND_FADE_IN = 1000, - STAGE_0_START = BACKGROUND_START + BACKGROUND_FADE_IN, - STAGE_0_FADE_IN = 2000, - GLOBAL_FADE_OUT = 1000, - RELOAD_START = STAGE_0_START + STAGE_0_FADE_IN, - EXCEPTION_TRANSFORM = 500; - private static final int - BACKGROUND_COLOR_DEFAULT_RED = 0x35, - BACKGROUND_COLOR_DEFAULT_GREEN = 0x86, - BACKGROUND_COLOR_DEFAULT_BLUE = 0xE7, - BACKGROUND_COLOR_EXCEPTION_RED = 0xFF, - BACKGROUND_COLOR_EXCEPTION_GREEN = 0x29, - BACKGROUND_COLOR_EXCEPTION_BLUE = 0x29; + private static final int BACKGROUND_COLOR_DEFAULT_RED = 0x35; + private static final int BACKGROUND_COLOR_DEFAULT_GREEN = 0x86; + private static final int BACKGROUND_COLOR_DEFAULT_BLUE = 0xE7; + private static final int BACKGROUND_COLOR_EXCEPTION_RED = 0xFF; + private static final int BACKGROUND_COLOR_EXCEPTION_GREEN = 0x29; + private static final int BACKGROUND_COLOR_EXCEPTION_BLUE = 0x29; - private static final Object - BACKGROUND_DEFAULT_DELTA_KEY = new Object(), - BACKGROUND_EXCEPTION_DELTA_KEY = new Object(), - STAGE_0_DEFAULT_DELTA_KEY = new Object(), - STAGE_0_EXCEPTION_DELTA_KEY = new Object(); - - private static final Double2DoubleFunction - SIN_90_DELTA = delta -> MathHelper.sin((float) (delta * Math.PI / 2)), - COS_90_DELTA = delta -> MathHelper.cos((float) (delta * Math.PI / 2)), - INVERSE_DELTA = delta -> 1 - delta; - private static final Long2DoubleFunction - BACKGROUND_FADE_IN_DELTA = time -> (double) Longs.constrainToRange(time - BACKGROUND_START, 0, BACKGROUND_FADE_IN) / BACKGROUND_FADE_IN, - STAGE_0_FADE_IN_DELTA = time -> (double) Longs.constrainToRange(time - STAGE_0_START, 0, STAGE_0_FADE_IN) / STAGE_0_FADE_IN; - private static final Function - GLOBAL_FADE_OUT_DELTA_FACTORY = fadeOutStartGetter -> INVERSE_DELTA.composeLong(time -> (double) Longs.constrainToRange(time - fadeOutStartGetter.getAsLong(), 0, GLOBAL_FADE_OUT) / GLOBAL_FADE_OUT), - BACKGROUND_EXCEPTION_FADE_IN_FACTORY = fadeInStartGetter -> time -> (double) Longs.constrainToRange(time - fadeInStartGetter.getAsLong(), 0, EXCEPTION_TRANSFORM) / EXCEPTION_TRANSFORM, - STAGE_0_EXCEPTION_TRANSFORM_FACTORY = transformStartGetter -> time -> (double) Longs.constrainToRange(time - transformStartGetter.getAsLong(), 0, EXCEPTION_TRANSFORM) / EXCEPTION_TRANSFORM; + private static final Object BACKGROUND_DEFAULT_DELTA_KEY = new Object(); + private static final Object BACKGROUND_EXCEPTION_DELTA_KEY = new Object(); private static final String LOGO_TEMPLATE = "/assets/station-resource-loader-v0/textures/gui/stationapi_reload%s.png"; @@ -76,19 +44,10 @@ private static UnaryOperator when(BooleanSupplier condition private final Screen parent; private final Runnable done; private final Tessellator tessellator; - private boolean firstRenderTick = true; - private long initTimestamp; - private long currentTime; private float progress; - private final Effect - backgroundEmitter, - stage0Emitter; private boolean finished; - private long fadeOutStart; - private float scrollProgress; private final String logo; private boolean exceptionThrown; - private long exceptionStart; private Exception exception; ReloadScreen( @@ -108,52 +67,87 @@ private static UnaryOperator when(BooleanSupplier condition default -> ""; } ); + } - val globalFadeOutComposer = when(() -> finished, GLOBAL_FADE_OUT_DELTA_FACTORY.apply(() -> fadeOutStart)); - val deltaMap = of( - BACKGROUND_DEFAULT_DELTA_KEY, globalFadeOutComposer.apply(BACKGROUND_FADE_IN_DELTA).andThenDouble(SIN_90_DELTA), - BACKGROUND_EXCEPTION_DELTA_KEY, BACKGROUND_EXCEPTION_FADE_IN_FACTORY.apply(() -> exceptionStart).andThenDouble(COS_90_DELTA).andThenDouble(INVERSE_DELTA), - STAGE_0_DEFAULT_DELTA_KEY, globalFadeOutComposer.apply(STAGE_0_FADE_IN_DELTA).andThenDouble(SIN_90_DELTA), - STAGE_0_EXCEPTION_DELTA_KEY, STAGE_0_EXCEPTION_TRANSFORM_FACTORY.apply(() -> exceptionStart).andThenDouble(COS_90_DELTA) - ); - ToDoubleFunction deltaFunc = key -> deltaMap.get(key).applyAsDouble(currentTime); + private static final NumberFormat NUMBER_FORMAT = NumberFormat.getNumberInstance(); - backgroundEmitter = FluentFunctions - .>expression(this::renderBackground) - .partiallyApply(deltaFunc)::get; + static { + NUMBER_FORMAT.setMinimumFractionDigits(2); + NUMBER_FORMAT.setMaximumFractionDigits(2); + } - stage0Emitter = - expression(this::renderProgressBar) - .before(this::renderLogo) - .partiallyApply(deltaFunc)::get; - if(StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.NO_ANIMATE)) { - MAX_FPS = - BACKGROUND_START = - BACKGROUND_FADE_IN = - STAGE_0_START = - STAGE_0_FADE_IN = - GLOBAL_FADE_OUT = - RELOAD_START = - EXCEPTION_TRANSFORM = 0; + @Override + public void render(int mouseX, int mouseY, float delta) { + super.render(mouseX, mouseY, delta); + if (parent == null) renderEarly(); + else renderNormal(delta); + + Option reload; + progress = Floats.constrainToRange(progress * .95F + ((reload = ReloadScreenManager.getCurrentReload()).isPresent() ? reload.orElse(null).getProgress() : 0) * .05F, 0, 1); + if (Float.isNaN(progress)) progress = 0; + if (!exceptionThrown && !finished && ReloadScreenManager.isReloadComplete()) { + try { + ReloadScreenManager.getCurrentReload().peek(ResourceReload::throwException); + finished = true; + } catch (CompletionException e) { + exceptionThrown = true; + exception = e; + LOGGER.error("An exception occurred during resource loading", e); + } } - else { - MAX_FPS = 60; - BACKGROUND_START = 0; - BACKGROUND_FADE_IN = 1000; - STAGE_0_START = BACKGROUND_START + BACKGROUND_FADE_IN; - STAGE_0_FADE_IN = 2000; - GLOBAL_FADE_OUT = 1000; - RELOAD_START = STAGE_0_START + STAGE_0_FADE_IN; - EXCEPTION_TRANSFORM = 500; + if (finished) { + ReloadScreenManager.onFinish(); + done.run(); } } + private void renderEarly() { + GL11.glBindTexture(3553, minecraft.textureManager.getTextureId("/title/mojang.png")); + fill(0, 0, width, height, 0xFFFFFFFF); + drawMojangLogoQuad((width-256)/2, (height-256)/2); + GL11.glEnable(GL11.GL_BLEND); + renderText(Color.BLACK, false); + GL11.glDisable(GL11.GL_BLEND); + } + + /** + * See {@link net.minecraft.client.Minecraft#method_2109(int, int, int, int, int, int)} + */ + private void drawMojangLogoQuad(int i, int j) { + float f = 0.00390625f; + float f2 = 0.00390625f; + tessellator.startQuads(); + tessellator.vertex(i, j + 256, 0.0, 0, 256 * f2); + tessellator.vertex(i + 256, j + 256, 0.0, 256 * f, 256 * f2); + tessellator.vertex(i + 256, j, 0.0, 256 * f, 0); + tessellator.vertex(i, j, 0.0, 0, 0); + tessellator.draw(); + } + + private void renderNormal(float delta) { + parent.render(-1, -1, delta); + this.fillGradient(0, 0, this.width, this.height, -1072689136, -804253680); + + renderText(Color.WHITE, true); + } + + private void renderText(Color textColor, boolean shadow) { + if (exceptionThrown) textRenderer.draw("Oh noes! An error occurred, check your logs.", 0,0, textColor.getRGB(), shadow); + else textRenderer.draw("Loading resources...", 0, 0, textColor.getRGB(), shadow); + List locations = ReloadScreenManager.LOCATIONS; + String s = locations.isEmpty() ? "Doing the do": locations.get(locations.size() - 1); + textRenderer.draw(s, 5, height-10, textColor.getRGB(), shadow); + String text = NUMBER_FORMAT.format(progress*100f) + "%"; + int textRendererWidth = textRenderer.getWidth(text); + textRenderer.draw(text, width-textRendererWidth-5, height-10, textColor.getRGB(), shadow); + } + private void renderBackground(ToDoubleFunction deltaFunc) { - val delta = deltaFunc.applyAsDouble(BACKGROUND_DEFAULT_DELTA_KEY); + var delta = deltaFunc.applyAsDouble(BACKGROUND_DEFAULT_DELTA_KEY); final int color; if (exceptionThrown) { - val exceptionDelta = deltaFunc.applyAsDouble(BACKGROUND_EXCEPTION_DELTA_KEY); + var exceptionDelta = deltaFunc.applyAsDouble(BACKGROUND_EXCEPTION_DELTA_KEY); color = ColorHelper.Argb.getArgb( 0xFF, lerp(exceptionDelta, BACKGROUND_COLOR_DEFAULT_RED, BACKGROUND_COLOR_EXCEPTION_RED), @@ -183,199 +177,17 @@ private void renderBackground(ToDoubleFunction deltaFunc) { fill(0, 0, width, height, color); } - private void renderProgressBar(ToDoubleFunction deltaFunc) { - val delta = deltaFunc.applyAsDouble(STAGE_0_DEFAULT_DELTA_KEY); - if (delta == 0) return; - val color = (int) (delta * 0xFF) << 24 | 0xFFFFFF; - val v = (float) (10 - delta * 10); - val ev = exceptionThrown ? (float) (10 - deltaFunc.applyAsDouble(STAGE_0_EXCEPTION_DELTA_KEY) * 10) * 3 - 1 : 0; - drawHorizontalLine(40, width - 40 - 1, (int) (height - 90 + v * 5), color); - if (exceptionThrown) drawHorizontalLine(40, width - 40 - 1, (int) (height - 90 + v * 5 + ev), color); - drawHorizontalLine(40, width - 40 - 1, (int) (height - 50 + v), color); - drawHorizontalLine(40, width - 40 - 1, (int) (height - 40 - 1 + v), color); - drawVerticalLine(40, (int) (height - 40 + v), (int) (height - 90 + v * 5), color); - drawVerticalLine(width - 40 - 1, (int) (height - 40 + v), (int) (height - 90 + v * 5), color); - fill(40 + 3, (int) (height - 50 + 3 + v), ceil((width - (40 + 3) * 2) * progress + 40 + 3), (int) (height - 40 - 3 + v), color); - val xScale = (float) minecraft.displayWidth / width; - val yScale = (float) minecraft.displayHeight / height; - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - val locationsScissorsHeight = (int) ((40 - 1 - v * 4 + ev) * yScale); - if (locationsScissorsHeight > 0) { - val to = ceil(scrollProgress); - val scrollDelta = scrollProgress - to; - glEnable(GL_SCISSOR_TEST); - glScissor((int) ((40 + 3) * xScale), (int) ((50 - v) * yScale), (int) ((width - (40 + 3) * 2) * xScale), locationsScissorsHeight); - for (int i = 0; i < to; i++) { - val y = ceil(height - 88 + (10 * i) + (scrollDelta * 10) + v * 5 + ev); - if (y > height - 50 + v) break; - drawTextWithShadow(textRenderer, ReloadScreenManager.LOCATIONS.get(to - i - 1), 40 + 3, y, color); - } - glDisable(GL_SCISSOR_TEST); - } - val exceptionScissorsHeight = (int) ((-1 - v * 4 + ev) * yScale); - if (exceptionThrown && exceptionScissorsHeight > 0) { - glEnable(GL_SCISSOR_TEST); - glScissor((int) ((40 + 3) * xScale), (int) ((91 - v - ev) * yScale), (int) ((width - (40 + 3) * 2) * xScale), exceptionScissorsHeight); - val line = exception.getMessage(); - var curHeight = height - 88; - val lineWidth = textRenderer.getWidth(line); - if (lineWidth > width - (40 + 3) * 2) { - var begin = 0; - var lastSpace = -1; - for (int cur = 0, lineLength = line.length(); cur < lineLength; cur++) { - val isSpace = line.charAt(cur) == ' '; - val isEnd = cur + 1 == lineLength; - if (isSpace || isEnd) { - val newLine = isEnd ? line.substring(begin) : line.substring(begin, cur); - val newLineWidth = textRenderer.getWidth(newLine); - if (newLineWidth > width - (40 + 3) * 2) { - drawTextWithShadow(textRenderer, line.substring(begin, lastSpace), 40 + 3, curHeight, color); - curHeight += 10; - begin = lastSpace + 1; - } - if (isSpace) - lastSpace = cur; - if (isEnd) { - drawTextWithShadow(textRenderer, line.substring(begin), 40 + 3, curHeight, color); - curHeight += 10; - } - } - } - } else drawTextWithShadow(textRenderer, line, 40 + 3, curHeight, color); - glDisable(GL_SCISSOR_TEST); - } - drawTextWithShadow(textRenderer, "Minecraft: " + ( - ReloadScreenManagerImpl.isMinecraftDone ? - "Done" : - "Working..." - ), 40 + 3, (int) (height - 100 + v * 5), color); - val stationStatus = "StationAPI: " + ( - isReloadStarted() ? - ReloadScreenManager.isReloadComplete() ? - "Done" : - "Working..." : - "Idle" - ); - drawTextWithShadow(textRenderer, stationStatus, width - 40 - 3 - textRenderer.getWidth(stationStatus), (int) (height - 100 + v * 5), color); - glDisable(GL_BLEND); - } - private void renderLogo(ToDoubleFunction deltaFunc) { - val delta = deltaFunc.applyAsDouble(STAGE_0_DEFAULT_DELTA_KEY); - if (delta == 0) return; - val v = 10 - delta * 10; minecraft.textureManager.bindTexture(minecraft.textureManager.getTextureId(logo)); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); tessellator.startQuads(); - tessellator.color(0xFF, 0xFF, 0xFF, (int) (0xFF * delta)); - tessellator.vertex(width / 2D - 120, (height - 90D) / 2 - 20 - v, 0, 0, 0); - tessellator.vertex(width / 2D - 120, (height - 90D) / 2 + 20 - v, 0, 0, 1); - tessellator.vertex(width / 2D + 120, (height - 90D) / 2 + 20 - v, 0, 1, 1); - tessellator.vertex(width / 2D + 120, (height - 90D) / 2 - 20 - v, 0, 1, 0); - tessellator.draw(); - glDisable(GL_BLEND); - } - - @Override - public void renderBackground() { - backgroundEmitter.run(); - } - - private long lastRender; - - @Override - public void render(int mouseX, int mouseY, float delta) { - if (firstRenderTick) { - firstRenderTick = false; - initTimestamp = System.currentTimeMillis(); - } - currentTime = System.currentTimeMillis() - initTimestamp; - val partial = currentTime - lastRender < (1000 / MAX_FPS); - if (partial) currentTime = lastRender; - else lastRender = currentTime; - val locationsSize = ReloadScreenManager.LOCATIONS.size(); - if (!exceptionThrown && !finished && !(scrollProgress + .1 < locationsSize) && !(progress + .1 < 1) && ReloadScreenManager.isReloadComplete()) { - try { - ReloadScreenManager.getCurrentReload().peek(ResourceReload::throwException); - finished = true; - fadeOutStart = currentTime; - } catch (CompletionException e) { - exceptionThrown = true; - exceptionStart = currentTime; - exception = e; - LOGGER.error("An exception occurred during resource loading", e); - } - } - if (!partial) { - Option reload; - progress = Floats.constrainToRange(progress * .95F + (isReloadStarted() && (reload = ReloadScreenManager.getCurrentReload()).isPresent() ? reload.orElse(null/*safe*/).getProgress() : 0) * .05F, 0, 1); - scrollProgress = Floats.constrainToRange(scrollProgress * .95F + locationsSize * .05F, 0, locationsSize); - } - if ((finished ? currentTime <= fadeOutStart + GLOBAL_FADE_OUT : currentTime < BACKGROUND_START + BACKGROUND_FADE_IN) && parent != null) - parent.render(mouseX, mouseY, delta); - renderBackground(); - super.render(mouseX, mouseY, delta); - stage0Emitter.run(); - if (finished && currentTime - fadeOutStart > GLOBAL_FADE_OUT) { - ReloadScreenManager.onFinish(); - done.run(); - } - } - - boolean isReloadStarted() { - return currentTime > RELOAD_START; - } - - @Override - protected void drawHorizontalLine(int startX, int endX, int y, int color) { - if (endX < startX) { - val n = startX; - startX = endX; - endX = n; - } - fill(startX, y, endX + 1, y + 1, color); - } - - @Override - protected void drawVerticalLine(int x, int startY, int endY, int color) { - if (endY < startY) { - val n = startY; - startY = endY; - endY = n; - } - fill(x, startY + 1, x + 1, endY, color); - } - - @Override - protected void fill(int startX, int startY, int endX, int endY, int color) { - int n; - if (startX < endX) { - n = startX; - startX = endX; - endX = n; - } - if (startY < endY) { - n = startY; - startY = endY; - endY = n; - } - val a = (float)(color >> 24 & 0xFF) / 255.0f; - val r = (float)(color >> 16 & 0xFF) / 255.0f; - val g = (float)(color >> 8 & 0xFF) / 255.0f; - val b = (float)(color & 0xFF) / 255.0f; - glEnable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(r, g, b, a); - tessellator.startQuads(); - tessellator.vertex(startX, endY, 0.0); - tessellator.vertex(endX, endY, 0.0); - tessellator.vertex(endX, startY, 0.0); - tessellator.vertex(startX, startY, 0.0); + tessellator.color(0xFF, 0xFF, 0xFF); + tessellator.vertex(width / 2D - 120, (height - 90D) / 2 - 20, 0, 0, 0); + tessellator.vertex(width / 2D - 120, (height - 90D) / 2 + 20, 0, 0, 1); + tessellator.vertex(width / 2D + 120, (height - 90D) / 2 + 20, 0, 1, 1); + tessellator.vertex(width / 2D + 120, (height - 90D) / 2 - 20, 0, 1, 0); tessellator.draw(); - glEnable(GL_TEXTURE_2D); glDisable(GL_BLEND); } diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreenManager.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreenManager.java index 050c73880..d58365b38 100644 --- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreenManager.java +++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreenManager.java @@ -85,7 +85,7 @@ public static void open() { } public static boolean isReloadStarted() { - return reloadScreen != null && reloadScreen.isReloadStarted(); + return reloadScreen != null; } public static boolean isReloadComplete() { From 2114188102a4eb96f83e43f35fe2f7b3be895d74 Mon Sep 17 00:00:00 2001 From: calmilamsy Date: Thu, 11 Jul 2024 20:36:08 +0100 Subject: [PATCH 11/25] GRADLE LET THE PROJECT GET REPLACED BY A TRANSITIVE DEPENDENCY?! --- build.gradle.kts | 7 +++++-- gradle.properties | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 63535d4e2..beac3cc33 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -96,10 +96,13 @@ allprojects { } - modImplementation("net.glasslauncher.mods:GlassConfigAPI:${project.properties["gcapi_version"]}") - modLocalRuntime("net.glasslauncher:HowManyItems-Fabric-Unofficial:${project.properties["hmi_version"]}") { + implementation("me.carleslc:Simple-Yaml:1.8.4") + modImplementation("net.glasslauncher.mods:GlassConfigAPI:${project.properties["gcapi_version"]}") { isTransitive = false } +// modLocalRuntime("net.glasslauncher:HowManyItems-Fabric-Unofficial:${project.properties["hmi_version"]}") { +// isTransitive = false +// } // Optional bugfix mod for testing qol. Remove the // to enable. //modLocalRuntime "maven.modrinth:mojangfix:${project.properties["mojangfix_version"]}" } diff --git a/gradle.properties b/gradle.properties index f6bcd498e..db3201aa1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -33,7 +33,7 @@ fabric.loom.multiProjectOptimisation=true archives_base_name = StationAPI # Test properties - gcapi_version = 3.0.0-beta.1 + gcapi_version = 3.0.0-beta.2 hmi_version = 5.1.1 modmenu_version = 1.8.5-beta.8 mojangfix_version = 0.5.2 \ No newline at end of file From 1c126d0b97f0d2fbca787a681857916e203aff47 Mon Sep 17 00:00:00 2001 From: calmilamsy Date: Thu, 11 Jul 2024 20:36:27 +0100 Subject: [PATCH 12/25] Revert "Fuck you reloadscreen" This reverts commit ce4c7a789d3399fc14a5c14239e49d344629b451. --- .../api/client/resource/ReloadScreen.java | 362 +++++++++++++----- .../client/resource/ReloadScreenManager.java | 2 +- 2 files changed, 276 insertions(+), 88 deletions(-) diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java index 96ee466f2..20ccadc96 100644 --- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java +++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java @@ -1,22 +1,29 @@ package net.modificationstation.stationapi.api.client.resource; import com.google.common.primitives.Floats; +import com.google.common.primitives.Longs; import cyclops.control.Option; +import cyclops.function.Effect; +import cyclops.function.FluentFunctions; +import it.unimi.dsi.fastutil.doubles.Double2DoubleFunction; import it.unimi.dsi.fastutil.longs.Long2DoubleFunction; +import lombok.val; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.render.Tessellator; +import net.minecraft.util.math.MathHelper; import net.modificationstation.stationapi.api.resource.ResourceReload; import net.modificationstation.stationapi.api.util.math.ColorHelper; -import org.lwjgl.opengl.GL11; +import net.modificationstation.stationapi.config.LoadingScreenOption; +import net.modificationstation.stationapi.config.StationConfig; +import net.modificationstation.stationapi.impl.client.resource.ReloadScreenManagerImpl; -import java.awt.*; -import java.text.*; -import java.util.List; import java.util.Random; import java.util.concurrent.CompletionException; import java.util.function.*; +import static cyclops.function.FluentFunctions.expression; +import static java.util.Map.of; import static net.modificationstation.stationapi.api.StationAPI.LOGGER; import static net.modificationstation.stationapi.api.util.math.MathHelper.ceil; import static net.modificationstation.stationapi.api.util.math.MathHelper.lerp; @@ -24,15 +31,40 @@ @SuppressWarnings("UnstableApiUsage") class ReloadScreen extends Screen { - private static final int BACKGROUND_COLOR_DEFAULT_RED = 0x35; - private static final int BACKGROUND_COLOR_DEFAULT_GREEN = 0x86; - private static final int BACKGROUND_COLOR_DEFAULT_BLUE = 0xE7; - private static final int BACKGROUND_COLOR_EXCEPTION_RED = 0xFF; - private static final int BACKGROUND_COLOR_EXCEPTION_GREEN = 0x29; - private static final int BACKGROUND_COLOR_EXCEPTION_BLUE = 0x29; + private static long + MAX_FPS = 60, + BACKGROUND_START = 0, + BACKGROUND_FADE_IN = 1000, + STAGE_0_START = BACKGROUND_START + BACKGROUND_FADE_IN, + STAGE_0_FADE_IN = 2000, + GLOBAL_FADE_OUT = 1000, + RELOAD_START = STAGE_0_START + STAGE_0_FADE_IN, + EXCEPTION_TRANSFORM = 500; + private static final int + BACKGROUND_COLOR_DEFAULT_RED = 0x35, + BACKGROUND_COLOR_DEFAULT_GREEN = 0x86, + BACKGROUND_COLOR_DEFAULT_BLUE = 0xE7, + BACKGROUND_COLOR_EXCEPTION_RED = 0xFF, + BACKGROUND_COLOR_EXCEPTION_GREEN = 0x29, + BACKGROUND_COLOR_EXCEPTION_BLUE = 0x29; - private static final Object BACKGROUND_DEFAULT_DELTA_KEY = new Object(); - private static final Object BACKGROUND_EXCEPTION_DELTA_KEY = new Object(); + private static final Object + BACKGROUND_DEFAULT_DELTA_KEY = new Object(), + BACKGROUND_EXCEPTION_DELTA_KEY = new Object(), + STAGE_0_DEFAULT_DELTA_KEY = new Object(), + STAGE_0_EXCEPTION_DELTA_KEY = new Object(); + + private static final Double2DoubleFunction + SIN_90_DELTA = delta -> MathHelper.sin((float) (delta * Math.PI / 2)), + COS_90_DELTA = delta -> MathHelper.cos((float) (delta * Math.PI / 2)), + INVERSE_DELTA = delta -> 1 - delta; + private static final Long2DoubleFunction + BACKGROUND_FADE_IN_DELTA = time -> (double) Longs.constrainToRange(time - BACKGROUND_START, 0, BACKGROUND_FADE_IN) / BACKGROUND_FADE_IN, + STAGE_0_FADE_IN_DELTA = time -> (double) Longs.constrainToRange(time - STAGE_0_START, 0, STAGE_0_FADE_IN) / STAGE_0_FADE_IN; + private static final Function + GLOBAL_FADE_OUT_DELTA_FACTORY = fadeOutStartGetter -> INVERSE_DELTA.composeLong(time -> (double) Longs.constrainToRange(time - fadeOutStartGetter.getAsLong(), 0, GLOBAL_FADE_OUT) / GLOBAL_FADE_OUT), + BACKGROUND_EXCEPTION_FADE_IN_FACTORY = fadeInStartGetter -> time -> (double) Longs.constrainToRange(time - fadeInStartGetter.getAsLong(), 0, EXCEPTION_TRANSFORM) / EXCEPTION_TRANSFORM, + STAGE_0_EXCEPTION_TRANSFORM_FACTORY = transformStartGetter -> time -> (double) Longs.constrainToRange(time - transformStartGetter.getAsLong(), 0, EXCEPTION_TRANSFORM) / EXCEPTION_TRANSFORM; private static final String LOGO_TEMPLATE = "/assets/station-resource-loader-v0/textures/gui/stationapi_reload%s.png"; @@ -44,10 +76,19 @@ private static UnaryOperator when(BooleanSupplier condition private final Screen parent; private final Runnable done; private final Tessellator tessellator; + private boolean firstRenderTick = true; + private long initTimestamp; + private long currentTime; private float progress; + private final Effect + backgroundEmitter, + stage0Emitter; private boolean finished; + private long fadeOutStart; + private float scrollProgress; private final String logo; private boolean exceptionThrown; + private long exceptionStart; private Exception exception; ReloadScreen( @@ -67,87 +108,52 @@ private static UnaryOperator when(BooleanSupplier condition default -> ""; } ); - } + val globalFadeOutComposer = when(() -> finished, GLOBAL_FADE_OUT_DELTA_FACTORY.apply(() -> fadeOutStart)); + val deltaMap = of( + BACKGROUND_DEFAULT_DELTA_KEY, globalFadeOutComposer.apply(BACKGROUND_FADE_IN_DELTA).andThenDouble(SIN_90_DELTA), + BACKGROUND_EXCEPTION_DELTA_KEY, BACKGROUND_EXCEPTION_FADE_IN_FACTORY.apply(() -> exceptionStart).andThenDouble(COS_90_DELTA).andThenDouble(INVERSE_DELTA), + STAGE_0_DEFAULT_DELTA_KEY, globalFadeOutComposer.apply(STAGE_0_FADE_IN_DELTA).andThenDouble(SIN_90_DELTA), + STAGE_0_EXCEPTION_DELTA_KEY, STAGE_0_EXCEPTION_TRANSFORM_FACTORY.apply(() -> exceptionStart).andThenDouble(COS_90_DELTA) + ); - private static final NumberFormat NUMBER_FORMAT = NumberFormat.getNumberInstance(); + ToDoubleFunction deltaFunc = key -> deltaMap.get(key).applyAsDouble(currentTime); - static { - NUMBER_FORMAT.setMinimumFractionDigits(2); - NUMBER_FORMAT.setMaximumFractionDigits(2); - } + backgroundEmitter = FluentFunctions + .>expression(this::renderBackground) + .partiallyApply(deltaFunc)::get; - @Override - public void render(int mouseX, int mouseY, float delta) { - super.render(mouseX, mouseY, delta); - if (parent == null) renderEarly(); - else renderNormal(delta); - - Option reload; - progress = Floats.constrainToRange(progress * .95F + ((reload = ReloadScreenManager.getCurrentReload()).isPresent() ? reload.orElse(null).getProgress() : 0) * .05F, 0, 1); - if (Float.isNaN(progress)) progress = 0; - if (!exceptionThrown && !finished && ReloadScreenManager.isReloadComplete()) { - try { - ReloadScreenManager.getCurrentReload().peek(ResourceReload::throwException); - finished = true; - } catch (CompletionException e) { - exceptionThrown = true; - exception = e; - LOGGER.error("An exception occurred during resource loading", e); - } + stage0Emitter = + expression(this::renderProgressBar) + .before(this::renderLogo) + .partiallyApply(deltaFunc)::get; + if(StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.NO_ANIMATE)) { + MAX_FPS = + BACKGROUND_START = + BACKGROUND_FADE_IN = + STAGE_0_START = + STAGE_0_FADE_IN = + GLOBAL_FADE_OUT = + RELOAD_START = + EXCEPTION_TRANSFORM = 0; } - if (finished) { - ReloadScreenManager.onFinish(); - done.run(); + else { + MAX_FPS = 60; + BACKGROUND_START = 0; + BACKGROUND_FADE_IN = 1000; + STAGE_0_START = BACKGROUND_START + BACKGROUND_FADE_IN; + STAGE_0_FADE_IN = 2000; + GLOBAL_FADE_OUT = 1000; + RELOAD_START = STAGE_0_START + STAGE_0_FADE_IN; + EXCEPTION_TRANSFORM = 500; } } - private void renderEarly() { - GL11.glBindTexture(3553, minecraft.textureManager.getTextureId("/title/mojang.png")); - fill(0, 0, width, height, 0xFFFFFFFF); - drawMojangLogoQuad((width-256)/2, (height-256)/2); - GL11.glEnable(GL11.GL_BLEND); - renderText(Color.BLACK, false); - GL11.glDisable(GL11.GL_BLEND); - } - - /** - * See {@link net.minecraft.client.Minecraft#method_2109(int, int, int, int, int, int)} - */ - private void drawMojangLogoQuad(int i, int j) { - float f = 0.00390625f; - float f2 = 0.00390625f; - tessellator.startQuads(); - tessellator.vertex(i, j + 256, 0.0, 0, 256 * f2); - tessellator.vertex(i + 256, j + 256, 0.0, 256 * f, 256 * f2); - tessellator.vertex(i + 256, j, 0.0, 256 * f, 0); - tessellator.vertex(i, j, 0.0, 0, 0); - tessellator.draw(); - } - - private void renderNormal(float delta) { - parent.render(-1, -1, delta); - this.fillGradient(0, 0, this.width, this.height, -1072689136, -804253680); - - renderText(Color.WHITE, true); - } - - private void renderText(Color textColor, boolean shadow) { - if (exceptionThrown) textRenderer.draw("Oh noes! An error occurred, check your logs.", 0,0, textColor.getRGB(), shadow); - else textRenderer.draw("Loading resources...", 0, 0, textColor.getRGB(), shadow); - List locations = ReloadScreenManager.LOCATIONS; - String s = locations.isEmpty() ? "Doing the do": locations.get(locations.size() - 1); - textRenderer.draw(s, 5, height-10, textColor.getRGB(), shadow); - String text = NUMBER_FORMAT.format(progress*100f) + "%"; - int textRendererWidth = textRenderer.getWidth(text); - textRenderer.draw(text, width-textRendererWidth-5, height-10, textColor.getRGB(), shadow); - } - private void renderBackground(ToDoubleFunction deltaFunc) { - var delta = deltaFunc.applyAsDouble(BACKGROUND_DEFAULT_DELTA_KEY); + val delta = deltaFunc.applyAsDouble(BACKGROUND_DEFAULT_DELTA_KEY); final int color; if (exceptionThrown) { - var exceptionDelta = deltaFunc.applyAsDouble(BACKGROUND_EXCEPTION_DELTA_KEY); + val exceptionDelta = deltaFunc.applyAsDouble(BACKGROUND_EXCEPTION_DELTA_KEY); color = ColorHelper.Argb.getArgb( 0xFF, lerp(exceptionDelta, BACKGROUND_COLOR_DEFAULT_RED, BACKGROUND_COLOR_EXCEPTION_RED), @@ -177,17 +183,199 @@ private void renderBackground(ToDoubleFunction deltaFunc) { fill(0, 0, width, height, color); } + private void renderProgressBar(ToDoubleFunction deltaFunc) { + val delta = deltaFunc.applyAsDouble(STAGE_0_DEFAULT_DELTA_KEY); + if (delta == 0) return; + val color = (int) (delta * 0xFF) << 24 | 0xFFFFFF; + val v = (float) (10 - delta * 10); + val ev = exceptionThrown ? (float) (10 - deltaFunc.applyAsDouble(STAGE_0_EXCEPTION_DELTA_KEY) * 10) * 3 - 1 : 0; + drawHorizontalLine(40, width - 40 - 1, (int) (height - 90 + v * 5), color); + if (exceptionThrown) drawHorizontalLine(40, width - 40 - 1, (int) (height - 90 + v * 5 + ev), color); + drawHorizontalLine(40, width - 40 - 1, (int) (height - 50 + v), color); + drawHorizontalLine(40, width - 40 - 1, (int) (height - 40 - 1 + v), color); + drawVerticalLine(40, (int) (height - 40 + v), (int) (height - 90 + v * 5), color); + drawVerticalLine(width - 40 - 1, (int) (height - 40 + v), (int) (height - 90 + v * 5), color); + fill(40 + 3, (int) (height - 50 + 3 + v), ceil((width - (40 + 3) * 2) * progress + 40 + 3), (int) (height - 40 - 3 + v), color); + val xScale = (float) minecraft.displayWidth / width; + val yScale = (float) minecraft.displayHeight / height; + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + val locationsScissorsHeight = (int) ((40 - 1 - v * 4 + ev) * yScale); + if (locationsScissorsHeight > 0) { + val to = ceil(scrollProgress); + val scrollDelta = scrollProgress - to; + glEnable(GL_SCISSOR_TEST); + glScissor((int) ((40 + 3) * xScale), (int) ((50 - v) * yScale), (int) ((width - (40 + 3) * 2) * xScale), locationsScissorsHeight); + for (int i = 0; i < to; i++) { + val y = ceil(height - 88 + (10 * i) + (scrollDelta * 10) + v * 5 + ev); + if (y > height - 50 + v) break; + drawTextWithShadow(textRenderer, ReloadScreenManager.LOCATIONS.get(to - i - 1), 40 + 3, y, color); + } + glDisable(GL_SCISSOR_TEST); + } + val exceptionScissorsHeight = (int) ((-1 - v * 4 + ev) * yScale); + if (exceptionThrown && exceptionScissorsHeight > 0) { + glEnable(GL_SCISSOR_TEST); + glScissor((int) ((40 + 3) * xScale), (int) ((91 - v - ev) * yScale), (int) ((width - (40 + 3) * 2) * xScale), exceptionScissorsHeight); + val line = exception.getMessage(); + var curHeight = height - 88; + val lineWidth = textRenderer.getWidth(line); + if (lineWidth > width - (40 + 3) * 2) { + var begin = 0; + var lastSpace = -1; + for (int cur = 0, lineLength = line.length(); cur < lineLength; cur++) { + val isSpace = line.charAt(cur) == ' '; + val isEnd = cur + 1 == lineLength; + if (isSpace || isEnd) { + val newLine = isEnd ? line.substring(begin) : line.substring(begin, cur); + val newLineWidth = textRenderer.getWidth(newLine); + if (newLineWidth > width - (40 + 3) * 2) { + drawTextWithShadow(textRenderer, line.substring(begin, lastSpace), 40 + 3, curHeight, color); + curHeight += 10; + begin = lastSpace + 1; + } + if (isSpace) + lastSpace = cur; + if (isEnd) { + drawTextWithShadow(textRenderer, line.substring(begin), 40 + 3, curHeight, color); + curHeight += 10; + } + } + } + } else drawTextWithShadow(textRenderer, line, 40 + 3, curHeight, color); + glDisable(GL_SCISSOR_TEST); + } + drawTextWithShadow(textRenderer, "Minecraft: " + ( + ReloadScreenManagerImpl.isMinecraftDone ? + "Done" : + "Working..." + ), 40 + 3, (int) (height - 100 + v * 5), color); + val stationStatus = "StationAPI: " + ( + isReloadStarted() ? + ReloadScreenManager.isReloadComplete() ? + "Done" : + "Working..." : + "Idle" + ); + drawTextWithShadow(textRenderer, stationStatus, width - 40 - 3 - textRenderer.getWidth(stationStatus), (int) (height - 100 + v * 5), color); + glDisable(GL_BLEND); + } + private void renderLogo(ToDoubleFunction deltaFunc) { + val delta = deltaFunc.applyAsDouble(STAGE_0_DEFAULT_DELTA_KEY); + if (delta == 0) return; + val v = 10 - delta * 10; minecraft.textureManager.bindTexture(minecraft.textureManager.getTextureId(logo)); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); tessellator.startQuads(); - tessellator.color(0xFF, 0xFF, 0xFF); - tessellator.vertex(width / 2D - 120, (height - 90D) / 2 - 20, 0, 0, 0); - tessellator.vertex(width / 2D - 120, (height - 90D) / 2 + 20, 0, 0, 1); - tessellator.vertex(width / 2D + 120, (height - 90D) / 2 + 20, 0, 1, 1); - tessellator.vertex(width / 2D + 120, (height - 90D) / 2 - 20, 0, 1, 0); + tessellator.color(0xFF, 0xFF, 0xFF, (int) (0xFF * delta)); + tessellator.vertex(width / 2D - 120, (height - 90D) / 2 - 20 - v, 0, 0, 0); + tessellator.vertex(width / 2D - 120, (height - 90D) / 2 + 20 - v, 0, 0, 1); + tessellator.vertex(width / 2D + 120, (height - 90D) / 2 + 20 - v, 0, 1, 1); + tessellator.vertex(width / 2D + 120, (height - 90D) / 2 - 20 - v, 0, 1, 0); + tessellator.draw(); + glDisable(GL_BLEND); + } + + @Override + public void renderBackground() { + backgroundEmitter.run(); + } + + private long lastRender; + + @Override + public void render(int mouseX, int mouseY, float delta) { + if (firstRenderTick) { + firstRenderTick = false; + initTimestamp = System.currentTimeMillis(); + } + currentTime = System.currentTimeMillis() - initTimestamp; + val partial = currentTime - lastRender < (1000 / MAX_FPS); + if (partial) currentTime = lastRender; + else lastRender = currentTime; + val locationsSize = ReloadScreenManager.LOCATIONS.size(); + if (!exceptionThrown && !finished && !(scrollProgress + .1 < locationsSize) && !(progress + .1 < 1) && ReloadScreenManager.isReloadComplete()) { + try { + ReloadScreenManager.getCurrentReload().peek(ResourceReload::throwException); + finished = true; + fadeOutStart = currentTime; + } catch (CompletionException e) { + exceptionThrown = true; + exceptionStart = currentTime; + exception = e; + LOGGER.error("An exception occurred during resource loading", e); + } + } + if (!partial) { + Option reload; + progress = Floats.constrainToRange(progress * .95F + (isReloadStarted() && (reload = ReloadScreenManager.getCurrentReload()).isPresent() ? reload.orElse(null/*safe*/).getProgress() : 0) * .05F, 0, 1); + scrollProgress = Floats.constrainToRange(scrollProgress * .95F + locationsSize * .05F, 0, locationsSize); + } + if ((finished ? currentTime <= fadeOutStart + GLOBAL_FADE_OUT : currentTime < BACKGROUND_START + BACKGROUND_FADE_IN) && parent != null) + parent.render(mouseX, mouseY, delta); + renderBackground(); + super.render(mouseX, mouseY, delta); + stage0Emitter.run(); + if (finished && currentTime - fadeOutStart > GLOBAL_FADE_OUT) { + ReloadScreenManager.onFinish(); + done.run(); + } + } + + boolean isReloadStarted() { + return currentTime > RELOAD_START; + } + + @Override + protected void drawHorizontalLine(int startX, int endX, int y, int color) { + if (endX < startX) { + val n = startX; + startX = endX; + endX = n; + } + fill(startX, y, endX + 1, y + 1, color); + } + + @Override + protected void drawVerticalLine(int x, int startY, int endY, int color) { + if (endY < startY) { + val n = startY; + startY = endY; + endY = n; + } + fill(x, startY + 1, x + 1, endY, color); + } + + @Override + protected void fill(int startX, int startY, int endX, int endY, int color) { + int n; + if (startX < endX) { + n = startX; + startX = endX; + endX = n; + } + if (startY < endY) { + n = startY; + startY = endY; + endY = n; + } + val a = (float)(color >> 24 & 0xFF) / 255.0f; + val r = (float)(color >> 16 & 0xFF) / 255.0f; + val g = (float)(color >> 8 & 0xFF) / 255.0f; + val b = (float)(color & 0xFF) / 255.0f; + glEnable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(r, g, b, a); + tessellator.startQuads(); + tessellator.vertex(startX, endY, 0.0); + tessellator.vertex(endX, endY, 0.0); + tessellator.vertex(endX, startY, 0.0); + tessellator.vertex(startX, startY, 0.0); tessellator.draw(); + glEnable(GL_TEXTURE_2D); glDisable(GL_BLEND); } diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreenManager.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreenManager.java index d58365b38..050c73880 100644 --- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreenManager.java +++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreenManager.java @@ -85,7 +85,7 @@ public static void open() { } public static boolean isReloadStarted() { - return reloadScreen != null; + return reloadScreen != null && reloadScreen.isReloadStarted(); } public static boolean isReloadComplete() { From 50434b4ef6b2f03209748085b815e67616080f5b Mon Sep 17 00:00:00 2001 From: calmilamsy Date: Thu, 11 Jul 2024 20:41:59 +0100 Subject: [PATCH 13/25] Why does the bar go backwards --- .../api/client/resource/ReloadScreen.java | 68 ++++++++----------- 1 file changed, 30 insertions(+), 38 deletions(-) diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java index 20ccadc96..16e91fb20 100644 --- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java +++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java @@ -31,40 +31,35 @@ @SuppressWarnings("UnstableApiUsage") class ReloadScreen extends Screen { - private static long - MAX_FPS = 60, - BACKGROUND_START = 0, - BACKGROUND_FADE_IN = 1000, - STAGE_0_START = BACKGROUND_START + BACKGROUND_FADE_IN, - STAGE_0_FADE_IN = 2000, - GLOBAL_FADE_OUT = 1000, - RELOAD_START = STAGE_0_START + STAGE_0_FADE_IN, - EXCEPTION_TRANSFORM = 500; - private static final int - BACKGROUND_COLOR_DEFAULT_RED = 0x35, - BACKGROUND_COLOR_DEFAULT_GREEN = 0x86, - BACKGROUND_COLOR_DEFAULT_BLUE = 0xE7, - BACKGROUND_COLOR_EXCEPTION_RED = 0xFF, - BACKGROUND_COLOR_EXCEPTION_GREEN = 0x29, - BACKGROUND_COLOR_EXCEPTION_BLUE = 0x29; + private static final long + MAX_FPS = 60; + private static long BACKGROUND_START = 0; + private static long BACKGROUND_FADE_IN = 1000; + private static long STAGE_0_START = BACKGROUND_START + BACKGROUND_FADE_IN; + private static long STAGE_0_FADE_IN = 2000; + private static long GLOBAL_FADE_OUT = 1000; + private static long RELOAD_START = STAGE_0_START + STAGE_0_FADE_IN; + private static long EXCEPTION_TRANSFORM = 500; + private static final int BACKGROUND_COLOR_DEFAULT_RED = 0x35; + private static final int BACKGROUND_COLOR_DEFAULT_GREEN = 0x86; + private static final int BACKGROUND_COLOR_DEFAULT_BLUE = 0xE7; + private static final int BACKGROUND_COLOR_EXCEPTION_RED = 0xFF; + private static final int BACKGROUND_COLOR_EXCEPTION_GREEN = 0x29; + private static final int BACKGROUND_COLOR_EXCEPTION_BLUE = 0x29; - private static final Object - BACKGROUND_DEFAULT_DELTA_KEY = new Object(), - BACKGROUND_EXCEPTION_DELTA_KEY = new Object(), - STAGE_0_DEFAULT_DELTA_KEY = new Object(), - STAGE_0_EXCEPTION_DELTA_KEY = new Object(); + private static final Object BACKGROUND_DEFAULT_DELTA_KEY = new Object(); + private static final Object BACKGROUND_EXCEPTION_DELTA_KEY = new Object(); + private static final Object STAGE_0_DEFAULT_DELTA_KEY = new Object(); + private static final Object STAGE_0_EXCEPTION_DELTA_KEY = new Object(); - private static final Double2DoubleFunction - SIN_90_DELTA = delta -> MathHelper.sin((float) (delta * Math.PI / 2)), - COS_90_DELTA = delta -> MathHelper.cos((float) (delta * Math.PI / 2)), - INVERSE_DELTA = delta -> 1 - delta; - private static final Long2DoubleFunction - BACKGROUND_FADE_IN_DELTA = time -> (double) Longs.constrainToRange(time - BACKGROUND_START, 0, BACKGROUND_FADE_IN) / BACKGROUND_FADE_IN, - STAGE_0_FADE_IN_DELTA = time -> (double) Longs.constrainToRange(time - STAGE_0_START, 0, STAGE_0_FADE_IN) / STAGE_0_FADE_IN; - private static final Function - GLOBAL_FADE_OUT_DELTA_FACTORY = fadeOutStartGetter -> INVERSE_DELTA.composeLong(time -> (double) Longs.constrainToRange(time - fadeOutStartGetter.getAsLong(), 0, GLOBAL_FADE_OUT) / GLOBAL_FADE_OUT), - BACKGROUND_EXCEPTION_FADE_IN_FACTORY = fadeInStartGetter -> time -> (double) Longs.constrainToRange(time - fadeInStartGetter.getAsLong(), 0, EXCEPTION_TRANSFORM) / EXCEPTION_TRANSFORM, - STAGE_0_EXCEPTION_TRANSFORM_FACTORY = transformStartGetter -> time -> (double) Longs.constrainToRange(time - transformStartGetter.getAsLong(), 0, EXCEPTION_TRANSFORM) / EXCEPTION_TRANSFORM; + private static final Double2DoubleFunction SIN_90_DELTA = delta -> MathHelper.sin((float) (delta * Math.PI / 2)); + private static final Double2DoubleFunction COS_90_DELTA = delta -> MathHelper.cos((float) (delta * Math.PI / 2)); + private static final Double2DoubleFunction INVERSE_DELTA = delta -> 1 - delta; + private static final Long2DoubleFunction BACKGROUND_FADE_IN_DELTA = time -> (double) Longs.constrainToRange(time - BACKGROUND_START, 0, BACKGROUND_FADE_IN) / BACKGROUND_FADE_IN; + private static final Long2DoubleFunction STAGE_0_FADE_IN_DELTA = time -> (double) Longs.constrainToRange(time - STAGE_0_START, 0, STAGE_0_FADE_IN) / STAGE_0_FADE_IN; + private static final Function GLOBAL_FADE_OUT_DELTA_FACTORY = fadeOutStartGetter -> INVERSE_DELTA.composeLong(time -> (double) Longs.constrainToRange(time - fadeOutStartGetter.getAsLong(), 0, GLOBAL_FADE_OUT) / GLOBAL_FADE_OUT); + private static final Function BACKGROUND_EXCEPTION_FADE_IN_FACTORY = fadeInStartGetter -> time -> (double) Longs.constrainToRange(time - fadeInStartGetter.getAsLong(), 0, EXCEPTION_TRANSFORM) / EXCEPTION_TRANSFORM; + private static final Function STAGE_0_EXCEPTION_TRANSFORM_FACTORY = transformStartGetter -> time -> (double) Longs.constrainToRange(time - transformStartGetter.getAsLong(), 0, EXCEPTION_TRANSFORM) / EXCEPTION_TRANSFORM; private static final String LOGO_TEMPLATE = "/assets/station-resource-loader-v0/textures/gui/stationapi_reload%s.png"; @@ -80,9 +75,8 @@ private static UnaryOperator when(BooleanSupplier condition private long initTimestamp; private long currentTime; private float progress; - private final Effect - backgroundEmitter, - stage0Emitter; + private final Effect backgroundEmitter; + private final Effect stage0Emitter; private boolean finished; private long fadeOutStart; private float scrollProgress; @@ -128,17 +122,15 @@ private static UnaryOperator when(BooleanSupplier condition .before(this::renderLogo) .partiallyApply(deltaFunc)::get; if(StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.NO_ANIMATE)) { - MAX_FPS = BACKGROUND_START = BACKGROUND_FADE_IN = STAGE_0_START = STAGE_0_FADE_IN = GLOBAL_FADE_OUT = RELOAD_START = - EXCEPTION_TRANSFORM = 0; + EXCEPTION_TRANSFORM = 1; } else { - MAX_FPS = 60; BACKGROUND_START = 0; BACKGROUND_FADE_IN = 1000; STAGE_0_START = BACKGROUND_START + BACKGROUND_FADE_IN; From 546a38db3d5cf51dd0c9f1e3842dc7e6b56f2fe8 Mon Sep 17 00:00:00 2001 From: calmilamsy Date: Tue, 16 Jul 2024 19:06:12 +0100 Subject: [PATCH 14/25] Wip code or something --- .../container/CustomTooltipRendererImpl.java | 2 +- .../item/client/DrawContextAccessor.java | 2 +- .../api/client/resource/ReloadScreen.java | 52 ++++++++++++++++--- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/station-items-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/screen/container/CustomTooltipRendererImpl.java b/station-items-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/screen/container/CustomTooltipRendererImpl.java index dee1b5e8b..e338657aa 100644 --- a/station-items-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/screen/container/CustomTooltipRendererImpl.java +++ b/station-items-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/screen/container/CustomTooltipRendererImpl.java @@ -23,7 +23,7 @@ private static void renderCustomTooltips(TooltipRenderEvent event) { if (newTooltip != null) Arrays.stream(newTooltip).mapToInt(event.textManager::getWidth).max().ifPresent(tooltipWidth -> { int tooltipX = event.mouseX - event.containerX + 12; int tooltipY = event.mouseY - event.containerY - 12; - ((DrawContextAccessor) event.container).invokeFillGradient(tooltipX - 3, tooltipY - 3, tooltipX + tooltipWidth + 3, tooltipY + (8 * newTooltip.length) + (3 * newTooltip.length), -1073741824, -1073741824); + ((DrawContextAccessor) event.container).invokeFill(tooltipX - 3, tooltipY - 3, tooltipX + tooltipWidth + 3, tooltipY + (8 * newTooltip.length) + (3 * newTooltip.length), -1073741824); IntStream.range(0, newTooltip.length).forEach(currentTooltip -> event.textManager.drawWithShadow(newTooltip[currentTooltip], tooltipX, tooltipY + (8 * currentTooltip) + (3 * currentTooltip), -1)); }); event.cancel(); diff --git a/station-items-v0/src/main/java/net/modificationstation/stationapi/mixin/item/client/DrawContextAccessor.java b/station-items-v0/src/main/java/net/modificationstation/stationapi/mixin/item/client/DrawContextAccessor.java index b0c02dbf2..9d62e591f 100644 --- a/station-items-v0/src/main/java/net/modificationstation/stationapi/mixin/item/client/DrawContextAccessor.java +++ b/station-items-v0/src/main/java/net/modificationstation/stationapi/mixin/item/client/DrawContextAccessor.java @@ -7,5 +7,5 @@ @Mixin(DrawContext.class) public interface DrawContextAccessor { @Invoker - void invokeFillGradient(int x1, int y1, int x2, int y2, int startColour, int endColour); + void invokeFill(int x1, int y1, int x2, int y2, int color); } diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java index 16e91fb20..95df1a257 100644 --- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java +++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java @@ -61,8 +61,8 @@ class ReloadScreen extends Screen { private static final Function BACKGROUND_EXCEPTION_FADE_IN_FACTORY = fadeInStartGetter -> time -> (double) Longs.constrainToRange(time - fadeInStartGetter.getAsLong(), 0, EXCEPTION_TRANSFORM) / EXCEPTION_TRANSFORM; private static final Function STAGE_0_EXCEPTION_TRANSFORM_FACTORY = transformStartGetter -> time -> (double) Longs.constrainToRange(time - transformStartGetter.getAsLong(), 0, EXCEPTION_TRANSFORM) / EXCEPTION_TRANSFORM; - private static final String - LOGO_TEMPLATE = "/assets/station-resource-loader-v0/textures/gui/stationapi_reload%s.png"; + private static final String LOGO_TEMPLATE = "/assets/station-resource-loader-v0/textures/gui/stationapi_reload%s.png"; + private static final String LOGO_MOJANG = "/title/mojang.png"; private static UnaryOperator when(BooleanSupplier condition, Long2DoubleFunction ifTrue) { return ifFalse -> value -> (condition.getAsBoolean() ? ifTrue : ifFalse).applyAsDouble(value); @@ -84,6 +84,7 @@ private static UnaryOperator when(BooleanSupplier condition private boolean exceptionThrown; private long exceptionStart; private Exception exception; + private final String stapiLogo; ReloadScreen( Screen parent, @@ -95,7 +96,7 @@ private static UnaryOperator when(BooleanSupplier condition this.done = done; this.tessellator = tessellator; - logo = LOGO_TEMPLATE.formatted( + stapiLogo = LOGO_TEMPLATE.formatted( switch (new Random().nextInt(100)) { case 0 -> "_dimando"; case 1 -> "_old"; @@ -103,6 +104,15 @@ private static UnaryOperator when(BooleanSupplier condition } ); +// if(StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.FORGE) || StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.HIDE)) { +// logo = LOGO_MOJANG; +// } +// else { +// logo = stapiLogo; +// } + + logo = stapiLogo; + val globalFadeOutComposer = when(() -> finished, GLOBAL_FADE_OUT_DELTA_FACTORY.apply(() -> fadeOutStart)); val deltaMap = of( BACKGROUND_DEFAULT_DELTA_KEY, globalFadeOutComposer.apply(BACKGROUND_FADE_IN_DELTA).andThenDouble(SIN_90_DELTA), @@ -254,6 +264,34 @@ private void renderProgressBar(ToDoubleFunction deltaFunc) { } private void renderLogo(ToDoubleFunction deltaFunc) { + if (StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.FORGE)) { + renderStapiLogo(deltaFunc, width * 0.6f, height * 0.6f, 0.5f, 0.5f); + } + if (StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.HIDE)) { + renderMojangLogo(deltaFunc); + } + } + + private void renderMojangLogo(ToDoubleFunction deltaFunc) { + val delta = deltaFunc.applyAsDouble(STAGE_0_DEFAULT_DELTA_KEY); + if (delta == 0) return; + val v = 10 - delta * 10; + minecraft.textureManager.bindTexture(minecraft.textureManager.getTextureId(LOGO_MOJANG)); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + int vWidth = (width - 256) / 2; + double vHeight = (double) (height - 256) / 2 - v; + tessellator.startQuads(); + tessellator.color(0xFF, 0xFF, 0xFF, (int) (0xFF * delta)); + tessellator.vertex(vWidth, vHeight, 0, 0, 0); + tessellator.vertex(vWidth, vHeight, 0, 0, 1); + tessellator.vertex(vWidth, vHeight, 0, 1, 1); + tessellator.vertex(vWidth, vHeight, 0, 1, 0); + tessellator.draw(); + glDisable(GL_BLEND); + } + + private void renderStapiLogo(ToDoubleFunction deltaFunc, float x, float y, float heightMultiplyer, float widthMultiplier) { val delta = deltaFunc.applyAsDouble(STAGE_0_DEFAULT_DELTA_KEY); if (delta == 0) return; val v = 10 - delta * 10; @@ -261,11 +299,13 @@ private void renderLogo(ToDoubleFunction deltaFunc) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); tessellator.startQuads(); + tessellator.translate(x, y, 0); tessellator.color(0xFF, 0xFF, 0xFF, (int) (0xFF * delta)); tessellator.vertex(width / 2D - 120, (height - 90D) / 2 - 20 - v, 0, 0, 0); - tessellator.vertex(width / 2D - 120, (height - 90D) / 2 + 20 - v, 0, 0, 1); - tessellator.vertex(width / 2D + 120, (height - 90D) / 2 + 20 - v, 0, 1, 1); - tessellator.vertex(width / 2D + 120, (height - 90D) / 2 - 20 - v, 0, 1, 0); + tessellator.vertex(width / 2D - 120, ((height - 90D) / 2 + 20 - v) * heightMultiplyer, 0, 0, 1); + tessellator.vertex((width / 2D + 120) * widthMultiplier, ((height - 90D) / 2 + 20 - v) * heightMultiplyer, 0, 1, 1); + tessellator.vertex((width / 2D + 120) * widthMultiplier, (height - 90D) / 2 - 20 - v, 0, 1, 0); + tessellator.translate(-x, -y, 0); tessellator.draw(); glDisable(GL_BLEND); } From 6cb34608f4854375e1c39d8b99dfbdaa1c840aec Mon Sep 17 00:00:00 2001 From: calmilamsy Date: Thu, 18 Jul 2024 03:30:02 +0100 Subject: [PATCH 15/25] Latest boom --- build.gradle.kts | 6 ++---- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index beac3cc33..8caa0bc8f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,8 +5,8 @@ import net.modificationstation.stationapi.gradle.SubprojectHelpers.addDependency plugins { id("maven-publish") - id("fabric-loom") version "1.6.6" - id("babric-loom-extension") version "1.6.8" + id("fabric-loom") version "1.7.2" + id("babric-loom-extension") version "1.7.3" } // https://stackoverflow.com/a/40101046 - Even with kotlin, gradle can't get it's shit together. @@ -112,8 +112,6 @@ allprojects { mixin { useLegacyMixinAp.set(true) } - customMinecraftManifest.set("https://babric.github.io/manifest-polyfill/${project.properties["minecraft_version"]}.json") - intermediaryUrl.set("https://maven.glass-launcher.net/babric/babric/intermediary/%1\$s/intermediary-%1\$s-v2.jar") } sourceSets { diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 48c0a02ca..0d1842103 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From 1db84abe3171a795d97b1c668f91847742e7a6be Mon Sep 17 00:00:00 2001 From: calmilamsy Date: Fri, 16 Aug 2024 18:18:10 +0100 Subject: [PATCH 16/25] Yeet deprecated code --- .../screen/container/TooltipRenderEvent.java | 7 ---- .../stationapi/api/recipe/StationRecipe.java | 18 ---------- .../impl/recipe/StationShapedRecipe.java | 27 +-------------- .../impl/recipe/StationShapelessRecipe.java | 24 ++----------- .../mixin/recipe/CraftingRecipeMixin.java | 19 ----------- .../mixin/recipe/ShapedRecipeMixin.java | 34 ------------------- .../mixin/recipe/ShapelessRecipeMixin.java | 27 --------------- .../resources/station-recipes-v0.mixins.json | 3 -- 8 files changed, 3 insertions(+), 156 deletions(-) delete mode 100644 station-recipes-v0/src/main/java/net/modificationstation/stationapi/api/recipe/StationRecipe.java delete mode 100644 station-recipes-v0/src/main/java/net/modificationstation/stationapi/mixin/recipe/CraftingRecipeMixin.java delete mode 100644 station-recipes-v0/src/main/java/net/modificationstation/stationapi/mixin/recipe/ShapedRecipeMixin.java delete mode 100644 station-recipes-v0/src/main/java/net/modificationstation/stationapi/mixin/recipe/ShapelessRecipeMixin.java diff --git a/station-items-v0/src/main/java/net/modificationstation/stationapi/api/client/event/gui/screen/container/TooltipRenderEvent.java b/station-items-v0/src/main/java/net/modificationstation/stationapi/api/client/event/gui/screen/container/TooltipRenderEvent.java index 910373f32..a52aba416 100644 --- a/station-items-v0/src/main/java/net/modificationstation/stationapi/api/client/event/gui/screen/container/TooltipRenderEvent.java +++ b/station-items-v0/src/main/java/net/modificationstation/stationapi/api/client/event/gui/screen/container/TooltipRenderEvent.java @@ -21,13 +21,6 @@ public class TooltipRenderEvent extends ItemStackEvent { public final HandledScreen container; public final TextRenderer textManager; public final PlayerInventory inventory; - /** - * These will be removed in a3, due to the fact the container var already exists. - */ - @Deprecated(forRemoval = true) - public final int - containerX, - containerY; public final int mouseX, mouseY; diff --git a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/api/recipe/StationRecipe.java b/station-recipes-v0/src/main/java/net/modificationstation/stationapi/api/recipe/StationRecipe.java deleted file mode 100644 index 047a084fb..000000000 --- a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/api/recipe/StationRecipe.java +++ /dev/null @@ -1,18 +0,0 @@ -package net.modificationstation.stationapi.api.recipe; - -import net.minecraft.item.ItemStack; - -/** - * This entire interface is slated for removal in alpha 3. - * Stop using it, it's shit and was made specifically for HMI, for all the wrong reasons. - * - calm - */ -@Deprecated(forRemoval = true) -public interface StationRecipe { - - @Deprecated(forRemoval = true) - ItemStack[] getIngredients(); - - @Deprecated(forRemoval = true) - ItemStack[] getOutputs(); -} diff --git a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/impl/recipe/StationShapedRecipe.java b/station-recipes-v0/src/main/java/net/modificationstation/stationapi/impl/recipe/StationShapedRecipe.java index d2d63f841..2afd4cdb9 100644 --- a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/impl/recipe/StationShapedRecipe.java +++ b/station-recipes-v0/src/main/java/net/modificationstation/stationapi/impl/recipe/StationShapedRecipe.java @@ -5,17 +5,11 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.recipe.CraftingRecipe; -import net.modificationstation.stationapi.api.recipe.StationRecipe; -import net.modificationstation.stationapi.api.registry.ItemRegistry; import net.modificationstation.stationapi.api.tag.TagKey; import java.util.*; -import java.util.function.Function; - -public class StationShapedRecipe implements CraftingRecipe, StationRecipe { - - private static final Random RANDOM = new Random(); +public class StationShapedRecipe implements CraftingRecipe { public final int width, height; private final Either, ItemStack>[] grid; public final ItemStack output; @@ -84,25 +78,6 @@ public ItemStack getOutput() { return output; } - @Override - public ItemStack[] getIngredients() { - ItemStack[] stacks = new ItemStack[9]; - for (int h = 0; h < height; h++) - for (int w = 0; w < width; w++) { - int localId = (h * width) + w; - Either, ItemStack> ingredient = grid[localId]; - if (ingredient == null) continue; - int id = (h * 3) + w; - stacks[id] = ingredient.map(tag -> new ItemStack(ItemRegistry.INSTANCE.getEntryList(tag).orElseThrow(() -> new RuntimeException("Identifier ingredient \"" + tag.id() + "\" has no entry in the tag registry!")).getRandom(RANDOM).orElseThrow().value()), Function.identity()); - } - return stacks; - } - - @Override - public ItemStack[] getOutputs() { - return new ItemStack[] { output }; - } - public Either, ItemStack>[] getGrid() { //noinspection unchecked return (Either, ItemStack>[]) Arrays.stream(grid).map(entry -> entry == null ? null : entry.mapRight(ItemStack::copy)).toArray(Either[]::new); diff --git a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/impl/recipe/StationShapelessRecipe.java b/station-recipes-v0/src/main/java/net/modificationstation/stationapi/impl/recipe/StationShapelessRecipe.java index b82e2eb6e..b095b311e 100644 --- a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/impl/recipe/StationShapelessRecipe.java +++ b/station-recipes-v0/src/main/java/net/modificationstation/stationapi/impl/recipe/StationShapelessRecipe.java @@ -5,14 +5,11 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.recipe.CraftingRecipe; -import net.modificationstation.stationapi.api.recipe.StationRecipe; -import net.modificationstation.stationapi.api.registry.ItemRegistry; import net.modificationstation.stationapi.api.tag.TagKey; import java.util.*; -import java.util.function.Function; -public class StationShapelessRecipe implements CraftingRecipe, StationRecipe { +public class StationShapelessRecipe implements CraftingRecipe { private static final Random RANDOM = new Random(); @@ -78,24 +75,7 @@ public ItemStack getOutput() { return output; } - @Override - public ItemStack[] getIngredients() { - ItemStack[] inputs = new ItemStack[ingredients.length]; - for (int i = 0, ingredientsLength = ingredients.length; i < ingredientsLength; i++) - inputs[i] = ingredients[i].map(tag -> new ItemStack(ItemRegistry.INSTANCE.getEntryList(tag).orElseThrow(() -> new RuntimeException("Identifier ingredient \"" + tag.id() + "\" has no entry in the tag registry!")).getRandom(RANDOM).orElseThrow().value()), Function.identity()); - return inputs; - } - - @Override - public ItemStack[] getOutputs() { - return new ItemStack[] { output }; - } - - /** - * To be renamed to getIngredients in a3, use with caution. - */ - @Deprecated - public Either, ItemStack>[] getInputs() { + public Either, ItemStack>[] getIngredients() { //noinspection unchecked return (Either, ItemStack>[]) Arrays.stream(ingredients).map(entry -> entry == null ? null : entry.mapRight(ItemStack::copy)).toArray(Either[]::new); } diff --git a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/mixin/recipe/CraftingRecipeMixin.java b/station-recipes-v0/src/main/java/net/modificationstation/stationapi/mixin/recipe/CraftingRecipeMixin.java deleted file mode 100644 index ccd3ac845..000000000 --- a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/mixin/recipe/CraftingRecipeMixin.java +++ /dev/null @@ -1,19 +0,0 @@ -package net.modificationstation.stationapi.mixin.recipe; - -import net.minecraft.item.ItemStack; -import net.minecraft.recipe.CraftingRecipe; -import net.modificationstation.stationapi.api.recipe.StationRecipe; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(CraftingRecipe.class) -public interface CraftingRecipeMixin extends StationRecipe { - @Override - default ItemStack[] getIngredients() { - throw new UnsupportedOperationException("Your custom recipe registry needs to implement the methods found in \"net.modificationstation.stationapi.api.recipe.StationRecipe\"!"); - } - - @Override - default ItemStack[] getOutputs() { - throw new UnsupportedOperationException("Your custom recipe registry needs to implement the methods found in \"net.modificationstation.stationapi.api.recipe.StationRecipe\"!"); - } -} diff --git a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/mixin/recipe/ShapedRecipeMixin.java b/station-recipes-v0/src/main/java/net/modificationstation/stationapi/mixin/recipe/ShapedRecipeMixin.java deleted file mode 100644 index 9f9ed3f84..000000000 --- a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/mixin/recipe/ShapedRecipeMixin.java +++ /dev/null @@ -1,34 +0,0 @@ -package net.modificationstation.stationapi.mixin.recipe; - -import net.minecraft.ShapedRecipe; -import net.minecraft.item.ItemStack; -import net.modificationstation.stationapi.api.recipe.StationRecipe; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -@Mixin(ShapedRecipe.class) -class ShapedRecipeMixin implements StationRecipe { - @Shadow private int width; - @Shadow private int height; - @Shadow private ItemStack output; - - @Shadow private ItemStack[] input; - - @Override - public ItemStack[] getIngredients() { - ItemStack[] stacks = new ItemStack[9]; - for (int h = 0; h < height; h++) { - for (int w = 0; w < width; w++) { - int localId = (h * width) + w; - int id = (h * 3) + w; - stacks[id] = input[localId]; - } - } - return stacks; - } - - @Override - public ItemStack[] getOutputs() { - return new ItemStack[] { output }; - } -} diff --git a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/mixin/recipe/ShapelessRecipeMixin.java b/station-recipes-v0/src/main/java/net/modificationstation/stationapi/mixin/recipe/ShapelessRecipeMixin.java deleted file mode 100644 index 2270e4279..000000000 --- a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/mixin/recipe/ShapelessRecipeMixin.java +++ /dev/null @@ -1,27 +0,0 @@ -package net.modificationstation.stationapi.mixin.recipe; - -import net.minecraft.item.ItemStack; -import net.minecraft.recipe.ShapelessRecipe; -import net.modificationstation.stationapi.api.recipe.StationRecipe; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import java.util.List; - -@Mixin(ShapelessRecipe.class) -class ShapelessRecipeMixin implements StationRecipe { - @Shadow @Final private List input; - - @Shadow @Final private ItemStack output; - - @Override - public ItemStack[] getIngredients() { - return input.toArray(ItemStack[]::new); - } - - @Override - public ItemStack[] getOutputs() { - return new ItemStack[] { output }; - } -} diff --git a/station-recipes-v0/src/main/resources/station-recipes-v0.mixins.json b/station-recipes-v0/src/main/resources/station-recipes-v0.mixins.json index ff2373bb4..cb789d3bc 100644 --- a/station-recipes-v0/src/main/resources/station-recipes-v0.mixins.json +++ b/station-recipes-v0/src/main/resources/station-recipes-v0.mixins.json @@ -5,12 +5,9 @@ "compatibilityLevel": "JAVA_17", "mixins": [ "CraftingRecipeManagerMixin", - "CraftingRecipeMixin", "CraftingResultMixin", "FurnaceBlockEntityMixin", "RecipeComparatorMixin", - "ShapedRecipeMixin", - "ShapelessRecipeMixin", "SmeltingRecipeManagerAccessor", "SmeltingRecipeManagerMixin", "StatsMixin" From bf4e97e11263f53cc22cec5ea55c30fd96503cda Mon Sep 17 00:00:00 2001 From: mineLdiver Date: Fri, 6 Sep 2024 21:05:51 +0500 Subject: [PATCH 17/25] *actually* remove deprecated stuff --- .../container/CustomTooltipRendererImpl.java | 12 ++++++++---- .../mixin/item/client/ContainerScreenMixin.java | 1 - .../mixin/item/client/HandledScreenAccessor.java | 14 ++++++++++++++ .../main/resources/station-items-v0.mixins.json | 1 + 4 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 station-items-v0/src/main/java/net/modificationstation/stationapi/mixin/item/client/HandledScreenAccessor.java diff --git a/station-items-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/screen/container/CustomTooltipRendererImpl.java b/station-items-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/screen/container/CustomTooltipRendererImpl.java index edfe77658..ac3f3173b 100644 --- a/station-items-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/screen/container/CustomTooltipRendererImpl.java +++ b/station-items-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/screen/container/CustomTooltipRendererImpl.java @@ -1,19 +1,23 @@ package net.modificationstation.stationapi.impl.client.gui.screen.container; import net.mine_diver.unsafeevents.listener.EventListener; +import net.minecraft.client.gui.DrawContext; import net.modificationstation.stationapi.api.StationAPI; import net.modificationstation.stationapi.api.client.TooltipHelper; import net.modificationstation.stationapi.api.client.event.gui.screen.container.TooltipRenderEvent; import net.modificationstation.stationapi.api.mod.entrypoint.Entrypoint; import net.modificationstation.stationapi.api.mod.entrypoint.EventBusPolicy; import net.modificationstation.stationapi.mixin.item.client.DrawContextAccessor; +import net.modificationstation.stationapi.mixin.item.client.HandledScreenAccessor; -import java.util.*; +import java.util.ArrayList; import java.util.stream.IntStream; @Entrypoint(eventBus = @EventBusPolicy(registerInstance = false)) @EventListener(phase = StationAPI.INTERNAL_PHASE) public final class CustomTooltipRendererImpl { + private static final DrawContext CONTEXT = new DrawContext(); + @EventListener private static void renderCustomTooltips(TooltipRenderEvent event) { if(event.isCanceled()) { @@ -24,9 +28,9 @@ private static void renderCustomTooltips(TooltipRenderEvent event) { if (!newTooltip.isEmpty()) { newTooltip.stream().mapToInt(event.textManager::getWidth).max().ifPresent(tooltipWidth -> { - int tooltipX = event.mouseX - event.containerX + 12; - int tooltipY = event.mouseY - event.containerY - 12; - ((DrawContextAccessor) event.container).invokeFillGradient(tooltipX - 3, tooltipY - 3, tooltipX + tooltipWidth + 3, tooltipY + (8 * newTooltip.size()) + (3 * newTooltip.size()), -1073741824, -1073741824); + int tooltipX = event.mouseX - (event.container == null ? 0 : ((event.container.width - ((HandledScreenAccessor) event.container).stationapi_getBackgroundWidth()) / 2)) + 12; + int tooltipY = event.mouseY - (event.container == null ? 0 : ((event.container.height - ((HandledScreenAccessor) event.container).stationapi_getBackgroundHeight()) / 2)) - 12; + ((DrawContextAccessor) CONTEXT).invokeFillGradient(tooltipX - 3, tooltipY - 3, tooltipX + tooltipWidth + 3, tooltipY + (8 * newTooltip.size()) + (3 * newTooltip.size()), -1073741824, -1073741824); IntStream.range(0, newTooltip.size()).forEach(currentTooltip -> event.textManager.drawWithShadow(newTooltip.get(currentTooltip), tooltipX, tooltipY + (8 * currentTooltip) + (3 * currentTooltip), -1)); }); event.cancel(); diff --git a/station-items-v0/src/main/java/net/modificationstation/stationapi/mixin/item/client/ContainerScreenMixin.java b/station-items-v0/src/main/java/net/modificationstation/stationapi/mixin/item/client/ContainerScreenMixin.java index 1f2fc98e5..d69cf53ef 100644 --- a/station-items-v0/src/main/java/net/modificationstation/stationapi/mixin/item/client/ContainerScreenMixin.java +++ b/station-items-v0/src/main/java/net/modificationstation/stationapi/mixin/item/client/ContainerScreenMixin.java @@ -36,7 +36,6 @@ private void stationapi_renderTooltip(int mouseX, int mouseY, float delta, Callb .container((HandledScreen) (Object) this) .textManager(this.textRenderer) .inventory(inventory) - .containerX(containerX).containerY(containerY) .mouseX(mouseX).mouseY(mouseY) .delta(delta) .originalTooltip(originalTooltip) diff --git a/station-items-v0/src/main/java/net/modificationstation/stationapi/mixin/item/client/HandledScreenAccessor.java b/station-items-v0/src/main/java/net/modificationstation/stationapi/mixin/item/client/HandledScreenAccessor.java new file mode 100644 index 000000000..495231844 --- /dev/null +++ b/station-items-v0/src/main/java/net/modificationstation/stationapi/mixin/item/client/HandledScreenAccessor.java @@ -0,0 +1,14 @@ +package net.modificationstation.stationapi.mixin.item.client; + +import net.minecraft.client.gui.screen.ingame.HandledScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(HandledScreen.class) +public interface HandledScreenAccessor { + @Accessor("backgroundWidth") + int stationapi_getBackgroundWidth(); + + @Accessor("backgroundHeight") + int stationapi_getBackgroundHeight(); +} diff --git a/station-items-v0/src/main/resources/station-items-v0.mixins.json b/station-items-v0/src/main/resources/station-items-v0.mixins.json index 77cd0e61a..2fd54f374 100644 --- a/station-items-v0/src/main/resources/station-items-v0.mixins.json +++ b/station-items-v0/src/main/resources/station-items-v0.mixins.json @@ -30,6 +30,7 @@ "client.ContainerScreenMixin", "client.DrawContextAccessor", "client.GameRendererMixin", + "client.HandledScreenAccessor", "client.InteractionManagerMixin", "client.ItemRendererMixin", "client.MultiplayerInteractionManagerMixin", From c20f1264596bf7a12f1d198e28a06aa379fbb425 Mon Sep 17 00:00:00 2001 From: calmilamsy Date: Wed, 11 Sep 2024 15:36:56 +0100 Subject: [PATCH 18/25] Update to use an actually good inveditor --- build.gradle.kts | 8 +++++--- gradle.properties | 7 +++---- .../stationapi/config/FactoryProvider.java | 12 ++++++------ .../stationapi/config/StationConfig.java | 2 +- .../stationapi/config/StationConfigData.java | 2 +- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 8caa0bc8f..a17202bed 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -97,12 +97,14 @@ allprojects { implementation("me.carleslc:Simple-Yaml:1.8.4") + implementation("net.glasslauncher.mods:glass-networking:1.0.2") modImplementation("net.glasslauncher.mods:GlassConfigAPI:${project.properties["gcapi_version"]}") { isTransitive = false } -// modLocalRuntime("net.glasslauncher:HowManyItems-Fabric-Unofficial:${project.properties["hmi_version"]}") { -// isTransitive = false -// } + // Requires gcapi + modLocalRuntime("net.glasslauncher.mods:AlwaysMoreItems:${project.properties["ami_version"]}") { + isTransitive = false + } // Optional bugfix mod for testing qol. Remove the // to enable. //modLocalRuntime "maven.modrinth:mojangfix:${project.properties["mojangfix_version"]}" } diff --git a/gradle.properties b/gradle.properties index db3201aa1..db1ce15fa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -33,7 +33,6 @@ fabric.loom.multiProjectOptimisation=true archives_base_name = StationAPI # Test properties - gcapi_version = 3.0.0-beta.2 - hmi_version = 5.1.1 - modmenu_version = 1.8.5-beta.8 - mojangfix_version = 0.5.2 \ No newline at end of file + gcapi_version = 3.0.0 + ami_version = 1.0.2 + modmenu_version = 1.8.5-beta.9 \ No newline at end of file diff --git a/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/FactoryProvider.java b/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/FactoryProvider.java index 9df4eee87..cdd29c886 100644 --- a/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/FactoryProvider.java +++ b/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/FactoryProvider.java @@ -1,12 +1,12 @@ package net.modificationstation.stationapi.config; import com.google.common.collect.ImmutableMap; -import net.glasslauncher.mods.gcapi.api.ConfigEntry; -import net.glasslauncher.mods.gcapi.api.ConfigFactoryProvider; -import net.glasslauncher.mods.gcapi.impl.factory.DefaultFactoryProvider; -import net.glasslauncher.mods.gcapi.impl.object.ConfigEntryHandler; -import net.glasslauncher.mods.gcapi.impl.object.entry.EnumConfigEntryHandler; -import uk.co.benjiweber.expressions.function.SeptFunction; +import net.glasslauncher.mods.gcapi3.api.ConfigEntry; +import net.glasslauncher.mods.gcapi3.api.ConfigFactoryProvider; +import net.glasslauncher.mods.gcapi3.impl.SeptFunction; +import net.glasslauncher.mods.gcapi3.impl.factory.DefaultFactoryProvider; +import net.glasslauncher.mods.gcapi3.impl.object.ConfigEntryHandler; +import net.glasslauncher.mods.gcapi3.impl.object.entry.EnumConfigEntryHandler; import java.lang.reflect.*; import java.util.function.*; diff --git a/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfig.java b/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfig.java index 7f60edbd6..47c4e0acf 100644 --- a/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfig.java +++ b/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfig.java @@ -1,6 +1,6 @@ package net.modificationstation.stationapi.config; -import net.glasslauncher.mods.gcapi.api.ConfigRoot; +import net.glasslauncher.mods.gcapi3.api.ConfigRoot; public class StationConfig { diff --git a/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfigData.java b/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfigData.java index 648662267..b61e99b0a 100644 --- a/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfigData.java +++ b/station-api-configuration/src/main/java/net/modificationstation/stationapi/config/StationConfigData.java @@ -1,6 +1,6 @@ package net.modificationstation.stationapi.config; -import net.glasslauncher.mods.gcapi.api.ConfigEntry; +import net.glasslauncher.mods.gcapi3.api.ConfigEntry; public class StationConfigData { From a8abb7b1b061fd71053ac5fc3aecf9b5bce5723c Mon Sep 17 00:00:00 2001 From: calmilamsy Date: Wed, 11 Sep 2024 15:37:22 +0100 Subject: [PATCH 19/25] Well, the bar no longer goes backwards, but the stapi logo is now inverted lmao --- .../stationapi/api/client/resource/ReloadScreen.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java index 95df1a257..eaafca4f1 100644 --- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java +++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java @@ -138,7 +138,7 @@ private static UnaryOperator when(BooleanSupplier condition STAGE_0_FADE_IN = GLOBAL_FADE_OUT = RELOAD_START = - EXCEPTION_TRANSFORM = 1; + EXCEPTION_TRANSFORM = 0; } else { BACKGROUND_START = 0; From 6b2d36ed3fe90a180ea5b1d3c2caecb02dd080bc Mon Sep 17 00:00:00 2001 From: calmilamsy Date: Thu, 12 Sep 2024 14:36:41 +0100 Subject: [PATCH 20/25] Fix launching --- .gitignore | 1 + run/config/fabric_loader_dependencies.json | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 run/config/fabric_loader_dependencies.json diff --git a/.gitignore b/.gitignore index 550b373cd..27f0d50d8 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ bin/ # fabric run/ +!/run diff --git a/run/config/fabric_loader_dependencies.json b/run/config/fabric_loader_dependencies.json new file mode 100644 index 000000000..80c91c3df --- /dev/null +++ b/run/config/fabric_loader_dependencies.json @@ -0,0 +1,10 @@ +{ + "version": 1, + "overrides": { + "alwaysmoreitems": { + "-depends": { + "stationapi": "IGNORED" + } + } + } +} \ No newline at end of file From 24bb2fc2ff77487433a3a8f6350033c94911c93a Mon Sep 17 00:00:00 2001 From: calmilamsy Date: Thu, 12 Sep 2024 14:49:55 +0100 Subject: [PATCH 21/25] Update CustomTooltipRendererImpl.java --- .../client/gui/screen/container/CustomTooltipRendererImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/station-items-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/screen/container/CustomTooltipRendererImpl.java b/station-items-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/screen/container/CustomTooltipRendererImpl.java index ac3f3173b..6fe2870bd 100644 --- a/station-items-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/screen/container/CustomTooltipRendererImpl.java +++ b/station-items-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/screen/container/CustomTooltipRendererImpl.java @@ -30,7 +30,7 @@ private static void renderCustomTooltips(TooltipRenderEvent event) { newTooltip.stream().mapToInt(event.textManager::getWidth).max().ifPresent(tooltipWidth -> { int tooltipX = event.mouseX - (event.container == null ? 0 : ((event.container.width - ((HandledScreenAccessor) event.container).stationapi_getBackgroundWidth()) / 2)) + 12; int tooltipY = event.mouseY - (event.container == null ? 0 : ((event.container.height - ((HandledScreenAccessor) event.container).stationapi_getBackgroundHeight()) / 2)) - 12; - ((DrawContextAccessor) CONTEXT).invokeFillGradient(tooltipX - 3, tooltipY - 3, tooltipX + tooltipWidth + 3, tooltipY + (8 * newTooltip.size()) + (3 * newTooltip.size()), -1073741824, -1073741824); + ((DrawContextAccessor) CONTEXT).invokeFill(tooltipX - 3, tooltipY - 3, tooltipX + tooltipWidth + 3, tooltipY + (8 * newTooltip.size()) + (3 * newTooltip.size()), -1073741824); IntStream.range(0, newTooltip.size()).forEach(currentTooltip -> event.textManager.drawWithShadow(newTooltip.get(currentTooltip), tooltipX, tooltipY + (8 * currentTooltip) + (3 * currentTooltip), -1)); }); event.cancel(); From 631122cd02861b10d1ecd186e277f535dc237c81 Mon Sep 17 00:00:00 2001 From: calmilamsy Date: Thu, 12 Sep 2024 14:53:11 +0100 Subject: [PATCH 22/25] Goddammit I did it again --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index cff4d0373..e16a4e32c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -96,7 +96,7 @@ allprojects { implementation("me.carleslc:Simple-Yaml:1.8.4") - implementation("net.glasslauncher.mods:glass-networking:1.0.2") + modImplementation("net.glasslauncher.mods:glass-networking:1.0.2") modImplementation("net.glasslauncher.mods:GlassConfigAPI:${project.properties["gcapi_version"]}") { isTransitive = false } From 35db488f4c4aee57119ade480cd380bcd4cebc2c Mon Sep 17 00:00:00 2001 From: calmilamsy Date: Thu, 12 Sep 2024 15:17:58 +0100 Subject: [PATCH 23/25] AMI will have to wait until a3 hits main --- build.gradle.kts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index e16a4e32c..31f3751bc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -101,9 +101,9 @@ allprojects { isTransitive = false } // Requires gcapi - modLocalRuntime("net.glasslauncher.mods:AlwaysMoreItems:${project.properties["ami_version"]}") { - isTransitive = false - } +// modLocalRuntime("net.glasslauncher.mods:AlwaysMoreItems:${project.properties["ami_version"]}") { +// isTransitive = false +// } // Optional bugfix mod for testing qol. Remove the // to enable. //modLocalRuntime "maven.modrinth:mojangfix:${project.properties["mojangfix_version"]}" } From 8754750ddbb257c897f328249fc10552e0ea5d59 Mon Sep 17 00:00:00 2001 From: calmilamsy Date: Thu, 12 Sep 2024 16:44:35 +0100 Subject: [PATCH 24/25] Fix --- station-api-configuration/src/main/resources/fabric.mod.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/station-api-configuration/src/main/resources/fabric.mod.json b/station-api-configuration/src/main/resources/fabric.mod.json index dde39c648..8cf4e1211 100644 --- a/station-api-configuration/src/main/resources/fabric.mod.json +++ b/station-api-configuration/src/main/resources/fabric.mod.json @@ -19,10 +19,10 @@ "environment": "*", "entrypoints": { - "gcapi": [ + "gcapi3": [ "net.modificationstation.stationapi.config.StationConfig" ], - "gcapi:factory_provider": [ + "gcapi3:factory_provider": [ "net.modificationstation.stationapi.config.FactoryProvider" ] }, From 163ff3d44f92bead4851105296fede153a3b75e4 Mon Sep 17 00:00:00 2001 From: calmilamsy Date: Thu, 12 Sep 2024 18:33:38 +0100 Subject: [PATCH 25/25] Stapi logo rendering is broken, but somehow forge one works, what the fuck? --- .../api/client/resource/ReloadScreen.java | 167 ++++++++++++------ 1 file changed, 109 insertions(+), 58 deletions(-) diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java index eaafca4f1..267fba6fc 100644 --- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java +++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java @@ -104,15 +104,31 @@ private static UnaryOperator when(BooleanSupplier condition } ); -// if(StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.FORGE) || StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.HIDE)) { -// logo = LOGO_MOJANG; -// } -// else { -// logo = stapiLogo; -// } - logo = stapiLogo; + if( + StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.NO_ANIMATE) || + StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.HIDE) || + StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.FORGE) + ) { + BACKGROUND_START = + BACKGROUND_FADE_IN = + STAGE_0_START = + STAGE_0_FADE_IN = + GLOBAL_FADE_OUT = + RELOAD_START = + EXCEPTION_TRANSFORM = 1; + } + else { + BACKGROUND_START = 0; + BACKGROUND_FADE_IN = 1000; + STAGE_0_START = BACKGROUND_START + BACKGROUND_FADE_IN; + STAGE_0_FADE_IN = 2000; + GLOBAL_FADE_OUT = 1000; + RELOAD_START = STAGE_0_START + STAGE_0_FADE_IN; + EXCEPTION_TRANSFORM = 500; + } + val globalFadeOutComposer = when(() -> finished, GLOBAL_FADE_OUT_DELTA_FACTORY.apply(() -> fadeOutStart)); val deltaMap = of( BACKGROUND_DEFAULT_DELTA_KEY, globalFadeOutComposer.apply(BACKGROUND_FADE_IN_DELTA).andThenDouble(SIN_90_DELTA), @@ -131,66 +147,70 @@ private static UnaryOperator when(BooleanSupplier condition expression(this::renderProgressBar) .before(this::renderLogo) .partiallyApply(deltaFunc)::get; - if(StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.NO_ANIMATE)) { - BACKGROUND_START = - BACKGROUND_FADE_IN = - STAGE_0_START = - STAGE_0_FADE_IN = - GLOBAL_FADE_OUT = - RELOAD_START = - EXCEPTION_TRANSFORM = 0; - } - else { - BACKGROUND_START = 0; - BACKGROUND_FADE_IN = 1000; - STAGE_0_START = BACKGROUND_START + BACKGROUND_FADE_IN; - STAGE_0_FADE_IN = 2000; - GLOBAL_FADE_OUT = 1000; - RELOAD_START = STAGE_0_START + STAGE_0_FADE_IN; - EXCEPTION_TRANSFORM = 500; - } } private void renderBackground(ToDoubleFunction deltaFunc) { val delta = deltaFunc.applyAsDouble(BACKGROUND_DEFAULT_DELTA_KEY); + int red = BACKGROUND_COLOR_DEFAULT_RED; + int green = BACKGROUND_COLOR_DEFAULT_GREEN; + int blue = BACKGROUND_COLOR_DEFAULT_BLUE; + if ( + StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.HIDE) || + StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.FORGE) || + StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.NO_RECOLOR) + ) { + red = green = blue = 0xFF; + } final int color; if (exceptionThrown) { val exceptionDelta = deltaFunc.applyAsDouble(BACKGROUND_EXCEPTION_DELTA_KEY); color = ColorHelper.Argb.getArgb( 0xFF, - lerp(exceptionDelta, BACKGROUND_COLOR_DEFAULT_RED, BACKGROUND_COLOR_EXCEPTION_RED), - lerp(exceptionDelta, BACKGROUND_COLOR_DEFAULT_GREEN, BACKGROUND_COLOR_EXCEPTION_GREEN), - lerp(exceptionDelta, BACKGROUND_COLOR_DEFAULT_BLUE, BACKGROUND_COLOR_EXCEPTION_BLUE) + lerp(exceptionDelta, red, BACKGROUND_COLOR_EXCEPTION_RED), + lerp(exceptionDelta, green, BACKGROUND_COLOR_EXCEPTION_GREEN), + lerp(exceptionDelta, blue, BACKGROUND_COLOR_EXCEPTION_BLUE) ); } else color = parent == null ? finished ? ColorHelper.Argb.getArgb( 0xFF, - lerp(delta, 0xFF, BACKGROUND_COLOR_DEFAULT_RED), - lerp(delta, 0xFF, BACKGROUND_COLOR_DEFAULT_GREEN), - lerp(delta, 0xFF, BACKGROUND_COLOR_DEFAULT_BLUE) + lerp(delta, 0xFF, red), + lerp(delta, 0xFF, green), + lerp(delta, 0xFF, blue) ) : ColorHelper.Argb.getArgb( 0xFF, - (int) (delta * BACKGROUND_COLOR_DEFAULT_RED), - (int) (delta * BACKGROUND_COLOR_DEFAULT_GREEN), - (int) (delta * BACKGROUND_COLOR_DEFAULT_BLUE) + (int) (delta * red), + (int) (delta * green), + (int) (delta * blue) ) : ColorHelper.Argb.getArgb( (int) (delta * 0xFF), - BACKGROUND_COLOR_DEFAULT_RED, - BACKGROUND_COLOR_DEFAULT_GREEN, - BACKGROUND_COLOR_DEFAULT_BLUE + red, + green, + blue ); fill(0, 0, width, height, color); } private void renderProgressBar(ToDoubleFunction deltaFunc) { + if (StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.HIDE)) return; + if (StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.FORGE)) { + if(ReloadScreenManager.LOCATIONS.isEmpty()) return; + String text = ReloadScreenManager.LOCATIONS.get(ReloadScreenManager.LOCATIONS.size() - 1); + fill(3, height, textRenderer.getWidth(text) + 7, height - 12, -1073741824); + glEnable(GL_BLEND); + drawTextWithShadow(textRenderer, text, 5, height - 10, 0xFFFFFF); + glDisable(GL_BLEND); + return; + } val delta = deltaFunc.applyAsDouble(STAGE_0_DEFAULT_DELTA_KEY); if (delta == 0) return; val color = (int) (delta * 0xFF) << 24 | 0xFFFFFF; val v = (float) (10 - delta * 10); val ev = exceptionThrown ? (float) (10 - deltaFunc.applyAsDouble(STAGE_0_EXCEPTION_DELTA_KEY) * 10) * 3 - 1 : 0; + if (StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.NO_RECOLOR)) + fill(38, height - 37 + (int) v, width - 38, (int) (height - 105 + v * 5), ColorHelper.Argb.getArgb(lerp(delta, 0, 192), 0, 0, 0)); drawHorizontalLine(40, width - 40 - 1, (int) (height - 90 + v * 5), color); if (exceptionThrown) drawHorizontalLine(40, width - 40 - 1, (int) (height - 90 + v * 5 + ev), color); drawHorizontalLine(40, width - 40 - 1, (int) (height - 50 + v), color); @@ -264,48 +284,79 @@ private void renderProgressBar(ToDoubleFunction deltaFunc) { } private void renderLogo(ToDoubleFunction deltaFunc) { - if (StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.FORGE)) { - renderStapiLogo(deltaFunc, width * 0.6f, height * 0.6f, 0.5f, 0.5f); + if ( + StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.SHOW) || + StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.NO_ANIMATE) || + StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.NO_RECOLOR) + ) { + int color = 0x000000; + if (StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.NO_RECOLOR)) { + color = 0xDD4F3B; // mojang colour + } + renderStapiLogo(deltaFunc, width - 50, height - 14, 48, 8, color); + renderStapiLogo(deltaFunc, (width / 2f), (height / 2f), 120, 20, color); } - if (StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.HIDE)) { - renderMojangLogo(deltaFunc); + + if ( + StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.HIDE) || + StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.FORGE) + ) { + renderMojangLogo(deltaFunc, width / 2f, height / 2f, width, height, 0, 0); // Draws the top left pixel of the logo, which is white, normally. + renderMojangLogo(deltaFunc, (width / 2f) - 1, (height / 2f) + 1, 128, 128, 1, 1); + } + + if (StationConfig.stationConfigData.loadingScreenOption.equals(LoadingScreenOption.FORGE)) { + // Stapi logo is 6:1 aspect + int color; + if (exceptionThrown) { + val exceptionDelta = deltaFunc.applyAsDouble(BACKGROUND_EXCEPTION_DELTA_KEY); + color = ColorHelper.Argb.getArgb( + 0xFF, + lerp(exceptionDelta, BACKGROUND_COLOR_DEFAULT_RED, BACKGROUND_COLOR_EXCEPTION_RED), + lerp(exceptionDelta, BACKGROUND_COLOR_DEFAULT_GREEN, BACKGROUND_COLOR_EXCEPTION_GREEN), + lerp(exceptionDelta, BACKGROUND_COLOR_DEFAULT_BLUE, BACKGROUND_COLOR_EXCEPTION_BLUE) + ); + } + else { + color = ColorHelper.Argb.getArgb(0xFF, BACKGROUND_COLOR_DEFAULT_RED, BACKGROUND_COLOR_DEFAULT_GREEN, BACKGROUND_COLOR_DEFAULT_BLUE); + } + renderStapiLogo(deltaFunc, width - 50, height - 14, 48, 8, color); } } - private void renderMojangLogo(ToDoubleFunction deltaFunc) { + private void renderMojangLogo(ToDoubleFunction deltaFunc, float x, float y, float w, float h, float u, float v) { val delta = deltaFunc.applyAsDouble(STAGE_0_DEFAULT_DELTA_KEY); if (delta == 0) return; - val v = 10 - delta * 10; minecraft.textureManager.bindTexture(minecraft.textureManager.getTextureId(LOGO_MOJANG)); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - int vWidth = (width - 256) / 2; - double vHeight = (double) (height - 256) / 2 - v; tessellator.startQuads(); - tessellator.color(0xFF, 0xFF, 0xFF, (int) (0xFF * delta)); - tessellator.vertex(vWidth, vHeight, 0, 0, 0); - tessellator.vertex(vWidth, vHeight, 0, 0, 1); - tessellator.vertex(vWidth, vHeight, 0, 1, 1); - tessellator.vertex(vWidth, vHeight, 0, 1, 0); + tessellator.color(0xFF, 0xFF, 0xFF, 0xFF); + tessellator.vertex(x - w, y - h - v, 0, 0, 0); + tessellator.vertex(x - w, y + h - v, 0, 0, v); + tessellator.vertex(x + w, y + h - v, 0, u, v); + tessellator.vertex(x + w, y - h - v, 0, u, 0); tessellator.draw(); glDisable(GL_BLEND); } - private void renderStapiLogo(ToDoubleFunction deltaFunc, float x, float y, float heightMultiplyer, float widthMultiplier) { + private void renderStapiLogo(ToDoubleFunction deltaFunc, float x, float y, float w, float h, int color) { val delta = deltaFunc.applyAsDouble(STAGE_0_DEFAULT_DELTA_KEY); if (delta == 0) return; val v = 10 - delta * 10; + val a = (float)(color >> 24 & 0xFF) / 255.0f; + val r = (float)(color >> 16 & 0xFF) / 255.0f; + val g = (float)(color >> 8 & 0xFF) / 255.0f; + val b = (float)(color & 0xFF) / 255.0f; minecraft.textureManager.bindTexture(minecraft.textureManager.getTextureId(logo)); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); tessellator.startQuads(); - tessellator.translate(x, y, 0); - tessellator.color(0xFF, 0xFF, 0xFF, (int) (0xFF * delta)); - tessellator.vertex(width / 2D - 120, (height - 90D) / 2 - 20 - v, 0, 0, 0); - tessellator.vertex(width / 2D - 120, ((height - 90D) / 2 + 20 - v) * heightMultiplyer, 0, 0, 1); - tessellator.vertex((width / 2D + 120) * widthMultiplier, ((height - 90D) / 2 + 20 - v) * heightMultiplyer, 0, 1, 1); - tessellator.vertex((width / 2D + 120) * widthMultiplier, (height - 90D) / 2 - 20 - v, 0, 1, 0); - tessellator.translate(-x, -y, 0); + tessellator.color(r, g, b, (int) (a * delta)); + tessellator.vertex(x - w, y - h - v, 0, 0, 0); + tessellator.vertex(x - w, y + h - v, 0, 0, 1); + tessellator.vertex(x + w, y + h - v, 0, 1, 1); + tessellator.vertex(x + w, y - h - v, 0, 1, 0); tessellator.draw(); glDisable(GL_BLEND); }