add_lang('captcha_qa'); // read input $this->confirm_id = request_var('qa_confirm_id', ''); $this->answer = utf8_normalize_nfc(request_var('qa_answer', '', true)); $this->type = (int) $type; $this->question_lang = $user->lang_name; // we need all defined questions - shouldn't be too many, so we can just grab them // try the user's lang first $sql = 'SELECT question_id FROM ' . CAPTCHA_QUESTIONS_TABLE . " WHERE lang_iso = '" . $db->sql_escape($user->lang_name) . "'"; $result = $db->sql_query($sql, 3600); while ($row = $db->sql_fetchrow($result)) { $this->question_ids[$row['question_id']] = $row['question_id']; } $db->sql_freeresult($result); // fallback to the board default lang if (!sizeof($this->question_ids)) { $this->question_lang = $config['default_lang']; $sql = 'SELECT question_id FROM ' . CAPTCHA_QUESTIONS_TABLE . " WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'"; $result = $db->sql_query($sql, 7200); while ($row = $db->sql_fetchrow($result)) { $this->question_ids[$row['question_id']] = $row['question_id']; } $db->sql_freeresult($result); } // okay, if there is a confirm_id, we try to load that confirm's state. If not, we try to find one if (!$this->load_answer() && (!$this->load_confirm_id() || !$this->load_answer())) { // we have no valid confirm ID, better get ready to ask something $this->select_question(); } } /** * API function */ function &get_instance() { $instance =& new phpbb_captcha_qa(); return $instance; } /** * See if the captcha has created its tables. */ function is_installed() { global $db, $phpbb_root_path, $phpEx; if (!class_exists('phpbb_db_tools')) { include("$phpbb_root_path/includes/db/db_tools.$phpEx"); } $db_tool = new phpbb_db_tools($db); return $db_tool->sql_table_exists(CAPTCHA_QUESTIONS_TABLE); } /** * API function - for the captcha to be available, it must have installed itself and there has to be at least one question in the board's default lang */ function is_available() { global $config, $db, $phpbb_root_path, $phpEx, $user; // load language file for pretty display in the ACP dropdown $user->add_lang('captcha_qa'); if (!phpbb_captcha_qa::is_installed()) { return false; } $sql = 'SELECT COUNT(question_id) AS question_count FROM ' . CAPTCHA_QUESTIONS_TABLE . " WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); return ((bool) $row['question_count']); } /** * API function */ function has_config() { return true; } /** * API function */ function get_name() { return 'CAPTCHA_QA'; } /** * API function */ function get_class_name() { return 'phpbb_captcha_qa'; } /** * API function - not needed as we don't display an image */ function execute_demo() { } /** * API function - not needed as we don't display an image */ function execute() { } /** * API function - send the question to the template */ function get_template() { global $template; if ($this->is_solved()) { return false; } else { $template->assign_vars(array( 'QA_CONFIRM_QUESTION' => $this->question_text, 'QA_CONFIRM_ID' => $this->confirm_id, 'S_CONFIRM_CODE' => true, 'S_TYPE' => $this->type, )); return 'captcha_qa.html'; } } /** * API function - we just display a mockup so that the captcha doesn't need to be installed */ function get_demo_template() { global $config, $db, $template; if ($this->is_available()) { $sql = 'SELECT question_text FROM ' . CAPTCHA_QUESTIONS_TABLE . " WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'"; $result = $db->sql_query_limit($sql, 1); if ($row = $db->sql_fetchrow($result)) { $template->assign_vars(array( 'QA_CONFIRM_QUESTION' => $row['question_text'], )); } $db->sql_freeresult($result); } return 'captcha_qa_acp_demo.html'; } /** * API function */ function get_hidden_fields() { $hidden_fields = array(); // this is required - otherwise we would forget about the captcha being already solved if ($this->solved) { $hidden_fields['qa_answer'] = $this->answer; } $hidden_fields['qa_confirm_id'] = $this->confirm_id; return $hidden_fields; } /** * API function */ function garbage_collect($type = 0) { global $db, $config; $sql = 'SELECT c.confirm_id FROM ' . CAPTCHA_QA_CONFIRM_TABLE . ' c LEFT JOIN ' . SESSIONS_TABLE . ' s ON (c.session_id = s.session_id) WHERE s.session_id IS NULL' . ((empty($type)) ? '' : ' AND c.confirm_type = ' . (int) $type); $result = $db->sql_query($sql); if ($row = $db->sql_fetchrow($result)) { $sql_in = array(); do { $sql_in[] = (string) $row['confirm_id']; } while ($row = $db->sql_fetchrow($result)); if (sizeof($sql_in)) { $sql = 'DELETE FROM ' . CAPTCHA_QA_CONFIRM_TABLE . ' WHERE ' . $db->sql_in_set('confirm_id', $sql_in); $db->sql_query($sql); } } $db->sql_freeresult($result); } /** * API function - we don't drop the tables here, as that would cause the loss of all entered questions. */ function uninstall() { $this->garbage_collect(0); } /** * API function - set up shop */ function install() { global $db, $phpbb_root_path, $phpEx; if (!class_exists('phpbb_db_tools')) { include("$phpbb_root_path/includes/db/db_tools.$phpEx"); } $db_tool = new phpbb_db_tools($db); $tables = array(CAPTCHA_QUESTIONS_TABLE, CAPTCHA_ANSWERS_TABLE, CAPTCHA_QA_CONFIRM_TABLE); $schemas = array( CAPTCHA_QUESTIONS_TABLE => array ( 'COLUMNS' => array( 'question_id' => array('UINT', Null, 'auto_increment'), 'strict' => array('BOOL', 0), 'lang_id' => array('UINT', 0), 'lang_iso' => array('VCHAR:30', ''), 'question_text' => array('TEXT_UNI', ''), ), 'PRIMARY_KEY' => 'question_id', 'KEYS' => array( 'lang' => array('INDEX', 'lang_iso'), ), ), CAPTCHA_ANSWERS_TABLE => array ( 'COLUMNS' => array( 'question_id' => array('UINT', 0), 'answer_text' => array('STEXT_UNI', ''), ), 'KEYS' => array( 'qid' => array('INDEX', 'question_id'), ), ), CAPTCHA_QA_CONFIRM_TABLE => array ( 'COLUMNS' => array( 'session_id' => array('CHAR:32', ''), 'confirm_id' => array('CHAR:32', ''), 'lang_iso' => array('VCHAR:30', ''), 'question_id' => array('UINT', 0), 'attempts' => array('UINT', 0), 'confirm_type' => array('USINT', 0), ), 'KEYS' => array( 'session_id' => array('INDEX', 'session_id'), 'lookup' => array('INDEX', array('confirm_id', 'session_id', 'lang_iso')), ), 'PRIMARY_KEY' => 'confirm_id', ), ); foreach($schemas as $table => $schema) { if (!$db_tool->sql_table_exists($table)) { $db_tool->sql_create_table($table, $schema); } } } /** * API function - see what has to be done to validate */ function validate() { global $config, $db, $user; $error = ''; if (!sizeof($this->question_ids)) { return false; } if (!$this->confirm_id) { $error = $user->lang['CONFIRM_QUESTION_WRONG']; } else { if ($this->check_answer()) { // $this->delete_code(); commented out to allow posting.php to repeat the question $this->solved = true; } else { $error = $user->lang['CONFIRM_QUESTION_WRONG']; } } if (strlen($error)) { // okay, incorrect answer. Let's ask a new question. $this->new_attempt(); $this->solved = false; return $error; } else { return false; } } /** * Select a question */ function select_question() { global $db, $user; if (!sizeof($this->question_ids)) { return false; } $this->confirm_id = md5(unique_id($user->ip)); $this->question = (int) array_rand($this->question_ids); $sql = 'INSERT INTO ' . CAPTCHA_QA_CONFIRM_TABLE . ' ' . $db->sql_build_array('INSERT', array( 'confirm_id' => (string) $this->confirm_id, 'session_id' => (string) $user->session_id, 'lang_iso' => (string) $this->question_lang, 'confirm_type' => (int) $this->type, 'question_id' => (int) $this->question, )); $db->sql_query($sql); $this->load_answer(); } /** * New Question, if desired. */ function reselect_question() { global $db, $user; if (!sizeof($this->question_ids)) { return false; } $this->question = (int) array_rand($this->question_ids); $this->solved = 0; $sql = 'UPDATE ' . CAPTCHA_QA_CONFIRM_TABLE . ' SET question_id = ' . (int) $this->question . " WHERE confirm_id = '" . $db->sql_escape($this->confirm_id) . "' AND session_id = '" . $db->sql_escape($user->session_id) . "'"; $db->sql_query($sql); $this->load_answer(); } /** * Wrong answer, so we increase the attempts and use a different question. */ function new_attempt() { global $db, $user; // yah, I would prefer a stronger rand, but this should work $this->question = (int) array_rand($this->question_ids); $this->solved = 0; $sql = 'UPDATE ' . CAPTCHA_QA_CONFIRM_TABLE . ' SET question_id = ' . (int) $this->question . ", attempts = attempts + 1 WHERE confirm_id = '" . $db->sql_escape($this->confirm_id) . "' AND session_id = '" . $db->sql_escape($user->session_id) . "'"; $db->sql_query($sql); $this->load_answer(); } /** * See if there is already an entry for the current session. */ function load_confirm_id() { global $db, $user; $sql = 'SELECT confirm_id FROM ' . CAPTCHA_QA_CONFIRM_TABLE . " WHERE session_id = '" . $db->sql_escape($user->session_id) . "' AND lang_iso = '" . $db->sql_escape($this->question_lang) . "' AND confirm_type = " . $this->type; $result = $db->sql_query_limit($sql, 1); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if ($row) { $this->confirm_id = $row['confirm_id']; return true; } return false; } /** * Look up everything we need and populate the instance variables. */ function load_answer() { global $db, $user; if (!strlen($this->confirm_id) || !sizeof($this->question_ids)) { return false; } $sql = 'SELECT con.question_id, attempts, question_text, strict FROM ' . CAPTCHA_QA_CONFIRM_TABLE . ' con, ' . CAPTCHA_QUESTIONS_TABLE . " qes WHERE con.question_id = qes.question_id AND confirm_id = '" . $db->sql_escape($this->confirm_id) . "' AND session_id = '" . $db->sql_escape($user->session_id) . "' AND qes.lang_iso = '" . $db->sql_escape($this->question_lang) . "' AND confirm_type = " . $this->type; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if ($row) { $this->question = $row['question_id']; $this->attempts = $row['attempts']; $this->question_strict = $row['strict']; $this->question_text = $row['question_text']; return true; } return false; } /** * The actual validation */ function check_answer() { global $db; $answer = ($this->question_strict) ? utf8_normalize_nfc(request_var('qa_answer', '', true)) : utf8_clean_string(utf8_normalize_nfc(request_var('qa_answer', '', true))); $sql = 'SELECT answer_text FROM ' . CAPTCHA_ANSWERS_TABLE . ' WHERE question_id = ' . (int) $this->question; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $solution = ($this->question_strict) ? $row['answer_text'] : utf8_clean_string($row['answer_text']); if ($solution === $answer) { $this->solved = true; break; } } $db->sql_freeresult($result); return $this->solved; } /** * API function - clean the entry */ function delete_code() { global $db, $user; $sql = 'DELETE FROM ' . CAPTCHA_QA_CONFIRM_TABLE . " WHERE confirm_id = '" . $db->sql_escape($confirm_id) . "' AND session_id = '" . $db->sql_escape($user->session_id) . "' AND confirm_type = " . $this->type; $db->sql_query($sql); } /** * API function */ function get_attempt_count() { return $this->attempts; } /** * API function */ function reset() { global $db, $user; $sql = 'DELETE FROM ' . CAPTCHA_QA_CONFIRM_TABLE . " WHERE session_id = '" . $db->sql_escape($user->session_id) . "' AND confirm_type = " . (int) $this->type; $db->sql_query($sql); // we leave the class usable by generating a new question $this->select_question(); } /** * API function */ function is_solved() { if (request_var('qa_answer', false) && $this->solved === 0) { $this->validate(); } return (bool) $this->solved; } /** * API function - The ACP backend, this marks the end of the easy methods */ function acp_page($id, &$module) { global $db, $user, $auth, $template; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; $user->add_lang('acp/board'); $user->add_lang('captcha_qa'); if (!$this->is_installed()) { $this->install(); } $module->tpl_name = 'captcha_qa_acp'; $module->page_title = 'ACP_VC_SETTINGS'; $form_key = 'acp_captcha'; add_form_key($form_key); $submit = request_var('submit', false); $question_id = request_var('question_id', 0); $action = request_var('action', ''); // we have two pages, so users might want to navigate from one to the other $list_url = $module->u_action . "&configure=1&select_captcha=" . $this->get_class_name(); $template->assign_vars(array( 'U_ACTION' => $module->u_action, 'QUESTION_ID' => $question_id , 'CLASS' => $this->get_class_name(), )); // show the list? if (!$question_id && $action != 'add') { $this->acp_question_list($module); } else if ($question_id && $action == 'delete') { if ($this->get_class_name() !== $config['captcha_plugin'] || !$this->acp_is_last($question_id)) { if (confirm_box(true)) { $this->acp_delete_question($question_id); trigger_error($user->lang['QUESTION_DELETED'] . adm_back_link($list_url)); } else { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( 'question_id' => $question_id, 'action' => $action, 'configure' => 1, 'select_captcha' => $this->get_class_name(), )) ); } } else { trigger_error($user->lang['QA_LAST_QUESTION'] . adm_back_link($list_url), E_USER_WARNING); } } else { // okay, show the editor $error = false; $input_question = request_var('question_text', '', true); $input_answers = request_var('answers', '', true); $input_lang = request_var('lang_iso', '', true); $input_strict = request_var('strict', false); $langs = $this->get_languages(); foreach ($langs as $lang => $entry) { $template->assign_block_vars('langs', array( 'ISO' => $lang, 'NAME' => $entry['name'], )); } $template->assign_vars(array( 'U_LIST' => $list_url, )); if ($question_id) { if ($question = $this->acp_get_question_data($question_id)) { $answers = (isset($input_answers[$lang])) ? $input_answers[$lang] : implode("\n", $question['answers']); $template->assign_vars(array( 'QUESTION_TEXT' => ($input_question) ? $input_question : $question['question_text'], 'LANG_ISO' => ($input_lang) ? $input_lang : $question['lang_iso'], 'STRICT' => (isset($_REQUEST['strict'])) ? $input_strict : $question['strict'], 'ANSWERS' => $answers, )); } else { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($list_url)); } } else { $template->assign_vars(array( 'QUESTION_TEXT' => $input_question, 'LANG_ISO' => $input_lang, 'STRICT' => $input_strict, 'ANSWERS' => $input_answers, )); } if ($submit && check_form_key($form_key)) { $data = $this->acp_get_question_input(); if (!$this->validate_input($data)) { $template->assign_vars(array( 'S_ERROR' => true, )); } else { if ($question_id) { $this->acp_update_question($data, $question_id); } else { $this->acp_add_question($data); } add_log('admin', 'LOG_CONFIG_VISUAL'); trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($list_url)); } } else if ($submit) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($list_url), E_USER_WARNING); } } } /** * This handles the list overview */ function acp_question_list(&$module) { global $db, $template; $sql = 'SELECT * FROM ' . CAPTCHA_QUESTIONS_TABLE; $result = $db->sql_query($sql); $template->assign_vars(array( 'S_LIST' => true, )); while ($row = $db->sql_fetchrow($result)) { $url = $module->u_action . "&question_id={$row['question_id']}&configure=1&select_captcha=" . $this->get_class_name() . '&'; $template->assign_block_vars('questions', array( 'QUESTION_TEXT' => $row['question_text'], 'QUESTION_ID' => $row['question_id'], 'QUESTION_LANG' => $row['lang_iso'], 'U_DELETE' => "{$url}action=delete", 'U_EDIT' => "{$url}action=edit", )); } $db->sql_freeresult($result); } /** * Grab a question and bring it into a format the editor understands */ function acp_get_question_data($question_id) { global $db; if ($question_id) { $sql = 'SELECT * FROM ' . CAPTCHA_QUESTIONS_TABLE . ' WHERE question_id = ' . $question_id; $result = $db->sql_query($sql); $question = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$question) { return false; } $question['answers'] = array(); $sql = 'SELECT * FROM ' . CAPTCHA_ANSWERS_TABLE . ' WHERE question_id = ' . $question_id; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $question['answers'][] = $row['answer_text']; } $db->sql_freeresult($result); return $question; } } /** * Grab a question from input and bring it into a format the editor understands */ function acp_get_question_input() { $answers = utf8_normalize_nfc(request_var('answers', '', true)); $question = array( 'question_text' => request_var('question_text', '', true), 'strict' => request_var('strict', false), 'lang_iso' => request_var('lang_iso', ''), 'answers' => (strlen($answers)) ? explode("\n", $answers) : '', ); return $question; } /** * Update a question. * param mixed $data : an array as created from acp_get_question_input or acp_get_question_data */ function acp_update_question($data, $question_id) { global $db, $cache; // easier to delete all answers than to figure out which to update $sql = 'DELETE FROM ' . CAPTCHA_ANSWERS_TABLE . " WHERE question_id = $question_id"; $db->sql_query($sql); $langs = $this->get_languages(); $question_ary = $data; $question_ary['lang_id'] = $langs[$question_ary['lang_iso']]['id']; unset($question_ary['answers']); $sql = 'UPDATE ' . CAPTCHA_QUESTIONS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $question_ary) . " WHERE question_id = $question_id"; $db->sql_query($sql); $this->acp_insert_answers($data, $question_id); $cache->destroy('sql', CAPTCHA_QUESTIONS_TABLE); } /** * Insert a question. * param mixed $data : an array as created from acp_get_question_input or acp_get_question_data */ function acp_add_question($data) { global $db, $cache; $langs = $this->get_languages(); $question_ary = $data; $question_ary['lang_id'] = $langs[$data['lang_iso']]['id']; unset($question_ary['answers']); $sql = 'INSERT INTO ' . CAPTCHA_QUESTIONS_TABLE . ' ' . $db->sql_build_array('INSERT', $question_ary); $db->sql_query($sql); $question_id = $db->sql_nextid(); $this->acp_insert_answers($data, $question_id); $cache->destroy('sql', CAPTCHA_QUESTIONS_TABLE); } /** * Insert the answers. * param mixed $data : an array as created from acp_get_question_input or acp_get_question_data */ function acp_insert_answers($data, $question_id) { global $db, $cache; foreach ($data['answers'] as $answer) { $answer_ary = array( 'question_id' => $question_id, 'answer_text' => $answer, ); $sql = 'INSERT INTO ' . CAPTCHA_ANSWERS_TABLE . ' ' . $db->sql_build_array('INSERT', $answer_ary); $db->sql_query($sql); } $cache->destroy('sql', CAPTCHA_ANSWERS_TABLE); } /** * Delete a question. */ function acp_delete_question($question_id) { global $db, $cache; $tables = array(CAPTCHA_QUESTIONS_TABLE, CAPTCHA_ANSWERS_TABLE); foreach ($tables as $table) { $sql = "DELETE FROM $table WHERE question_id = $question_id"; $db->sql_query($sql); } $cache->destroy('sql', $tables); } /** * Check if the entered data can be inserted/used * param mixed $data : an array as created from acp_get_question_input or acp_get_question_data */ function validate_input($question_data) { $langs = $this->get_languages(); if (!isset($question_data['lang_iso']) || !isset($question_data['question_text']) || !isset($question_data['strict']) || !isset($question_data['answers'])) { return false; } if (!isset($langs[$question_data['lang_iso']]) || !strlen($question_data['question_text']) || !sizeof($question_data['answers']) || !is_array($question_data['answers'])) { return false; } return true; } /** * List the installed language packs */ function get_languages() { global $db; $sql = 'SELECT * FROM ' . LANG_TABLE; $result = $db->sql_query($sql); $langs = array(); while ($row = $db->sql_fetchrow($result)) { $langs[$row['lang_iso']] = array( 'name' => $row['lang_local_name'], 'id' => (int) $row['lang_id'], ); } $db->sql_freeresult($result); return $langs; } /** * See if there is a question other than the one we have */ function acp_is_last($question_id) { global $config, $db; if ($question_id) { $sql = 'SELECT question_id FROM ' . CAPTCHA_QUESTIONS_TABLE . " WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "' AND question_id <> " . (int) $question_id; $result = $db->sql_query_limit($sql, 1); $question = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$question) { return true; } return false; } } } ?>%yʧ ɐ`8%e}J=a{oBG7ǿ/Q5)i=8K!ȀVQ 8` uK]c ؉"!d ; '>Tk3D5xsNu3;7Ȃ.kC[&U5f~@h`4bnϥ!+ *r1d{t^+ /(Նe9d󏠊/(2]=T ̤y2SW9eyf>G"(SOTL&dnQZfX0;Pq[zMó\I&GUY>jܕJⰬx˫yЍO]x m*x !4Oe0]P@"F=xEN.XOQwܷ'/F3g5"|d$Jp<_ vVtq-7SE6BcqON,dJvI<\x{,āiK3,}9oMgQ|m U`|SMEzgM }qIٵt}?{{JOomD:_';k4Ymtmꚧ͚hJ7ĩC7mmGme3PKu[rp@A2ybirqS˖E, LI؃>$`ޕc`J=-; 8VKQfRLEiՏ.nX /URtݎ]y-"Mۧqێ"crQ0 YڻC)v~m%KxqjT9PĜMZgb OOXF5=Ϋj&3`Qr6bZߛz$;*#Т/)C7_ 7A|9qUZ2n<3Q`$RJF̣ T Im\40 6y-;cndboJ!on,wd4NH3 [OA%H#߅!GҢZ,;;6$l:7fm4s#).gkcy7@5- !e'-]G&-1STڔA9gDҴVHYp;q+c'ܿ N [E/|7a`e  `;0:hPu@||EnRwZF .7֦=׭6W3m1U|LDᄚ@=,KcŶL)@nXAE3 7jYi|U>Wʃjtrh `? i OcA"^Cq?_=^όӽ7"$x5WaEF[?}1T7=dl e (Y"B 2p4Ѳ\*,&,ZXkYTQhLxQ`odW73Bm*bu}y3L m+atVyaQSs'm˝E}dD/Ro_+'zm9mSMr..Ѕ(ً0;Va |Rْ82^:W=𢱣*0>y c ( c5JL+EFt‹ 9 \YƧ`r_ǿvnζxq]vN W) (1Wξ˜K7/ZsQpMHf*Kcw3fjMi3q@6_UksROwV3B7Yb*,ѸX`O b)] xL;V@2PNqhh? {C"n\v03g*k=PNWJ%jke|俺߼xvS\D @/\!inLO ki' 6$w4px͆)dv! su煯C79Ѣ5ԶPl4KbVU$yyl$SeΫC '6WY4[M(_q@**ҒoٙI9ZdmY-^^g`s23^lIYibld1l7RC[JogBnQ 7L3u)*DBU E)[谄V]2[ٙz6) {ʉni(ϗ)JPCS}۴0n;k״J3FwlݩV&yݳr)۔>xv2B$ƸA/a;Mbb7,%Bj ?4WY>2n*EiJLZIy9+DIei-<ʫZ 9Cez\\xX[\fׂJMToϊ:%K*1CwEaZ||;ܵ|UЩt2-L75?f(ӧ$sEk{jNR c7(p6 l;]#+-ZL;-ol MQ~\* e5\C!7e\`AqDyd;K@rPH5RJ>+Ѥa㺬6T>؀|{D.*<(5'xm(K{>dmk3jk%׉@%gڀ%t+/KxRV!+` g@gb!7P e"j)g["nf2ZTN΋iaIH~odND`ij6+i@̱ 4 Ou+f>yfd9";@ԩ=iQ`]8m/j pO)\ZJJk}9Jňet5w5/~ȡ7IkĴK*3T#‰OTךxra}^kzii2?# CU;|5#Ob*teaW!5 V=m峷܆n7L -bVە+rӶ芄̓yŅK۸{TWvbXŸfmxa,]X.*껌-FXI/jLaPwM2O˔qt4-sfr^a#7ʄ(Y|MZ]+4d_Lb̧vP8R+ s6Qphnܾ 6XCuކrbUi%n(693n7@pjKەdə*I2*əy 1"K)3+j̎uyI݈BBYcX+[)Ei[IKX)%9J7!3!_ί`NKJ̵'LKep@8&iۦ_Fo W $3cզT6rE;!FMJ5duFxJ;uqr3G뮥2hڮ":ؙaPvZ͕ghJ2䥶J<2T`Ā0 ͅG'"mɐx`8a\N԰_cWIC s0#F7m թ,/\_ ۍ 4wq1e2'W-n&L^FJsUP Ǭsq \z"^ohhSY~ 1 <67Vfo'0pY Y"uq띧eQwD#A/ nEesz3Iz'^UQD \:KĬQrcC8q].n vv|! yb* 8ԒgN@&u|q D"ͯZL9f Vim(Z%D-G yw (M Hz\٠=~K4N֧) xKdCX) i`rނl# Qh[*0! =bLԻ Di`7XUC TMΩ,F: y)cJlqbs3_2-)B8.q +\A,CTT̏=Xg*0G=x*6*[ç8&h$zpщ?- i-7gʛ 'ZP?[q,Eԏp:>P]ɛjfL[A( D (TܲOmtoM9%ަXLu GݍuND aa֙Ozǎ\AEɨS&d J˰6#RʢT G27 V[o'ATT'Br7 ʰ(c<;}V~~* ]6hj{sϨMD=O, eڔrR;(d!ԉOvj[) =SB-4T@}5 &yC2#6Y-VLJGWUA8-DRO|`;#AB~oyrV[L0x liaށvBݦiPiJ])If _C1`.BSR bk)r)x:Fqj,; vLM_'ZJÞ [XdD5x l<#Z&LoUDܾ#; _so]k[%)н4t<2qYE-".M6V|0%{8!X(B+ a͜,JԨʱG8Ӱ3N)ȐIJ{3 yKhM7}DQc[2-ɸph<ɀfHT4@P(@&|Dٰi!KsBYB6[s0Ѫ3/ЋA@~y=4nn bDkeia`4E_e{(`Rl=R/7V(O"98CL,tbdaY9LRIm⏗;4[! 7ȬԌ׿RE.ؤ%XlJF "E+i.g FZc88Bl?xmV&VZfimr㞕e,)U<7WD.,BnXgpNYX2䆝ww%y,*h~\i?~AYg,x|^dI'6/߭,"r?3SUF89j:=R p`ʋITyJp`FSslڬ;$ 쇁_D@8OSrqGN 7^ ],rKbF[J"ԣAoP@OtWkEVդT]Q\FK'ީcqcy18Kx! mH-;M f.TXs+2g7ZSt OR,ZVecJ4j}l,[ &Xm 5X/v_DWh/Xjoyi׳ٲӏ'd%p1&TqAr_ݼȍ_xm8x, \/UnI((FQHQɍEٮb՜sdJc 1I]RF@^2ٕȫO4xrRJR};|E(t쯏R˔ȶ5G~`;!GWR>4$-zv&/KR+87)M Ue0J{},.L!()a2*JWM|YY~X*Y6D%r&~yIOi͛䉢mW;.RaQn5ʜcYt32abއYj^p*L"F 7޽Pio(vhGx:e5eT==xK2 'vcd{VȊ\+E^&+B(3հM1P0h[<>ۯq۱IѲ!;EPT50.ǩ-NQUkPD}'RaDΎEZDW\EWY7Tg4?@U/8%1"=:X).rɊZK<<.z4P.\yl\p`m+䳌`cR9gw:|HkT8 >Fb띲@eWe; i)pCe?oG߁"`ĥ @򥼶] 98bvƐ*tִd~^bÉ xY:8hC^ftU0E1SPd P"C\%y6unD y|:ZE84^AUʡ^񞎚IZVK:Hkʉ/=>y <а;INu57ִ:R{@ůYT[tJך*]Ո<~+IIZًݥgY2eG%>)ӦK5T^8;tI5Kj/POzC/y[k`\(W%jEp^$ŵUJ'oJσڽF1;%Zp۟Q|fi:IO:~ˑTė\kl%9n*<7IyZ'g*,tt=WN o&mpbؒⲈNaQMN:+SWʞޜ3_VQgĵ)Jsb<:$A\<#05bTpO|qq H m଎%)]BR"KIÙV*Mu{qx1KˈN-e^pDޅB%VA.`}$a8XdHLNZANƁYod fzd:*kMDQ5$?[.xu\ZRɇV=> KGn껨<vlMrO/`z6DaƙIs ֩\4V* -,uKWGZ VдcAsCtρIA5^BBK ǗM o`uqthCR3kN{OY KWnXm~cυ8'xB\-W]ufv5OHF*;6ߟjavVH /_90o y$KY1QUЦE%chZTjlboO"S;h0,o٤̣뉅:J2I-lCSӲ*E {h%7hN79Iê*|o}:Ft}鈋fQ&\lꚔC8]eYlB1[.S播lo,4г\*剑YcMٺTJ [¸ά( RήБ|6="$1 JvنT(3gj&UK=_G 7Ⱥl"K 1ѻ',6`.AYWslfX|#,S!#9y&dQ,UqB 3+%Xe bJX-nXRy@?bĬǃ\##fQ6WTv@70$"|D.Qg1J&E#(՟@8l4v_z_~DzmUa6HQ(. ;50`M9wciz,:96ݲ#{b4)<ǦX@Ob8`sT +MOJM1#JBaUϡz 'HР3}Z|/azQ^ &M`mrL9P7\ #1U'0`Wɷ2? Z4$OD&d^IA|'g5ݭ-_V(!D:(vUZ yb$%[HJ݆#+ .V36e3#bI[Z|q`鏕 IWw+S$ '("f4;Դ9 gtHFDEȈ-"sH/@|HksM;DlĹ,lwEjn442,a͚da;ҋ"mEC#8g Pi1I%BAGe?4.b\zbSV#yx`j3' (6͇Ih9oe'፾s[了[=ڋl)'9,6M5 8#l9",= ( dy%G70#< *2iN 70{kcʭF}V>D*]wt%c{uLF(e}q%*w)H)9<~Z}^RD6"c֏XSYE2YDk o&/CȠu@,W/w4ϓXt93ϐ|D7s,'fcVE/]pbc6"tI⴬$Dl+{Y(fN86n)WӘFNxcbhH}R2%C#OQasi/ίr .Xn줤2Ɔ^gO/IC[/. A~kxA,Y~}Y}yWNNj$ B,ͳNY~,B&Te4MegGD%q &Ʋۗ%t-9rg3S} 4!YK) Fu'"I1!/EyRNh6=[֨؇XT0 ΂-`y23kG wӤn8B "^|힅wE:D\Va_oUZ9/ S% dON9vHYهhtكlwM8C$/A\Re|DǧwAzXj5f킅XWHNԄ5MAa^a|^ўC]dJg)ßkaɠ-Pf$b3ӴMS8k۞bP/J ɿ[3i|vK7oZ9$ι,2|MMwؑovЄm>;b!R CiL BQzx, =NŽV uK:a {9P<v1}ԲiɣPBMTC\@I0"_A(۔zn|&C7 ]`٭̃09\F*j@ 1HUy1[۸78o; u=7wz} zM7 4/|v/|h'\oCLuPbyifϾܿg71&uDgFהE@ob#:g xC܇g8WOO|Dn)G_\DMٽijU UQmnwck+@`k_[kkwً/з5*PWİEO 8_'Q(݆ŚjW%4K9wxIk']Go\CSPd=X_."}ȣ݃5ئkwR~\__) ?Rv~h:Bո> $U dwv7D@98 ڋoq.L@;8  OD&pn+;'cэMsJ^ɀb`Ҫmo´~z}wﷶ7ϭJ9xrW'O|Mߨ* wNJp!'ye!zGoo[~}٣oEx/.2iS&vX"Dq&Z`ñڝp =Y^$xW <<jx.ic'Ǥ nDxPM#2`%8;}a ʷEDG:Aߟ~Q\ !HTcU$N<~/>oTѐ XGk6'v0 )(]x`g[6߾::>o΍ÿȵjڋ HB\vzt,y؁ded-L6`LGo0]׹6i贮an`Wno~I›%oh#(J)Q U+pƱ7ԎEH!G4[uFyM-~=~v\cտ y8r!Ǣh(3vQ`ĥ.s WĦфK Δ0r̶67 .7EckFj-~c~l?7tr\m@f[wZ;9޹s_ #!j:juoB2G[-ʋX o'5ݿvMhEaM!x,b 8$PiiMHI( G~`PO>eq".q]`X'%PճV\tk7^zniU7`,B/Nx"6@o^|{&=OW=?Äq߸ Ƀ a '+ώ_}O<b=?>=O^GN}x/NkB2gOs753rtޠzoU+g$p_z`bOXO-N~m[gH\8 v- >{$Mi6vc[|{LmQõ4!`y; 4݈u؁$y'HSxYS IN +[kw8!6'nscc[n;ј\~E"ÏpP=5=tr=>|Lxz{._Q_tW7u>;o{V|C!Ӟ,'rqH-I{^ ;a^Kk=C?#f%4iyd儡8Eb#+# VfPNOY1^t-H|^ 3g< ͔I+NN۝tIaѨh7H>0G@MLdUFsgkܑAzDP/t7tHMJ!] x-õkk?o 7rӺ?' p&,o[TGƏ8ԝ, ^Wjo>]o!LPQT֛ U]y31yXf·jHx!J|I<>Ǥtw k1{D#2io'ޯH~CbVMTEk~߆Q˳q̠=i/}_/?5<7$Ըa!YF3wo M^(j߻']&07w[k|4m=4?ėAu$[Um0tdK_7i;ww?fX0^:*'hwvPLz.GbD\>|C/>^fǏ_Iu=3FwYh>^?ųG'sbxTp$ql1xfyUf=G%o1Ejա-X8N*.ɕ:tԳU**l’!m20s{ 'qd(; MM@3{ /]ܦDȿ[iF我y)/3w/B =Z@}tDCW!b/Hd0@'4T Zq ``HFD)}.$1I(ȵM+jJ"u$0AFwICC/YNe.L>+k6tA&y@0xo^)^>xS"sSH1S+ C) >|:S*Ub 8ۮC^xq{ݎT$]P1VCsr`\E0 ܸ~:!>w1´ ϖ4MѼh&Ȼ~$Owik0A D62c9\ [dN'g6_CP>ZOt9>ߒ_+5mz^o&2p1}z3f 1OJ?J%>J%]d~B$,fci0 GYCnbRlmU[oy1#WwQnz]D8d;+OA򇶀~` ')~қOMB>Pvw g]+:3tpyV'? 6Ƥ?\xE">~JӇ\w]kŃY#DphET]^wTrιVwQkU??^}t܁_;OA\QAO> cM݁CDQ@r&~F.ert(yt@cJkb3F+Xv0/^tmxܱu*0f]d67h6dM[(5BQFfs,o pn׾~mj_lZ^(LV4Sad!pAL1HlW5eR)Uow}]8fn+Kۍ|0W{Hzax\qyvƱrA/gAW H99B*ɧ'GOe 0h͋COqJO#}{=sCtx<3v!_͓nm5ڹ{>_'~\U$0I#W@7L%BnúԺsϜa]25Gpc'v:Ǔ] H#-KvCؐӼ"UUiqX.6DJr@>t4L}W޻_wXqQӧW$JnU4 Ϗ{\#on7S[ʟssSwA}n|Cz;s'Omqip_81 :ȉ0qYDȯk.K)J]M&쳴ϸ`~xLϫyw]8@{ի=:=+E={tw$!c>@[}Yf*n3}ή#$u/^zqbL;I}~*\U!/]A7fVJɢO^+&[v[*N3k3?@QHa;T=AĘkIb2Y\yMsG"YyهڥޑkN i@]\oo vRg˻U*':)߀_jֶH~{f $ \ﲋ*yGfol'Jq#HZ$ }q&µ8 L;5Hj,Gp_U<_e7類Q9~oχ EߧvS*xΘp-0?\OFu aTӳ ldXU A(];euogTJv(L5Gy0uuXRZ )|Wʧ;R$ELW9_) m ?I 7'4Rt1)6~1&!70pR!Z"Mr5goHDKY#kb#&PS1rG/Zߨ[4b?dDU1q1sC"˄njﻍ #hӇ=Bga$14 ojҬe0%-x~_0#UN{pvcQOliܨR%_IVS2D5\W-lԹQ Ԟ{)6:lD0\']lUft0xLvY-pw\7Q .5)5s em ." v:}eЍo*t ڈ65"1%G)u 7.q 1ΓRNWX2>u=~ DO@07ʙ"&g^j OIjEgM%)އS9Us>Ik[RR[Jx%h8UJ<N䊮I b28w@ZCY j W9GU%?t?~??sϱnsvtG~,}y?wlw۷?>G u1,X䐢LWGg/^g`ko8n8ҦOc|ǧ?{|rlf :yyP [>wC;kw`-m0C P'۪+9*m2@eQxzFF nڪ5o΃ݏ3%$uvU ڧj ;BO^S{~<`X+I|~ P_bOH5j_CX+r{>?(1k6s-b'W$ qLWSQk{|6XX'/,yЏPgig_1xuO2jc hx}9Eᛙd`onϬJ&xB.T!]Iu*[)~"XmQRpX-񟿸`-#_.,俒(% w"荻-Q/oSG!{9mߥl [yϷ{ 8z(d ӽb|/O\z!sA8c^|&qiX~82G8c{'D%6G4CpSvP *kܟi {p9WK?"<ׂBOl]ρ+?)xFy4ž?_\?lJ@(]ݷgO޹hĀߗ߾;CmP ĵo:gϗ^|3L.fxC>;:\}pQk0yy8ߞ^>:=}ŷ_cށY=0%[G C5 *6D+N:m,麼 eoțIVWfHn '#w$OoGCla6l\͕lcN 6l7rM#Ǒ@Fing5 oj8 ,D6Ps7h~?PhY\ɐIG^>>y1O=u{7ݡCH b8LɗX|B QpJ %: qE^~Aq㭶*?TU˩ڨޫu;?&X2#gуЃ|u%)8%kan "?|e]z(.Zŭ7õ16g/wh8WAV0Fᅞ%oF9R\&)"Sd3\0ap9:ed"]I=ҮKN]y2Z!]ɓuEԔG l46]\'~K[}qQ>}O䘠m_" AթA%#~"GmAeIN(Y,d%rR4_<HW9b/1鏂鳈G Ucg]}ׯ%[le&JS;P.b$3 N,Eh; < Fxk1"U NժbLƻZ{*K.>@32l] AL<e0E`f“KAE +7אrjp Rm`Gr$jB蹘U 0SgC9Rj qHJYneՋ_?OXӰlQ"av`7!aFS%Br)b>ћL_1]f\oQ ޖP"$$Ad{y~C8u^}X@K )qɀjn O!HCڠOK|„nv)QR2SCOx[7leZ\mQrLمI@J 9W1U.j{z5HwTOq@ zApE8G%'߉PY)\ ,B0'`TguLH@כuDfMpEȼDAsYؼ=`x4 IP!)b=+;noQe8CR=eATAIWfQe$8yޅN$byzqv?mPuaoAf*:IFjgNsU#A҅_l~׳iy7\oTiYzB'}194Rq)vwRasrhYh2Ƌ1&mSӯL\ 9Lc~b_d6xPiVC-ɢmuFSi8еA E Bl0S;טGgSuN [Q^kR3V}?f WbK~My1mGC7AIh2k&Ըk;%#G@4TӷKvMEuU|(" wzZ"*&P;2HsT氯=BA(/VmKsQacb𕏟rًO'G/WrBM2U: KPh@5RoΥk#;|4'z6rW@.&_ ܢtF+舛8t?_eso2qJ];:Mᅷ-H L[opv|1@8>W2-M(oߍ:&Aԁ80;wrSz.ldTjytB9̳Q³2y|OxgQv 0%-UZj ;U |aAfT֕,O A5":-CfJqDιRX;H"c9s࿷oߊ͠;C.\?s]R8V"rn$ujۚҩ+GcYAYZH5U/r\u0N[1pQ薈\hg! ̆vzV >?gwc58K""WLK)67>ƣL7U=#򋎜^=o\{]\v{, /[[%AXF-]8tHm³[+<sDq˰tVæ]P4[$ɮi I4[ʷj=7ĊI;[ܥ[Te"y6Xo}JrZ])=Ƽ>Ŕ}X[YԞ2DWnKهY`@s%8mEzB&bEb29Pepۤ<1d*dԄ$ܓRE'Hl"U,ʛJퟛ ?~~J^:b| R _P5|oߢ:{z+纏ˤԸo,áVGx*e}HRM,i % 7btmb"vE>MS;K .q5/SkkY)DQJw 5.8_ҭ/0Q3(7䨍9H :؁+ԑװ4.M򔸏Iғ!!pK'wO^HOPXXh/P[Bt=3厳zpbp`Qj ->-;V̧)YNsY@U @ >@\o>:^@ŕ'8͕^DŽ\jmjaej+q]\X"ztdNC}˵Pahn]GpV^(=d#ek1{ ze›i"zǵΤ gwX)/oRmlJ`|׸C ֿIqQgV ]<9.W봜iڌq&ֻNyIW14Nfufa$|9Yn[K<9{ }nNgvs ~_aSS{Y'kNP A{#w󓂮|Y[QsmXJp(!d,yй7!Ĥ;Ffi7s27 N c%`5o|L߫ >|:ZQ~A3+s?B92@m?~{nZ{o{c|fSuIGh㟋*"N% z(>CfF.mG7g0OHn^>? y۾3ki,$Zs_&m?~?Wygo68^ +.[Zn?zGΨo-1>)N<[5 -%?J Y//=y;i{&eeJU~]A[}I@f=5>VrZ%ܕda:]J F?&nxP?7A8x4~]^*;Zk _Oޯ[_7#p~(߳eþ:ax↥8fFs[c|r"k?jwOn?g?,ٺ( 2J֨ x !O W"V )U'xPv?7/wuu\'~=~Kx˙سx*˄4A#o\/>|y2(uHOFub'<GOe ^szCw|#.&¼FwKw8Trw)iItx? Ibf%VH5?"$ ,zHK/0\Ce =xq*_z)A'E);}_u/u^1|7FTF诎Q0+'?pb6!$JE|'שV1(d%&QP 2{_sC]%&G,^X.?D<NX䜷enVB7i'/; e6Qg&x \ yI'de㯾z9J]ڳWuNh -#'>S3VL ]V"r#{9p2D6'2X!S>OsS<1<=.j)Y7dh ̔Sof5 8E'ckhuC\q@ECe9 EJ p%ZN)-,;jbLYNF_z)w;JFkkt:}Tmk׿1E.׿1©*|1WCQs)``][prLdGfɀ,F ]?g}h`8Avdj11Hj(.eq0]e07@4d-mJvfٍRҝ]5/^/ZZJiZF +Qt>|\M4pBm)X.E,@6[G,;X,?{`nskk{mU.T}w/xrǯ*\t1?c) ;o^*6oQo%My{ڹ`F ưp^!./( ]xQh;Zn8a|U~ #6OU| RZݥSӬЍ1y/lj?FT? RU0\GL!L Eޅ)K V UD( 0oO>eXh;55'3whcL0cNT{&FE#% Ҿ`zե0U1csJJhTΈ 7llCOGI570SS=+zV}tuoJw@ }:M߃>hx{pww{)hmr 0c0q 5{ƜkSnZK6LJ{˱`=Caa2L&@u~*8(k)`8D 9.nIvzkG5Ѽת5jFj?w[ȷKUQGq]4|`*Z.ߊ͗[Tc>V FVA?J"&LX,벐)B4gK%{mS;kIcJG3(`t[k33`1^eY[oەjSGNo`*y{{"%tȆsr> ̚8yYD!„ )ദZr3Hcd #I0( ܍/ 9&(jCf5"-=s4mJPtn;8&a- 41LSHEr z вDg!:N dĸ|N@ҵCqєag{4}׎ksY yr].J-YIأACu̝7ȕw'aʳe.{oA(I"ZJc"iK]*b2H%46A|,k0H.&VRz6Sp1'7hojTw%䥨u:'#=qjL+DZf6=nK&(צJ4éMqQv.emBYeiIZ?{; ,udv+21;&Aڦٺ5rje=c1k-=wkw'(xh*_렴$chE}wxm"iI?CR\nvwQbڛM/x"U 1&{!:ۚ?HgTYXV!H7&lD.G+Ԇ$Y87Q UnOϓgE1hܣh1c2%pÙMM' tJcUKZ^I.~C[ .J|+t9ʜBgO1:$0'JԨؙRC51IU[2 }`7ʙb<qe˄p zHZa&KҭF}4] 3 f hT7#A Wɗ-ԚY`tJZk†@-EΣ:b¿PLhI7 ϢvLVȉJ^ϏϞ=:F>*H$PO]äcR]zZL1_xUbF)x4&%_?6T_6X%CEe2zÓ$E'ɯ-`T-Z6:uxuV[pި5 F]fʓ܁ =$Ocx%M6[n+{S{ OS Nn}Qk):nB6Ĵ*URZYd7l*"dwưs-HՆ}[X״Hm]牡˭ez/PKXq0_ yW@+=8^L ߕ`M%j(Jh/[R}g0? Q^MZizD궆RЂ87|Y)$"2CC'B\JvӢ8j_d(VBSTv?x 6)K AOpホsQyJʾh<3.q͎0}^W=o)fVsgt߼Jp8ﵴu@XLqy8SnvoK;Rs{ăp vt2p9Z^L@j: avkU'cn5o5JCia`?LJk|Nid9xQF|v.:Fkw$Rpֻ:c5o:)W-@iqUfK#"FlT#acc8hȊKE̼CN~?V.N^pggO^ kg!p;rL T,/7`;|WGIJϼ@h=`Pd8Dc-U$V@oHA9i)hΏ6_CdN+^g*灉\.싗^/{>-o\SZаO3Am{T.{ECGxdC;EY>I Sz5(A9PI1kEYP0 Pub3;ƒJNT/Aɍjx*d5lw <:hVئoPV|݁r{4¿+.+Vsggª(sdqIE-cQ_@/a^Iq W@JR[uxA"ʨJ J]7բ$ᬇH$.^J*żo `@`4l /% Wp-bzu8z vu:]Jt jӍLN;m8.No[Rr3&`1?}QJ72Հ(TCKB6I3;LFqԴj׆XF -V +#nupРV~W8WNe@ڟ%W?Uok6wrvokQrN#NG~"k\,w_ O.EWܖY !Wz=&m+aEl _Ÿ^ϲ"N_t'YO%֝;.C?y ;~5gAc"RvS9\Si8ʹt^(Y1M9=ffӲaq?+=LiY{?Jujꏞ??;y 2]oY~VϚ*O^aS -?O%/~ՙT_5R==;'/i\?%W/;Nz_[;x搜=:gQtTRRrD޴?*'/_< 1%G@k=gfaf۳Gg"aqaUQy*^,Z ^"xӪK,Nɫp3}}1A( ;e9|:p)w4eg3 -tgUQlh0`.mBo6[/^ݖpD jǺ7apmP(kZAj]c` `K۴K2La- ^" ˳W %r 9xS!C޺Z*Lu]:J`Ǵss*zQR#+:rZ^LLc*i\hU%\ET̾)@7ӬCՀWҍInz?|_y#cZF􊮅ħ{ߋ~{ejwd0j@<-kR)7V/UU),UTTg5 X^v60{7ccnDI2{Zʈi:HuZ6BWgmXbtz/bIłzC$nzq_S`'.*+^ e< Ds:E&C8`Y7q {8aP̏] *ݳUPW LTVj+闲Iz׷(Y?q ݻӽ 2 }zak1MvΡۡbbzT2 W-aQhڔU6a 4<]Y9'6{iƉ{*oä8GD[{vk8褥B?z)A!B]=D7|E 9ڕ e %$/ 9FWS6*]0Î&3yA\DRM}DKUlM >xfN@х a(ٗoK䏸ʹ!gMKe~xO̸io'Ɲ3| &JYDMRoDGK?iA&[yq6Y#*@H=bc:5xNdF`5{Bfc]X,#Q :8vuǛ6 F0|c8} qp4_q=:qSm?z=y~|O+-@fρoVjm1STvf~aԍ`׎G1B90B0^݂Щ,xVr/\=N 0i/4aEin+R}֝+K*ZAPc"Y.ͿWN<ǧaݿ xD8yO_<)֯&0L; $o$=~ ['l:-gr~4whimAhBHMl=( (x# ⊢^"*K9/y͛7yLVǢWc~"z-uM&JŰPڊJ􃯜Nj&hj.vUe>vE͈,8;ZS ȢldOj*GhڴMTEP[-0IQk~Į!LIjۦd´D9G&-AsZNh5QYp[$MÅ ?ܷR8g}D%juMOLPh (BX hs - JmZlE4B%@Kǝ ;ԇN7v$wN@D.⧘"Z>HY.ZTJShK[pIHzR"i6$;aM{K3T$T<~,6"[7jK,Y$mJ^ncZF"f"fQHڜ\]eyyW鐦C FnK,%23Akey$U֣gnƖ.*EBh-#3 *$ @++/,D=BF!zD&3eU *O3=BquqyYn Tg\8M4&SWVYhNU/ '-fanfq2yu.t rwE]ܼ.w ]-e}L#%nLsaUcQFΜKQ0}Q# G1BpyԌ&]`d[d@U2jb6d*dY4Jf֙tHa8qåd7j:2l54t *vɀ*d+éыz嗮ѨX?SX@+Fs dLeR +K3Т'YdI.Iw"IEeLUu "l0fLF7z@Vc@U:lhK1ISd6XAhG.k)xӅd{0DYrp)|-9qE2) *2|@X:he00x89 4C &[Kx+zhkK[,e3{ԀOSxkmg.""hs\ZgNOU]T8zRneS\TTO,/gԹU]WT"uF+/B#xB)_\W[\Z䖔p_ `\ne>S]BL/.XJqiEI1X_^ C𚤜)XPVDtRVflSR;)C<4Q%*ъ%S'`{T[]U^D* & 1=e))PU2ɭdʨUɠ(/e[]KSV0x\AY^cjP*VWA[_I"*ed΀F%e(DPJ; , ¤6%73Fq ސ7cZbSΝ" GVYA8^D ǴMNk'dAIP܉ׇt|FhLڦhcM)0՜OOj|qOHCz<9@6/6 G#!W_ 6Z$C@P`s|"ɡ婳$Q@'g-K]6}f$G$GCHb!z;]Pbm.TP1Z1> 0$JР7Yp>2*)QI}̋FtOl 9ς|Y,`&Rj-&RTv@#+g+DɗH-$p5Lr)CM6ȣSA1U1ϚAOz,s2KG\;G~4z&D]UFZɩf .HȾs$(]i&txɐ ;/j6q8KpFce6-J4xO Cdak@y6p~M/+g"_^a)heߵoĥZ;b Hf F+ O.:r22~ }nLIx~)A'<:J`% /6oN<8!"en%!f 'nm6XZj6 QQrޣ1S<8@at::QrqJ"Ļ.xcuL)x Fߒs)?TZj~Cx \t^AnhX YhGQ YNWJ3H},t0ul8 @oqpk0fMBWsiFߊD̀W7rb*cw &3Ze"nhH o F2 ix&7#Npe\73U"xx9{kNW6xBZhĿgnm@vR >+P&q !>u799ĩ- On#I/,e=-&mu^#~RDhp/i^u.pM(?Yو!D4|tt1K1iljd4FIO7rӍ2e 7C9^thV䱳Y,_KkrC5كBe;vOSj#UJBbR@ AC!9Na.̉>VO[nkCm:.nHQI:4^?;uYsi1`L9 NtT n9 #/yzW\ɇ`EvB] Rq>h >%&;ȩ+v+spB,EE<ѣG )ctsNҔشSRr<`o Yv`V&S3H|hyΎU0OU*% 6,"F)n+@tKido i83@j$)0o6=O0ΊM'~pHcnIOARNOO)v'F<؝̈́R )sfIq^AYU>MB`[0ye˃FFU"oe<t!$k0,ld=˃748!d _/b]A\dƸ92r16+dx3]x"SIJD: ~x z-q] _E)c0qzq4l a{YV]Φ lg u3j D' cHL˄<*5K6|.)˚& o6^"ZxmVW yO4Z?Ce;U'=>qqIJZl]Q;FFj5uZMk\KB-eU3ZY' ?B)%d#{j֊dQUd(y6$ovM6+M in*'Jכ:zS']o]Dzכdz0.IF~2猜J.?TyƫWOpv&t -bl:s&Y?˫ܩ1IPsp` 8`LºmpKF{U0;"d.| 3"غT 'J 8x$yo nUHYi HDo\“!*DELg >^ *]U]ZQX\R51an2~f0g3Td#UT]הIq#O4n0DE`PS"Ϙ6- Dw%D)D}IU1CHiB#T>2Z4wT tX{糬UU:]52 Xk֫kU*X]/npdđP0_1 wRI!^Ap,DZ f]d2Դ?ak  c AX'm˵.o w 1ѲG\&!?44kHk'0B"S;[]u2M $C8TJS̛$h5!o^dwVe! _CN M]xE^-4]u$)g'GML4D@"W*bp(N04=[q ܎j)23TO`l\ "A J 2cKt5_*oD^L"@JIjdk󦸨N/ƾK*4C9БȧIiOIt:&/9@ELW |rmȿoHb`]m@P _O4ZjAZ,; |7 O9iHkf]ɜJтTƦiT*ވ5}=KmTlPӀ`heD_BnhP` xF8#Mgȣ),W\T؝DFnmSn^cv" 52]r'Sj%| F H3(2MNw0Cٓ14Jɘf~{a)fgÄ I*) F/9-E2ۭ%0=xk!9 ؿ-^UDȫ ކ}qY%Ք*t2irTJڊ* yXDt)[$a?MWM^._CdN=1")xW5/Ru9똙- xL ]j d S(>KEAaAib2?ŭahGZAhU1>WcrxaIg+ 0\`f1VR< .$ݨ>ҁ$A&74_f [v kѯx (o0w m1X'v@&n7+c[2z?,+rDV_ E2>y^Z B 6Y t$g4h="mm`#IC`A'W$8m0BPuWU1v+=6W%#FKZ:QvlbBܜ~k09{P̟RS&WḵN8V~n%eKO?F&6'ލL 1aSD1&UJ7# `f0 Mެ606G>46uN3<  mHY+Q(vqg*q{XEov. |%]@9ӡ`K `DqTJu-5=υ6DBjåMk Ͽv&!'|K;R Vюù`ԴA(*$\DFAI+`u=NiL\M';eiɄٌN2D9 `>f 49kA HvMB͡+8R%#GV*F γrxmBWJYoI8y_ZPd尸Jӈ,d-i` ; H]p-TA&]{ө} '4L;UE @6)8*jyI@3q@,#8 ԏHAlUHZ(;'0t1Cݿ q?:эJb #?zw8GzJjD9xT #OqQ~%~%:{CniB'@Ϫȵ{X"6s ;F軾8?uiŮ_ w4nI7Un]Pۓӿߋ} Tݒo75lv炉1}zɼb.t?0k}#_rZiBe۪Շ~}Ȏw]Ww~Z7XE]Ŷn9}KSӱzem~aͪU漑QZVvˁ/O8&1c\m{pM)̽_E/ wW̫G}%^'?1[<#1#>~׌]W\xe~ꚚׯϿue-|{gyh1?Yue팗uѢk{d>R|#v֯;妤#uiMϹ@ˋn9i~' [\_x__U^th?-y>aM!S򜴃Wf>/zϥLz|Vkfػ߸cGܸu{9/ucWEcww]hSS'l2ax eԨ"CG {>.¿Oۏ>;ԫo3>)kٟ.bLZ;}y#:b/5 N78~^1ź/t4*f{4fߕ?߶ڿ|7}W_}zq}Ҫm\̋9lig u=򵗞,YѶ)U?tƗ؅nxuGꓶ>zn#隞0\Q=ạw_6_\4hS{'M{+ _0u/̼|]6fޛsV\/.5%z܇E6SyJjQXb;rw(Ҩd LyF-vkڳ=mᛊ{7>7MѦ$pq=W?zwhyFsUխ<x5VqSYTUQ=׊:~.ߪӮO7ZѩO'= o8[Gfb+^]ڹ7؋rTk1o-J_߱4Srl_+,o5s{eQC'v?Lr΃w*r^ٿ#}&=Nݴc.6mڂwV/by]-d~şg1Y;WZ xضl{=9~m+MH}BW)-9wl7/LJJlI+<70vb<ǒ>7<Rn8X >?ᷱ;`g`n{˵y74w {β&옳lPG<|ٗmD/u_0vr?;_ڡp+]r%iG`͛?ּo)9K._cs_ئp0smX;sɡ;~yr[|mόO8~V& صq]܃Ͻz{ѳ*㙟fkmx psu=_s") o5[޿&fusPkynC^ؽ>8{1_.*d:xaѷ341q`7^qݟ=ԛN]>cw .3z_`eWffXشG/Q\r_&hY=\oG}oaLgqucaՒ fd Wۡ2vO{x2kݳ$e,?j7?7}Wخtod+im[5#6eU߮|"6{{3- !/1y>58c~lY?9|ῦl]=H_{37yi?rK{=ar^aWo6З[߬xejw3p{&{MǍ_nZSV}+W>so_RS5mO2{rO^tP1NJO˜͇;/˖ۿ:P?y$ob͹ Guo+o;ҕqG=Wq  ;}}ybi>~]9)A /}0{|x{6%{/7^ϔnm+ϋσZop ♅_\{MZ^pg*ow>˭WyrWQךk/㶛.7߻ ]uYَEE]t÷{W_4{ɘewxsv޴nى=M} =`CsdL}gH֪MW$sv3<[}hΧZɐ>hܾԸ"\צO]s]N*pIc0wbUExݏ;pf_S2#wiOՔq+z+w>*̙}۱Os7pW{߲齅L}ih6̭]zᶩ=ww.Mq[kQK_zm-\4Šچ]({O$Wq #M@jaϽv!fWBB73ow;0ofbPqB(( (0!T82m !U #AI!PYiw? u_^e3}q{\7_zz>ܷ,gWao!^ҞE4?SP\C=wK[o]Mwi r닋|ǃ_̧[z9{.{dY¯ѦS[?,_ؿ0xzԖ<잁O *VѲ@'jЂ_hy>rG߽]J\߱{oLÒn~}ǛU/즧˧x-{m0m-|mx.xrmٯCs&vOzN?\tE$؂W\_79xai=p[zlK>+nzウ[xaj᭷ש{tܷ4uqyyZ ^E?})~ oĞ7MJ׿Bj78p.y^ ~s;oU'7=|3饩;G]]wOp3H[crnykyh3W{vf9{mz޹S=/`K,;{OF/p1ۿ?;!{}7t;D#kW\|Ѻ>]k6qW?~~{˧]zؾMO^?|??}goK=῿z[ᶷnxsSfiUV]S:vg^O:]>/ 7vëX;wݳ?kz??koomy[?<4:xMK(tǣݼe׭_|[rDo/xO]gѴ_?pi;N;~i>^?Wn3Џ?.#qxOg=?,sTxlĜΙD17 iKʱ%6wFln ͘bdI>qC''Kx@&Śu5eZJzL؄)m'f3ǐ8^(uLzY!tŲ 8ñH@̲gH;< ;^NYpi&;?8֘86>c[IJ`d”mj\ߘT]DsYVަf_ 617Wuۘ-kK`VC-bQ+$ bV51(do6K!Jq#LA'm@a~F9 .{ \m|H‡k_4svVA:/R*a$\=Tfh*Cq@!+ Qv_H)B &y q)jjIfe<*җkPU}Z=w?\t_& zíђ1]Jvo(::7Ƿa*f{S~ es[򧁮V6[XhL3]$1f`lǛ%])L3>W6kHAGٺȉs"@|h#ܔgܜ4$tʙwwU@)cb,bL\SG?U2ZT9o^/"Wcԇ 84lDOP0vѥǭ/TurKh*bg{Dim @rα~ƌ.uoEVFHvWML3F|Ox{^l(NZ #`X՗Hq5۞ʩu/RTi{28(]VC,afuY\!7 ˆVk.5 ®is)ĊiiXAQ:w Ec>!meE(e \ [.vBkBO[+%[k") dem9L$'O wY6 'W޲l* zJx}ҼKig;h au*@e7"2/p(;nK{]niw|EڌhotMZQ;q\clJHP t6) nN,O"%"N>HuA1tL PDѦp؆X. +YS`-s\|.`4& 94 zoVQ-\nLעﷻRnۉo6 =Xl rt`Vm!>tF2>,#[8~5X4NM 9FE2&Phzр+$i΍N՞ @; zsPon J qP(zI2F㑡Ō#ۅ=7E ^he,W$HagCuߋ' 鶞 Jr2E H6"t~f90Favaf *9J+x񪑱@^&3M:9 s_3aglߔfc H+]9sЁ@V͉*lӗ-N~7L] $r")X㨻S4)!=N dNB jdohs_d8XHē0Uu:8en,M%_BI3*:{ RV4Z2WwɱYZUH䅩tL]j=F P6ߧ*6^p`nYqwxc60XXHcuY6IKN,ŴsA!g'%ȝ:u%V4O۝9`%2RӜx fYj0lOήk27`Yud= n/6K:3=kzJbJv(tuKKr/XL7gAm>+ 9$V[8޺ @vtcY%rCV}rM(R &%/rq)u I7r+m ^hlvq%phc2̘T3pomL ǒ"y (t#Xkn>g /&fu6r@JOts??ͪ"nwEhY4_zbx# 2,hk+khptp,F %# ?g1k.ƥ0#$|hF:bϢD.) k*Twf%؄dg*˓UXVrJ*/~N rCGڕuFwq@)MH~N5B ;&Bqk 2Ƞ>BT|{ $0R%w'bs]9ǟBaWNnD C\NoZ%}tz+H՟4 UT% muDfUR,V`uhijT! DgVMX =yW#XղZ᠊1YJhnVѣ+'9,ҍ~{HCMLX.NpQ 01Jt3<)JnEr.2<\ VN#YȬGH }0`)`U`Mdgi{͞AB~# Q!vETӢ.h29F3;ՕnZ]c)T׫JU(6D pfQ%"yBLJ GX? 1 Af|5(OEHhP]h]fA1tԧA'12@20B(;UqIќnJF{SD teNSe Z.fH%QorL3͠ S6ԺǐiOm^؏{:@LhS“b#+tqCtqqH=+ La~~n:2dZAJVE0mO`fU?L7/C\H)0Qz|8Cظ : w O71yG&j;-MQ(IgdĻh![mGtȮ@y1P;-I-t;82C+*9aB=S&@ZETTf`;֪nfЧKaF>kқ%W$oP"Ҍ 3Ky:wj4ЈTM=VPF6g8gDZ('f 'l1Z/+zJzHHTqRZVP:#+ :ߺm:A;[&&WtxH'JݳK'SE^@w.#1njJ5,qJhŠQ| s%P#R0QG}]Fӆq֮݇LBЅwnfI+.5l#Sb4ݹ.xwU>#?0oFA`Q >!>ƒ Nl|%+b )1#mos/rMx뇯N