From 1f259a7e2240b2875828a3bfb69977feed05f74d Mon Sep 17 00:00:00 2001 From: Sollace Date: Mon, 4 Feb 2019 15:25:12 +0200 Subject: [PATCH] Added rainbows --- rainbow.svg | 128 ++++++++++++++++++ .../minelittlepony/unicopia/UEntities.java | 25 ++-- .../unicopia/entity/EntityRainbow.java | 128 ++++++++++++++++++ .../unicopia/forgebullshit/BiomeBS.java | 17 +++ .../unicopia/render/RenderRainbow.java | 67 +++++++++ .../unicopia/textures/environment/rainbow.png | Bin 0 -> 11349 bytes 6 files changed, 353 insertions(+), 12 deletions(-) create mode 100644 rainbow.svg create mode 100644 src/main/java/com/minelittlepony/unicopia/entity/EntityRainbow.java create mode 100644 src/main/java/com/minelittlepony/unicopia/render/RenderRainbow.java create mode 100644 src/main/resources/assets/unicopia/textures/environment/rainbow.png diff --git a/rainbow.svg b/rainbow.svg new file mode 100644 index 00000000..4f03bf9e --- /dev/null +++ b/rainbow.svg @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/minelittlepony/unicopia/UEntities.java b/src/main/java/com/minelittlepony/unicopia/UEntities.java index 908a35ff..424e9fd5 100644 --- a/src/main/java/com/minelittlepony/unicopia/UEntities.java +++ b/src/main/java/com/minelittlepony/unicopia/UEntities.java @@ -1,23 +1,23 @@ package com.minelittlepony.unicopia; -import java.util.List; - import com.minelittlepony.unicopia.entity.EntityCloud; import com.minelittlepony.unicopia.entity.EntityConstructionCloud; import com.minelittlepony.unicopia.entity.EntityRacingCloud; +import com.minelittlepony.unicopia.entity.EntityRainbow; import com.minelittlepony.unicopia.entity.EntitySpell; import com.minelittlepony.unicopia.entity.EntitySpellbook; import com.minelittlepony.unicopia.entity.EntityProjectile; import com.minelittlepony.unicopia.entity.EntityWildCloud; +import com.minelittlepony.unicopia.forgebullshit.BiomeBS; import com.minelittlepony.unicopia.forgebullshit.EntityType; import com.minelittlepony.unicopia.render.RenderCloud; import com.minelittlepony.unicopia.render.RenderGem; import com.minelittlepony.unicopia.render.RenderProjectile; +import com.minelittlepony.unicopia.render.RenderRainbow; import com.minelittlepony.unicopia.render.RenderSpellbook; import net.minecraft.entity.EnumCreatureType; import net.minecraft.world.biome.Biome; -import net.minecraft.world.biome.Biome.SpawnListEntry; import net.minecraft.world.biome.BiomeEnd; import net.minecraft.world.biome.BiomeHell; import net.minecraftforge.common.BiomeManager; @@ -38,6 +38,8 @@ public class UEntities { builder.creature(EntityConstructionCloud.class, "construction_cloud"), builder.creature(EntitySpell.class, "magic_spell"), builder.creature(EntitySpellbook.class, "spellbook"), + builder.creature(EntityRainbow.Spawner.class, "rainbow_spawner"), + builder.projectile(EntityRainbow.class, "rainbow", 500, 5), builder.projectile(EntityProjectile.class, "thrown_item", 10, 5) ); } @@ -47,19 +49,18 @@ public class UEntities { RenderingRegistry.registerEntityRenderingHandler(EntitySpell.class, RenderGem::new); RenderingRegistry.registerEntityRenderingHandler(EntityProjectile.class, RenderProjectile::new); RenderingRegistry.registerEntityRenderingHandler(EntitySpellbook.class, RenderSpellbook::new); + RenderingRegistry.registerEntityRenderingHandler(EntityRainbow.class, RenderRainbow::new); } static void registerSpawnEntries(Biome biome) { - if (!(biome instanceof BiomeHell || biome instanceof BiomeEnd)) { - List entries = biome.getSpawnableList(EnumCreatureType.AMBIENT); - entries.stream().filter(p -> p.entityClass == EntityWildCloud.class).findFirst().orElseGet(() -> { - entries.add( - BiomeManager.oceanBiomes.contains(biome) ? - EntityWildCloud.SPAWN_ENTRY_LAND : EntityWildCloud.SPAWN_ENTRY_OCEAN - ); - return null; - }); + + BiomeBS.addSpawnEntry(biome, EnumCreatureType.AMBIENT, EntityWildCloud.class, b -> + BiomeManager.oceanBiomes.contains(b) ? EntityWildCloud.SPAWN_ENTRY_LAND : EntityWildCloud.SPAWN_ENTRY_OCEAN + ); + BiomeBS.addSpawnEntry(biome, EnumCreatureType.CREATURE, EntityRainbow.Spawner.class, b -> EntityRainbow.SPAWN_ENTRY); } } + + } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/EntityRainbow.java b/src/main/java/com/minelittlepony/unicopia/entity/EntityRainbow.java new file mode 100644 index 00000000..28385c11 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/EntityRainbow.java @@ -0,0 +1,128 @@ +package com.minelittlepony.unicopia.entity; + +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.effect.EntityWeatherEffect; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.World; +import net.minecraft.world.biome.Biome.SpawnListEntry; + +public class EntityRainbow extends EntityWeatherEffect { + + public static final SpawnListEntry SPAWN_ENTRY = new SpawnListEntry(EntityRainbow.Spawner.class, 1, 1, 1); + + private int ticksAlive; + + private double radius; + + public static final int RAINBOW_MAX_SIZE = 180; + public static final int RAINBOW_MIN_SIZE = 50; + + public EntityRainbow(World world) { + this(world, 0, 0, 0); + } + + public EntityRainbow(World world, double x, double y, double z) { + super(world); + + float yaw = (int)MathHelper.nextDouble((world == null ? rand : world.rand), 0, 360); + + setLocationAndAngles(x, y, z, yaw, 0); + + radius = MathHelper.nextDouble(world == null ? rand : world.rand, RAINBOW_MIN_SIZE, RAINBOW_MAX_SIZE); + ticksAlive = 10000; + + ignoreFrustumCheck = true; + + width = (float)radius; + height = width; + } + + @Override + public void setPosition(double x, double y, double z) { + posX = x; + posY = y; + posZ = z; + + setEntityBoundingBox(new AxisAlignedBB( + x - width, y - radius/2, z, + x + width, y + radius/2, z + )); + } + + @Override + public AxisAlignedBB getRenderBoundingBox() { + return super.getRenderBoundingBox(); + } + + @Override + public SoundCategory getSoundCategory() { + return SoundCategory.WEATHER; + } + + @Override + public boolean isInRangeToRenderDist(double distance) { + return true; + } + + public double getRadius() { + return radius; + } + + @Override + public void onUpdate() { + super.onUpdate(); + + if (ticksAlive-- <= 0) { + setDead(); + } + } + + @Override + protected void entityInit() { + } + + @Override + protected void readEntityFromNBT(NBTTagCompound compound) { + } + + @Override + protected void writeEntityToNBT(NBTTagCompound compound) { + } + + public static class Spawner extends EntityLiving { + + public static final AxisAlignedBB SPAWN_COLLISSION_RADIUS = new AxisAlignedBB(0, 0, 0, RAINBOW_MAX_SIZE, RAINBOW_MAX_SIZE, RAINBOW_MAX_SIZE); + + public Spawner(World worldIn) { + super(worldIn); + this.setInvisible(true); + } + + @Override + public boolean getCanSpawnHere() { + if (super.getCanSpawnHere()) { + return world.getEntitiesWithinAABB(EntityRainbow.class, SPAWN_COLLISSION_RADIUS.offset(getPosition())).size() == 0; + } + + return false; + } + + @Override + public int getMaxSpawnedInChunk() { + return 1; + } + + @Override + public void onUpdate() { + super.onUpdate(); + setDead(); + + EntityRainbow rainbow = new EntityRainbow(world); + rainbow.setPosition(posX, posY, posZ); + world.spawnEntity(rainbow); + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/forgebullshit/BiomeBS.java b/src/main/java/com/minelittlepony/unicopia/forgebullshit/BiomeBS.java index ff933eca..c04a0cb9 100644 --- a/src/main/java/com/minelittlepony/unicopia/forgebullshit/BiomeBS.java +++ b/src/main/java/com/minelittlepony/unicopia/forgebullshit/BiomeBS.java @@ -1,10 +1,15 @@ package com.minelittlepony.unicopia.forgebullshit; +import java.util.List; import java.util.Optional; +import java.util.function.Function; import com.google.common.collect.Lists; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.EnumCreatureType; import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biome.SpawnListEntry; import net.minecraftforge.common.BiomeManager; import net.minecraftforge.common.BiomeManager.BiomeType; @@ -24,4 +29,16 @@ public class BiomeBS { .isPresent() ).findFirst(); } + + /** + * Adds a spawn entry for the specified entity if one does not already exist. + */ + public static void addSpawnEntry(Biome biome, EnumCreatureType list, Class type, Function func) { + List entries = biome.getSpawnableList(list); + + entries.stream().filter(p -> p.entityClass == type).findFirst().orElseGet(() -> { + entries.add(func.apply(biome)); + return null; + }); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/render/RenderRainbow.java b/src/main/java/com/minelittlepony/unicopia/render/RenderRainbow.java new file mode 100644 index 00000000..82624b13 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/render/RenderRainbow.java @@ -0,0 +1,67 @@ +package com.minelittlepony.unicopia.render; + +import org.lwjgl.opengl.GL11; + +import com.minelittlepony.unicopia.entity.EntityRainbow; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.util.ResourceLocation; + +public class RenderRainbow extends Render { + + public RenderRainbow(RenderManager renderManager) { + super(renderManager); + } + + private static final ResourceLocation TEXTURE = new ResourceLocation("unicopia", "textures/environment/rainbow.png"); + + public void doRender(EntityRainbow entity, double x, double y, double z, float entityYaw, float partialTicks) { + bindEntityTexture(entity); + + GlStateManager.pushMatrix(); + GlStateManager.disableLighting(); + GlStateManager.disableCull(); + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + + GlStateManager.translate(x, y, z); + GlStateManager.rotate(entityYaw, 0, 1, 0); + + float distance = Minecraft.getMinecraft().getRenderViewEntity().getDistance(entity); + + + float maxDistance = 16 * Minecraft.getMinecraft().gameSettings.renderDistanceChunks; + + GlStateManager.color(1, 1, 1, ((maxDistance - distance) / maxDistance) * 0.9f); + + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + + double r = entity.getRadius(); + + bufferbuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + bufferbuilder.pos(-r, r, 0).tex(1, 0).endVertex(); + bufferbuilder.pos( r, r, 0).tex(0, 0).endVertex(); + bufferbuilder.pos( r, 0, 0).tex(0, 1).endVertex(); + bufferbuilder.pos(-r, 0, 0).tex(1, 1).endVertex(); + + tessellator.draw(); + + GlStateManager.disableBlend(); + GlStateManager.enableCull(); + GlStateManager.enableLighting(); + GlStateManager.popMatrix(); + } + + @Override + protected ResourceLocation getEntityTexture(EntityRainbow entity) { + return TEXTURE; + } + +} diff --git a/src/main/resources/assets/unicopia/textures/environment/rainbow.png b/src/main/resources/assets/unicopia/textures/environment/rainbow.png new file mode 100644 index 0000000000000000000000000000000000000000..018f310c071edad6ee5e3dfc024f601184e1137a GIT binary patch literal 11349 zcmeHNS77-^z>x6aj7&~_Dm@B_&XGguJlpM~-b3v}nHJm_@!i~gJQAEg!e9`9>AJw_KwIONId=Do zHpdR}@>l^q|3i;vl80L%IXU1|M{|wEQ@Nw|(}6B+7`_xb-Tznr7aL%c^UVm*KK{*X zxg4i8GU}H=Q4iPHX*pr0EWxZA%-5pk9LUPU3jRE3n2%EAqp=>1$R=Ta;3^U~ttuLT zK4`=E_UIjXY`ObkV(1-x6lD^OX5cFEJ;KM2QU8v!!w$!#4=;nGgD!(F=vu4nt)Jd0 zc7$tW$}@O;)^hs+dahFnrq1^z1j?V`5y5RiBLzj4h)x8GMzM1Oh}zQrpwu;#fatAu zdD=4sF)`oSR(F4Cf6e?r!bfR|(9N6Wk#GI%$fIbL|9ue@Ih)JJ@fFJ7n6QXBOgn#VVI2g~Ae-pm- z7OPC7hwE&#f{;E&zV>=wWC(j5koebv(%042>YtrOJmJWJB>&zkA%^w3{)J~k%YSy} z5`3jle1ce9IA2dn`$odSs#b)LWK(%xewnc=J^}6?)z>F%igAigqz@Zs=1&t&Bs~<) z9tzV~%NX9kSsI?H6;UGL0poyTI`r@p-P`qb&KUt$;UBQ(A3l{`sPj(($r+q8x6>SG z=q13c89CbP-(8HuD*g;X76E&@XxFg&r>dGnhIL$y&|-#Da4@El^hUnX1ttI|c_^B1Bv^ z)NE&1EkPL=p;6!pH^XJ*>EgcroH4CSL2a0K92Rf5cW?9buKL09`mFbK?=IyN14aNa zpky6-Ua?kJf&VskXpW%onACw|tr`427qlYkFL@VpF!xWampVz1jK#@bz z3A6#kElwo&9^*IG16rikOr)ku5r=ET(s)nj$_~imrLcLW)G&$*U9`t+FoRh<>|>`l3sP-)!q1`>qvXg6LH{oIIv z#uY2+VT*Z8pWgmS?D4F)(%2m$avTccFyIfBfN9q?mXCKMKgdK(Fn74nz73PWM?|>X zC1wTPnLXN!2i&9JZ zY=!H5W=#(oaGte3o^<71r`5Z319pu9Fn^?_u;^>x<4SVk^_ZfEYa-Ba=c0v2cp(xx z%U?;h<88`4Q_&Rq3QAJclJclSs@B@(UgY07-~KbMKWo4a=&)P#Lkt$+#HdLhLSi&u z`-gV;*Z2eaj-)X#?2=BLCgf+q=}K?Hp%mzi8P~T#S`xn4UX$;y2=uq8P{QwbuGYi@ z-r4C?^JC*|bus$F$3>*wJf4{pS0U&9J&?Ry<&(Yb6eMr&A0TVs#YLoNo^Oh>R3&MC zM={rabjFD+`+LqU#I`>=Cs3X@q#QcpFWzdegT-W_2AW0~Hys%w2G0-ia`EF`T8k&F zp!#!S%gU;&Cu835&>jxD(=8!&tWGYQx8e!;vW>Pt~8gRd(U|K{_6~slm)j)))MnfH@&(O?Cf-UkzxyQO7vMYOX8L#H`{0WU!vuOv3vB+C%;u`_5S08t40xBS;_L>VDH`e)A)R^q zS8r=6aLqpNA8^tLM~?u^p$^Jv&=*S()7y4gu`_6n-RhhP`RBl&KK)T2lb50vGsklf z84-B?tTkj4aUy^;z{Oh;SZHqe=tV%0LBFRz6V;Mb-pC%o45eNNw!OzsqwZr#5>^Ht zxu`xtRS;R(=LSR&<@eBFdd9o!;gmF3D+la0XM`*M?!8{?PZM-S7UjS-vd09UY_wK% zw`U9*?>uRXwU*yy5qWr8*xy1F{RKPneEvN7JZgTwmXgaPV;-HGF(s-+>Eb~mFM1B< zvppeGzzY8)b9T72RD&pf?OunZJgB^Gxm7YYA|MI+A}SbvgSlchSyVP53nSsWN(taC zHFj#1bPqj1F5#I~$4<3CT*Av_56%ov{nH23_Y^E~A&+1%G!V>O5)0nEHzXLhkk|q}& za!~7jJ?Eh<#C+g4J2e_r>|RY@mv_Kf{*OK0;Ny11&rMgU=|DW;WERgv5tn(DJuxeL zoAX7=L2W5zc^o5SBiO_#fD*P@d`eY!QWx2_VgzgPtox*(flBI?h+NG6SZn{JSHKjF zI=pL+*vU<=uBw8@^e^2`Vg;jgj*A-8q7xS==K`0z7%kUklV)LY{7+Xr;Rh%sD2S2D z1wWEX5Ct%ftBUFVxJA(7+6`J@Ev?#OS9O)nRU2h4;%txCVm)j9K2m{X2zm@4SS2i) zq-hkZfppSWgGDW=caqGzsZz+3MS9Bw1;_BMk(o$|eG@UJ0k7Lg5Zf>4I4JK^nPWMh zZ9wv3^xi-%W`L1_FZCIDQ?DKZ%x+ZpK{+{D$~(n-euB`*1Q94S7c&t3T=o_@18O55 zOJt#$kGG_O6iQ}<#zSHP!hZxF9CnGVfDt29&JJ5!4=3RYcBf@;1tUlK8_*+vx?pdU zS~w+`Gt28px*)a?XP92uQWIq1q927y@GNGl9vz0xG1iwd6QOZUhj^Gr-@3w}X*2Z` zxJgmWz1uY!^Ru)0*W`ypgJx^zPrzN4LG0ZW-NY1->|}c{6XQ^uAAczjomax7Yl!1d zMvjBviuKgDrzo>lgen~?F)3TyD)_M@nyb`Ra)jueyV2^aPwtvkz~o63=L;oeXAb#1 zt2Z<}?fnCSJ>-n7$0m;BcAYXs%~HaqBdON@?L>y4<6O#zDEx{6Q{e#c-Qt_Y$9|5V zp~#va0=y-OjJ$*2hIcz)hKjuj^ZA2!qe0?OAX<}B*UsM)Ot+AwCY{$WiX&L1=acA? zG&zSzMTX0N)IW;u6)5GM;pBDhw4h-p{~wuD$sE4a3V(?49_6^b&mRsR{#zWFyAfY= zNypXSzKpkP=;vFRRh;vS_d4e1FDq8Ijslzblt9Xv-&*)bKi|D@&W6Wo5%YdFT99{_ z+!~CPt1hEPKM93O)=j_vCcEKOKSX|2LF7e~=@Zh$MEU%vE&z}wd2DU+AU+G4Rgi^x zL$Yn2{&0l+HRqN`8s)Y_&2OPw1t zrXHETHlK)j_pWpc%-X_B48ynrBp*l?3|E*tN zl}4H8!zj148+u|AUBcE!arcNNABTzB@Gjt~<(%@GgoDm%34ktWSI z!zxc$#Gx>1bV}OGPqYa^bKv@*KQ&JfG6W7WjG_QJX18f|K0qk-e>37bgUl)rabDgA zobbPi_`9WCoCAs@>r+x@v=X{TYh$ea?anT;1fHHUNXaB6WZk&H&EGrsXz+J^Q>=obOdpaMzUdfwcR6#D|#N z5WZ*&gf$gweB=2W@K)d8Y&Nk4GGpRc1bmjAoquV3ioO$I?yk|TDrZdhBYnH|4;c*- zzqm1{!;Ci&!!zsrZe!og&7+N>jRhbFQ1-7XoU_ zaNjd>E>B}fj(+RREo;x$C@sG+LS1Hy=v&-%Z8|#48f8J_u=HJKbvZxOVSnQxEqOps z8R|r{ElW3p7K|*YfR6iPA`x3k)DB2U_brlEAN?=lK3mwA;QL#XS1Z7JesS=4&iD#` z#8T@~KtJJIMOY6F(a&5A!fmU}iElJ-ML=q%A#ahMonJpal|9<#y>n;SthF3LO>XU( z#xRBX9qDd=Kp`&pIkUIjWnO$jnDl4ZQKn$wFMo6zuHkra_4jlT=li#ji5|@MJh@nH zw1GdG5}lAHjm&_pig|5sgh!xb8dL@slvTmaxv$(?2p$6QKNh zCh+zx(pt|EqSIH526aP;t`gkAVMkisR+k9Tln2# z9*-WykNn`O$i0ilPICSH^!Np|E%ku6A2WY85M#DRNGk4fHJFnJ-C*vQ1~q;D{ZDlp zB|l5|2^DLwUCLQ7)JBk&#VFVUF#{K_gso_n1JFkmEk~;2_-s2L06TmZ9bQ~dH2!7w zUeSAGZ3GDz><>fhv~nvBy52%=fyOApRoi@1#6VxzNW z(g#(}RbPYjd1JGXyNrKd7#iNnwpTWe3?g?Pi#Qr1XvJTqRF(AZuC9&s6tAj?nJ?Dv z>EF01U;D@Qu)kde6yRk9=Cb=>{qz>)jU922#&_9drF`Hfjep?r4j!HRBN$27AQZY3 zntkllGSvB_binR?lPk0!hn~7izsevj358e>?^(*tAU*#yEo*HbNTW(vj@Q%Du}k&rHgANjLX>BkPxfUr;?aa7m-5z% zB+frQ=mKPG*iYB;zAroYzdFh zuBMwnz)SKCl$P<#UhbNuT-lp#`2kbX&tW(I{?)X1$8rMjgZZ?^p1y4LMc#JQ;|LAi z50qKhv0GzyQpJpKPK&@7G!XUn`CC4%88;+KaULK2Oksp<;78O(BuCfsF_{8riI)G< zGVtUex$efZRJSTajr*Sb-`7(VPX9;l=x7$pDYs~)s?(8IFh7n)S+p)~G)AbMzhb$~ zvYxy=!{h>&`G$+#tyn%x*%Jm$w%aDM-qr3Hv|@aTd(4}#Y+Yidz&+^$8B6$9=+RnK zVDS(yyxjHjC+kDT#1QHTAK^F4m;VlZi8TdoXDCNSJ5|WrTt=bB!T#q@7LEVbtu#!w zOy-eu9``TjqU}H8b~mu8i@s}ee9M?jM!CW_!a!!3FSs(qr4D_vRPM5YR{@9b08ffRix|&KOSy<36*Nr#!ni&`Kv5yHJ^Kx{W3g+zYy)5cACY_Z7#GA9~dK}ndl zS|pqswLg_8inz+9g+Gj>ejxQBic66PHz`7lxPJaGw#ilA6EEayE8=^tFUgf91VgOe zk7ZufzvpGf1hFR*dd{;!a?G~{Xu^im>Sl!daHRmFLgD!8 z#R5CiDHuUhq9?PgF1a2R-~ZevBxkex;qu6XAYEJSs?YsZah+a`g3&J!KUYJpu=jMj zHZEU25v>#`3qbi#^K0kdu|3<)beH zh-Mi7p*vCgobxCH2aRd-fkS|De`~2sjq}w*b&l(H;0H{wk~M95e&ob#&w=~3pT5HD z+l~?Cpy%1)&d9`|v$17f59JOd!M`S2JUN7msFLQ|{qx5&{~J7!2SsnY2f~SHrz{5L zMcgFdyUbCw1c~5I$_j)F-X>$bbmZ<^O(Wd zuse1rxM$aNw)qx%1?T{Vu%HwSmNa$UjI%{{x}J$0U3pBSJeuBK zw+KHKeBbK18e@h62aVAgu6Lh16j?hyF!q2HhwX zM}l-01GaB_ouHgkLLK0hv{Uhb{@mJ1lXvZ@<_%>X-S5;bDF4}aqA*E?;(vKgeD_xd zA>JO;a}sBh6Gu}|1NJw8-;-JEMA7`bKToH=VuJUIAJmz|EI00+2E}~LWeBZx2l76! z#(qg(@7YX0^wTEQc?IR5oYdq`)CYD65ikkt&wAn9M7_uHyX9Dks*qRNq9Sw1mh~0k zc*^ZPBR(UN0dmw+umZv9Hl46{J8gz7 z?+b$?-}u=UD$nAOcE#{-F(qgAL25{|GMtc&vVwlJU)F;FcI!?MY^DhibP1vomz!%B;#{ z0((J>2vpEur5ympnWmxN|FSz}t;xb!yMDnSUJq#Fq6jA!*SWq1-TIW@!a%<^1Cm>- z)>&AgzT*LccmpbR<+X>Y>E3?g1@Pr%@MY$)lBm5mA6R@eU|sa$;RkX+GDvYd(eX|n z^Bw%W$G??fZo~+)GkC&?+@Qi_MCf@ALz#JPWUQXLnA0M6i1_i((Yx*J2~-mnxf|4P zTY^|Kp?E&}W7{9@uFJKjpYq!w*T6X zh@w1iA9Gq}p4zlik#{<2%XI9Yx+RQ9(CmNs*o_zb{_f5(DpCarW~Ermu+m*sKM!9r zVr~&h!GfjCfw7_BE{Rz0M{#thk2WZ5f%(Or=J~*4>1-T7 zY1@;2U)+C#83UPDCd*=I$y0`6J0Het0#z~&wt>oNP7=au588iHx$p+YtHSbjLC1SUU` zpC`ZESrXUiRh?i7vLaV%UY6rQy*VUvcK*c7MU{B2LhF6S%^wmO2BrP@*K!4uxg8;r z(f7juaJRcUs4|U1%|Ol-`d`WmIfx_YD)ze<4UFX@m#jdC24nDGW7TQot=yBz3UWYM zS9V%XOt+=(TES!5Hv+w1`@RPqdoV)SNYLz&k29LzrY!Sig5lF}x6)$mL;aj>YvPv5 zkkgF{y&PkJ~ zFdqjov(K9NeT`n(NKmlVFQ2pSK{a>z)>6@c9}{%547q{UF$>b!I=k zL0SpUqdHC2WqA$sR5MCjS5`{~G0>~^z@f1X%*UsA?yjo+Dh`Lk7f;h=4VoNxPHBYG zu04E-w3XxL*4YWI69HvW+#;v6b?dlHN*v@@$w*4`%66kI#BOvBS%z7KZc z?c2j~lY0_b5DRY1bf7=MT@k=!fUW5Iv5nh!5)1f)8<(v8i{BDb(8IZLY-^Q?fV?F9 z*|s^TcB9Pe1Ftk(X^VtRu3||$5vyv2*6>AH;44gpq%5#3u)51J7d|)x-`(m2#odA| z@0ly0p3!U%QXgIuD$lNmQ4PVT45rG%yWA0PW?=R4yelMV-g75Js-j<5 z7;h6ew|(0e?d5g((PtA$fP0wlUn>yx_68Y|RsTwCr)DkbtwwHaX)hmvI}doMc28D& zhiw;w%R0lHJ7 zy&^uc^^~lupR%MH7hD(*uco;1OSP}EaZt=eq@2C+tvSU(zKdb)6?>YI(UNw2&j+n( z&moHI{>`!MNp|b0a>4uHCMxR}M|O9^fZvd=!a~2|KJp!O^rBqEjxriT#i8eSpZfG@ z_RYWwoVgt(K+d7)Th)8X0svqQ{C5^$WyZeK<@)vzz!!b;nPzc4{VhiI3k7i-cm9cb zRF`?4m~%XVvSr8;Bhv8!WSo9Eb@})ha)9a^K#seY$sRpl+#A;0M>VVFYl(;DyFD)X8}nb3q};ygBuYQC!cSuq6kXBjc|e}3V_;< ze%vTY%ByFkX`FxwEIT%iAUP@fwHViLL@SA%7*>(|167JTIBaaUDKc^lcE_Cfa+NQA zd=Ydeu^xFB{hGcz>x;{rv?->D5`k5ER#{>D68oJDpO$$ZsS?pIrc}(HA|bGMZ%O1O zh1~i$!jun@jhQliQ>{E&aO+X zzHzpxyKv@?>#EnVfc43A)6Lyo=JpLwD1&4tvz7P78t*GYh>ddXMpW*JROuh zGte|1RMn3HPiveO2ksO)PMAiNkW%o?`K|?UrnK6o^WU$mvD}x6sYL%&aq#$V`AY?- ztA#uNdFX`IS-6!yKO-Mp|5w~wXicH#Q6R6cZu?mYjs2F_#GkbplhAmbSK5?g%P~6s zajV5?CSm!q?2L0%SHpp?iZs{0i$BnJ+0Gc~WwW%!czVWHbZfUL_&fz?bzW)(<_lja z{Z{Sv;TS|C1Sdf3kzh9EaOCd_V4+&3@P2h}iHl5~dCL2}^V9w_c!5ds4U6Z)~38jXAYIx%=hx&sjIA?Ak+nFeUPnTNgi0TrA^ozi2I37{#`D zb2ZFq#;ljzlE31-0j0x5xyk;;Szo!)D5t5i_2E^NS|5;k z`3G%fbX?l$fa9wkzys-XDf5ub;F5a|*iD>ODAh z0fS>UMBW$qoPz=G{!)^w*90l|sLPu%^}P9TeHaPM(>RX9kxQ?b-~98k{@&SZ%BSK% zQ8lbE4ek8-;idjst$IX+?k<#xBS<^$wjT-d0b@RY4gk%)@sE)1u+ezYP;v{sF~3@` z`d*q=H9`2!(njXGKe~nZEEz)>p0~KMIPeN;^Gnkjq3chNtno-e8?_&D1GRqSf7Xo0 zdp3c=6qt14ZnD~HE@>U^Te>RDg=+)~)%+lJy}$~^?#qepmpT!pZ%IZEDzjAK6hX}$ zl;Qz+$_@H7cU?O2c{kkjKE|I3f1CS<=(^5MlU9E@AtvrU+@0!&QFe>`{SL8AS^{;rZ|5Vtl5S*DXU>jBwWQ)_Mti`39!Ff^+_- z$?}S^-NDm-U>?33QW7vw$|Vn$t3bMQ+PI*064=@ZHkg(+S1Y?lIby zQ))@m4a0i*cjkvTv~;LWDl$~+PW06L7@wh8o?{Yuy2rmcWQzH(OVJ=lvCQR9n6F@SDyBGI^mfXPHVor!DOfoXNTQzK{1 z-G6E8lK^CsGS!FJPnLfk|F@f^j93w@!Z>a$dWl0Iu>M?X&E`4mmMB?IbngQ$i<~qk zMDWAi?6IwQUj9J`uM(2@uFleNUBPG3-}A!&6zwcO?eT zziJ||%dIlzB)a>O(vQfiZ{*i3+E`_Zt^yS-!G2^v&UbxdiA`X6tw>v|<@!wl=6IKR z6P!ZbEW=2ldd~X&gg3Lb`WoWwLkCDewhh;F_^TKf6|NAE|dCRxkS@= zim!07573yj@WKIJFe5CV7ECkTmK_j9(W*@nj>0)4N^w&NYS5fQB|0KKel@!IlaXbD zDxJ*Dtjr7%=EuQ8WI(@NvxsD1Pj$=>a(qoqOZS7Rx*$rXBt#wn#~v z8#WG!JJ$vsMdd?k?Y*~5UD;ZLvFpxEzpNYq&a29N0l&x z5YTn#T1Y|3ydR+;(qVip*!BBsW8G4y(Ko}kSC`4liZpd|KnxCA24{^ly_}{x3kvB~ zY3a%aI33N4G2vGfC3He}656t8_rCJrLv9eBW<%2oLFHJZD;Bx{x}ASh&aA(HO5Y^^ z6T+pYP_laZ5NF6kF&X-mlx;seTfp}tLNV+w!zkAHmyY7x(|e-ng!}6IjZ`G2s(brb zor{s%t_+W_j#^1%_YJkWA3FW}Z%fnO7;|OWRL$0}?*H=n0??kV$T~lteJ3&rL~PkUW`-`ymeE5%Ux1q2G6HM9GmrRthrRWo=&aFYKCU9HJ%k#hNi+|# zaZ0OZag4v{e!ReA3PPjxatv8 zV8}+$3g#T`jO((UB&ir{ig!L$+(z3CK2aNEN-EMYNi)Oq&Paz$-5yN{<=`&0*_J0}T_RW54;|jN413+GU3%|A(vr+r0;B2;Bj_}DM`)7i zGW7kEa4-m&=<)7EDW${{PK2X>hUHwmjQ@9@SrcVJbH!d5FJmzKYA5aQBc>Pg#n9+S z4W%