From 4f3e6e1d5866a1eafccff33caefe5a532d52b937 Mon Sep 17 00:00:00 2001 From: ayunami2000 Date: Fri, 22 Jul 2022 01:11:49 -0400 Subject: [PATCH] Voice chat --- .../me/ayunami2000/ayungee/ExpiringSet.java | 71 ++++++ .../java/me/ayunami2000/ayungee/Main.java | 19 +- .../ayunami2000/ayungee/PluginMessages.java | 2 +- .../java/me/ayunami2000/ayungee/Voice.java | 209 ++++++++++++++++++ .../ayunami2000/ayungee/WebSocketProxy.java | 6 +- src/main/resources/config.yml | 12 + ...gee-1.0-SNAPSHOT-jar-with-dependencies.jar | Bin 2985397 -> 2992338 bytes 7 files changed, 316 insertions(+), 3 deletions(-) create mode 100644 src/main/java/me/ayunami2000/ayungee/ExpiringSet.java create mode 100644 src/main/java/me/ayunami2000/ayungee/Voice.java diff --git a/src/main/java/me/ayunami2000/ayungee/ExpiringSet.java b/src/main/java/me/ayunami2000/ayungee/ExpiringSet.java new file mode 100644 index 0000000..596ed18 --- /dev/null +++ b/src/main/java/me/ayunami2000/ayungee/ExpiringSet.java @@ -0,0 +1,71 @@ +package me.ayunami2000.ayungee; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; + +// note that there's a few things not implemented, but I don't care. + +public class ExpiringSet extends HashSet { + private final long expiration; + private final ExpiringEvent event; + + private final Map timestamps = new HashMap<>(); + + public ExpiringSet(long expiration) { + this.expiration = expiration; + this.event = null; + } + + public ExpiringSet(long expiration, ExpiringEvent event) { + this.expiration = expiration; + this.event = event; + } + + public interface ExpiringEvent { + void onExpiration(T item); + } + + public void checkForExpirations() { + Iterator iterator = this.timestamps.keySet().iterator(); + long now = System.currentTimeMillis(); + while (iterator.hasNext()) { + T element = iterator.next(); + if (super.contains(element)) { + if (this.timestamps.get(element) + this.expiration < now) { + if (this.event != null) this.event.onExpiration(element); + iterator.remove(); + super.remove(element); + } + } else { + iterator.remove(); + super.remove(element); + } + } + } + + public boolean add(T o) { + checkForExpirations(); + boolean success = super.add(o); + if (success) timestamps.put(o, System.currentTimeMillis()); + return success; + } + + public boolean remove(Object o) { + checkForExpirations(); + boolean success = super.remove(o); + if (success) timestamps.remove(o); + return success; + } + + public void clear() { + this.timestamps.clear(); + super.clear(); + } + + public boolean contains(Object o) { + checkForExpirations(); + return super.contains(o); + } +} \ No newline at end of file diff --git a/src/main/java/me/ayunami2000/ayungee/Main.java b/src/main/java/me/ayunami2000/ayungee/Main.java index f1d491e..fddaea4 100644 --- a/src/main/java/me/ayunami2000/ayungee/Main.java +++ b/src/main/java/me/ayunami2000/ayungee/Main.java @@ -23,9 +23,11 @@ public class Main { public static byte[] serverIcon = null; public static boolean forwarded = false; - public static boolean serverCmd = true; + public static boolean voiceEnabled = true; + public static List voiceICE = new ArrayList<>(); + public static boolean useAuth = false; public static int authIpLimit = -1; @@ -117,6 +119,21 @@ public class Main { } } + voiceICE.add("stun:openrelay.metered.ca:80"); + voiceICE.add("turn:openrelay.metered.ca:80;openrelayproject;openrelayproject"); + voiceICE.add("turn:openrelay.metered.ca:443;openrelayproject;openrelayproject"); + voiceICE.add("turn:openrelay.metered.ca:443?transport=tcp;openrelayproject;openrelayproject"); + + Map configVoice = new LinkedHashMap<>(); + configVoice.put("enabled", true); + configVoice.put("ice", voiceICE); + + configVoice = (LinkedHashMap) config.getOrDefault("voice", configVoice); + + voiceEnabled = (boolean) configVoice.getOrDefault("enabled", true); + + voiceICE = (List) configVoice.getOrDefault("ice", voiceICE); + Map configAuth = new LinkedHashMap<>(); configAuth.put("enabled", false); configAuth.put("ip_limit", -1); diff --git a/src/main/java/me/ayunami2000/ayungee/PluginMessages.java b/src/main/java/me/ayunami2000/ayungee/PluginMessages.java index 1554586..4498301 100644 --- a/src/main/java/me/ayunami2000/ayungee/PluginMessages.java +++ b/src/main/java/me/ayunami2000/ayungee/PluginMessages.java @@ -30,7 +30,7 @@ public class PluginMessages { } public static boolean fromClient(Client client, String name, byte[] data) { - return Skins.setSkin(client.username, client.conn, name, data); + return Skins.setSkin(client.username, client.conn, name, data) || Voice.handleVoice(client.username, client.conn, name, data); } public static boolean serverPluginMessage(Client client, byte[] packet) { diff --git a/src/main/java/me/ayunami2000/ayungee/Voice.java b/src/main/java/me/ayunami2000/ayungee/Voice.java new file mode 100644 index 0000000..3a2670d --- /dev/null +++ b/src/main/java/me/ayunami2000/ayungee/Voice.java @@ -0,0 +1,209 @@ +package me.ayunami2000.ayungee; + +import org.java_websocket.WebSocket; + +import java.io.*; +import java.util.*; + +public class Voice { + private static final Map voicePlayers = new HashMap<>(); + private static final Map> voiceRequests = new HashMap<>(); + private static final Set voicePairs = new HashSet<>(); + + private static final int VOICE_SIGNAL_ALLOWED = 0; + private static final int VOICE_SIGNAL_REQUEST = 0; + private static final int VOICE_SIGNAL_CONNECT = 1; + private static final int VOICE_SIGNAL_DISCONNECT = 2; + private static final int VOICE_SIGNAL_ICE = 3; + private static final int VOICE_SIGNAL_DESC = 4; + private static final int VOICE_SIGNAL_GLOBAL = 5; + + public static boolean handleVoice(String user, WebSocket connection, String tag, byte[] msg) { + synchronized (voicePlayers) { + if (!Main.voiceEnabled) return false; + if (!("EAG|Voice".equals(tag))) return false; + try { + if (msg.length == 0) return true; + DataInputStream streamIn = new DataInputStream(new ByteArrayInputStream(msg)); + int sig = streamIn.read(); + switch (sig) { + case VOICE_SIGNAL_CONNECT: + if (voicePlayers.containsKey(user)) return true; // user is already using voice chat + // send out packet for player joined voice + // notice: everyone on the server can see this packet!! however, it doesn't do anything but let clients know that the player has turned on voice chat + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + dos.write(VOICE_SIGNAL_CONNECT); + dos.writeUTF(user); + byte[] out = baos.toByteArray(); + for (WebSocket conn : voicePlayers.values()) sendVoicePacket(conn, out); + voicePlayers.put(user, connection); + for (String username : voicePlayers.keySet()) sendVoicePlayers(username); + break; + case VOICE_SIGNAL_DISCONNECT: + if (!voicePlayers.containsKey(user)) return true; // user is not using voice chat + try { + String user2 = streamIn.readUTF(); + if (!voicePlayers.containsKey(user2)) return true; + if (voicePairs.removeIf(pair -> (pair[0].equals(user) && pair[1].equals(user2)) || (pair[0].equals(user2) && pair[1].equals(user)))) { + ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); + DataOutputStream dos2 = new DataOutputStream(baos2); + dos2.write(VOICE_SIGNAL_DISCONNECT); + dos2.writeUTF(user); + sendVoicePacket(voicePlayers.get(user2), baos2.toByteArray()); + baos2 = new ByteArrayOutputStream(); + dos2 = new DataOutputStream(baos2); + dos2.write(VOICE_SIGNAL_DISCONNECT); + dos2.writeUTF(user2); + sendVoicePacket(connection, baos2.toByteArray()); + } + } catch (EOFException e) { + removeUser(user); + } + break; + case VOICE_SIGNAL_REQUEST: + if (!voicePlayers.containsKey(user)) return true; // user is not using voice chat + String targetUser = streamIn.readUTF(); + if (user.equals(targetUser)) return true; // prevent duplicates + if (checkVoicePair(user, targetUser)) return true; // already paired + if (!voicePlayers.containsKey(targetUser)) return true; // target user is not using voice chat + if (!voiceRequests.containsKey(user)) voiceRequests.put(user, new ExpiringSet<>(2000)); + if (voiceRequests.get(user).contains(targetUser)) return true; + voiceRequests.get(user).add(targetUser); + + // check if other has requested earlier + if (voiceRequests.containsKey(targetUser) && voiceRequests.get(targetUser).contains(user)) { + if (voiceRequests.containsKey(targetUser)) { + voiceRequests.get(targetUser).remove(user); + if (voiceRequests.get(targetUser).isEmpty()) voiceRequests.remove(targetUser); + } + if (voiceRequests.containsKey(user)) { + voiceRequests.get(user).remove(targetUser); + if (voiceRequests.get(user).isEmpty()) voiceRequests.remove(user); + } + // send each other add data + voicePairs.add(new String[]{user, targetUser}); + ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); + DataOutputStream dos2 = new DataOutputStream(baos2); + dos2.write(VOICE_SIGNAL_CONNECT); + dos2.writeUTF(user); + dos2.writeBoolean(false); + sendVoicePacket(voicePlayers.get(targetUser), baos2.toByteArray()); + baos2 = new ByteArrayOutputStream(); + dos2 = new DataOutputStream(baos2); + dos2.write(VOICE_SIGNAL_CONNECT); + dos2.writeUTF(targetUser); + dos2.writeBoolean(true); + sendVoicePacket(connection, baos2.toByteArray()); + } + break; + case VOICE_SIGNAL_ICE: + case VOICE_SIGNAL_DESC: + if (!voicePlayers.containsKey(user)) return true; // user is not using voice chat + String targetUser2 = streamIn.readUTF(); + if (checkVoicePair(user, targetUser2)) { + String data = streamIn.readUTF(); + ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); + DataOutputStream dos2 = new DataOutputStream(baos2); + dos2.write(sig); + dos2.writeUTF(user); + dos2.writeUTF(data); + sendVoicePacket(voicePlayers.get(targetUser2), baos2.toByteArray()); + } + break; + default: + break; + } + } catch (Throwable t) { + // hacker + // t.printStackTrace(); // todo: remove in production + removeUser(user); + } + } + return true; + } + + public static void onLogin(String username, WebSocket conn) { + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + dos.write(VOICE_SIGNAL_ALLOWED); + dos.writeBoolean(Main.voiceEnabled); + dos.write(Main.voiceICE.size()); + for(String str : Main.voiceICE) { + dos.writeUTF(str); + } + sendVoicePacket(conn, baos.toByteArray()); + sendVoicePlayers(username); + } catch (IOException ignored) { } + } + + public static void onQuit(String username) { + removeUser(username); + } + + private static void sendVoicePlayers(String name) { + synchronized (voicePlayers) { + if (!Main.voiceEnabled) return; + if (!voicePlayers.containsKey(name)) return; + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + dos.write(VOICE_SIGNAL_GLOBAL); + Set mostlyGlobalPlayers = new HashSet<>(); + for (String username : voicePlayers.keySet()) { + if (username.equals(name)) continue; + if (voicePairs.stream().anyMatch(pair -> (pair[0].equals(name) && pair[1].equals(username)) || (pair[0].equals(username) && pair[1].equals(name)))) + continue; + mostlyGlobalPlayers.add(username); + } + if (mostlyGlobalPlayers.size() > 0) { + dos.writeInt(mostlyGlobalPlayers.size()); + for (String username : mostlyGlobalPlayers) dos.writeUTF(username); + sendVoicePacket(voicePlayers.get(name), baos.toByteArray()); + } + } catch (IOException ignored) { + } + } + } + + private static void removeUser(String name) { + synchronized (voicePlayers) { + voicePlayers.remove(name); + for (String username : voicePlayers.keySet()) { + if (!name.equals(username)) sendVoicePlayers(username); + } + for (String[] voicePair : voicePairs) { + String target = null; + if (voicePair[0].equals(name)) { + target = voicePair[1]; + } else if (voicePair[1].equals(name)) { + target = voicePair[0]; + } + if (target != null && voicePlayers.containsKey(target)) { + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + dos.write(VOICE_SIGNAL_DISCONNECT); + dos.writeUTF(name); + sendVoicePacket(voicePlayers.get(target), baos.toByteArray()); + } catch (IOException ignored) { + } + } + } + voicePairs.removeIf(pair -> pair[0].equals(name) || pair[1].equals(name)); + } + } + + private static boolean checkVoicePair(String user1, String user2) { + return voicePairs.stream().anyMatch(pair -> (pair[0].equals(user1) && pair[1].equals(user2)) || (pair[0].equals(user2) && pair[1].equals(user1))); + } + + private static void sendVoicePacket(WebSocket conn, byte[] msg) { + byte[] packetPrefix = new byte[] { (byte) 250, 0, 9, 0, 69, 0, 65, 0, 71, 0, 124, 0, 86, 0, 111, 0, 105, 0, 99, 0, 101, (byte) ((msg.length >>> 8) & 0xFF), (byte) (msg.length & 0xFF) }; + byte[] fullPacket = new byte[packetPrefix.length + msg.length]; + System.arraycopy(packetPrefix, 0, fullPacket, 0, packetPrefix.length); + System.arraycopy(msg, 0, fullPacket, packetPrefix.length, msg.length); + conn.send(fullPacket); + } +} \ No newline at end of file diff --git a/src/main/java/me/ayunami2000/ayungee/WebSocketProxy.java b/src/main/java/me/ayunami2000/ayungee/WebSocketProxy.java index 2e614d4..ba8bd65 100644 --- a/src/main/java/me/ayunami2000/ayungee/WebSocketProxy.java +++ b/src/main/java/me/ayunami2000/ayungee/WebSocketProxy.java @@ -66,6 +66,7 @@ public class WebSocketProxy extends WebSocketServer { if (selfClient != null) { Main.printMsg("Player " + selfClient + " left!"); Skins.removeSkin(selfClient.username); + Voice.onQuit(selfClient.username); if (selfClient.socket.isClosed()) { try { selfClient.socket.close(); @@ -169,7 +170,10 @@ public class WebSocketProxy extends WebSocketServer { if (!selfClient.authed && data[0] == 13) selfClient.positionPacket = data; boolean loginPacket = data[0] == 1; if (loginPacket && !selfClient.hasLoginHappened) selfClient.hasLoginHappened = true; - if (selfClient.firstTime && loginPacket) selfClient.clientEntityId = selfClient.serverEntityId = EntityMap.readInt(data, 1); + if (selfClient.firstTime && loginPacket) { + selfClient.clientEntityId = selfClient.serverEntityId = EntityMap.readInt(data, 1); + Voice.onLogin(username, conn); + } if (!selfClient.firstTime && loginPacket) { selfClient.serverEntityId = EntityMap.readInt(data, 1); // assume server is giving valid data; we don't have to validate it because it isn't a potentially malicious client diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index c2a5cc1..9a24eca 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -13,6 +13,18 @@ origin_blacklist: "https://g.eags.us/eaglercraft/origin_blacklist.txt" origins: [] # enable /server command? server_cmd: true +# voice chat +voice: + # enable voice chat + enabled: true + # voice chat ICE servers + # format is like OR ;; + # chances are you won't have to change these + ice: + - "stun:openrelay.metered.ca:80" + - "turn:openrelay.metered.ca:80;openrelayproject;openrelayproject" + - "turn:openrelay.metered.ca:443;openrelayproject;openrelayproject" + - "turn:openrelay.metered.ca:443?transport=tcp;openrelayproject;openrelayproject" # authentication info auth: # use auth diff --git a/target/ayungee-1.0-SNAPSHOT-jar-with-dependencies.jar b/target/ayungee-1.0-SNAPSHOT-jar-with-dependencies.jar index 91f923e292d6c46665cb145170f96407a5de3a81..db66873964653fcca6cdcec84109c12f362d6997 100644 GIT binary patch delta 25601 zcmYhi1x%%}*0zn?;O-3WzHtTycXxMphk;>Z8+UhicXxMpm%-hg`RAPTzsc7;Y3?+6 zl6JLgwP~-_l+g@6Ki3S7q$mRkg#h-SVrYIBheQFXXMX1o00F>300k0O%k91_*!&0$_mv*dPE72!IO$ z;DG@6AOHafKnMa5fdIrH00{{29Rwf+0mwiAau9$51fT=~s6YT}5P${*palWwngH~0 zgOLCFlOi}sPyAnDI7mhKNYN~}kvj)D zsH0kM5AO-lxvHq64x_NM*bGC%ukTRKmm*LW@UDK5&XsbRIFHu+__L>;KqwZ-1I+Y( zP--_XpZC2zKQDx>O$SxL_$xOtN2B&QJv4YG{Lf?5Z|)O4SXk@ke!Ehc^>H2>Pf)^D z2)$qk4VBQxebr4{REn?&H+Jq4mgZb7im2v)5^iZcx`lF-l7*wGVuPIY8_+5d%e@QQ z(wRMS46Wg~pj6fCKquc9fZ!Uz-y7AfIs}Mgel;9!Gk~PfOt9u(eX>xiMU+E${u11c zn-CwzAjP*vVMyiDx>Cd`a#COzawgn~h)Ex(*JIe%S%F76$?aC7^7p%hk88=$g-bAD zSVowcorrduK`1n2T!h2X`urv3uGfpZ_jSLhW0*77=rCeZ8;gqQ241~2J87epLhzVA zUx{~l+$kajIyx}6LW0=~=wGicowxeMAM$$@T*EW{I;8aJ-sqWO_8i?dminkmNNGlZd0+J~}&D^^DdVA~PX%8p1i@p3sqV~wp(wWV{H7Z`kVr}7d>cT}F z=7`Jg(KGPDxn)!)YOtT&;>HL#%ur&@a)n;_sU%)|LZhuyAaf+Ju+cthNlLgT3su2; zm$XL;^I#XUos~lqsbo1sar23a-#cZ;ePyo2$d^OQP#8Kt1hkdZ%N9AS7wn>fVQYhn zYQ{unc##fvIbBt54q-x}woz{rU*{`)Fm^6&-Di@HUnoC{Zmyln6JIDAwid9DAf7m% zMEeVUjYgaK1S9O~_=>7*N+z`z2pZASBZ;1de3=tiMSVwMg&oX8k@NquzWernUJ3{H zpQYbIG(x`y{vUT}c^##n`=6Q`r&mGvZyWg%y)W{ARp9}>0n~pL%n7|O6xzQ(R3qzn zY*+vJi!nGD7-tIW5VYk$x=yc`1112zcl#b%UN2#^yE#MJ>Cqj7WWY zZ}#yxPxd0Elwy;8x=D=N9Hm_!G$n%J?j#f1LReO#y{IlY?6i3o$-@gD^Y_Jd#27A+ zooG_5)n`IY&B@GrnuIj+i`fY-2su5EI4>f5NkiRjSMzZ~_d(}@rS_y??G}xD8|DAE zDjFEve}bQC+_j#?&wtT`?^_Df5II1;YZ@mlIw~D;W%2sTVtcF*uhh z{}C)y8yZVVC&9RhI;A!kWST%l0A*)mu@0Qw=05oC(0MA0Wo5zJbtVQ>9wE;5Xn+qZ zEO8zR2Z(*h>J`ME(!}pKoY_R%zn5E)MhMHIrP5uMj+SaF&kA&@ z*M=u&rRj6nN%;GYHBargRVvY?Q9`HF8V}UnHA9%G3q@$n5oAoHIhl0X67bkC#7VXu zM_LV6e8mHc**AB+g@tV9$5(?@n9>oVdzu5sRIQD}^#LQ}X_OQ6>tZRX z`BM}K*1QTV$F@vhGAS!4>h!arOddJgHJMenB0GTrzd0^V=GInf+Dtib1rh0mhT8eM zOp7(l?}kp-DOj9>94=SfLFdvwc1CNmGV6Q{BZXq!rMV^5v?=^d93SpqOtgWt zCpP)YQ(Zq!aZj<_7pgK4WQN!-BZtJG`3g2nVm9|1kKk)nJ;2b1)9r%JN(}>b#qZ~ZA)nKpkm9)#xBa$amBCK474%wrz?HGgOvH>>O;TdlcPsg`Cf z;B*$R)NWnPbCtD#Ub`iuu;g_R`_7K;1#BR-E#6KyYdDIsO&iERzC3L|ZaV!wkz54~ ze{15~6cbQm?lu!uq`~M5qgt*B3R_s2A%X6Vsf{F8FiMl8SsiIW8R&FTw|Q>KyCWQe zvx>}wVEp`e8sW?x^!2|!g85KD4Mh?Vl9BZa*o~=vR+`sujCCjL%_&B9%?s&%pN)d7 zo}|`yL=6FZrm(~u^jdzc8b$w*ei#5QCZFugyX*=Ukl3RCF2U(ane$+Mv*&tKqzti} zJET~;>ELc=q2jNCJ3n})V;BEjty{!2jy4?U`D`LcS_`k%N99hF>K(k?P>?Z;$sg1w zk`ZwGvy!ZSir3%&LM@#go$W8BKCUN7g@{$B()NId(%Tm%5a zPZ6eBxr;jvf6ssiih&pxFzU1K$cz8^+?RwZ8T$QT>tHHldK~Y7rQUwkB2JIONpl-= zS1@nQ*rb1kd85>eXQ#Pgt+Pe+KRh8z>RoZH;Y&irrHj-smPuB8Y^wk8-)B_o*iET}+n}j=$+}{>-0pLUE){sRIc1)} zfTAPtwC!>7e1%fgG?S2wc8FCL;8teg@_nr-XZy zdA0;UpLjBFm+ULJec*lR4!!HWfL+ZxQ45sri{QJT8?q&ZbpS5roVWxkO_&AtA&5xS zoMM7wPGe(Y?hkMfKZ*!|AO*)~DXix+7UGac$8OxW-@R?Ib%U!V%2LME1TRDH2FFJTvdoPM_9+IE z;L=SF-B*OrU-R@Cz=t4_`u;J#Z{H`g+6T&W&;IlZkoRif6W@0rO8`k?PREZbc1IW^ zoQg2r(V9#IqnrvL*9yq9>92wp!Aj$Wx^?&U$q!>lH!!v7F9;))OHChL8idpP6BhS@ zTNE+ZUlHabhiRFwh+*Q&svdbD5l1zQfx_y4%rA^J#G6SU{byRKJyo(DgOW*!j_TAg zk7hv>$fG49yDSP_rmcEsf*=^ZEQ-}rVr`sGRcw>5jWJ@muPH}Z0-r-=ZfRUh6}>XZ zAeWgNhQYzAgW&>DDhO*!Pb~?1P1no~2l3icCxvVOiV#cJoV+H(E{kH}3#1a1CZ;5f^le2kE+?;CeRg_Ps0LZCstITBFs;t2Kt6)tmy6ukVZBGFp`|1Pz-U4yNTEb|1fDAKlom z3p@Z$-%$RBlC+fXa}s?i#EzsI^NIM%W(aTQh4XRTV#v9k-XyikV0hT<6YFi#Umc7n zXh8}t49;Zr0tr{j#YX!H_nox^T@Upd5%+=ob`1-$^4VMyWRZKgE>gfn52G(1bI8Cr` z6bIBT`J11ou@_<<{s_jt=te@ZG0{ismk+ zRcs2S2C0)^Ny7xJ7L7nfb)2wfRknmj0Cs{&QZr3b1uQxH&QBUk&_UtS1*Xv1=Ov)o zl*QDXcUUT#9l7ujpT}P}$RrRb$ZuK<6EWp6XgCV)8cP%gqZ6>lLkcuh2~`EL&@yIS zh*x3T*c`F}`R&C9%KlX71UgMn&7|TX!X7lBCdSXJQRvGRjv3zu7}-ckY{1aB2V4#z zqr$(4RD8^Rf5!MJ(a9khf#;Izw(=fmr0+t|g(jX{Nz_e~4G1JGP zOSPl*uLgGDwb|DG7BdA#=Om`{gc6;zk#<>(@&k&wwCes4GD@mjU{FuR zv+zWjAwwl=>qltH%t=}VnDteuhf=YGTtHfFPo`oPqAPA(fMr3F5X+*5&8B&D-n=yX*mN?4WDs6g$CwAx?g*k7{L! zvPyEIs-{5UJ^~O+LfJ_Y`ny`P>QUJ~DV+yRQF(rbGK-mXJkKd?p=4DSRm94OC=|4l1fIqEF2xGKr>d}V2S`uALV#~WjQN9ZJ^7I4yWtZ= z*5gE3rcZ3+SbY&etrIdN3hzP?=ID zXf6E7F@p3dyhKtk=@U$i-!9Z*u%X;@8g(YZ07#G;LQacYq)pL>FtFu*TjwR2>Ko8PEXiGVIatD z5j7`N0f{i8nC{Ce6j*o3A?<$d#R_wjYqd*5B}bUBtnz7^n?jmaQKk5O-W+R)T+B|@ zGg`W}@6XdH_Oe`@9BVez&iq+S_D_du50gyuPaRrj@qYKu^Y0S*D{&12Vj^0T1UFAm ze9DR)db^HNOfsn-kSmM;i(V4TCLlM&X9irrUE;Cj-N@%d{Wpf=#PITPS|4P%X07s< zNz}j80$hVQ`!Z@DAxSS-F-ku~N(n}%bp_*fooq1r_;>^4%3sz|-v@m~e8~0xBxoi+ zkrUL$1j;Z)=Qa@;j!;B|nazzZ%dgWS;Bq5Js6vZ|*uqRySbm<5 z?rOw##SkR49bUjW?5^_{WJUK^a>zmaNu|r!bY3e!FJH5>r{lB|>}L1B4AoNp{aNff zxQ{lRtQgXigwh|q!1sb>A_R;u#~e!wH;37nqSTyRa?3ITt@e+y~j^30@G z08KUy!EufW(T)RJ>C)E6j^j7Wc+v_P_t(8J34h0}5sn$CL4MdZ5q0{{l+4-FoqHz)C3t zTN^@;Y1YvrTd;?8K5z5CXvcajOpvhJ|4<+if%A?Jrt=Bs$+uaqbH+zf9!^nX39HEF z?x6h%56LceU-J~9HOIl5)LSQ${jf=i>kRiX$ALBx+mq}ZCB|1sAe8DUIN^%(rG)#| zJ=7j99g1bevu*8$-2`+S46RZ#9SKv0oEdBg4o^g-soPcFwqeSsOJw4b6B1WUUL)CW zTumc;rg(FzO0tI-o64B>?w4CuS9fU3lU1iHRVt%XK|HjK<}yLnRw0na8kr+kf2hbc zNXk<03@zZ?gM##J%S$R72Z*FG38*Dmi|~l^EThs19_8|=8Us&{;)yzFt+udL-yqd? z{#3GDp_Z7_eHJRhdwqyyeC8RdC~59TAM5b0GhR0S7$(RM7EVqr0ZYo~h->BykBKi% zvyqD5D4A4DN(*-8SIZk`xD`rYw{_e10hA^-`4jHaNaxwpP}4OanIVTXp;?_1XO4H$00ugIY44rvUX~S|U-EB>lZ@SP)z`-3DT-1r6e^Cu@Rz)mfc(NR4E(E3Z96vu z$nriY*n1F7trT9q(wo1NkbCfQL)pP9;9p;*X;P3cCaO~Te@;cOg`wvGwn%%JeVXRniqIhFNGbDl?2m)+&DR5CYt|o$zO)GRo^Ab2b#N8RErS!>)9U0Z3 z541}}PUGpZNty3_qAkcbz4@Uj%=pFVltIyUP6^zL6d|TE?K^@;y>CrINLO@r94_+N zNaoutIH|0uD|D-WAXJKfLZ?2=Wr%SP?HnyvExUujLob=tGD? z6)2%xC?o``3Dfzkqr|j)&HZi=7?r#jBrR1wpuIj>xm;*Wfh^?%5+m@xUa;$>8@9Mu zSG^eQlhnToK7c25{#=LL30ZBagXvh(>$A`sxekPddV6{H(o1$eRH4W15;${g`eiLd%^nQ`LmL}@Oemc zcm9Ddo{)GR3DG;G`_^rcvHM4Q`jd*Mjuc>FT)(?=1iU{!ntp8tU{Ka%5Lg4jPv^0Q*^uf zcIqXs7Pd`fJTvM;lYMaAiu2sihJ8-kw=%&%c%3YR@hYo7M&-3Go22A6j>k!Nw>yV~ z;00~hVbawxl_au03r0eK@BU51Ik{LUN&PSCPL}8~Xf=fW4^Q5hfX@iSYaWpHawSSz zzz%k%76v-}mmn-tQ508hLt%4r9Re(YWoZsQ8gd?FhZ`PH6;D|L3FbZu=~?(AFXnFh z!gG_v(ypOm$A2s91)HpA$3C)Fl)AXOpm>SIE?3VQ1gUOqpBQF5@H3CqbAa!#1*f}f z{|}Z9(VxfSrI=05x$iOrp^d<%37g~a#?y1Zonk95_pJKCb>kf!?~7XH4fJSHM!pl% zTRlVT+l(EDPgeuXNnDNQ#xvX<)Fz!dPm4FtlrQgO{Mxj+#t%80@4n9Yf{Kh6ksyW$ zW*Zt{r83rpVtP^(%(n0`S|@T1*Nt}PY_H7?I%LmCRYlvQp1s~s)iu!ZT-si*uWF*r z4X=giXjyEt9gMl~hro9ymQJ4fvGU3U5{a{_)}A$z+)V`;w-%%aRS;1R6Z+bs&^%sK zV|^(mFP2e)nAYDtiXhqX zPDTf`XL3dKc=>Trc=3T?u}DnaU9f|;XYdb-g0OPd9WT+!-S>`#J~91scb9UV_ZZg! zm~X;oF;cxFR4X6buCxJVJD*iqh07 zj`Hi!FMgtFvNMSAfVzO};3&T&ZZUZvKphPm?Kp~@AAKzJF#u?}2`#Os#mtQ_cg!?; z0`urJd)8rihOWZ3wPlzpf2cHi;m2g~~LC=VL(oR54FFF7;$2;_!Q)=FARUh^*^FFY*b89bg@k7*8i z+tdR9K{-+YuN}~mj)vTyo7dk{3C8`=?wQvkpatiSpy&dc;+=`+!7Nwdah`4%@YdKB z+WI`++o(um>stYCQRz4AH$ctVQoE5b&ZKN_F`6tn)w+oQ4o0K` zCGOrr*v}NG^dK+27^Q`jIY@~IVJDL|FH>ehG56F~0%;(oC!w@QUtyM_x_xp+0!FT^ z0Zf9rZD6Ng!h49vPd8@51xw-#3{P(y z!WIIb#%gDm;aEH=PdBbf(N=i*@9|rX{8@Q$Y~TD>nhE58uEGp$@}d>-S3_CU*x*by zuem>VbwdJ=QaRjXGF)KO?_tvKFU^@5zN2a8q-&j@_=|NI)j?F0X-H_gmuyxZ^AyE? zQ)Z$I3}Gr& ziabJ{HKYpn{xf3kwoThf_)ZR2Q@OS_cialM!y_Q=fTmafA&NW0|GW|Y{~ zd#e~&JC9gnWPfuO=7wk9%TCtDa>iL!_G7|UzFDX9>g%xOSJa<7c5hP2NUpc~H-fco z+y2o;3(`va)yDLnr1~QHM7evt_Ldl*fqRL4RQR^iM7E@UnO!+r$#}Qs)Y_Lvr(wxr zmdijey=1&ge@(7I?_6^5RoiANZJo)gFm(%*%sC_rs$UkAhofh~4IceGU5@q#$eIn` zrZ?b^ul?>j_8|C>btQKr-1~+I;rOG^2=C*GTLH`#8S5vHijp^J`U{du7q62ZGHgTH}q4gyX!DvCRwm8F$= z&qOu2T3S$l-!}w1ZwSwDe0{b#F!`ep&*^ zYmooUa1D3Qx8=CRnOUKF>^Ao0VFpYOe8*bs(SC}^+9Z+rydL`sMZB_5`isBjQMwr7 zPzq#x-eZq?CsFy!y9QhtfV#m3uTJqx`4PYG1>s`=;d>fK(FN5i1VMb$itC61ZlCD4 z!OsiXjJ6Al?$|UkiL32ji0IHCEt+ zJVM{ahQIORM@*IWBa!-9MjZl<0q0l&75S8kI7-@Uho1Y(x#Irr?#ifxk2>&^I>q-K zqX&Ebku_|G;1p<#=V!boC;|F(iI)9LYe}GX=kYz5+B#@O3imeRvzs8v@NfkVWHpm) zTYUu)Z_QHP`qo2Uts{AmUj%#8xE~A1ZVO+&L-8XD9xl&7**)aEi~o|iYJ(pSHrmM< z^fkn7-q<8PPCXzxB{(E%D*4r@d^vT06t#^k;Vp6KRpIlx{Q+xqZ10JhXD}P0Is0LM z(oESoDuegJr8mw6t2I;Y|40L@K~AWprro>3gx4ZYzA=(=%kW5aX!LlR)G{`4qK( zulddl^3yEL22*`Hn&YWFkV z;nr#{qzPi3w1~IF!HQ*My6(q8nZfqdn8#L5e5q9v%+P&wp{*$9s6W3dV^S>tc8_q6 z&nco@NqtxG3`P{%^diX^Wl(IJ7lkl0!wW75IS)+RF-4$N>rhf>8 zj!)TvtaQjzC065btnqeIh)}6OQ8cim=s*lDJy1s^FhJt za!?_9KvwHGGVpwv=pY8evD}3gpiWwdGsTaTz>)6-g*{7Q5-ao}StHbo^o^9!0xDqhwR{92nf~A(f<>8m+HXC$9xXlvJj0t8{gl0FSTNL7`3^3W1<;G?T zIM|iG=|ciIqf7!R-bqlH2N+)b40C$JZtxa!za7ot*$GIgh_KI$$ZJaet6dDivr!^$ zuuBKtbBRfUC?$u8DNmMObhz>ULXrBwlD$A@GHs$_c%kB$0SHCAaI;O?JW4Z)RzpcB7TFI`q>$^KmbIa%CQU!Ig9f z_Gw))-#|SJ@Xu|9a0CatM3H4$#IE2qaqnnGev35Iv;pj*ADHS|R}PtpgDJ3SJGRxK zY2c#inu$7bklfyy(@^GUIMR7leXpq*v;uMyVZJcE)ZxpG_7aZvnK(jOrh>EbW5(PPoxEjk)#YpAPV;U-t5Z$c7`AI_9kOtE?lmz_3lc3Vh^- zwK0qo$Z+q~%_pi*0GWqroc#KhJ?It0wXO%oJ59Zc%QY{r{gb68Z?4aobS%Yz0R~7t zru^;o%4646SJYGg7|oi9iORRQLAR=pxAJ&@JaiA;8r*W2N;iB0EN?nBRr8h31Ti~k z!s-ww&X>RuntNCJ`Mnig0{!p%sCh-GL9pX_Rbd;0_BCZSaCc0!BCJJk#hAQFcRXqR zy){_e?U3n`M^}ciWxnEZmlvOd&>mQoM797m>KZw_d{EX(Tu*4ysOE{^RG+nGjqxVc zL0nSyM(Z0zH3cKN?uL17`;8+mvw3h)T2eVRv5=NlN<}%ozmNhXC6yi@4-leq25%$8 zf1^2p$I4K%1y`+eBT+5K-Gs%Wv;TmR#o{W%?XTHw{B$iH;lvs!P{Z zm%P3R)@^5X@_r6>^XdU3-S~DFwr&)Hqn^4gIj_#O{C9~c9#2aM~5yAvfVyC}}hWB88?MQxk z!@BqCwQ7|&g(}Z^rZTA1e1|spuEN|Kh1tmS2oYjm3O(aXQ#)`WfGgB(L+nLBLR=X=TAlL0Of&~)kk%!^=INexK%SL(YY{+ zN`+w*o7%eE<0WtrJWcP>E=?~o1@Y55?k`OzVDT~n_IFcjqF^@at(lb65e3Bo5N*FHC1^|7l_2jt~=ykh=MKNH=f5~}jPwGxvTdMjK8%Da8yOv^Q?=ejCf(ijN zysY^0uAsNZyjx+%(thFeQr^A!vA(&2^gc1=Fe&gW#f^LxWlCY*7kDl-2mMQrX&(G@ z9_{2r2w@&5Sap8Zp(CvXc~6VGECN}XPiP4{q}97awxZ0WDKYT_)W2S)x=~&7^Eiau z2r?@VQglT&QLYw@A>W?zEebO{uoj4JJ;sGE_@09)kerQCx-S@x?4x2xh=nQU$RK1MA8>@>iYHsRsUcj^rPjV?CymaL6t*|iw2PpA*X&R&fcdX_UrTHD+M!KJq z$|xhgRuO$UImnH|C?lbE8p<|}TZQ2-P*Dc^e~9+~C`E^_9`6nqFt7l`6h|rsq7?2( zMoeIoI=nZ*64no9_H^nf>I@=Ev^9TPPCHHkX}_jkaUGQ-i;s zBPn3rVa&1@!v#u_X}BXngC^)Z>}Y)lRIWh&yyOF=RaQ(zfKmX)0L3^_YJkl?lze$n zzIz2aM_4;Lfwk9sP)IR62_r_!eqz`HcR{jM6F=qcZw#HA(qFIs@!9J0C`k{IVI+H6 zW)CJ!AENs_VL1r6u$$@UJB+!M9TLzFvR!}RDyP~wjwLI!9XruF6!VJNHJI0vls14a zOWrzV?<)2xh7Q$dg%_vlQ`POCzkmPs*LBZa97s}Mt3u+ND%NvP7lAk`)TlWkx=uWR zN2JiGpHS5;IYK#c`u!B)Yv)}2)aPtl)X|HI88*QycdgU{`r1S8HWDPlN+bVq@@sq9J90#QLVFUxkl zF_bXiPTotG+dD(y%fyQN)QBWrOjJ;T_oo|*)nCT}N(nA>&X7jJ3tpvreBw=N#ie@w zvODhhcDBh;OCj$&DoR{ATKPlcb)il|LUf7Z-KFz1X(AQKb)qU!6&8KPHMa{W_N`12 zK^7orDgN8JzN~(wT&_FZDeQR6^w;Eyj{Y3a1zoipBjtkc;Z8sC#bKLktXJ_>5?npV zU>Dk7jvkPrg=H=4mN2A51U8myalZPsBjn zzSy)!wO@TISu|55CLgl}s@vJ9y(2a_G{fpPik1Cv3I9{l`=q-?Uy_(WEzbus*P9Al zWG#tBp$Oh-7e0DTu&=@^yrNgy{W6p8>Ap`odXOfSIJb{W^N?L@QXaDEIW76o(bt!k z-q~L|H{O>h>F&}gPJ3K(re8YR07l2A(u~t-p;|(KR5C2@AZK0;Eb8wEgnP*+O??X` zcszF@)R#R!ExvZNAGGD54}TnP{5iu$IK@;j?jB=|)8pVF@`;CPZR{j>$2e57%RcV{ zzpsK&F}o!IB|0~-gn(j5^6NFSjDP??0=6t^G3m*zx*hJ4khlZ!_XQi7Nmq)YZUDdY zhL|YqW6(CfxeRowvBn+)3?eFztP-0 zY`vU0^V~i8NMpqFxL&RsZr-_=u-!6f9uz~jSi8s>sAXf=Wu>0%5?-q|a9FgGPx19l z(TXYVX#)yq+i%uBer|+=RQ+=!>(_&fk+U;r?z>?2C4~znz~r8?D?^6m3C$gZUWQv+ zpq~P~hf(YalG0VkEyo)rvZT*DLLVo^Rq-flUNi|@n8;s$NtsRZ?);Ec{D8}10ItH& znn-K=OOKJkHN*Zfq}SK)10Kmw2v@Q|P6(qFcWA6j#2=Fu?G^$HKO)#TaxWK=%TDk% zH=+eZC)9k#fyBRe7&xbN#lpAz-=p^8yq?jY=gOR2J@F*gouk`p&PP=Z*zK}^_sXYk z@@>2q-7@K4F4-GAFY$S1f45aflp#EDUhpGc*%?f4B~II~L$_;8n^a;fb7qIQqw4i|LL69{g_?-0-s_U|BcGPiia36YwO4)?j2E7bNGHk_>#;?#HdEOoazGQTDXlD{-pLBRN8rymCw2@$hB^osu{*4Delb&UM zAd=!#&6~MfL@yD|eXk=DRb_Wd#3z~OC=fdnsTaA-Q8CWFXD}4ipg?3FZQl6+3qQ@Y z2CkKlEHV8;t)>@Ce0Dv<^}A<>YDmoI{}K8B1M*vxuo&>6|C_#GkI%pb@n2O+$j}b| z-$Vv?E-keWR4}mHf8;3H{}LJ09jr{u{>SQ9X?^oiJxuxwbg?*+H@EMn=w$ou5EKi$ zcSz5l7z7pvHEU?u8_qTMQ=E#OlwD|ledNu4X{%XVr&8OkWf(R&fDu)(cHbmL+ij(~ zz5U#}s(JaUeaoF*8SpN+la)3Z6ubVZ=KGp`{CnDCy6vD&0fiU_So^c;&VJOS;BMb>sU*%wui76Eb zcYt5Xtt{BgJ`dhk-=N^z*q_wRPto9G$QRmd*4qHW9-2P}=(JyDp~hWw9yRcbJ?Wl$ zVB4{KJ5akja-FCCz^@sfu^9A^5JZQun`T78ls%%pPmrRQ&fu?=LGS!6X2=(;?G*n= zpxr*C;Pj9^_`4ihV(llh56#9i^m&imrXCc|R|y=9{^P;(%MMuhEi4AfYn?2jqi)|i zaZF?Iiuh%=qlU1N=qJ{bdq+JVUYI)PYSuTbJA85-WB2+FAbn*m;MqN{A!@yjF)3=S zTGDo+|IKqHS(<0d)vT2g&0z~)UcDNn1#q_1Pg$5!gQripy-XxeG3IoTQ@n;&-RRwJ z;x1vjoyp_!@JohUSF59doeV5$?+>b`41lYrAe#uUk}%Hm$B$>zx#7GMnn-JH6%Cb+ zvO4>rv!cfgVDj=xjg~=&tk9BDR=OucT%*Yt72i4$=U`Rf9&>fqN&Nb-TVRaMa;3hW zPJ_H+V*hGphnZWH)(R8IaGE2<*`5aTD1V7_c@(5$WI8<*{>HH+bAC8pu&aj|CKfM) z85yr7hj5kdsiPT*5eCxm@MsL`SYBgP%Enw8(Ydq)CTwBF{XUz`vW=Nd#85a+q^jeR z!?tWOv74*irmLiRbrCsKeTiCX;EV;@@MB|q4H(nEv}5csNtZlwgRoBmBKx0ZfV>}}G=+`Kz4mbLoyeCeKAo&7jme;h^ z;lZ&?t9_Fr02Ku^J8?yfLs;zahu}sJx)%&^$(Yzgbl3#PO+xgF^aRe71ueRXeiLnn*gbRKt+UTGRf-zZ zFw`_padw^9erp{7#_2+{kXimGShaTYP=-)(8Cyr`EPgL)tVD=hD+}MpPQ%m16qWhmeU<6cUh?!73+{iBc_)v}g^jb0oQHS+wLBRyI+qi+#6IRW6mBURkVZU7ijUpFv8x zVc3)^Z-w1yszsp3D*igXV=7LwFJqr`D8pl$Ow1E?%_=L_vQDNmLq(3eV^Av|ms2w; zTN{@QRLpJX!1K}+fmQC8=9^>sP%TOqsX9ux&MrEN5dM}J18Wf$ZQ4p1)FPNErsWduhqHQM8g}iJr4weUD}x0}CHz1}S&6w^m-uK? zL~bfr9y`ta^hBYb*^#kFbZov-ULJ#8436V8G!8w zluO|7qW?5iGBd4A`Hmow^c&0HH*KBT7jC%CI=cRvoQ zVn$lr@27O!Y|%Qb^WDivQ664xPn91s>1vf%4hLOfokD-|6XiFW{q2znIlO6YkngIh zE0`1Kb;&DZQsoBTv!4zqMD6XdfJh!EUd;|ixUD!e5zqc)AmKRo(AgNw{Ftyb?+Jcy zY7KplcuokfJvtfEk28qp*oeKEd-Ui$=-b`5hpH~1BZo#?&ic0l`IpGp_mgTe zk5>WD`Ht`b-8M5fxa}hmmJIr*fff=kwd`06k`D`S32&0+o?zS+-k$K@DU^NONzTe(Yy+q=u+35CSLf=DOpR?$mZ=YB2K7N)u#kkpfLfj_zD73p&`d5wwN{Cg0gV z4vBAoDck=bPWeZdVGD;Msbib@SK;>Wsx0gDjo%tIp-JhnB>W?FU#$eh zYxpJMQSVN~a;>3`XG6)a^nAb%mIxnFiyNSQf11k7PR!{+|MtSIr| zqxva3^Y0ns{PoA9_YV>ewb6@o8&NY(-l$^$kO%`bOz(3qmRfi`mRfYId@<`1gHO%= zI=ONW@tBw$Q?Bv&k^W0#=DIBA!Do|0!u&35LRNtJ{1xi}Np2?Ar=&bB$e;C(Kyqfp zm>VHa^oVe#zqRa7KB_!e6(^+PJ#}j!!L%vORBu;m7>-iF3ad;Sjhb&_#cgU;alSGm zu$Qn2!evQ&QiY(bE(+TE+qAOAfvww*X(fY!wln0+k}L6~UtltpOJZke4C)uw~=?ZiW3)#RF|_lR@kQ z=|%zr@xj)Aj~oUA>IZzG_|F9co~W!QT>HZdxizyQ4sHZ93-ru;bO&-DN!3_A`JdT& zSQ}_UV4s!v8iw>5E4x&pbA1^)x6p&A7ItkZ9$Blw{Mx1PdYwqK@)fbWj6Fn7K%)4; z#|0{TR};RE#nK`F0{wFp$B{)Yr=nh^?V;7aB(X9a%T}Lp0hs|T#fqkf+|l~kR%i_+ zeU$R3b0?07f|Osav@1AX!`8vfXvn|B_#__>&T71l<|}OezqYk$S@}I$u`kzIQB{`A*W|>0^cXd9o|SB=3O3$NF7o7;XZsX`BfT!>#tbGmt;;(-=4_RT3%_M1}ryUw(DD~%Z8oeQtxigm#3)c zl|&h^mTC8%Yb*4z>_HA6Weu7V-YXRZcP&@T3sAs69tw?4^@#G*X43_LB>}M#;le8B z?!#Rd2RW|h7+!Sm($nW|0>XUF7)D2giAcv&y@=8Q!$~jzBht>RSahlnXCl63cxpR3 zU%l%QUMx#lmVpaa=Mz1FL>-%RxZus%0^D2lgb!2FBV*_4Dv%5mu|%`AFkSFe-2D5* z?n#dJGC@>h9_ARB9gQN5&T*Z_kD9!9HD_(kYV}X2eBz-XKY!CCkwzU0t0eA#*mBMA ztMHbB=C*h5e*d&}*ta^8bQpLSpBfh#o&V-+Z$4gR!;8hl4U#43`lU;(xJ-fV$^u&M zc|&CPs|3@J3Iie{ELcz|YT~ejYs1R8u9tVw@mEK2fBO=fen*j;vivU-&`{ECJ{gYn1e=U|IbSbK=o+4lt89k^> zM{#+@hFvbHfr+N*BN@Bd8Z?E$TOr_a1UHqkE+ubbQ42`UZ$YR`83=ZA)!nI_!3uF6 z=O~gKGlNu=E)n;MGFc-NANlDVnG$(;s|K_rkUp@oCnk4g>{XK#{r(GfBrQ4_!Fd8! z-g|rXwb4B7x&C9&^(+^MLbB{aQ5VC&PapG?k?#&W?|Nrjmgem72x}Va(5rDXAJWJ z@!0WBUYgGXf}z5wu9?2bl?f*v7g)Awf?1O4ColGPu3$O7vnd`AVmKB|o6{e2t>F`? z0>%*Uzm&Dqd}p)A5ZiTgR+OlH?FpxH`)8#Jm*Q>cOohnW(w2Tc?g#5_wsgLhCbf(D zvj%nADg3`kJdDdh*a$zt4D z6KyoAlhzds;;_So;@Cwf&rM7sA2H=|TV`_pRf&&7O10+qhCcNE>f%3EP@3DuMr%Q(o<(;OjQE#jhbrb}9! zzqoJJzRoralvJGm8X>UOJ-@j-8*g@$saN=OLO(NUx3=r-{2S+u>QY~&im|PTWsNk1 zc|CHTS$?1tPVf~Rn&J*4cQDR=-4`-UA4f*v%WO)iw-xEZboMRW?nXQLxW52dUAJqX z#M_iCk5U}}F>Iz4D8DSiy=ThR(hR!`>rF|Z>w}9Y%%mFl*aXrEnHk}yfHA+N%sSG9 z0Bh4yS=wP1H8MGq0nd4>M8(+p@5NSDkiYff>kizuYo%BnJXU~H8{thYdK(GQ5WosU11^NYeZWI_%kkJ2< zLP+5SqiPV!0A8VX17uW*!&4Qxxl^G$gzU#gvsR}+R*<5|kLjc^vx|!n&8GYQKezqM z_nXVcyofh-E(GL}kZVt$8(N?HtrXdo5R!d^4Au9KyEK$=>4-!<(L?exG|{#tUZhKs&=^cl#en-uK!Zf}6PnH>CEJcQDV4NVXj2KYjxx{NG^;SF z*pNaI`*3Got*zmq+;#hg2%F4w*G$j7n6Ifk)P&{EpIg+pTSU1LXiFe$T z@esz>Z!;n_IMk&{!k!>Uvu%RI3mg&|*K%L;?ana|Fi-Xv6BUI9RY{FL)QXcf zw}U1az$MY_dEaEie@5dtSw8}MsP&q6AS}&><4)FR_58&Ux+TlKeei9FDqCo|+|MD! z5ic*0R9Q&*rlS!bE5MH1 z=lEW^TXd}idi#F0sZC$uWFwnz;;$$|xoKYXZvka#bZvd(DHD0}K!i9MYdWbhM3`yM zj6`KPN>;D3bOY_}gnqD3teh=B8eM2=7~h2c`}x7P&9+`(u=2X2r>%jFj~PY4$2TpV zjjZ~*#CT|Q&=TerP1N!90H_RSUtKF-O?A1@3v76A@I_~mP3^E+Qr8<+ZJMY^eMikX z(h`pJgvhX07k7MR?BqtP(P+UzkUhq&d79Xh;h^8!i7P5Ra%2~aWK8E!`GB{l;ZG&T zmd=`U+h!zqy@ZxgF=U`=xz?{~mO5HPl(Hs8aX*WY899@vK?E)RV6z0n@+rfN%Gq7? z@8-Ok#BqJ8KL8ljsuw?ojEX-GRDB+xetx?)5s6HmhjrQ!hN>q@R>?#B20~WHF~-HD zeHJvnD@R;4WY9e^aBePoRA#5SiE;M1RiAM5y2X5{%J3zY>^H^=CDhGpRI9DEzd8Zs z=uSO84tSmFJNaAcf`7#nm{d+x4yq;9aF3R5&zGTnA!;kjz-<%?4 z{_dJHDkJnd6plD@>4X_Vyt*=0s~_~G4CYeh<^wLAo8>lVdvra}eIZ`-)C5=FXi{EY z00>C%OVsvhWvo1Kb3vwm$>@d>Rj@QPFQCTm#`-wlKueDI4mV)s6*G9CEtHo@n<+Rp zX)we(N@`$Pt9hu7YOb-=&NiQyhma}z2*H78$NQJKm0)wASNPzF{Vfx#cl*1(H6KCg{s= zugJh0%S=1>=wfg1Ju&%;-|mRYPzY5X)1gw-K^MFhoYfj&)mm!(GK=gZP=G3lVh-o${7RKT12WG%!oMW!3E>s+NU_>0VNpVha zZ;%EzfZVJ?%uOt-B_TO_I0qfV8K!(YeEzaUv$*~t7`tx+Y{!l2f({pAv&hdI0=OA( zZL(iMZig50aQ)@$?%2~~e&k(Yjb$0q+LdRoO(Uyv1_ehw5v>^BKcBNXE3?~-Si2E1 z>}S7_ebxC)`k`6Bj?0WC`3@m0pNFl=%6#(s4!1KH5+zeEq_5ersVUjJ^C|eRqPyTI zVKc$ekO_s9XaL`jeAL+V-!U2auVLi9U{wxg{Yr777-~M->7C$D$k6i`?=^z`Vfh}^OaS_FN*y}sx>h?!m5wv@yqIQaNzWeTMH<_Zxe8|glw)b}9kcq3B zt9GpUXw@|R=5f7dfAH>Vw6dD@v61sQ{y9xZV15>O!Df8yJUacz4rB4~ySaV7L$fUx zZ<#IO?3|;$_uH`vK8&wfTfEgsB0_JrvM6odL(tK`6>{vQeH*Xgm7et{Gi6v|_ttX>WS4L9jf2J0T~%5915xf93=} zq?M*9#+|GWkfu;EdufP-f$W0$-JMm5JAS$yQNf=WM&WGVT_?JwL@~O$`{6|j*5M0J zT!;&*6B*kuO64>*u1mgd55p+ZWLyrh6GOOeY3$lmF|I%z_vvqo_R?Jbx`~C(X8yj8 z2*akzSiU;xI*)Mg;+<1Y2fSGpoC-~fDkpie1=K?YX%Qs~YkNWiRhLh?y*e&i_ImPy zoV{u31f6fvgt`V?bL&bFI2-jGFeb*02zdZw(t-)(nwyGi((8o9WH}U5y*5>TuFau)c&DJ6 z`I3|C$nERO@dvs!%s6`)?5tACZ~(R#-!fWrpTjmK~Dj3Wsq2H$Exy3f@G zDK%eskU!TIbb&YykLurDuS3dUBo*$QG5l$fManzzTz(``KopVuzSP1@9An$KlFR3o z>mrr*?RElin}@yV-hi?VG^hL}c&+Bd*<5zd$!)gZ&(HLFg5nLh6B}rWZpXs-3IiIx zNtn9z5}k9+#?Nj;2)ix1ES60Y0!@q?Ip8wmLMjKT5tfZKwKm^mYn=4u z{OjyEia`==sO$YKtQOKWVmwS=^5yv@Z{rR(YY7igbeU38w4mxP-eVK`rilRyVmx74X0<_(dzrG?Nea6;^gTk`vZftCQj-3g%u z?Xvz8(`9JiZ$_re&D>m;A-M2nJ>P_HX#*UT#tOv%>si}KMY)bfAM3;x)MnKKSekd1 zN04+x_W~18<{ifbvbAS&7=_nMa%GibS~H`k=`4)zGd_d>;88+3zFzrdH!8Jy^39@b zvceRtb^_fFPuWa9tuM->%8U}V!rUNr&^#{l4yAvL7%89y;aR&96c(Czd=P zo#c=1>xW43##TXkB~JYw0l#(5z)e5B1@J>W(AhEG>_q&u!oAYtEL>Hw<_dWFxwv$s zPQ?MjAjo1-4M8O5KXF`mSn*3sX5IHSY2J0dp{}$kZWMYsyNbVe>?yXP^Fi^&_ci|n z`g_dh;D^g)etpuq&W4wlFAI#a3CBiUL!^V8JS?F7O=#@6#JW`%4v45m+US$)**&g> zi99s1R$ao;1`Y>#)iA!=I{XmReG&wpoaS@CXo#^?*of02GVFlQI6E`6f4r>gsQz8W z;eeC;aq@Z8_vNbk9JS}+$-cMV-HKnFS7*kfka|U@VdHTRhh!^4#Z)L2R@03xWOdoT zz_XwcvZXlWiO)I?N7lNc*YL0hvQQ*4Xb2}Z3Rm(M={ZpzjSv1fl62v(f>#klbSc|X z<&gE%eT^90*S#4nYkkfq{tXkJ(5o;7N{f&ZB2DU8wcbW~;xQG|t zg|*q2_u_9gT43(G7562RF<#C? znHM<&I&EW4h#IW&XTQh2Qsa_7e7*aoWVYc&p0IlIfxI%rU8JwBBLnrDkwsax#K3Qr zZfD9d@-MG5NWZir6Ml?U+<~%uUz#W{7!)MvKN&6&z0%J#iS zTi+nE?hUoZQOd=lgQ;aG_PNp>#6n}MnOn~z8q%Ns6P+g~RLe0RT+jumJXsseozC)G z`;@~}61_YkeZO3E5{x0dDHmRm3zs8MB7iX0&YWK63+-x6VfFdA(?h{79!U%NhV|Fz zqJ(e5TsrAJCR*0`wV6|b@*2&#Q3@dxzmf~Ru~$~S`S551ZEm%Bk{8TZm>1qTsQ>xfJ8r(k>8%q=Bn9+vSZW$a3bSK$)eRUh5{Cx)_~r%q8QrfiJgp^-uRV70oV7mddL zjIw}*E9uy5@2~9wvG#f%44e^&01QXIU=okj-lCP+J_pOCC%1lw=^o2z)ndkA7NE?F zV86NP$rwn^R2x=gJHbSx=BY)8u1m_@_~ zEWSpAj?JhpY$QDvl=7#7Ld!F4BsHyr&+IENm9lwW4)+?=u#?&WHz;%9(I8^aOy|_- zU&Nk4?^?hRQkIQZJ_%q_;D*myT@ykE03Tv(LZ|@X=>x~aHGQp8%|Ig0f*m1JJ?0HZ z(3BIAXN3suvKRJE$h%-L8@7Q{4X9Phm2VDar!Y-7NRF{q!orknmGR4S9VNUR_}V~wcE z*AM_n1f@pX5uKGQuBc)AsT$LfjsZ8&v@keWHW;*YAi4wJ75| zJxBkx-0QP%lfd_!_H(iCIYsC5pA8Gf4DcIKZ6463Ezwou!NZ$QCtTAbuQ!AIANatu zJ}VBCm=#bcrMyL9CP8fUvTh(trgX~Lo6o%1`q_PHM&u8SC-{VR2P%a!m- zT6)H_1Tj7aXRcG`pGJv_a`-9Q&@nmR2iBks;ZSiD8)15IGqps*KcVe>jKUptO5M*e z*%UG=s)0?~&=hIiDRuBo${rzVxNG#w}?Cf{OBU?B~uf_PGu zzuw^h-F~wXZ|5uPA}QPGtS0hX@b{%>YM?Fasc}!hN!I6I4JFVyCGxJ!R?7e2XiW=q zN{wVnV=q`3Pwby<)XEQz(wS=jj5-l$o(+oW9laQtWZh1q_X+(<1vIkI-Wl90>v3}H zcLa&#MgDGTfvLGSv3e5MqZJYSgjC%QHTEX63BGM8Nl>i#DxoxFx$XN|^FWfF ziJM<1XsbI8J7c1@rMVYmD>6#GJpl3@HO7bQRk=5GrEen~uHr;7)IeuMRa2j~cRGX^ zOzkj6U4mM@u3WIi)jHWq-B-FsnKPTIRUaC#kR&VibBv5E>SI8gO@{GWklZL4c_?2= z9|=zUsW?MR&qB~IgKxO$>SjZ-ztNOj{S(@!fP-UqGyCAgCvRF+8(RYu*}bzoW)S5q ztVSU&SUgTAdQ}#ugj(wx?Z`q&hP}(aQDv z6hWcN<2{f{)6E2VdwWK(5K71ZW^=rEcmu3qDK8Oe3ae5gU9l`*Tk#FMP{u3LGnCM3 zRU+c0oVnYi#M|3GBR&wt*?c~%VCo^tz7ajQ*>a2BS80K*w?<&xJ2!)4@=fwmc&YR7 zet3bu&7nP%;)KDqN5HwltU6Qrek5R|ISgT$BmTth;*J4{?aI&&`f5*dRM?A%NOR}N z2>*RO36iMj3<0Ao?07rpSIo(%smK_;cahq66#HsIbC{^$d4vc--rme-x(Jr865Z=z}|LLg5NR;uB?U<#_zb%CNoY^GQ=jBkL+YY#;Up>y7jH-** zrz_TtRpfdPkx=qrIX^%;!{@F}^X)=$D4Gp)y|w`98)WalWf9-1(nT$|TO|w_QmmM0 zMuzm-RrA2TRWq`bUo{4%E0yCg5CWw=@283Cq+7WaU;PZ0oC^c+`U?zg#=iZLbWPyU z#`->|R;=kUoo+1ik%wjTsKj(*uSSrPrnfo*{jkt+!@E|U@!OblKALy!PwPWFc6AGm zz0`V0y4&&c8FB^e6a}XZ)n~^Q-g3?aM3s2XNE`-N8z_Et(e{ao_F+R}=SiWtq^0Pqs(bC%p`ppB1$nBym zi3Saahpz73+#_S*4_d_XkCTOEXOVSQ^{IxqEz@I($+y4Uo>BEk1Z}CaQDspY$)G$? zs4F8O6QN)~(c1oLu>c22vhx1jWFewdlC`l^l1*Cv@4ROCNhBNlp8){MCj4h$3T2bR z`|nN%@Jc8f%io*fi%>QSin4y-Gl!?X2kh>ycK=cHr%VX`B8rUyC2|l5w;*OEgUd&; z(fk2*_*-oJ?O)=oC^izn-weEyt)Z48c+Z}Z&_8?j`j4sq-138JX8yJID2k2h4+LKH z69mu3zr@4qKpePwG#k#JIkUg#l6L+z$G!u^hhuKB;{4I^U&QnOrGw<~pAAI+CZGS` zMD*~}Bv#Tt0RQ1<|G!2`9sL7<`ELMtP8cgO?f;Kk_}_~2g9d)V$D`Re{y_hysOs4> z;J=qVJ@bP)Nm&1Rg->->w10dwih1&}m+FuBHT*_{^&i)({}!*k`Xi=+AI7i||3Ox0 zX%>Eu_3T;WQ>OY;qWb?_`9YKnf7ZT)i^l%zEBseR`~R%`+lqPif2=_LJHs9Bp~p)2 p2mC*Q+y84e@tc1(z+)L%iQrkWY?ye%D8neSZ;_t)7_mNK|3BEj?v(%l delta 18867 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