6o={I >Q[/BU:hh2=Z |yKv @hǒ>;Q&#+HLԧ9T8Rum"h(|2t3#:#]Gg[A AQ\ @:ҙu?'nH_.4,ew1rɟ7ж=%rΔfc\ekb jăοB~xi) N;2=\_K$N6U%ە!aպ5q-soo  _heԴČۂa(ѫ-QL ȉ/{B'(tR$i?3T)yIAH^WTU"*ܩB6p줨#ϊ\f$D v+ oHǍI[eZe9Þh~,FROv,nMy>s iY6DdUZ AGnUjk+גh Wj <ܞK%5N昢 zf ^ 6jHh] ᎕#FCyAm [:+ #U]ٝHɅGWktӰCR?Kx4qnj ȲN 6[&mUR>-i]c6Wd8^P!P,sR}]j+V[nj$ {9V"CW%ߺoWXSR1aϩvF%}OubV'eOY]i4|$`$DNr ,)5-mެ2),v#:E)A=>< {g.)%8/6{Zdm?ָ%)U~s1IWS5zEya~, W@o4{!p kͬUHgz瘅-v~3f:ʬm&oU&ƃ=f tT+&K 7He/7XDB%j}7@i'Lחt07)+NX_?8߾1>\c4~34i3hpvnJu7gҥ_m &]onHsJї1Ns95+p2_zj'iO6I-95hF쇱gsbx2Y)稳"F՛< :B`}忮k^F !a^1%CIWu͔aim[&kyʌk+ ȣF$Iי6Y3kE?̹*5`ͪb,=U#5s?4-A~ŢSBuf.X`Rx0+n%JNu項DbeGwFȮXDq2WFNC&uU|& ٽ84I('unsno?lc(*S(H٢K_(YJi)},/̉MF l0T;GCN],+4vۘuV  0LGwT٧u7}S{T[{Fvo'S}$u{*wLPؒf2_s87 UP(0¦ag_c?eK# Y($[wcO/E_0~/'~. ۱RjL-Epw?߿$B X֫v{rmx$ô!5\3>$NsJF?wdu!NQs +bWH!2'EN$'\b Xr \OTEKFxѝcPD}XOy[Ox.}e|m&^,|fnP4wZzu2 zdK 9!lQQNE7ӉEXxLϺb߰'j& ;Ra?p|E#U4ϼ GuOYpw8{2h 7(3cAZQ^ޤ|&g]I܇}=ÍO^8{?YYVD)=yB#4gkaa=uIk 8 lG2p_饖$\76C(9ڲcMؘ]'q9ZAcDm}9Bd#/e[2 _8 %Y>seP+es)IN$?D)yaaը3qܽpTfˎ9n;I3% gdvqr+Aޞg y։[liMXj@AUFó >}h`MܥB+@^ftԃ]k;A()D.sG+㌰Mq;3(:ŲZZ)A.X {MNg1jo*Ͳr5qFnYghkto̔ύ*z`#yi%Ikr$^ÁLaq{2Ck`2w#/GJ#kb`9,r풪#q.|S ѳZ/~6{^ETVư;zT3eAģp[Y\B.󮆪=@zwE@-ԇ%V_QaY)꾎|Z./G%VHkZ^yLX2Z^V1qI4?_ȿ\獤c4jK=7[w;SO$tpTS s`5A`u3bI "HydgWk_{YcD<}>pK+]!DܦzeERwdeJ̿-pu1_b7N4Do@n ?bt2:얱/nBCmY&DF6._KULpǑhj8 _Y9 _Cꚉͳ<.Ԑi4Pd)=D c+pBW->`0ix}'6{BbSHtNgqYtmH)5!>N>i+Uri~|x>2OT b`މr Xđï.s۶DʬaIͽ޷J0h$"{,kd =6VV˃f[6񣮃4 KD*1);I1w*umW_c擜ORAb=畃vލrl(k I \!,)Z(wYejg#bx\΄^8YZ9T9tQ 9l; 8(/JE 7x~|~%T/E T*5ɍvwp/ji άsckUGdo20ū|grAmkKF@m: p{*h~q#xmV6{(M|p>!>x,@D/LBQl}?JG|$Cs ~|m=WaݴoE/wv$ #ZNò .JqVz{ $ r6D%Xqܚ/"2}k\*ZI\֞ӻj\{[{4NPw_֖ x!c(ö2-J_n\33lh,͆6i!Qa0UPy55%B 7MfѹKN/9RZRtpa|&1Gzg/{ẒG*U D㹠w8^:ǚ ~Z46dc'aUz+pBk2l9=HfpcU1 $this->setState('user.id', $user->id); return true; } /** * Method to delete rows. * * @param array &$pks An array of item ids. * * @return boolean Returns true on success, false on failure. * * @since 1.6 */ public function delete(&$pks) { $user = JFactory::getUser(); $table = $this->getTable(); $pks = (array) $pks; // Check if I am a Super Admin $iAmSuperAdmin = $user->authorise('core.admin'); JPluginHelper::importPlugin($this->events_map['delete']); $dispatcher = JEventDispatcher::getInstance(); if (in_array($user->id, $pks)) { $this->setError(JText::_('COM_USERS_USERS_ERROR_CANNOT_DELETE_SELF')); return false; } // Iterate the items to delete each one. foreach ($pks as $i => $pk) { if ($table->load($pk)) { // Access checks. $allow = $user->authorise('core.delete', 'com_users'); // Don't allow non-super-admin to delete a super admin $allow = (!$iAmSuperAdmin && JAccess::check($pk, 'core.admin')) ? false : $allow; if ($allow) { // Get users data for the users to delete. $user_to_delete = JFactory::getUser($pk); // Fire the before delete event. $dispatcher->trigger($this->event_before_delete, array($table->getProperties())); if (!$table->delete($pk)) { $this->setError($table->getError()); return false; } else { // Trigger the after delete event. $dispatcher->trigger($this->event_after_delete, array($user_to_delete->getProperties(), true, $this->getError())); } } else { // Prune items that you can't change. unset($pks[$i]); JError::raiseWarning(403, JText::_('JERROR_CORE_DELETE_NOT_PERMITTED')); } } else { $this->setError($table->getError()); return false; } } return true; } /** * Method to block user records. * * @param array &$pks The ids of the items to publish. * @param integer $value The value of the published state * * @return boolean True on success. * * @since 1.6 */ public function block(&$pks, $value = 1) { $app = JFactory::getApplication(); $dispatcher = JEventDispatcher::getInstance(); $user = JFactory::getUser(); // Check if I am a Super Admin $iAmSuperAdmin = $user->authorise('core.admin'); $table = $this->getTable(); $pks = (array) $pks; JPluginHelper::importPlugin($this->events_map['save']); // Prepare the logout options. $options = array( 'clientid' => $app->get('shared_session', '0') ? null : 0, ); // Access checks. foreach ($pks as $i => $pk) { if ($value == 1 && $pk == $user->get('id')) { // Cannot block yourself. unset($pks[$i]); JError::raiseWarning(403, JText::_('COM_USERS_USERS_ERROR_CANNOT_BLOCK_SELF')); } elseif ($table->load($pk)) { $old = $table->getProperties(); $allow = $user->authorise('core.edit.state', 'com_users'); // Don't allow non-super-admin to delete a super admin $allow = (!$iAmSuperAdmin && JAccess::check($pk, 'core.admin')) ? false : $allow; if ($allow) { // Skip changing of same state if ($table->block == $value) { unset($pks[$i]); continue; } $table->block = (int) $value; // If unblocking, also change password reset count to zero to unblock reset if ($table->block === 0) { $table->resetCount = 0; } // Allow an exception to be thrown. try { if (!$table->check()) { $this->setError($table->getError()); return false; } // Trigger the before save event. $result = $dispatcher->trigger($this->event_before_save, array($old, false, $table->getProperties())); if (in_array(false, $result, true)) { // Plugin will have to raise its own error or throw an exception. return false; } // Store the table. if (!$table->store()) { $this->setError($table->getError()); return false; } // Trigger the after save event $dispatcher->trigger($this->event_after_save, array($table->getProperties(), false, true, null)); } catch (Exception $e) { $this->setError($e->getMessage()); return false; } // Log the user out. if ($value) { $app->logout($table->id, $options); } } else { // Prune items that you can't change. unset($pks[$i]); JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); } } } return true; } /** * Method to activate user records. * * @param array &$pks The ids of the items to activate. * * @return boolean True on success. * * @since 1.6 */ public function activate(&$pks) { $dispatcher = JEventDispatcher::getInstance(); $user = JFactory::getUser(); // Check if I am a Super Admin $iAmSuperAdmin = $user->authorise('core.admin'); $table = $this->getTable(); $pks = (array) $pks; JPluginHelper::importPlugin($this->events_map['save']); // Access checks. foreach ($pks as $i => $pk) { if ($table->load($pk)) { $old = $table->getProperties(); $allow = $user->authorise('core.edit.state', 'com_users'); // Don't allow non-super-admin to delete a super admin $allow = (!$iAmSuperAdmin && JAccess::check($pk, 'core.admin')) ? false : $allow; if (empty($table->activation)) { // Ignore activated accounts. unset($pks[$i]); } elseif ($allow) { $table->block = 0; $table->activation = ''; // Allow an exception to be thrown. try { if (!$table->check()) { $this->setError($table->getError()); return false; } // Trigger the before save event. $result = $dispatcher->trigger($this->event_before_save, array($old, false, $table->getProperties())); if (in_array(false, $result, true)) { // Plugin will have to raise it's own error or throw an exception. return false; } // Store the table. if (!$table->store()) { $this->setError($table->getError()); return false; } // Fire the after save event $dispatcher->trigger($this->event_after_save, array($table->getProperties(), false, true, null)); } catch (Exception $e) { $this->setError($e->getMessage()); return false; } } else { // Prune items that you can't change. unset($pks[$i]); JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); } } } return true; } /** * Method to perform batch operations on an item or a set of items. * * @param array $commands An array of commands to perform. * @param array $pks An array of item ids. * @param array $contexts An array of item contexts. * * @return boolean Returns true on success, false on failure. * * @since 2.5 */ public function batch($commands, $pks, $contexts) { // Sanitize user ids. $pks = array_unique($pks); $pks = ArrayHelper::toInteger($pks); // Remove any values of zero. if (array_search(0, $pks, true)) { unset($pks[array_search(0, $pks, true)]); } if (empty($pks)) { $this->setError(JText::_('COM_USERS_USERS_NO_ITEM_SELECTED')); return false; } $done = false; if (!empty($commands['group_id'])) { $cmd = ArrayHelper::getValue($commands, 'group_action', 'add'); if (!$this->batchUser((int) $commands['group_id'], $pks, $cmd)) { return false; } $done = true; } if (!empty($commands['reset_id'])) { if (!$this->batchReset($pks, $commands['reset_id'])) { return false; } $done = true; } if (!$done) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_INSUFFICIENT_BATCH_INFORMATION')); return false; } // Clear the cache $this->cleanCache(); return true; } /** * Batch flag users as being required to reset their passwords * * @param array $user_ids An array of user IDs on which to T՘8{otjQȒ -C6:<2 \4:T}%<OGZ$oʠI"ꎎi\&v=:NQ4][3J(bE@ڠF-3gy?F>Iz^xuVu C}2}ZZv,Y5ʿ@3MURϒ Io yD G%rj BŢ奡<|6 uStfQ;Xe)+#M"e 6jtG$QTwt[^Yg=uzzk"bpX^̌eIg,U+#?dR|!Kd+ܣ8}bP sYN/zG̠ê*;Ccs jlp}DL%_]ywֈGz# ??ZsL BWZSU0#y@8bs7أT4+uiQ,{lfľ9Z,c`,O+Ixw_\ڔ$6ς()-7~ȃݹc*L>ca\yg0&S!q>nZ}LM16c@w qB~1)yA&5)tH̋N+j3HVDJǏ]e@ȶˑe^j< F5B)䅒(r۩S6^e*/9'(Xށ8,`~xmRu8` RM@M~/peuYĎ*"]a~oBwL;UIĘ yx~qlīv&Ӡ0!jlT  NT{tOvSێޙggS&|U~[v>^n.TcQo( ?R< ZfzadqYRuo Aq\{1ۀP#77lE{Uy]ՠYPR"Jޤ-➔@kgkLEm4t>,⮈60=  ƃ /99-[&CXh"ƅ?.,ZvSA),e1lPpHˆC HݤdeOӍ/um9V blv"1+3Dd&'?|}PT/)->e]cEDb%\pp4Ԥݜ^C?Q D. !+b*6FˬHb'#<9C"gl̟sчOO!H pY%%M# Nh GOlJ_ ݢ(B Jgj 5pz W5`X؈ ކVnF]c& P]pDX8nM\kpbf؊cD_ @9_WAu>Ez'#bd̖ަU!~@Q )o8D\~EH%1Z I7E.`_kUˌR5=Ofla{8]MmFA @h(ĸ14\X򫠝JTVO6=k=殯- ׂ~8u vZBKGYۧ|uiIVѫE FAuL]H/UA-EʾvB/Fi`ҲTAߝd9<^D0,|pJl>k]K@mn nAN5} QPxx4\24K]t+L=gr9Bq֕^~>Ƌ*2mDŽA$ 1kZ{=!!S-A&XWdE-)hyVI!`{ r@n0>+h׮fD(;4̱n]4=2K]j&#z:aX2W2|. FEL$}[ow%)iI(ijɮ1cOT˾`/OJ55s1ll9$ 축N ~Pã'{t-a,Wm-皿ma-<ɻ+23L0g#߫LɋOpuKٷ"It/G)!PC9YZ&I!^{~S2Q=2H;aNJqZ5mPcaǻp{jXӧ/}sSywe&yW1fq 0*ZHPW(۱+ynB` N55$@} $ldMbB19A$0L wԭ>Z>56֤X g` r@ 0ςb)$/fϊ9eW,|/o{p(@ӁOA ]C'д<϶^NG3Gh?_HkWfQ[DF A' K`[-9mk3L!>a$<_z ?;DRU7 ɰD- Pq@ĎH|""_V wm87{B%35ΩH=㎞x!a+P { ;"EsK"5[y:G V+^u( kT<F'ȗ窃T4ˆM E 7=qfBhnCkZ򑪺p2gA&{6TTIޙd-zf/@-dq84:IR%L؅Ga & _(XEk eU;HuΡ)GbZB-#ϭ(h){LoƨDZ&諤750)ڊ{kN${ۥd ƴyo0Catʷ˿1@RZsvޔBݧw7M!_Ŵ/ܻ~#G,Q581Jm2w6r:t;s(d_%C{l:/ (Ʌti[ӤX%<9%B6TWzv_z  smKK2$$j DͶjQ/3`pd'wG cp[f"[s1$J0TZh,LFw ~% ޚ60 -Z#^*%"lG6d )ǎ|f*4DbEa;_yZh|k#L _0s1cNZZ&n^^9"rDmT8́B le.ocZ6#pR;ئ9Ο ^2mtc2>7}a:Uы'{ce࿓/tUWO'(ΔȏܯanClջ=A ,rTRGSȫKQo_XW/l?O6"})EԙvҴL5_t0 wL4G U)@ ݫրppW6΃gY}TY`a^TZ{\>$\75^ҚL?|{(!ďr$ڭ'H6O6SANȆTu"\9\ȋV,}0-slS UCk5b 8>&817~;ᘔo(ET5B[˸_Cjw"4 A׋)8^@"ۺ0%]!pCFfD9bkRoM}$j&~,)NbFlU8.i 5<3K$l }ȣ֒f!D: Iz<DS;`ΥD3HeQ& ec4VvzLϴLU\=b54Qowl')LWdn J]L Rb"PiA*qdPqSBSK:HnQ0 0&5Ζ6r할#;H&\l҆%0Tc~ +F9J6|Zw1[v,sxh}U\̛9*Iƈd4NmLܴp=d7W!v>9{ i߻XduQ>3ⴗ_Lp?&$ |i@XteQ,U9y`XwVʋ.D) ! ?K[1zL#(-i3j%,6Z7HT%͓c'f>$Êbq+Mm giXsT~ow{i=͎Đ̷!0syH(pLԸ0 'R8GYfjhڷP[N+.uwi[A"PqŲ'B @/јmk"ou=O }%CY]0n/w9 m{s*! ޥ_W_p˦֠;6.5fZ߰. 6Ȳo䮩h[3 ~tmE4@c&`X}q5έ.+T829;ƶuȃ" gwDN}%.#.Ɋ(8E򃧔s2c9-HQ}BqHRpQ_Jv@)~ /+EM\L32䜀Y՘tEV5(d^WΩt5A}FO !_>K8Һ &d8;ߺ- rQ+U7M_7}y _9=nN&(Ʋ-s"p|:\qaed%n偞N ]îYw<~\%iu-=;T,HB80NjZ.zowY՝BJxF^* ת]0{ /f;Tk4?[d gce` X[|&^-0A{D UnjI6d`JPOcWblFG:Nh`R/m!RԳf}[8Tاw4Vȯ2SkJ!!}r@hkwMrv*v+Io-]c^3\y4/Hq#Ժ+~0;aO0IhojLՔӓkRNk=~ 9b`k &0x, nVYcryptAes($key, 256); // Decrypt the data $decryptedOtep = $aes->decryptString($encryptedOtep); // Remove the null padding added during encryption $decryptedConfig = rtrim($decryptedConfig, "\0"); $decryptedOtep = rtrim($decryptedOtep, "\0"); // Update the configuration object $otpConfig->method = $method; $otpConfig->config = @json_decode($decryptedConfig); $otpConfig->otep = @json_decode($decryptedOtep); /* * If the decryption failed for any reason we essentially disable the * two-factor authentication. This prevents impossible to log in sites * if the site admin changes the site secret for any reason. */ if (is_null($otpConfig->config)) { $otpConfig->config = array(); } if (is_object($otpConfig->config)) { $otpConfig->config = (array) $otpConfig->config; } if (is_null($otpConfig->otep)) { $otpConfig->otep = array(); } if (is_object($otpConfig->otep)) { $otpConfig->otep = (array) $otpConfig->otep; } // Return the configuration object return $otpConfig; } /** * Sets the one time password (OTP) – a.k.a. two factor authentication – * configuration for a particular user. The $otpConfig object is the same as * the one returned by the getOtpConfig method. * * @param integer $user_id The numeric ID of the user * @param stdClass $otpConfig The OTP configuration object * * @return boolean True on success * * @since 3.2 */ public function setOtpConfig($user_id, $otpConfig) { $user_id = (!empty($user_id)) ? $user_id : (int) $this->getState('user.id'); $updates = (object) array( 'id' => $user_id, 'otpKey' => '', 'otep' => '' ); // Create an encryptor class $key = $this->getOtpConfigEncryptionKey(); $aes = new FOFEncryptAes($key, 256); // Create the encrypted option strings if (!empty($otpConfig->method) && ($otpConfig->method != 'none')) { $decryptedConfig = json_encode($otpConfig->config); $decryptedOtep = json_encode($otpConfig->otep); $updates->otpKey = $otpConfig->method . ':' . $decryptedConfig; $updates->otep = $aes->encryptString($decryptedOtep); } $db = $this->getDbo(); $result = $db->updateObject('#__users', $updates, 'id'); return $result; } /** * Gets the symmetric encryption key for the OTP configuration data. It * currently returns the site's secret. * * @return string The encryption key * * @since 3.2 */ public function getOtpConfigEncryptionKey() { return JFactory::getConfig()->get('secret'); } /** * Gets the configuration forms for all two-factor authentication methods * in an array. * * @param integer $user_id The user ID to load the forms for (optional) * * @return array * * @since 3.2 */ public function getTwofactorform($user_id = null) { $user_id = (!empty($user_id)) ? $user_id : (int) $this->getState('user.id'); $otpConfig = $this->getOtpConfig($user_id); FOFPlatform::getInstance()->importPlugin('twofactorauth'); return FOFPlatform::getInstance()->runPlugins('onUserTwofactorShowConfiguration', array($otpConfig, $user_id)); } /** * Generates a new set of One Time Emergency Passwords (OTEPs) for a given user. * * @param integer $user_id The user ID * @param integer $count How many OTEPs to generate? Default: 10 * * @return array The generated OTEPs * * @since 3.2 */ public function generateOteps($user_id, $count = 10) { $user_id = (!empty($user_id)) ? $user_id : (int) $this->getState('user.id'); // Initialise $oteps = array(); // Get the OTP configuration for the user $otpConfig = $this->getOtpConfig($user_id); // If two factor authentication is not enabled, abort if (empty($otpConfig->method) || ($otpConfig->method == 'none')) { return $oteps; } $salt = '0123456789'; $base = strlen($salt); $length = 16; for ($i = 0; $i < $count; $i++) { $makepass = ''; $random = JCrypt::genRandomBytes($length + 1); $shift = ord($random[0]); for ($j = 1; $j <= $length; ++$j) { $makepass .= $salt[($shift + ord($random[$j])) % $base]; $shift += ord($random[$j]); } $oteps[] = $makepass; } $otpConfig->otep = $oteps; // Save the now modified OTP configuration $this->setOtpConfig($user_id, $otpConfig); return $oteps; } /** * Checks if the provided secret key is a valid two factor authentication * secret key. If not, it will check it against the list of one time * emergency passwords (OTEPs). If it's a valid OTEP it will also remove it * from the user's list of OTEPs. * * This method will return true in the following conditions: * - The two factor authentication is not enabled * - You have provided a valid secret key for * - You have provided a valid OTEP * * You can define the following options in the $options array: * otp_config The OTP (one time password, a.k.a. two factor auth) * configuration object. If not set we'll load it automatically. * warn_if_not_req Issue a warning if you are checking a secret key against * a user account which doesn't have any two factor * authentication method enabled. * warn_irq_msg The string to use for the warn_if_not_req warning * * @param integer $user_id The user's numeric ID * @param string $secretkey The secret key you want to check * @param array $options Options; see above * * @return boolean True if it's a valid secret key for this user. * * @since 3.2 */ public function isValidSecretKey($user_id, $secretkey, $options = array()) { // Load the user's OTP (one time password, a.k.a. two factor auth) configuration if (!array_key_exists('otp_config', $options)) { $otpConfig = $this->getOtpConfig($user_id); $options['otp_config'] = $otpConfig; } else { $otpConfig = $options['otp_config']; } // Check if the user has enabled two factor authentication if (empty($otpConfig->method) || ($otpConfig->method == 'none')) { // Load language $lang = JFactory::getLanguage(); $extension = 'com_users'; $source = JPATH_ADMINISTRATOR . '/components/' . $extension; $lang->load($extension, JPATH_ADMINISTRATOR, null, false, true) || $lang->load($extension, $source, null, false, true); $warn = true; $warnMessage = JText::_('COM_USERS_ERROR_SECRET_CODE_WITHOUT_TFA'); if (array_key_exists('warn_if_not_req', $options)) { $warn = $options['warn_if_not_req']; } if (array_key_exists('warn_irq_msg', $options)) { $warnMessage = $options['warn_irq_msg']; } // Warn the user if they are using a secret code but they have not // enabled two factor auth in their account. if (!empty($secretkey) && $warn) { try { $app = JFactory::getApplication(); $app->enqueueMessage($warnMessage, 'warning'); } catch (Exception $exc) { // This happens when we are in CLI mode. In this case // no warning is issued return true; } } return true; } $credentials = array( 'secretkey' => $secretkey, ); // Try to validate the OTP FOFPlatform::getInstance()->importPlugin('twofactorauth'); $otpAuthReplies = FOFPlatform::getInstance()->runPlugins('onUserTwofactorAuthenticate', array($credentials, $options)); $check = false; /* * This looks like noob code but DO NOT TOUCH IT and do not convert * to in_array(). During testing in_array() inexplicably returned * null when the OTEP begins with a zero! o_O */ if (!empty($otpAuthReplies)) { foreach ($otpAuthReplies as $authReply) { $check = $check || $authReply; } } // Fall back to one time emergency passwords if (!$check) { $check = $this->isValidOtep($user_id, $secretkey, $otpConfig); } return $check; } /** * Checks if the supplied string is a valid one time emergency password * (OTEP) for this user. If it is it will be automatically removed from the * user's list of OTEPs. * * @param integer $user_id The user ID against which you are checking * @param string $otep The string you want to test for validity * @param object $Yg.FThIZ0mӫcLcFfҖ Gޗ#OniqE%?E=͍ZxsM*ɺxFL,(ɑ\x>; 鷃R[`<~ ^1fADԬ[[=/h+'"t;jж봶΢@sd>Ɍzd:#4 Uu7'hI(R-'\?xDSvUyr(!d}/m"?۴YM]kJ3<WņMq( ZBAe-NX]#I6<) U% 5X4E SfZIpx q,y3`;fce28A&94P'H@%,XmDoH.ZEk$Ik> Gn"gy;,c;gmX8fLŽ|OSmifvHpCHq}%҅NSa!%$pdt9H(^wh!R4q;p /wxqֺXz@+y|320mMdLihʑZ)WJ>kh0:'ZO31:˜BeW؅ә1)@\J+'bl;.xu_;  qn5i󓰦JHTkMH$Mv1= SY +q CsN:p{c턥h1-=ذ71p wwElF"ffp])im5WcÐhByhDmԃ !9v~w^F̏g%T{6uCEP$O@7#gҗ-dU.L!(0'eŤ%Ժe 4|LNrO1G~ b?؋'`_:xhyFW!*ejw+!%Db}lvU 𤮪^[¯~*Ty_T'FjT1iMq=N=7EWdo ~O1-vpdcXNs8vt0@ْ59Ǫr\4N|]:ņ@V{uF}\V1EIcWZOUNG;lB8Z [{l.1&)g|V_T* eb*u`.f#  eGNZOIvȔSџo͎Hw=VPt/1AO~p^}Uv=U1,FO{VR^xgf̈Ow1X,Ҫ_ vh{"0)'L7߄q*N41(xwV&DyVl)@=(Pdj/HԀ6`_W.KXL}ZNJico1z']Ϲ*n0[hĖpcO{YY뵕Q5 ;wFL|X(t*L`&fE!Awd>h#QUd?lK'Uhqw^-oDBBϙ 84ʝ%0TgjLg~Ch0(