From be0371ba71547ef2e23ad593ab5689f0c0ce5ee7 Mon Sep 17 00:00:00 2001 From: LocusAzzurro Date: Sat, 22 Jul 2023 15:26:12 +0200 Subject: [PATCH] :sparkles: face side block logic and hanging painting Signed-off-by: LocusAzzurro --- src/generated/resources/.cache/cache | 5 +- .../blockstates/long_hanging_painting.json | 34 ++++++++ .../models/item/long_hanging_painting.json | 3 + .../blocks/long_hanging_painting.json | 16 ++++ .../tags/blocks/mineable_with_shears.json | 3 +- .../event/ModClientRenderEventHandler.java | 1 + .../data/registry/BlockRegistry.java | 3 + .../data/registry/ItemRegistry.java | 4 +- .../datagen/ModBlockModelProvider.java | 7 ++ .../world/block/SideFaceBlock.java | 76 ++++++++++++++++++ .../models/block/long_hanging_painting.json | 68 ++++++++++++++++ .../textures/block/long_hanging_painting.png | Bin 0 -> 1387 bytes 12 files changed, 217 insertions(+), 3 deletions(-) create mode 100644 src/generated/resources/assets/ultramarine/blockstates/long_hanging_painting.json create mode 100644 src/generated/resources/assets/ultramarine/models/item/long_hanging_painting.json create mode 100644 src/generated/resources/data/ultramarine/loot_tables/blocks/long_hanging_painting.json create mode 100644 src/main/java/com/voxelutopia/ultramarine/world/block/SideFaceBlock.java create mode 100644 src/main/resources/assets/ultramarine/models/block/long_hanging_painting.json create mode 100644 src/main/resources/assets/ultramarine/textures/block/long_hanging_painting.png diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index f887d44c..004670db 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -85,6 +85,7 @@ a00161538dcc0866b0c270ed457a563ac7a0a1a7 assets/ultramarine/blockstates/jade_can 2d1dd7ca69126dcb88a8f78acb1cad6bd44c26a0 assets/ultramarine/blockstates/light_cyan_floor_tile_slab.json 03962be776e3b2db289cc71fa1d3c50c2b26f371 assets/ultramarine/blockstates/light_cyan_floor_tile_stairs.json 6129b36a1e018253a1b09b1e7cf646b93d587e4a assets/ultramarine/blockstates/light_cyan_floor_tile_wall.json +42e040bdb5b24f69d29db55f41251aaab351ef10 assets/ultramarine/blockstates/long_hanging_painting.json de2ef08ba562cad26ba62896ad83bbf03c48220b assets/ultramarine/blockstates/magnesite_ore.json 643e08a9749e98b571c298ff0312a7dd04688a2b assets/ultramarine/blockstates/memorial_tablet.json c14aef2b2cb4f378fd0dc0455233eb5e9b64fffb assets/ultramarine/blockstates/oak_cabinet.json @@ -393,6 +394,7 @@ da8bb89178f57d9ade835f30e1386a96571ffc60 assets/ultramarine/models/item/large_bl bb28f340faeac8563249c2f8c761cb4c0de9ffc6 assets/ultramarine/models/item/light_cyan_floor_tile_slab.json 4277cff2f68c1ec4c26327263a793f8b41fa72f2 assets/ultramarine/models/item/light_cyan_floor_tile_stairs.json 2733946da9043d37eb81db48e0e0eaa570e16a9b assets/ultramarine/models/item/light_cyan_floor_tile_wall.json +1ea2ed714ec17cc658f86be0b2f307b9522bb4d9 assets/ultramarine/models/item/long_hanging_painting.json b4d3176457ddfb95af0c379bceaaa3a3f81108a8 assets/ultramarine/models/item/magnesite.json ff866531331de28904c8bc3de6a5aee2b76925e1 assets/ultramarine/models/item/magnesite_ore.json 9063f15d1c0f55274e06015d68f4482f508134db assets/ultramarine/models/item/memorial_tablet.json @@ -677,6 +679,7 @@ ea07703bd0102fc176121fac7082579cb162e73b data/ultramarine/loot_tables/blocks/jad 7dead99c26ef0794c05a573ba4b04806a9170020 data/ultramarine/loot_tables/blocks/light_cyan_floor_tile_slab.json 4fcaac4782ef0672d885b330ff22afb5277c486a data/ultramarine/loot_tables/blocks/light_cyan_floor_tile_stairs.json bd99fe35771783311c592c453316d7d316fa067c data/ultramarine/loot_tables/blocks/light_cyan_floor_tile_wall.json +c4345de1ce96304873419f82b7cdc06c5f019e72 data/ultramarine/loot_tables/blocks/long_hanging_painting.json 2114a76b69b7936384dc8501f263c9f24956ac8d data/ultramarine/loot_tables/blocks/magnesite_ore.json b3545373c621311f298df9dc5490665587467822 data/ultramarine/loot_tables/blocks/memorial_tablet.json 1d8922f4783a9bb430920819ca1616bcdd4d9da3 data/ultramarine/loot_tables/blocks/oak_cabinet.json @@ -844,5 +847,5 @@ daf52f68f622d70c0be6679947fc3eeb177e4753 data/ultramarine/recipes/yellow_roof_ti 9d963c46671a863353a8b469457bc55efd511e7f data/ultramarine/recipes/yellow_roof_tile_stairs.json fcfeebbc3040cb32e94a29f1a90f1c0e18ab6b64 data/ultramarine/recipes/yellow_roof_tiles.json 0a749c939400810233b1bfc6fba83efc5d4ed0fe data/ultramarine/recipes/yellow_sky_lantern.json -87c90ddea06addb10687f55f87ad475fc9cccabe data/ultramarine/tags/blocks/mineable_with_shears.json +bf54dad71fa5ffd9bbb0bc97ea9e1886474d8ea9 data/ultramarine/tags/blocks/mineable_with_shears.json c4efa9827b33be29f6dd9bff76d30e27d195bac6 data/ultramarine/tags/items/polished_planks.json diff --git a/src/generated/resources/assets/ultramarine/blockstates/long_hanging_painting.json b/src/generated/resources/assets/ultramarine/blockstates/long_hanging_painting.json new file mode 100644 index 00000000..e093e419 --- /dev/null +++ b/src/generated/resources/assets/ultramarine/blockstates/long_hanging_painting.json @@ -0,0 +1,34 @@ +{ + "variants": { + "facing=north,waterlogged=false": { + "model": "ultramarine:block/long_hanging_painting", + "y": 180 + }, + "facing=south,waterlogged=false": { + "model": "ultramarine:block/long_hanging_painting" + }, + "facing=west,waterlogged=false": { + "model": "ultramarine:block/long_hanging_painting", + "y": 90 + }, + "facing=east,waterlogged=false": { + "model": "ultramarine:block/long_hanging_painting", + "y": 270 + }, + "facing=north,waterlogged=true": { + "model": "ultramarine:block/long_hanging_painting", + "y": 180 + }, + "facing=south,waterlogged=true": { + "model": "ultramarine:block/long_hanging_painting" + }, + "facing=west,waterlogged=true": { + "model": "ultramarine:block/long_hanging_painting", + "y": 90 + }, + "facing=east,waterlogged=true": { + "model": "ultramarine:block/long_hanging_painting", + "y": 270 + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/ultramarine/models/item/long_hanging_painting.json b/src/generated/resources/assets/ultramarine/models/item/long_hanging_painting.json new file mode 100644 index 00000000..8e741708 --- /dev/null +++ b/src/generated/resources/assets/ultramarine/models/item/long_hanging_painting.json @@ -0,0 +1,3 @@ +{ + "parent": "ultramarine:block/long_hanging_painting" +} \ No newline at end of file diff --git a/src/generated/resources/data/ultramarine/loot_tables/blocks/long_hanging_painting.json b/src/generated/resources/data/ultramarine/loot_tables/blocks/long_hanging_painting.json new file mode 100644 index 00000000..f08b834b --- /dev/null +++ b/src/generated/resources/data/ultramarine/loot_tables/blocks/long_hanging_painting.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "name": "long_hanging_painting", + "rolls": 1.0, + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "ultramarine:long_hanging_painting" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/ultramarine/tags/blocks/mineable_with_shears.json b/src/generated/resources/data/ultramarine/tags/blocks/mineable_with_shears.json index a2c01b61..3204c3cd 100644 --- a/src/generated/resources/data/ultramarine/tags/blocks/mineable_with_shears.json +++ b/src/generated/resources/data/ultramarine/tags/blocks/mineable_with_shears.json @@ -7,6 +7,7 @@ "ultramarine:green_silk_fabric_roll", "ultramarine:purple_silk_fabric_roll", "ultramarine:painting_scroll", - "ultramarine:back_cushion" + "ultramarine:back_cushion", + "ultramarine:long_hanging_painting" ] } \ No newline at end of file diff --git a/src/main/java/com/voxelutopia/ultramarine/client/event/ModClientRenderEventHandler.java b/src/main/java/com/voxelutopia/ultramarine/client/event/ModClientRenderEventHandler.java index dabd7230..0ed3db8a 100644 --- a/src/main/java/com/voxelutopia/ultramarine/client/event/ModClientRenderEventHandler.java +++ b/src/main/java/com/voxelutopia/ultramarine/client/event/ModClientRenderEventHandler.java @@ -36,6 +36,7 @@ private static void setRenderLayers(FMLClientSetupEvent e) { ItemBlockRenderTypes.setRenderLayer(BlockRegistry.MEMORIAL_TABLET.get(), RenderType.cutout()); ItemBlockRenderTypes.setRenderLayer(BlockRegistry.BRONZE_CENSER.get(), RenderType.cutout()); ItemBlockRenderTypes.setRenderLayer(BlockRegistry.ROYAL_CENSER.get(), RenderType.cutout()); + ItemBlockRenderTypes.setRenderLayer(BlockRegistry.LONG_HANGING_PAINTING.get(), RenderType.cutout()); ItemBlockRenderTypes.setRenderLayer(BlockRegistry.GUNNY_SACK.get(), RenderType.cutout()); ItemBlockRenderTypes.setRenderLayer(BlockRegistry.PLATED_MUNG_BEAN_CAKES.get(), RenderType.cutout()); ItemBlockRenderTypes.setRenderLayer(BlockRegistry.PLATED_FISH.get(), RenderType.cutout()); diff --git a/src/main/java/com/voxelutopia/ultramarine/data/registry/BlockRegistry.java b/src/main/java/com/voxelutopia/ultramarine/data/registry/BlockRegistry.java index 35ab87d5..aa89f5db 100644 --- a/src/main/java/com/voxelutopia/ultramarine/data/registry/BlockRegistry.java +++ b/src/main/java/com/voxelutopia/ultramarine/data/registry/BlockRegistry.java @@ -163,6 +163,9 @@ public class BlockRegistry { public static final RegistryObject ROYAL_CENSER = BLOCKS.register("royal_censer", () -> new Censer(DecorativeBlock.with(BaseBlockProperty.BRONZE).shaped(DecorativeBlock.FULL_10).directional().luminous(), new Vec3(0.5, 0.5, 0.5))); + public static final RegistryObject LONG_HANGING_PAINTING = BLOCKS.register("long_hanging_painting", + () -> new SideFaceBlock(BaseBlockProperty.PAPER)); + public static final RegistryObject FRUIT_BOX = BLOCKS.register("fruit_box", () -> ContainerDecorativeBlock.with(BaseBlockProperty.WOOD).content(ContainerType.FOOD_REGULAR).shaped(DecorativeBlock.FULL_14).directional().diagonallyPlaceable().build()); public static final RegistryObject WOODEN_CRATE = BLOCKS.register("wooden_crate", diff --git a/src/main/java/com/voxelutopia/ultramarine/data/registry/ItemRegistry.java b/src/main/java/com/voxelutopia/ultramarine/data/registry/ItemRegistry.java index 5925e7db..e543efc3 100644 --- a/src/main/java/com/voxelutopia/ultramarine/data/registry/ItemRegistry.java +++ b/src/main/java/com/voxelutopia/ultramarine/data/registry/ItemRegistry.java @@ -101,7 +101,6 @@ public class ItemRegistry { public static final RegistryObject BLACK_ROOF_TILE_STAIRS = fromBlock(BlockRegistry.BLACK_ROOF_TILE_STAIRS, CreativeTabs.BUILDING_BLOCKS); public static final RegistryObject BLACK_ROOF_TILE_EDGE = fromBlock(BlockRegistry.BLACK_ROOF_TILE_EDGE, CreativeTabs.BUILDING_BLOCKS); - public static final RegistryObject ABACUS = fromBlock(BlockRegistry.ABACUS, CreativeTabs.DECORATIONS); public static final RegistryObject BRUSH_TOOLS = fromBlock(BlockRegistry.BRUSH_TOOLS, CreativeTabs.DECORATIONS); public static final RegistryObject BRUSH_AND_INKSTONE = fromBlock(BlockRegistry.BRUSH_AND_INKSTONE, CreativeTabs.DECORATIONS); @@ -132,6 +131,9 @@ public class ItemRegistry { public static final RegistryObject BLUE_AND_WHITE_PORCELAIN_BOWL = fromBlock(BlockRegistry.BLUE_AND_WHITE_PORCELAIN_BOWL, CreativeTabs.DECORATIONS); public static final RegistryObject BRONZE_CENSER = fromBlock(BlockRegistry.BRONZE_CENSER, CreativeTabs.DECORATIONS); public static final RegistryObject ROYAL_CENSER = fromBlock(BlockRegistry.ROYAL_CENSER, CreativeTabs.DECORATIONS); + + public static final RegistryObject LONG_HANGING_PAINTING = fromBlock(BlockRegistry.LONG_HANGING_PAINTING, CreativeTabs.DECORATIONS); + public static final RegistryObject FRUIT_BOX = fromBlock(BlockRegistry.FRUIT_BOX, CreativeTabs.DECORATIONS); public static final RegistryObject WOODEN_CRATE = fromBlock(BlockRegistry.WOODEN_CRATE, CreativeTabs.DECORATIONS); public static final RegistryObject GUNNY_SACK = fromBlock(BlockRegistry.GUNNY_SACK, CreativeTabs.DECORATIONS); diff --git a/src/main/java/com/voxelutopia/ultramarine/datagen/ModBlockModelProvider.java b/src/main/java/com/voxelutopia/ultramarine/datagen/ModBlockModelProvider.java index c69f6b68..0eae839c 100644 --- a/src/main/java/com/voxelutopia/ultramarine/datagen/ModBlockModelProvider.java +++ b/src/main/java/com/voxelutopia/ultramarine/datagen/ModBlockModelProvider.java @@ -136,6 +136,8 @@ protected void registerStatesAndModels() { else decorativeBlock(block); }); + wallSideBlock(BlockRegistry.LONG_HANGING_PAINTING.get()); + horizontalBlock(BlockRegistry.WOODWORKING_WORKBENCH.get(), models().getExistingFile(blockLoc(BlockRegistry.WOODWORKING_WORKBENCH.get()))); simpleBlock(BlockRegistry.JADE_ORE.get()); simpleBlock(BlockRegistry.MAGNESITE_ORE.get()); @@ -163,6 +165,11 @@ private void fence(Block baseBlock, Block fenceBlock){ fenceBlock((FenceBlock)fenceBlock, fenceBlock.getRegistryName().getPath(), blockLoc(baseBlock)); } + private void wallSideBlock(Block block){ + getVariantBuilder(block).forAllStates(blockState -> ConfiguredModel.builder().modelFile(models().getExistingFile(modLoc(BLOCK + name(block)))) + .rotationY((int) blockState.getValue(HORIZONTAL_FACING).toYRot()).build()); + } + public void chiralDirectionalBlock(Block block) { directionalBlock(block, state -> { String path = Objects.requireNonNull(block.getRegistryName()).getPath(); diff --git a/src/main/java/com/voxelutopia/ultramarine/world/block/SideFaceBlock.java b/src/main/java/com/voxelutopia/ultramarine/world/block/SideFaceBlock.java new file mode 100644 index 00000000..65a33bd4 --- /dev/null +++ b/src/main/java/com/voxelutopia/ultramarine/world/block/SideFaceBlock.java @@ -0,0 +1,76 @@ +package com.voxelutopia.ultramarine.world.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.HorizontalDirectionalBlock; +import net.minecraft.world.level.block.SimpleWaterloggedBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +import javax.annotation.Nullable; + +public class SideFaceBlock extends Block implements BaseBlockPropertyHolder, SimpleWaterloggedBlock { + + protected final BaseBlockProperty property; + + public static final DirectionProperty FACING = HorizontalDirectionalBlock.FACING; + public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; + + protected static final VoxelShape EAST_AABB = Block.box(0.0D, 0.0D, 0.0D, 1.0D, 16.0D, 16.0D); + protected static final VoxelShape WEST_AABB = Block.box(15.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D); + protected static final VoxelShape SOUTH_AABB = Block.box(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 1.0D); + protected static final VoxelShape NORTH_AABB = Block.box(0.0D, 0.0D, 15.0D, 16.0D, 16.0D, 16.0D); + public SideFaceBlock(BaseBlockProperty property) { + super(property.properties.noOcclusion()); + this.property = property; + this.registerDefaultState(this.getStateDefinition().any() + .setValue(FACING, Direction.NORTH) + .setValue(WATERLOGGED, false)); + } + + public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) { + return switch (pState.getValue(FACING)) { + case NORTH -> NORTH_AABB; + case SOUTH -> SOUTH_AABB; + case WEST -> WEST_AABB; + default -> EAST_AABB; + }; + } + + @Nullable + public BlockState getStateForPlacement(BlockPlaceContext pContext) { + BlockState state = this.defaultBlockState(); + FluidState fluidstate = pContext.getLevel().getFluidState(pContext.getClickedPos()); + + Direction direction = pContext.getClickedFace(); + if (direction.getAxis().isHorizontal()){ + return state.setValue(FACING, direction) + .setValue(WATERLOGGED, fluidstate.getType() == Fluids.WATER); + } + return null; + } + + protected void createBlockStateDefinition(StateDefinition.Builder pBuilder) { + pBuilder.add(FACING, WATERLOGGED); + } + + public FluidState getFluidState(BlockState pState) { + return pState.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(pState); + } + + @Override + public BaseBlockProperty getProperty() { + return this.property; + } +} diff --git a/src/main/resources/assets/ultramarine/models/block/long_hanging_painting.json b/src/main/resources/assets/ultramarine/models/block/long_hanging_painting.json new file mode 100644 index 00000000..239c1347 --- /dev/null +++ b/src/main/resources/assets/ultramarine/models/block/long_hanging_painting.json @@ -0,0 +1,68 @@ +{ + "credit": "Made with Blockbench", + "texture_size": [64, 64], + "render_type": "cutout", + "textures": { + "1": "ultramarine:block/long_hanging_painting", + "particle": "ultramarine:item/xuan_paper" + }, + "elements": [ + { + "from": [0, -16, 0.1], + "to": [16, 32, 0.1], + "faces": { + "north": {"uv": [4.25, 0, 8.25, 12], "texture": "#1"}, + "east": {"uv": [8.75, 0, 8.75, 12], "texture": "#1"}, + "south": {"uv": [0, 0, 4, 12], "texture": "#1"}, + "west": {"uv": [8.5, 0, 8.5, 12], "texture": "#1"}, + "up": {"uv": [13, 0, 9, 0], "rotation": 180, "texture": "#1"}, + "down": {"uv": [13, 0.25, 9, 0.25], "rotation": 180, "texture": "#1"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [72.91, 11.8, 4.18], + "translation": [1.75, -2.25, 0], + "scale": [0.375, 0.375, 0.375] + }, + "thirdperson_lefthand": { + "rotation": [72.91, 11.8, 4.18], + "translation": [1.75, -2.25, 0], + "scale": [0.375, 0.375, 0.375] + }, + "firstperson_righthand": { + "translation": [3, 3.25, 2], + "scale": [0.3, 0.3, 0.3] + }, + "firstperson_lefthand": { + "translation": [3, 3.25, 2], + "scale": [0.3, 0.3, 0.3] + }, + "ground": { + "translation": [0, 3, 2], + "scale": [0.25, 0.25, 0.25] + }, + "gui": { + "rotation": [30, 45, 0], + "translation": [1.75, -0.75, 0], + "scale": [0.33, 0.33, 0.33] + }, + "head": { + "translation": [0, -15.75, 1.25] + }, + "fixed": { + "rotation": [0, 0, 18.75], + "translation": [3.25, -1.25, -16.1], + "scale": [2, 2, 2] + } + }, + "groups": [ + { + "name": "group", + "origin": [8, 8, 8], + "color": 0, + "children": [0] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/ultramarine/textures/block/long_hanging_painting.png b/src/main/resources/assets/ultramarine/textures/block/long_hanging_painting.png new file mode 100644 index 0000000000000000000000000000000000000000..55f836b0be05fbbc6e065a75baf1d0e9e1797c1d GIT binary patch literal 1387 zcmV-x1(f=UP)}G`P4Jr8-EYK9n9@8cJ?~9Qy@~PbK*PJ|~b% zprL{G5Q;$rl_DzYV%S(IZV}!XS;lL{cP%;~Bdx66NK3sxFuTmoJo~=y zyz^&A2HKF#W>2%(>}k6?X4s+8bDE9r#tAz#dXAZqoj75KM$b8`QM~$gX!L`DuRi<4 zk`X`r^1Ce>R@z%(K&dXC%Cd}DEQW5bpQdgP{Pyejr`@)X#bOX66MYN7pe)O{5(=Q3 zD~nw^y=IWyTnPoby4uygUksX8`G0ef-2Aoh)0rB6aO+D$nH?Ivh6W%gv`)z#b+_vm zw9|D07tO15?u65w<>Af&jd2pFr$;< zp=tY;hEcCEtO9ezO?bUN!(U=%mZop3UMA1vg?S`qX1O|Z#m#r_)LGCCfw|%)Qh{Uq z_{X2f#G|^3%{^*13Gy-^w^BhW(0I>xlS3BFwhx*C4dadx6dJv&X$Jtn&4hLt!0UNd zFDUqs3LGQ1QhBG2bqcc;_F+fer}xG6ZA`u&(p4tu-461c%?3?7KyiJW2A90U2^dxZ z!S8{(SLaq{o$7WUAox8r&`v-XfS};R>YAeK9Zfrc*V}OSYB)^Gd1qkk^Q~Hqwr6S9 z?>966%{^bKDyUQy0KnIiAHnOrjICNt=VU8b=bsi|(Q?*t!SAtdy$u+KKv3{eaMrW0cT08Lxd={Ut{7Q;S3DwUz`)sY+@rDacxudr3C(VlJP z2q`CZ+1^i%k3!w6Ln@W+wBIr`0QrIhsZ>UKDyefY8W90BGT>2eu_Mt(xkZ{Wq&?6G zPV3Alc%8Rdhoj8WE{s$?;L$()i%XbG*DTjI>D_3w{q?UKqxMC(mga8T&+= z9a{ayFa$`CeJl!wGXJF$06^^0dt5P6PU^9}PxRO_C(!mpXgV>5J2!6t0Mb)Q3~TGA zshclI7}nO2o=O4$?%cdVCq*Y>*awi5C*%EYW&)Xb6!PH_0ANRqw-wwG;|MA%0Dw$9 zimh7BFn0t6pL2%*fuyQ@c!VWIg}PTqI+?^AaQ%2_r89h%K&!$=k3?06Jw@Z;j7^=chYm>HW*+6K#Xejp~5=VDhOFx~*7KF(nzB+|9L z8Ts%CBOwtFALsCTqt-Iz*-!3%Lo*=r#cghd40C^vx!-@gW32nHM&=v7R