From c2fa8c696f97be8788dcc3845aee276879b54e2c Mon Sep 17 00:00:00 2001 From: CrimsonShrike <29737699+CrimsonShrike@users.noreply.github.com> Date: Mon, 20 Nov 2023 16:57:46 +0300 Subject: [PATCH] [MIRROR] Adds support for cold mist effect for low temperatures --- code/__defines/__renderer.dm | 2 + code/__defines/_renderer.dm | 12 ++++- code/__defines/atmos.dm | 4 ++ code/controllers/configuration.dm | 9 ++++ code/game/objects/effects/misc.dm | 30 +++++++++++ .../objects/effects/particles/particles.dm | 50 ++++++++++++++++++ code/modules/xgm/xgm_gas_data.dm | 19 +++++++ code/modules/xgm/xgm_gas_mixture.dm | 26 +++++++-- icons/effects/particles.dmi | Bin 467 -> 2054 bytes icons/effects/tile_effects.dmi | Bin 1514 -> 2378 bytes 10 files changed, 146 insertions(+), 6 deletions(-) diff --git a/code/__defines/__renderer.dm b/code/__defines/__renderer.dm index 58f9737e378de..7a5cc1db9d3d6 100644 --- a/code/__defines/__renderer.dm +++ b/code/__defines/__renderer.dm @@ -40,6 +40,8 @@ #define HEAT_EFFECT_PLANE -4 #define HEAT_EFFECT_TARGET "*heat" +#define COLD_EFFECT_TARGET "*cold" +#define COLD_EFFECT_BACK_TARGET "*coldb" #define HEAT_COMPOSITE_TARGET "*heatc" #define WARP_EFFECT_PLANE -3 diff --git a/code/__defines/_renderer.dm b/code/__defines/_renderer.dm index 1e2f3aec47c51..8b8ff9d110fb6 100644 --- a/code/__defines/_renderer.dm +++ b/code/__defines/_renderer.dm @@ -237,7 +237,6 @@ GLOBAL_LIST_EMPTY(zmimic_renderers) group = RENDER_GROUP_FINAL plane = RENDER_GROUP_SCENE - /// Render group for stuff OUTSIDE the typical game context - UI, full screen effects, etc. /atom/movable/renderer/screen_group name = "Screen Group" @@ -279,6 +278,7 @@ GLOBAL_LIST_EMPTY(zmimic_renderers) mouse_opacity = MOUSE_OPACITY_UNCLICKABLE var/obj/gas_heat_object = null + var/obj/gas_cold_object = null // Not strictly a heat effect but similar setup so may as well /atom/movable/renderer/heat/proc/Setup() var/mob/M = owner @@ -289,17 +289,27 @@ GLOBAL_LIST_EMPTY(zmimic_renderers) if(gas_heat_object) vis_contents -= gas_heat_object + if(gas_cold_object) + vis_contents -= gas_cold_object + if (quality == GLOB.PREF_LOW) QDEL_NULL(gas_heat_object) gas_heat_object = new /obj/heat(null) + + QDEL_NULL(gas_cold_object) + gas_cold_object = new /obj/effect/cold_mist_gas(null) else QDEL_NULL(gas_heat_object) + QDEL_NULL(gas_cold_object) + gas_cold_object = new /obj/particle_emitter/mist/gas(null) if (quality == GLOB.PREF_MED) gas_heat_object = new /obj/particle_emitter/heat(null) else if (quality == GLOB.PREF_HIGH) gas_heat_object = new /obj/particle_emitter/heat/high(null) vis_contents += gas_heat_object + if(config.enable_cold_mist) + vis_contents += gas_cold_object /atom/movable/renderer/heat/Initialize() diff --git a/code/__defines/atmos.dm b/code/__defines/atmos.dm index 9df0577896c21..9dca486ef05d5 100644 --- a/code/__defines/atmos.dm +++ b/code/__defines/atmos.dm @@ -49,6 +49,9 @@ #define CARBON_LIFEFORM_FIRE_RESISTANCE (T0C + 200) #define CARBON_LIFEFORM_FIRE_DAMAGE 4 +#define FOGGING_TEMPERATURE (T0C + 5) +#define MAX_FOG_TEMPERATURE (T0C - 50) + // Phoron fire properties. #define PHORON_MINIMUM_BURN_TEMPERATURE (T0C + 126) //400 K - autoignite temperature in tanks and canisters - enclosed environments I guess #define PHORON_FLASHPOINT (T0C + 246) //519 K - autoignite temperature in air if that ever gets implemented. @@ -126,3 +129,4 @@ #define GAS_PHORON "phoron" #define GAS_BORON "boron" #define GAS_HEAT "heat" //Not a real gas, used for visual effects +#define GAS_COLD "cold" //Not a real gas, used for visual effects diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 8f19fe0a7e979..430fd2fe228cc 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -430,9 +430,13 @@ var/static/deletion_starts_paused = TRUE +<<<<<<< ours // [SIERRA-ADD] var/static/shutdown_on_reboot = FALSE // [/SIERRA-ADD] +======= + var/static/enable_cold_mist = FALSE +>>>>>>> theirs /datum/configuration/New() @@ -849,6 +853,7 @@ warn_if_staff_same_ip = TRUE if ("deletion_starts_paused") deletion_starts_paused = TRUE +<<<<<<< ours // [SIERRA-ADD] if ("shutdown_on_reboot") shutdown_on_reboot = TRUE @@ -861,6 +866,10 @@ if("minimum_byondacc_age") minimum_byondacc_age = text2num(value) // [/SIERRA-ADD] +======= + if ("enable_cold_mist") + enable_cold_mist = TRUE +>>>>>>> theirs else log_misc("Unknown setting in config/config.txt: '[name]'") diff --git a/code/game/objects/effects/misc.dm b/code/game/objects/effects/misc.dm index ae9a4dfc7fbf1..a798296b2d032 100644 --- a/code/game/objects/effects/misc.dm +++ b/code/game/objects/effects/misc.dm @@ -139,3 +139,33 @@ pixel_x = -176 pixel_y = -176 z_flags = ZMM_IGNORE + +/obj/effect/cold_mist + icon = 'icons/effects/tile_effects.dmi' + icon_state = "frontfog" + layer = FIRE_LAYER + alpha = 170 + +/obj/effect/cold_mist/Initialize() + . = ..() + AddOverlays(image(icon = 'icons/effects/tile_effects.dmi', icon_state = "backfog", layer = BELOW_OBJ_LAYER)) + +//Handling it as an overlay is not layering properly with render targets +/obj/effect/cold_mist_gas_back + icon = 'icons/effects/tile_effects.dmi' + icon_state = "backfog" + layer = BELOW_OBJ_LAYER + render_target = COLD_EFFECT_BACK_TARGET + +/obj/effect/cold_mist_gas + icon = 'icons/effects/tile_effects.dmi' + icon_state = "frontfog" + render_target = COLD_EFFECT_TARGET + layer = FIRE_LAYER + appearance_flags = DEFAULT_APPEARANCE_FLAGS | KEEP_TOGETHER + var/obj/effect/cold_mist_gas_back/b = null + +/obj/effect/cold_mist_gas/Initialize() + . = ..() + b = new() + vis_contents += b diff --git a/code/game/objects/effects/particles/particles.dm b/code/game/objects/effects/particles/particles.dm index 988b885fa6bf6..11aed547b2d3f 100644 --- a/code/game/objects/effects/particles/particles.dm +++ b/code/game/objects/effects/particles/particles.dm @@ -86,6 +86,28 @@ color = "white" +/particles/mist + name = "mist" + icon = 'icons/effects/particles.dmi' + icon_state = list("steam_1" = 1, "steam_2" = 1, "steam_3" = 1) + count = 500 + spawning = 4 + lifespan = 5 SECONDS + fade = 1 SECOND + fadein = 1 SECOND + velocity = generator("box", list(-0.5, -0.25, 0), list(0.5, 0.25, 0), NORMAL_RAND) + position = generator("box", list(-20, -16), list(20, -2), UNIFORM_RAND) + friction = 0.2 + grow = 0.0015 + + +/particles/mist/back + name = "mist_back" + spawning = 7 + position = generator("box", list(-20, -1), list(20, 20), UNIFORM_RAND) + lifespan = 6 SECONDS + fadein = 1.5 SECONDS + /particles/fire_sparks name = "fire sparks" width = 500 @@ -333,3 +355,31 @@ /obj/particle_emitter/heat/high particle_type = "high heat" + + +/obj/particle_emitter/mist + particle_type = "mist" + layer = FIRE_LAYER + +/obj/particle_emitter/mist/back + particle_type = "mist_back" + layer = BELOW_OBJ_LAYER + + +/obj/particle_emitter/mist/back/gas + render_target = COLD_EFFECT_BACK_TARGET + +/obj/particle_emitter/mist/back/gas/Initialize(mapload, time, _color) + . = ..() + filters += filter(type="alpha", render_source = COLD_EFFECT_TARGET, flags = MASK_INVERSE) + + +//for cold gas effect +/obj/particle_emitter/mist/gas + render_target = COLD_EFFECT_TARGET + var/obj/particle_emitter/mist/back/b = /obj/particle_emitter/mist/back/gas + +/obj/particle_emitter/mist/gas/Initialize(mapload, time, _color) + . = ..() + b = new b(null) + vis_contents += b diff --git a/code/modules/xgm/xgm_gas_data.dm b/code/modules/xgm/xgm_gas_data.dm index 0feb45d6323cc..85dd1adffd7db 100644 --- a/code/modules/xgm/xgm_gas_data.dm +++ b/code/modules/xgm/xgm_gas_data.dm @@ -117,3 +117,22 @@ var/global/datum/xgm_gas_data/gas_data . = ..() icon = null icon_state = null + +/obj/effect/gas_cold_back + render_source = COLD_EFFECT_BACK_TARGET + plane = DEFAULT_PLANE + layer = BELOW_OBJ_LAYER + +/obj/gas_overlay/cold + name = "gas" + desc = "You shouldn't be clicking this." + gas_id = GAS_COLD + render_source = COLD_EFFECT_TARGET + var/obj/effect/gas_cold_back/b = null + +/obj/gas_overlay/cold/Initialize(mapload, gas) + . = ..() + icon = null + icon_state = null + b = new() + vis_contents += b diff --git a/code/modules/xgm/xgm_gas_mixture.dm b/code/modules/xgm/xgm_gas_mixture.dm index b017f12a27093..62435d5cb39db 100644 --- a/code/modules/xgm/xgm_gas_mixture.dm +++ b/code/modules/xgm/xgm_gas_mixture.dm @@ -349,6 +349,8 @@ for(var/obj/gas_overlay/O in graphic) if(istype(O, /obj/gas_overlay/heat)) continue + if(istype(O, /obj/gas_overlay/cold)) + continue if(gas[O.gas_id] <= gas_data.overlay_limit[O.gas_id]) LAZYADD(graphic_remove, O) for(var/g in gas_data.overlay_limit) @@ -359,13 +361,20 @@ LAZYADD(graphic_add, tile_overlay) . = 0 - var/tile_overlay = get_tile_overlay(GAS_HEAT) + var/heat_overlay = get_tile_overlay(GAS_HEAT) //If it's hot add something if(temperature >= CARBON_LIFEFORM_FIRE_RESISTANCE) - if(!(tile_overlay in graphic)) - LAZYADD(graphic_add, tile_overlay) - else if (tile_overlay in graphic) - LAZYADD(graphic_remove, tile_overlay) + if(!(heat_overlay in graphic)) + LAZYADD(graphic_add, heat_overlay) + else if (heat_overlay in graphic) + LAZYADD(graphic_remove, heat_overlay) + + var/cold_overlay = get_tile_overlay(GAS_COLD) + if(temperature <= FOGGING_TEMPERATURE && (return_pressure() >= (ONE_ATMOSPHERE / 4))) + if(!(cold_overlay in graphic)) + LAZYADD(graphic_add, cold_overlay) + else if (cold_overlay in graphic) + LAZYADD(graphic_remove, cold_overlay) //Apply changes if(graphic_add && length(graphic_add)) @@ -382,6 +391,11 @@ if(new_alpha != O.alpha) O.update_alpha_animation(new_alpha) continue + if(istype(O, /obj/gas_overlay/cold)) + var/new_alpha = clamp(max(125, 200 * (1 - ((temperature - MAX_FOG_TEMPERATURE) / (FOGGING_TEMPERATURE - MAX_FOG_TEMPERATURE)))), 125, 200) + if(new_alpha != O.alpha) + O.update_alpha_animation(new_alpha) + continue var/concentration_mod = clamp(gas[O.gas_id] / total_moles, 0.1, 1) var/new_alpha = min(230, round(pressure_mod * concentration_mod * 180, 5)) if(new_alpha != O.alpha) @@ -391,6 +405,8 @@ if(!LAZYACCESS(tile_overlay_cache, gas_id)) if(gas_id == GAS_HEAT) //Not a real gas but functionally same thing LAZYSET(tile_overlay_cache, gas_id, new/obj/gas_overlay/heat(null, GAS_HEAT)) + else if(gas_id == GAS_COLD) //Not a real gas but functionally same thing + LAZYSET(tile_overlay_cache, gas_id, new/obj/gas_overlay/cold(null, GAS_COLD)) else LAZYSET(tile_overlay_cache, gas_id, new/obj/gas_overlay(null, gas_id)) return tile_overlay_cache[gas_id] diff --git a/icons/effects/particles.dmi b/icons/effects/particles.dmi index 4825d9701c591e0b5f6ab82108aed3a9fad3fc44..06c8b40733e751018a849c37cb6111d00ced9244 100644 GIT binary patch literal 2054 zcmZ`)eK-?p8{gJ^&6wecMnmSzY2+(9R%5;*A7^PQm5-1Rk$e*~vI#|cI~r;#-*1yq zoFbHlmRs_ye}yBS*lC#ot3ht49$V0< z2g}Yn{=RcZ;lT8YX=(558QY>k?qOs-zBQ$#Tx6H-5Rfvcyit{YUXz2^ap93Cchn^v z0FaS$w#O6Wi|0$)L&u%eJFQW(DjD`*6s;e51ve{iXc3$}{ zA$@Xv%=TI+uj~d2Ggig{((IF{)-nGcee0;wpQ^vSmG-c#TO*pgJE?4=px9ZDxyu0W?^BoU} z-`vdI5VQOkeV=7BhLx?bkbC$e&MK8KLP{KZ!6p#F55Vwzc4X7T(+g&?CzE^0XS^7? zUxt{}u3Rg057XyAf=1`zhS}&4S}bGD4{VgfiJX4Lu|i86yv(N+o#RV z=I)HRmvj1ornmOBO!Y7^gHL-Mnx4peeDn^q*9n+Q29BJ`VddivGtb4V0eu zOtbkxubceHeZ|VkPq#`}ZYMmumqZUh`Y zJHKEvnN3|0UV_7KxmT3D8VHen^C8pnScU19p|sD=R>q?xp-5bu!|-2=jk~{YNO}2n zO=w!;UNqG&USDQ2U`?_eOOaQCkm2BogB?3t@9fL1b*&giD8K)g`v{4~f4!Ie+SAt3 z(h|EJt=BLK&#mR{mEUDW^2+21oh$n1l2w?&&dkE2S=K3hT@y<2)UiFqw;Nx5c*G7j z?r&*)I((zlMeDesd&Vi9Ut-5bPBO4IPodsZ7h^CW)J&0*GVcEi|DQ?vUr+e8aT0EG z5)_NlZhTG%#~KuZGJ9#@_nAjiAJWo^@D0RPy9osJ>TDt?`xvEX1 z90%qrJbYC028l~ihUZuOw$o0M>_C}qaJYd(C@EtGN=1+x9}in$)tv-_Yza}JK(BK! z1{L!7n-2ERQm{2^Yl%iEC~jNq0-kn>Xgd*y$F3GNel2DlqxG!`vX@8A2I@~UI!xtH z@UkqHkc~N7aA3FHJB_?He4}r(Mjlo6nWzxB zi(+S-Mm}%dCzGQYEj--Th3}W)C~5vWvwDw|{{ren-w*1nAmyivck@+^quhgPD-V(- zD%GheiQEzgv`3~@;I~}$XV&?FrtA%pO>(6*7d4c(PDs<4vJ;h7WO%Xdq%w10{Ids8 zkSy3w>ZZ6rBt+c=_a`zm;eAp&1p?Jrxn~RyYOCaxiY4K&C>sINIqJwvzo0g%E-F#P{64xrt zZvMRo$SCis?JVx)Q?R}BYmF^Fz2dF1y3~OBVt0F>Av=SJC2xSkfK1(!!=!C*__ay~YG!fdKuvvk9*c;Fzx28*VnR0kB1bJswQIWWr$ zo4Qv1$?9YSNu=7^l#f)lQka}n!wU-3>DzapT{`>x3xS5Eq}cU5;Gj!`7almjh?mqI zm8T;lv{6I)L+q6rNQ*k0#YH7=Fe16oW7L8Pe1~$Ld&2nic`W&f*eB`I zGnc8BKNj9Idr#e|6+N@K>Wy+%UWwNA@08w%=)2y;R&xE(s`=4-OUS-W0HJ<`J}g=6 N0A~kxdxota`7b)Jt)2h? literal 467 zcmV;^0WAKBP)fFDZ*Bkp zc$`yKaB_9`^iy#0_2eo`Eh^5;&r`5fFwryM;w;ZhDainGjE%TBGg33tGfE(w;*!LY zR3K9+CBH<8i!&v&s2IpIWd&D1 z7jTdO03%>c(&?*DKmY&$KRY4BIFbr#uxUU%xU>P4^84noE3;6$IDB@B_ z&}vtxZ=LMe?Ib6Jjz33)6Gd+EWhjqh(y7i@-AaRtrDgcaeiN)9u$f9tz*&&aFyK** zL}Ez`LEz*Kjws+6Bd}BxlN92J94cbaebXTCG8@x5zi2 zE3V*+>tq|8i3JriPNdxC@FAK>new0uSR7QL{z=WOWYBu63PxQGLegqih~)OgsM(^7 zM5uq=5$iuYUdsvD0iTK7D`pG)GkmWv5c2&`dlyJ(Y^aW(#}jBl8VfqYA7%gm002ov JPDHLkV1lim$BX~~ diff --git a/icons/effects/tile_effects.dmi b/icons/effects/tile_effects.dmi index a1b92ff11dcb9f2167baf28d9daae8187d078c01..e06975542367fbe88f14ab170758029747dce13e 100644 GIT binary patch literal 2378 zcmV-Q3AOf#P)V=-0C=2@%DW1~AQ*<>S+C+F*-KBWOEDCO#{3d$*H;Qci}^u<%jDrOcHWb`~&CYN_#abDg*!k2zNy}_pTIxK0hb- z;Fz6#wr&nv_%;eExT0qZn zR8_Ke9EZvg5$RlCHYR_gs!f5v&&F-s7z2`E+ZBE)M?}QWJy&uFIsj^d=|!Xg(o6wB zRcSd;)lNjzz6+A|0Z9oDBJu*0Fk$0(E(P$QNmBlQYJwR=WXSki8y{vIRJw3pNJ@AV zk?Rfoj|Kiv`0d*vO=yR-kSkkohqMd4@PQtMdZ=(!1@ha1@&BL-18RzdsXd`tdc&HLZA;H zbnYX1_xG2z*}M0!v99bH0KUQGzK9)wUR4LYbd z+^5(=;4&1y#amMhg$xntRdr`pOpn3wZtQtL+AXbFbZh)RCXk<&Pk!${8YfKh54Nj4 zKgYYW=K*QAgrb321d)?0BKh-@7?`e!8>rt=T|XyY=WYuFZd84xim z6POS?=gRVNeRe`gG%Nf}VacDnjS_$BT-lRx?f-f34}o9IctBFs7nt&DrgmHiEjvH# z2rQ1+XJ>~g!IY)=L)Z(@yf&S!}Uf&Mu);V$S)gq`iCgR_pnBuq&0b*Z9{;+0PE1 zgo%9OJl%eSf1oo1g)Q1?f$c9aX$gQwdYB%j@8?P~ZL<3iEFE;Ux_>4)n1bOEQ{ zCsfz-weCJ46s*P6)bn{rI`uxGx}Gm}_X(k(b=B1K{aB~oC!C|6f9icgD8{k_>g)NZ z-Y1-^o`33nLMR$c!HE-mz+3@4*QUi(x)={umZB=m-`o1Q8}{~oRJ60}9x+$I z-nD5kl`h7E6_svddw$l3IQD>f=^|VaOx@R? zCxoIweLcVSKB2arUwfYriUz2z=b!67;naG5^?gDln7`N5^K0)DYU}y6_X(k37DSv{ z&p-El!m;)In)`%MjFZv&dj2`?6Kd-DRrd)|@Rh(*>-p!pPdK%nf3Ew45R5_CE$-BM z{<-cGj;-fc-zP+Z8G^Xa(MKN$R?Lc6ndCukHnw3$_e0Ce{I&la-Qod$?}j+-~ae?6xyfHAMx(}2i)J?7Tdmi|DpK*67n%#e*4|*`=`$z0RaF0 z*Ds+;2)zx;@$%d6o(Kw$h)ke|I|*-jcu%S#=4eu`WUI zM7RQgBoHr@tuAOykmqn?UjyL^@Yc^5Kq2KqT-pKbcc@+dd_#o0tM!Uo?H7R2=y3*E8za_c62*i{qt7;zSOSNHVWYi0DvFA|KZ91 za=#9g-Hf;RHG${-E+rORgaRnUl7J2gYUzNrrSB!Ut8fMQOos7bsm(FtoxAOGAzT5# z(`;rx`Gp8}_41f^QO$Gi6*Mun6X{^|2a+~3`vB{-J&J(l>RG46n4g;1J2{jaw+ zJ};eg*(ZuW8Z#HPCWIvmE1f>QwUsKHODEX~{%CZ08FwwE%S*?=`eJ;*^H+^t(9!(S znC*bl0f&B?--)e6Z;l0*>a7#w-geZB2h^p8H?l*W*x)rnK;A{wQ>%;uhfr;saMr04oVEl0O== zEGXZ)rJ~mB=ygKN2U^g0=+1EtYxe>GYiZ(dcp^0Ozrc wwG=Qfl11`IqXX7|b9qWmeQZH3nm-c%2k-sj1c@(s!2kdN07*qoM6N<$f(1ObSO5S3 literal 1514 zcmVV=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex7wuvIWN;^NFm z%}mcIfpCgT5=&AQY!#H!Q}a@bGLx0KI8!o)|IeJm9>=joVGin+T3kEH zidj~rM2i#}1o2K}=5MTH0&oFv1rRunw7J%10C#?K!Rzth`h(xxNJBIyKCAKY9sEX` zlhJrKX0Fft=I;0tfXGZlM9s_^5y;E~frtY?)d(~lA~U1gCpr>NM8ss@YP0Z5W|k-T zt)p9v#=?WuPw*w2hzRFBw3uY9MMTj~5|HGOnNvh0e+O3SgF?7P#Je3vhzEWE+;ZjA z-z6DaB4X+AtAxzUk4zay~mHt{D(g#+ZdU7A!AKaw!?!0XnYSo->_@Q zj+{A1#2?PZSbg%n<4?Shh5L#f9^_@=d+>R|t|5-!BI2XNF94Qe`#u27nc1-3ifksy zoNRc>qmDNF`@=o6t%I~KoCClw?B=8K0MIgXA%5cllgx^r9)GdF597u08+gIQzjFWj zk~ajb_C8TcNv0&VjW9I>I65b3$Bl=TMm=nwv_$h*$*1hR(H99{<_DUGOhgygUqoPa zauarqnr)x7MDvhjU1i+q>DH#qluZguw>)9J(TPBFWVnOL=G#;(m_!oG05kyb4LCf?|jnPL|93=)EQXjidH!RU~Ph?bcT z-l8;C^sbyQShc0{Ml11qpAa+)$6pM;=rD%AP^%qZ^e&t)0PaN+AtTjpSszvRrZfe2 zbS)xo*nI^+8@3zhHEg1%uUKt*0ZukfWZ6?^_6J1Q0l z-ar+z2%vFDQ+bHVOsS{q-dUWKPw*8&h3_Wv3cs2u{fjQ&HvkctdBagPlTvz+u?c(r zyk&q4U9N^v^f**?z)MJ#YA@`U%R#N9uVcDQEi$ zL-joOo$e=iKj3UVuW`1Ypz82cJ#X7i^%J(V7vuH(*?z)MJ#XVwKcQfE4%%?*1n{su z6?^Ke3J?sD3EDg9D~p`Dz6si5xH~5?eD4G>+n$0wsZx>z37xbZU-f}#FF2;oTTMPv z&yV&KhU$3?_7jw~jnwm_{e+=<9)taag7JEOw4X3k&ttHkP=Mij{-^p0r|NkO_7fDp zN9y^}e!@^akHLO|qQHiq=j!>N?k9Y^p0{(n!vD0Nu>Ft&A%m4dkgdy0`~UIYJLb2w z%zVcl*8}V)kU?oypX`J&SS+=c_us-Ec6E3BZ7nn3h_6ELVffOlaHhrhnR@=G`U$7% zc?|XwioFo=v-SK>^%MS6J#YA@`U#QizsLWtdj3281ZmKzdj1RiFZ&690cia=`?d<| QRsaA107*qoM6N<$f;TbqKmY&$