ukui-session-manager/0000775000175000017500000000000015252714370013554 5ustar fengfengukui-session-manager/NEWS0000664000175000017500000000024215252713362014251 0ustar fengfeng### ukui-session-manager 3.0.0 New design. ### ukui-session-manager 2.0.0 Migrate from gtk to Qt. ### ukui-session-manager 1.0.0 Fork from mate-session-manager ukui-session-manager/ukuismserver/0000775000175000017500000000000015252714370016320 5ustar fengfengukui-session-manager/ukuismserver/main.cpp0000664000175000017500000001461615252714370017760 0ustar fengfeng/* * Copyright (C) Copyright 2021 KylinSoft Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301, USA. **/ #include "ukuismserver.h" #include "ukuismserverdebug.h" #include #include #include #include #include #include #include #include extern UKUISMServer*& getGlobalServer(const QString &wm = ""); void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) { QString logPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/ukui-session/ukuismserver.log"; //判断log文件是否存在 if (!QFile::exists(logPath)) { QString logDir = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/ukui-session"; //不存在时,创建ukui-session文件夹 QDir dir(logDir); if (!dir.exists(logDir)) { if (!dir.mkdir(logDir)) { return; } } //创建log文件 QFile file(logPath); if (!file.open(QIODevice::WriteOnly)) { return; } file.close(); } if (!QFile::exists(logPath)) { return; } QByteArray localMsg = msg.toLocal8Bit(); QDateTime dateTime = QDateTime::currentDateTime(); QByteArray time = QString("[%1] ").arg(dateTime.toString("MM-dd hh:mm:ss.zzz")).toLocal8Bit(); QString logMsg; switch (type) { case QtDebugMsg: logMsg = QString("%1 Debug: %2 (%3:%4, %5)\n") .arg(time.constData()) .arg(localMsg.constData()) .arg(context.file) .arg(context.line) .arg(context.function); break; case QtInfoMsg: logMsg = QString("%1 Info: %2 (%3:%4, %5)\n") .arg(time.constData()) .arg(localMsg.constData()) .arg(context.file) .arg(context.line) .arg(context.function); break; case QtWarningMsg: logMsg = QString("%1 Warning: %2 (%3:%4, %5)\n") .arg(time.constData()) .arg(localMsg.constData()) .arg(context.file) .arg(context.line) .arg(context.function); break; case QtCriticalMsg: logMsg = QString("%1 Critical: %2 (%3:%4, %5)\n") .arg(time.constData()) .arg(localMsg.constData()) .arg(context.file) .arg(context.line) .arg(context.function); break; case QtFatalMsg: logMsg = QString("%1 Fatal: %2 (%3:%4, %5)\n") .arg(time.constData()) .arg(localMsg.constData()) .arg(context.file) .arg(context.line) .arg(context.function); break; } //clear file content when it is too large QFile file(logPath); qint64 fileSize = file.size(); if (fileSize >= 1024 * 1024 * 10) { file.open(QFile::WriteOnly | QFile::Truncate); file.flush(); file.close(); } QFile logFile(logPath); logFile.open(QIODevice::WriteOnly | QIODevice::Append); QTextStream ts(&logFile); ts << logMsg << Qt::endl; logFile.flush(); logFile.close(); } void IoErrorHandler(IceConn iceConn) { getGlobalServer()->ioError(iceConn); } void openDubug() { UKUISMSERVER().setFilterRules(QStringLiteral("org.ukui.ukuismserver=true")); qInstallMessageHandler(myMessageOutput); qCDebug(UKUISMSERVER) << "=================================================== UKUISMServer start. ==================================================="; } int main(int argc, char **argv) { openDubug(); QApplication a(argc, argv); a.setQuitOnLastWindowClosed(false); QCommandLineParser parser;//用于解析命令行参数,当程序以命令行形式执行时,可以解析命令行参数 parser.setApplicationDescription("ukuismserver"); parser.addHelpOption(); parser.addVersionOption(); QCommandLineOption restoreOption(QStringList() << QStringLiteral("r") << QStringLiteral("restore"), "Restores the saved user session if available"); parser.addOption(restoreOption); QCommandLineOption wmOption(QStringList() << QStringLiteral("w") << QStringLiteral("windowmanager"), "Starts in case no other window manager is \nparticipating in the session. Default is 'kwin'", "wm"); parser.addOption(wmOption); QCommandLineOption nolocalOption(QStringLiteral("nolocal"), "Also allow remote connections"); parser.addOption(nolocalOption); parser.process(a);//从a获取命令行参数, 也就是argc和argv // Load ts files const QString locale = QLocale::system().name(); QTranslator translator; qDebug() << "local: " << locale; qDebug() << "path: " << QStringLiteral(UKUI_TRANSLATIONS_DIR) + QStringLiteral("/ukui-session-manager"); if (translator.load(locale, QStringLiteral(UKUI_TRANSLATIONS_DIR) + QStringLiteral("/ukui-session-manager"))) { a.installTranslator(&translator); } else { qDebug() << "Load translations file failed!"; } QString wm = parser.value(wmOption);//应该是为了获取传入的窗管的值 为空 IceSetIOErrorHandler(IoErrorHandler); getGlobalServer(wm)->restoreWM(QStringLiteral("saved at previous logout")); qCDebug(UKUISMSERVER) << "ukuismserver register service"; QDBusConnection::sessionBus().registerService(QStringLiteral("org.ukui.ukuismserver")); return a.exec(); } ukui-session-manager/ukuismserver/ukuismclient.h0000664000175000017500000000416315252713362021211 0ustar fengfeng/***************************************************************** ksmserver - the KDE session management server Copyright 2000 Matthias Ettrich Copyright 2021 KylinSoft Co., Ltd. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #ifndef UKUISMCLIENT_H #define UKUISMCLIENT_H extern "C" { #include } #include #include #include class UKUISMClient { public: explicit UKUISMClient(SmsConn conn); ~UKUISMClient(); void resetState(); void registerClient(const char *previousId = nullptr); SmsConn connection() const { return m_smsConn; } QString program() const; QStringList restartCommand() const; QStringList discardCommand() const; int restartStyleHint() const; SmProp* property( const char* name ) const; const char* clientId() const { return m_id ? m_id : ""; } QString userId() const; public: QList m_properties; bool m_saveYourselfDone; bool m_pendingInteraction; bool m_waitForPhase2; bool m_wasPhase2; private: const char *m_id; SmsConn m_smsConn; }; #endif // UKUISMCLIENT_H ukui-session-manager/ukuismserver/ukuismserverdbusadaptor.cpp0000664000175000017500000000242515252714370024024 0ustar fengfeng/* * Copyright (C) Copyright 2021 KylinSoft Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301, USA. **/ #include "ukuismserverdbusadaptor.h" #include "ukuismserver.h" #include "ukuismserverdebug.h" #include ukuismserverdbusadaptor::ukuismserverdbusadaptor(UKUISMServer *server) : QDBusAbstractAdaptor(server) { } ukuismserverdbusadaptor::~ukuismserverdbusadaptor() { } bool ukuismserverdbusadaptor::closeSession() { return parent()->closeSession(); } bool ukuismserverdbusadaptor::isCloseSession() { return parent()->isCloseSession(); } void ukuismserverdbusadaptor::restoreSession() { return parent()->restoreSession(); } ukui-session-manager/ukuismserver/ukuismserverdebug.cpp0000664000175000017500000000172415252714370022603 0ustar fengfeng/* BEGIN_COMMON_COPYRIGHT_HEADER * (c)LGPL2+ * Copyright (C) Copyright 2021 KylinSoft Co., Ltd. * * This program or library is free software; you can redistribute it * and/or modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA * * END_COMMON_COPYRIGHT_HEADER */ #include "ukuismserverdebug.h" Q_LOGGING_CATEGORY(UKUISMSERVER, "org.ukui.ukuismserver") ukui-session-manager/ukuismserver/ukuismclient.cpp0000664000175000017500000001257215252714370021547 0ustar fengfeng/***************************************************************** ksmserver - the KDE session management server Copyright 2000 Matthias Ettrich Copyright 2005 Lubos Lunak Copyright (C) Copyright 2021 KylinSoft Co., Ltd. relatively small extensions by Oswald Buddenhagen some code taken from the dcopserver (part of the KDE libraries), which is Copyright 1999 Matthias Ettrich Copyright 1999 Preston Brown Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #include "ukuismclient.h" #include "ukuismserver.h" #include #include extern UKUISMServer*& getGlobalServer(const QString &wm = ""); /*用于生成客户端的唯一ID*/ Q_GLOBAL_STATIC(QString, my_addr) char * safeSmsGenerateClientID(SmsConn c) { char *ret = nullptr; if (!ret) { if (my_addr->isEmpty()) { char hostname[256]; if (gethostname(hostname, 255) != 0) { my_addr->asprintf("0%.8x", rand()); } else { std::string hostname_str(hostname); int addr[4] = {0, 0, 0, 0}; int pos = 0; for (unsigned int i = 0; i < hostname_str.length(); ++i, ++pos) { addr[pos % 4] += hostname[i]; } *my_addr = QStringLiteral("0"); for (int i = 0; i < 4; ++i) { *my_addr += QString::number(addr[i], 16); } } } size_t bufferSize = 1 + my_addr->length() + 13 + 10 + 4 + 1 + 0; ret = (char*)malloc(bufferSize); static int sequence = 0; if (ret == nullptr) { return nullptr; } snprintf(ret, bufferSize, "1%s%.13ld%.10d%.4d", my_addr->toLatin1().constData(), (long)time(nullptr), getpid(), sequence); //sprintf(ret, "1%s%.13ld%.10d%.4d", my_addr->toLatin1().constData(), (long)time(nullptr), getpid(), sequence); sequence = (sequence + 1) % 10000; } return ret; } UKUISMClient::UKUISMClient(SmsConn conn) : m_smsConn(conn), m_id(nullptr) { resetState(); } UKUISMClient::~UKUISMClient() { } void UKUISMClient::resetState() { m_saveYourselfDone = false; m_pendingInteraction = false; m_waitForPhase2 = false; m_wasPhase2 = false; } void UKUISMClient::registerClient(const char *previousId) { m_id = previousId; if (!m_id) { m_id = safeSmsGenerateClientID(m_smsConn); } SmsRegisterClientReply(m_smsConn, (char*)m_id); //此处向应用发出保存自身信号,应用收到信号后,调用SmcSetProperties将应用的名称等信息注册到server SmsSaveYourself(m_smsConn, SmSaveLocal, false, SmInteractStyleNone, false); SmsSaveComplete(m_smsConn); getGlobalServer()->clientRegistered(previousId); } QString UKUISMClient::program() const { SmProp *p = property(SmProgram); if (!p || qstrcmp(p->type, SmARRAY8) || p->num_vals < 1) { return QString(); } return QLatin1String((const char*)p->vals[0].value); } QStringList UKUISMClient::restartCommand() const { QStringList result; SmProp *p = property(SmRestartCommand); if (!p || qstrcmp(p->type, SmLISTofARRAY8) || p->num_vals < 1) { return result; } for (int i = 0; i < p->num_vals; i++) { result += QLatin1String((const char*)p->vals[i].value); } return result; } QStringList UKUISMClient::discardCommand() const { QStringList result; SmProp *p = property(SmDiscardCommand); if (!p || qstrcmp(p->type, SmLISTofARRAY8) || p->num_vals < 1) { return result; } for (int i = 0; i < p->num_vals; i++) { result += QLatin1String((const char*)p->vals[i].value); } return result; } int UKUISMClient::restartStyleHint() const { SmProp *p = property(SmRestartStyleHint); if (!p || qstrcmp(p->type, SmCARD8) || p->num_vals < 1) { return SmRestartIfRunning; } return *((unsigned char*)p->vals[0].value); } SmProp *UKUISMClient::property(const char *name) const { foreach (SmProp *prop, m_properties) { if (!qstrcmp(prop->name, name)) { return prop; } } return nullptr; } QString UKUISMClient::userId() const { SmProp *p = property(SmUserID); if (!p || qstrcmp(p->type, SmARRAY8) || p->num_vals < 1) { return QString(); } return QLatin1String((const char*)p->vals[0].value); } ukui-session-manager/ukuismserver/CMakeLists.txt0000664000175000017500000000135415252714370021063 0ustar fengfengset(UKUISMSERVER_SRCS main.cpp ukuismclient.cpp ukuismclient.h ukuismserver.cpp ukuismserver.h ukuismserverdebug.cpp ukuismserverdebug.h ukuismconnection.h ukuismserverdbusadaptor.cpp ukuismserverdbusadaptor.h ../ukui-session/xdgdesktopfile.h ../ukui-session/xdgdesktopfile.cpp ../ukui-session/xdgdirs.h ../ukui-session/xdgdirs.cpp ) qt6_add_dbus_interface(UKUISMSERVER_SRCS org.ukui.KWin.Session.xml ukuikwinsession_interface) add_executable(ukuismserver ${UKUISMSERVER_SRCS}) target_link_libraries(ukuismserver PRIVATE Qt6::Widgets Qt6::DBus KF6::WindowSystem KF6::ConfigCore KF6::ConfigGui KF6::CoreAddons -lSM -lICE) install(TARGETS ukuismserver DESTINATION bin) ukui-session-manager/ukuismserver/ukuismserver.cpp0000664000175000017500000016671015252714370021603 0ustar fengfeng/***************************************************************** ksmserver - the KDE session management server Copyright 2000 Matthias Ettrich Copyright 2005 Lubos Lunak Copyright (C) Copyright 2021 KylinSoft Co., Ltd. relatively small extensions by Oswald Buddenhagen some code taken from the dcopserver (part of the KDE libraries), which is Copyright 1999 Matthias Ettrich Copyright 1999 Preston Brown Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #include "ukuismserver.h" #include "ukuismclient.h" #include "ukuismconnection.h" #include "ukuismserverdebug.h" #include "ukuismserverdbusadaptor.h" #include "ukuikwinsession_interface.h" #include "../ukui-session/xdgdesktopfile.h" #include extern "C" { #include #include #include #include } #include #include #include #include #include #include #include #include #include #include #include #include #include #define VendorString "ukuismserver" #define ReleaseString "1.0" #define SESSION_PREVIOUS_LOGOUT "saved at previous logout" enum KWinSessionState { Normal = 0, Saving = 1, Quitting = 2 }; IceAuthDataEntry *authDataEntries = nullptr; static QTemporaryFile *remTempFile = nullptr; static IceListenObj *listenObjs = nullptr; int numTransports = 0; static bool onlyLocal = false; extern "C" int _IceTransNoListen(const char *protocol); UKUISMServer*& getGlobalServer(const QString &wm = "") { static UKUISMServer *server = new UKUISMServer(wm); return server; } static Bool HostBasedAuthProc(char *hostname) { if (onlyLocal) { return true; } else { return false; } } Status RegisterClientProc(SmsConn smsConn, SmPointer managerData, char *previousId) { UKUISMClient *client = static_cast(managerData); client->registerClient(previousId); //注意,在被恢复应用注册的时候有可能发生registered这条日志出现在后的情况 qCDebug(UKUISMSERVER) << "client " << client->clientId() << " registered."; return 1; } void InteractRequestProc(SmsConn smsConn, SmPointer managerData, int dialogType) { getGlobalServer()->interactRequest(static_cast(managerData), dialogType ); } void InteractDoneProc(SmsConn smsConn, SmPointer managerData, Bool cancelShutdown) { getGlobalServer()->interactDone(static_cast(managerData), cancelShutdown); } void SaveYourselfRequestProc(SmsConn smsConn, SmPointer managerData, int saveType, Bool shutdown, int interactStyle, Bool fast, Bool global) { //如果shutdown为true,则执行关机流程 if (shutdown) { getGlobalServer()->shutdown(); } else if (!global) { //如果global为false,则只向发送请求的客户端发送save yourself SmsSaveYourself(smsConn, saveType, false, interactStyle, fast); SmsSaveComplete(smsConn); } } void SaveYourselfPhase2RequestProc(SmsConn smsConn, SmPointer managerData) { getGlobalServer()->phase2Request(static_cast(managerData)); } void SaveYourselfDoneProc(SmsConn smsConn, SmPointer managerData, Bool success) { getGlobalServer()->saveYourselfDone(static_cast(managerData), success); } void CloseConnectionProc(SmsConn smsConn, SmPointer managerData, int count, char **reasonMsgs) { qCDebug(UKUISMSERVER) << "one app close connection"; getGlobalServer()->deleteClient(static_cast(managerData)); if (count) { SmFreeReasons(count, reasonMsgs); } IceConn iceConn = SmsGetIceConnection(smsConn); SmsCleanUp(smsConn); IceSetShutdownNegotiation(iceConn, false); IceCloseConnection(iceConn); } void SetPropertiesProc(SmsConn smsConn, SmPointer managerData, int numProps, SmProp **props) { UKUISMClient *client = static_cast(managerData); for (int i = 0; i < numProps; i++) { SmProp *p = client->property(props[i]->name); if (p) { client->m_properties.removeAll( p ); SmFreeProperty(p); } client->m_properties.append(props[i]); if (!qstrcmp(props[i]->name, SmProgram)) { getGlobalServer()->clientSetProgram(client); qCDebug(UKUISMSERVER) << client->clientId() << " and " << client->program(); } } if (numProps) { free(props); } } void DeletePropertiesProc(SmsConn smsConn, SmPointer managerData, int numProps, char **propNames) { UKUISMClient *client = static_cast(managerData); for (int i = 0; i < numProps; i++) { SmProp *p = client->property(propNames[i]); if (p) { client->m_properties.removeAll(p); SmFreeProperty(p); } } } void GetPropertiesProc(SmsConn smsConn, SmPointer managerData) { UKUISMClient *client = static_cast(managerData); SmProp **props = new SmProp*[client->m_properties.count()]; int i = 0; foreach (SmProp *prop, client->m_properties) { props[i++] = prop; } SmsReturnProperties(smsConn, i, props); delete[] props; } static Status NewClientProc(SmsConn conn, SmPointer manager_data, unsigned long *mask_ret, SmsCallbacks *cb, char **failure_reason_ret) { //根据XSMP协议的要求,出错时,这个函数应该返回状态0,并且错误原因要包含在failure_reason_ret中 *failure_reason_ret = nullptr; void *client = (static_cast(manager_data))->newClient(conn); cb->register_client.callback = RegisterClientProc; cb->register_client.manager_data = client; cb->interact_request.callback = InteractRequestProc; cb->interact_request.manager_data = client; cb->interact_done.callback = InteractDoneProc; cb->interact_done.manager_data = client; cb->save_yourself_request.callback = SaveYourselfRequestProc; cb->save_yourself_request.manager_data = client; cb->save_yourself_phase2_request.callback = SaveYourselfPhase2RequestProc; cb->save_yourself_phase2_request.manager_data = client; cb->save_yourself_done.callback = SaveYourselfDoneProc; cb->save_yourself_done.manager_data = client; cb->close_connection.callback = CloseConnectionProc; cb->close_connection.manager_data = client; cb->set_properties.callback = SetPropertiesProc; cb->set_properties.manager_data = client; cb->delete_properties.callback = DeletePropertiesProc; cb->delete_properties.manager_data = client; cb->get_properties.callback = GetPropertiesProc; cb->get_properties.manager_data = client; *mask_ret = SmsRegisterClientProcMask | SmsInteractRequestProcMask | SmsInteractDoneProcMask | SmsSaveYourselfRequestProcMask | SmsSaveYourselfP2RequestProcMask | SmsSaveYourselfDoneProcMask | SmsCloseConnectionProcMask | SmsSetPropertiesProcMask | SmsDeletePropertiesProcMask | SmsGetPropertiesProcMask; return 1; } /*用于打印16进制数据*/ static void fprintfhex(FILE *fp, unsigned int len, char *cp) { static const char hexchars[] = "0123456789abcdef"; for (; len > 0; len--, cp++) { unsigned char s = *cp; putc(hexchars[s >> 4], fp); putc(hexchars[s & 0x0f], fp); } } static void write_iceauth(FILE *addfp, FILE *removefp, IceAuthDataEntry *entry) { fprintf(addfp, "add %s \"\" %s %s ", entry->protocol_name, entry->network_id, entry->auth_name); fprintfhex(addfp, entry->auth_data_length, entry->auth_data); fprintf(addfp, "\n"); fprintf(removefp, "remove protoname=%s protodata=\"\" netid=%s authname=%s\n", entry->protocol_name, entry->network_id, entry->auth_name); } #define COOKIE_LEN 16 Status SetAuthentication_local (int count, IceListenObj *listenObjs) { int i; for (i = 0; i < count; i ++) { char *prot = IceGetListenConnectionString(listenObjs[i]); if (!prot) continue; char *host = strchr(prot, '/'); char *sock = nullptr; if (host) { *host=0; host++; sock = strchr(host, ':'); if (sock) { *sock = 0; sock++; } } if (sock && !strcmp(prot, "local")) { chmod(sock, 0700); } IceSetHostBasedAuthProc(listenObjs[i], HostBasedAuthProc); free(prot); } return 1; } Status SetAuthentication (int count, IceListenObj *listenObjs, IceAuthDataEntry **authDataEntries) { QTemporaryFile addTempFile; remTempFile = new QTemporaryFile; if (!addTempFile.open() || !remTempFile->open()) return 0; if ((*authDataEntries = (IceAuthDataEntry *) malloc(count * 2 * sizeof(IceAuthDataEntry))) == nullptr) return 0; FILE *addAuthFile = fopen(QFile::encodeName(addTempFile.fileName()).constData(), "r+"); FILE *remAuthFile = fopen(QFile::encodeName(remTempFile->fileName()).constData(), "r+"); for (int i = 0; i < numTransports * 2; i += 2) { (*authDataEntries)[i].network_id = IceGetListenConnectionString(listenObjs[i/2]); (*authDataEntries)[i].protocol_name = (char*)"ICE"; (*authDataEntries)[i].auth_name = (char*)"MIT-MAGIC-COOKIE-1"; (*authDataEntries)[i].auth_data = IceGenerateMagicCookie(COOKIE_LEN); (*authDataEntries)[i].auth_data_length = COOKIE_LEN; (*authDataEntries)[i+1].network_id = IceGetListenConnectionString(listenObjs[i/2]); (*authDataEntries)[i+1].protocol_name = (char*)"XSMP"; (*authDataEntries)[i+1].auth_name = (char*)"MIT-MAGIC-COOKIE-1"; (*authDataEntries)[i+1].auth_data = IceGenerateMagicCookie(COOKIE_LEN); (*authDataEntries)[i+1].auth_data_length = COOKIE_LEN; write_iceauth(addAuthFile, remAuthFile, &(*authDataEntries)[i]); write_iceauth(addAuthFile, remAuthFile, &(*authDataEntries)[i+1]); IceSetPaAuthData(2, &(*authDataEntries)[i]); IceSetHostBasedAuthProc(listenObjs[i/2], HostBasedAuthProc); } fclose(addAuthFile); fclose(remAuthFile); QString iceAuth = QStandardPaths::findExecutable(QStringLiteral("iceauth")); if (iceAuth.isEmpty()) { qCDebug(UKUISMSERVER) << "UKUISMServer: could not find iceauth"; return 0; } KProcess p; p << iceAuth << QStringLiteral("source") << addTempFile.fileName(); p.execute(); return (1); } void FreeAuthenticationData(int count, IceAuthDataEntry *authDataEntries) { /* Each transport has entries for ICE and XSMP */ if (onlyLocal) { return; } for (int i = 0; i < count * 2; i++) { free(authDataEntries[i].network_id); free(authDataEntries[i].auth_data); } free (authDataEntries); QString iceAuth = QStandardPaths::findExecutable(QStringLiteral("iceauth")); if (iceAuth.isEmpty()) { qCDebug(UKUISMSERVER) << "UKUISMServer: could not find iceauth"; return; } if (remTempFile) { KProcess p; p << iceAuth << QStringLiteral("source") << remTempFile->fileName(); p.execute(); } delete remTempFile; remTempFile = nullptr; } void UKUISMWatchProc(IceConn iceConn, IcePointer client_data, Bool opening, IcePointer *watch_data) { UKUISMServer *ds = static_cast(client_data); if (opening) { *watch_data = (IcePointer)ds->watchConnection(iceConn); } else { ds->removeConnection((UKUISMConnection*)*watch_data); } } UKUISMServer::UKUISMServer(const QString &windowManager) : m_kwinInterface(new OrgUkuiKWinSessionInterface(QStringLiteral("org.ukui.KWin"), QStringLiteral("/Session"), QDBusConnection::sessionBus(), this)) , m_state(Idle), m_saveSession(false), m_wmPhase1WaitingCount(0), m_clientInteracting(nullptr), m_sessionGroup(QStringLiteral("")) , m_wm(windowManager.isEmpty() ? QStringLiteral("ukwm") : windowManager), m_wmCommands(QStringList({m_wm})) { new ukuismserverdbusadaptor(this); m_restartNum = 0; bool success = QDBusConnection::sessionBus().registerObject(QStringLiteral("/UKUISMServer"), this);//注册d-bus对象 qCDebug(UKUISMSERVER) << "registered object is " << success; // connect(this, &UKUISMServer::UKUISMServerStartFinished, adaptor, &ukuismserverdbusadaptor::UKUISMServerStartFinished); onlyLocal = true; if (onlyLocal) { _IceTransNoListen("tcp"); } char errormsg[256]; if (!SmsInitialize((char*)VendorString, (char*)ReleaseString, NewClientProc, (SmPointer) this, HostBasedAuthProc, 256, errormsg)) { qCDebug(UKUISMSERVER) << "UKUISMServer: could not register XSM protocol"; } if (!IceListenForConnections(&numTransports, &listenObjs, 256, errormsg)) { qCDebug(UKUISMSERVER) << "UKUISMServer: Error listening for connections: " << errormsg; qCDebug(UKUISMSERVER) << "UKUISMServer: Aborting."; exit(1); } { QByteArray fName = QFile::encodeName(QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation) + QDir::separator() + QStringLiteral("UKUISMServer")); QString display = QString::fromLocal8Bit(::getenv("DISPLAY")); display.remove(QRegularExpression(QStringLiteral("\\.[0-9]+$"))); int i = 0; while ((i = display.indexOf(QLatin1Char(':'))) >= 0) { display[i] = '_'; } while ((i = display.indexOf(QLatin1Char('/'))) >= 0) { display[i] = '_'; } fName += '_'+display.toLocal8Bit(); FILE *f; //w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件 f = ::fopen(fName.data(), "w+"); if (!f) { QString str = QString(QStringLiteral("UKUISMServer: cannot open %s: %s")).arg(fName.data()).arg(strerror(errno)); qCDebug(UKUISMSERVER) << str; qCDebug(UKUISMSERVER) << "UKUISMServer: Aborting."; exit(1); } char *session_manager = IceComposeNetworkIdList(numTransports, listenObjs); fprintf(f, "%s\n%i\n", session_manager, getpid()); fclose(f); setenv("SESSION_MANAGER", session_manager, true); //这里要将session_manager变量传递给其他需要的进程 //同步环境变量到D-Bus中 syncDBusEnvironment(); //同步环境变量到ukui-session中 syncSessionEnv("SESSION_MANAGER", session_manager); free(session_manager); } if (onlyLocal) { if (!SetAuthentication_local(numTransports, listenObjs)) { qFatal("ukuismserver : authentication setup failed."); } } else { if (!SetAuthentication(numTransports, listenObjs, &authDataEntries)) { qFatal("ukuismserver : authentication setup failed."); } } IceAddConnectionWatch(UKUISMWatchProc, (IcePointer)this); UKUISMListener *con; for (int i = 0; i < numTransports; i++) { fcntl(IceGetListenConnectionNumber(listenObjs[i]), F_SETFD, FD_CLOEXEC); con = new UKUISMListener(listenObjs[i]); m_listener.append(con); connect(con, &UKUISMListener::activated, this, &UKUISMServer::newConnection); } connect(qApp, &QApplication::aboutToQuit, this, &UKUISMServer::cleanUp); connect(&m_restoreTimer, &QTimer::timeout, this, &UKUISMServer::tryRestoreNext); connect(&m_protectionTimer, &QTimer::timeout, this, &UKUISMServer::protectionTimeout); qCDebug(UKUISMSERVER) << "finish construct ukuismserver"; // QTimer::singleShot(0, [this](){ // this->UKUISMServerStartFinished(); // }); } UKUISMServer::~UKUISMServer() { qDeleteAll(m_listener); cleanUp(); } UKUISMClient *UKUISMServer::newClient(SmsConn conn) { UKUISMClient *client = new UKUISMClient(conn); m_clients.append(client); m_activeClients[client] = 0; return client; } void UKUISMServer::deleteClient(UKUISMClient *client) { int num = m_clients.removeAll(client); qCDebug(UKUISMSERVER) << "m_clients remove client " << client->clientId() << " num is " << num << ", remain " << m_clients.size(); if (client == m_clientInteracting) { m_clientInteracting = nullptr; handlePendingInteractions(); } delete client; if (m_state == Shutdown) { completeShutdownOrCheckpoint(); } if (m_state == Killing) { completeKilling(); } if (m_state == KillingWM) { completeKillingWM(); } } void UKUISMServer::clientRegistered(const char *previousId) { if (previousId && m_lastIdRestore == QString::fromLocal8Bit(previousId)) { qCDebug(UKUISMSERVER) << "call tryRestoreNext"; tryRestoreNext(); } } void UKUISMServer::interactRequest(UKUISMClient *client, int dialogType) { //如果是关机阶段,该客户端的请求就要暂时挂起 if (m_state == Shutdown) { //将pendingInteraction属性设置为true,以便在handlePendingInteractions中处理 qCDebug(UKUISMSERVER) << client->clientId() << "ask for interact" << "pending it"; client->m_pendingInteraction = true; } else { //非关机阶段,则直接授予客户端交互权限 qCDebug(UKUISMSERVER) << "sending interact permission to client " << client->clientId(); SmsInteract(client->connection()); } //处理被挂起的客户端请求 handlePendingInteractions(); } void UKUISMServer::interactDone(UKUISMClient *client, bool cancelShutdown_) { //如果交互完成的客户端与服务器保存的m_clientInteraction信息不一致,则返回,一般不会发生,因为退出时的交互对话框是模态的 if (client != m_clientInteracting) return; //重置m_clientInteraciton,以便处理下一个挂起的客户端 qCDebug(UKUISMSERVER) << m_clientInteracting->clientId() << "interact done"; m_clientInteracting = nullptr; //如果客户端取消关机,则向所有客户端发送取消关机信号 if (cancelShutdown_) { QString programPath = client->program(); QString programName = programPath.mid(programPath.lastIndexOf(QDir::separator()) + 1); if (programName != QLatin1String("ukui-screensaver-default")) { qCDebug(UKUISMSERVER) << client->clientId() << "cancel shutdown"; QString localName = findLocalName(programName); QString message; message = localName + QObject::tr(" canceled this operation"); bubbleNotify(message); cancelShutdown(client); } else { //屏保程序不正常退出时,会在注销阶段发送一个取消注销信号过来,忽略这个信号,才能正常完成注销 qCDebug(UKUISMSERVER) << "ukui-screensaver-default send cancel shutdown, ignore it"; handlePendingInteractions(); } } else { //处理下一个挂起的客户端 handlePendingInteractions(); } } void UKUISMServer::phase2Request(UKUISMClient *client) { qCDebug(UKUISMSERVER()) << "wm ask for phase2 request"; //这两个成员变量对于窗管才有用 client->m_waitForPhase2 = true; client->m_wasPhase2 = true; completeShutdownOrCheckpoint(); if (isWM(client) && m_wmPhase1WaitingCount > 0) { --m_wmPhase1WaitingCount; //窗管完成phase1保存,请求phase2,服务器先向所有其他客户端发送保存命令 if (m_wmPhase1WaitingCount == 0) { foreach (UKUISMClient *c, m_clients) { if (!isWM(c)) { qCDebug(UKUISMSERVER) << "wm done phase1, sending saveyourself to " << c->clientId(); SmsSaveYourself(c->connection(), m_saveType, m_saveType != SmSaveLocal, m_saveType != SmSaveLocal ? SmInteractStyleAny : SmInteractStyleNone, false); } } } } } void UKUISMServer::saveYourselfDone(UKUISMClient *client, bool success) { //此处是非shutdown状态时,客户端注册进来仍然会走saveyourselfdone,参考kde代码中的注释 if (m_state == Idle || m_state == LaunchingWM || m_state == Restoring) { m_activeClients[client] = 1; QStringList discard = client->discardCommand(); if (!discard.isEmpty()) { executeCommand(discard); } return; } if (success) { qCDebug(UKUISMSERVER) << client->clientId() << "successfully done save"; client->m_saveYourselfDone = true; completeShutdownOrCheckpoint(); } else { //即使保存不成功也要按照成功的方式进行下一步,否则无法保存下一个客户端 client->m_saveYourselfDone = true; completeShutdownOrCheckpoint(); } startProtection(); } void UKUISMServer::clientSetProgram(UKUISMClient *client) { //kde根据窗管开始设置client属性来确定窗管已经启动完成,ukui-session中不需要通过这种方式来确定,暂时注释这一段 // if (isWM(client)) { // qCDebug(UKUISMSERVER) << "windowManager loaded, wm set property"; // } } void UKUISMServer::ioError(IceConn iceConn) { //找出iceConn包含的信息,为什么一定需要这个 } void *UKUISMServer::watchConnection(IceConn iceConn) { UKUISMConnection *conn = new UKUISMConnection(iceConn); connect(conn, &UKUISMConnection::activated, this, &UKUISMServer::processData); return (void*)conn; } void UKUISMServer::restoreWM(const QString &sessionName) { if (m_state != Idle) return; m_state = LaunchingWM; KSharedConfig::Ptr config = KSharedConfig::openConfig(); m_sessionGroup = QLatin1String("Session: ") + sessionName; KConfigGroup configSessionGroup(config, m_sessionGroup); //如果以后要加上恢复会话功能,m_appsToStart会被用到 int count = configSessionGroup.readEntry("count", 0); m_appsToStart = count; //以下这段是从保存的会话文件中寻找wm的重启命令 QList wmStartCommands; if (!m_wm.isEmpty()) { for (int i = 1; i <= count; i++) { QString n = QString::number(i); if (isWM(configSessionGroup.readEntry(QStringLiteral("program") + n, QString()))) { wmStartCommands << configSessionGroup.readEntry(QStringLiteral("restartCommand") + n, QStringList()); } } } if (wmStartCommands.isEmpty()) { wmStartCommands << m_wmCommands; } launchWM(wmStartCommands); } void UKUISMServer::startDefaultSession() { if (m_state != Idle ) { return; } m_state = LaunchingWM; m_sessionGroup = QString(); launchWM(QList() << m_wmCommands); } void UKUISMServer::shutdown() { //保存关机 qCDebug(UKUISMSERVER) << "begin performlogout"; performLogout(); } QStringList listFileList() { QDir dir("/etc/ukui/ukui-session/logout/"); if (!dir.exists()) { qWarning("Cannot find the example directory"); return QStringList(); } dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks); dir.setSorting(QDir::Size | QDir::Reversed); QFileInfoList list = dir.entryInfoList(); QStringList filelist; for (int i = list.size() - 1 ; i >= 0 ; --i) { QFileInfo fileInfo = list.at(i); filelist<= Shutdown) { qCDebug(UKUISMSERVER) << "already perform Logout"; return; } deleteInactiveClients(); m_kwinInterface->setState(KWinSessionState::Saving); m_state = Shutdown; m_saveSession = true; if (m_saveSession) { m_sessionGroup = QStringLiteral("Session: ") + QString::fromLocal8Bit(SESSION_PREVIOUS_LOGOUT); } m_wmPhase1WaitingCount = 0; m_saveType = SmSaveBoth; //将该函数的调用放到注销开始阶段 //9a0的机器上session是由kwin启动的,所以kwin不会注册到ukuismserver中,注销的时候也不会先保存kwin,而是直接向所有客户端发送保存信号 changeClientOrder(); startProtection(); foreach (UKUISMClient *c, m_clients) { c->resetState(); if (isWM(c)) { ++m_wmPhase1WaitingCount; } } if (m_wmPhase1WaitingCount > 0) { foreach (UKUISMClient *c, m_clients) { //先向窗管发送保存自身的信号 if (isWM(c)) { qCDebug(UKUISMSERVER) << "sending saveyourself to wm first"; SmsSaveYourself(c->connection(), m_saveType, true, SmInteractStyleAny, false); } } } else { foreach (UKUISMClient *c, m_clients) { qCDebug(UKUISMSERVER) << "sending saveourself to client " << " " << c->clientId(); SmsSaveYourself(c->connection(), m_saveType, true, SmInteractStyleAny, false); } } if (m_clients.isEmpty()) { completeShutdownOrCheckpoint(); } return; } void UKUISMServer::cleanUp() { if (clean) { return; } clean = true; IceFreeListenObjs(numTransports, listenObjs); QByteArray fName = QFile::encodeName(QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation) + QLatin1Char('/') + QStringLiteral("UKUISMServer")); QString display = QString::fromLocal8Bit(::getenv("DISPLAY")); display.remove(QRegularExpression(QStringLiteral("\\.[0-9]+$"))); int i; while ((i = display.indexOf(QLatin1Char(':'))) >= 0) { display[i] = '_'; } while ((i = display.indexOf(QLatin1Char('/'))) >= 0) { display[i] = '_'; } fName += '_' + display.toLocal8Bit(); ::unlink(fName.data()); FreeAuthenticationData(numTransports, authDataEntries); } bool UKUISMServer::closeSession() { Q_ASSERT(calledFromDBus()); qCDebug(UKUISMSERVER) << "begin logout"; performLogout(); qCDebug(UKUISMSERVER) << "Setting D-Bus reply delayed"; setDelayedReply(true); //不清楚这一步是否有意义,但是kde目前是这么做的 m_performLogoutCall = message(); return false; } void UKUISMServer::newConnection(int socket) { IceAcceptStatus status; IceConn iceConn = IceAcceptConnection(((UKUISMListener*)sender())->listenObj, &status); if (iceConn == nullptr) return; IceSetShutdownNegotiation(iceConn, false); IceConnectStatus cstatus; while ((cstatus = IceConnectionStatus(iceConn)) == IceConnectPending) { (void)IceProcessMessages(iceConn, nullptr, nullptr); } if (cstatus != IceConnectAccepted) { if (cstatus == IceConnectIOError) { qCDebug(UKUISMSERVER) << "IO error opening ICE Connection!"; } else { qCDebug(UKUISMSERVER) << "ICE Connection rejected!"; } (void)IceCloseConnection(iceConn); return; } fcntl(IceConnectionNumber(iceConn), F_SETFD, FD_CLOEXEC); } void UKUISMServer::processData(int socket) { IceConn iceConn = ((UKUISMConnection*)sender())->iceConn; IceProcessMessagesStatus status = IceProcessMessages(iceConn, nullptr, nullptr); if (status == IceProcessMessagesIOError) { //如果有同类应用再次注册进来就会触发此处 IceSetShutdownNegotiation(iceConn, false); QList::iterator it = m_clients.begin(); QList::iterator const itEnd = m_clients.end(); //这里做的就是找出发出错误信息的那个client,然后从m_clients中移除掉 while ((it != itEnd) && *it && (SmsGetIceConnection((*it)->connection()) != iceConn)) { ++it; } if ((it != itEnd) && *it) { SmsConn smsConn = (*it)->connection(); qCDebug(UKUISMSERVER) << "earse duplicate app, or some app close connection"; deleteClient(*it); SmsCleanUp(smsConn); } (void)IceCloseConnection(iceConn); } } void UKUISMServer::wmProcessChange() { if (m_state != LaunchingWM) { m_wmProcess = nullptr; return; } if (m_wmProcess->state() == QProcess::NotRunning) { if (m_restartNum > 10) { qCDebug(UKUISMSERVER) << "windowmanager 重启次数用尽"; return; } m_restartNum++; launchWM(QList() << m_wmCommands); qCDebug(UKUISMSERVER) << "windowmanager " << m_wmCommands[0] << "异常退出,重启"; // if (m_wm == QLatin1String("ukui-kwin_x11")) { // return; // } // m_wm = QStringLiteral("ukui-kwin_x11"); // m_wmCommands = (QStringList() << QStringLiteral("ukui-kwin_x11")); // launchWM(QList() << m_wmCommands); return; } } void UKUISMServer::protectionTimeout() { if ((m_state != Shutdown) || m_clientInteracting) {//如果状态不是Shutdown,或者clientInteracing有值,则条件成立 //m_clientInteracting有可能为nullptr,所以在这里获取clientid不是很方便 qCDebug(UKUISMSERVER) << "protectionTimeout: state is " << m_state << "clientInteracting is " << m_clientInteracting << "protectionTimeout returned"; //如果有一个客户端正在interact,而这里已经超时了,则会直接return,protectiontimer不能用于更改正在interect的客户端的状态。 //也即protectionTimer只能作用于那些不响应saveyourself信号的客户端,但是现在因为加入了清理不响应信号客户端的机制,所以实际上protectionTimer可能不会再有起作用的机会 //目前主线取消了超时机制,所以如果有客户端正在交互且超时,应该不需要提醒 // if (m_clientInteracting) { // QString path = m_clientInteracting->program(); // QString programName = path.mid(path.lastIndexOf(QDir::separator()) + 1); // qCDebug(UKUISMSERVER()) << "protectionTimeou: state is" << m_state << "clientInteracting is " << programName << "protectionTimeout returned"; // QString localName = findLocalName(programName); // QString message; // message = localName + QObject::tr(" cancel shutdown"); // bubbleNotify(message); // } return; } bool hasAppNotSave = false; foreach (UKUISMClient *c, m_clients) { if (!c->m_saveYourselfDone && !c->m_waitForPhase2) {//非窗管这类客户端且没有完成保存自身 qCDebug(UKUISMSERVER) << "protectionTimeout: client " << c->clientId(); QString path = c->program(); QString programName = path.mid(path.lastIndexOf(QDir::separator()) + 1); qCDebug(UKUISMSERVER()) << "protectionTimeout: client " << programName; QString localName = findLocalName(programName); QString message; message = localName + QObject::tr(" not respond"); bubbleNotify(message); hasAppNotSave = true; c->m_saveYourselfDone = true; } } if (hasAppNotSave) { qCDebug(UKUISMSERVER()) << "some App not respond, add a time dalay to show the message"; QTimer::singleShot(3000, [this](){ qCDebug(UKUISMSERVER()) << "show message time delay reached"; this->completeShutdownOrCheckpoint(); this->startProtection(); }); } else { completeShutdownOrCheckpoint(); startProtection(); } } void UKUISMServer::timeoutQuit() { qCDebug(UKUISMSERVER()) << "killing count timeout"; // killWM(); //杀死客户端阶段有一个2秒的等待,若2秒过后还有客户端没有响应killconnection信号,则会强制调用killwm //由于现在改成了不杀死窗管,所以这里的强制操作也改为调用systemd的注销 //如果一个客户端无法响应interect信号,那他肯定也无法响应killing信号,因此这个客户端一共会造成protectiontimer + killingcount秒的等待 killingCompleted(); } void UKUISMServer::timeoutWMQuit() { if (m_state == KillingWM) { qCDebug(UKUISMSERVER) << "SmsDie WM timeout"; } killingCompleted(); } void UKUISMServer::completeShutdownOrCheckpoint() { //只能在shutdown阶段调用 if (m_state != Shutdown) return; QList pendingClients; pendingClients = m_clients; //此处判断除窗管之外的客户端是否全部完成保存,没有的话就返回 foreach (UKUISMClient *c, pendingClients ) { if (!c->m_saveYourselfDone && !c->m_waitForPhase2) { qCDebug(UKUISMSERVER) << c->clientId() << " haven't save"; return; } } //窗管正在等待phase2阶段的保存,则向其发送保存phase2的信号 bool waitForPhase2 = false; foreach (UKUISMClient *c, pendingClients) { if (!c->m_saveYourselfDone && c->m_waitForPhase2) { c->m_waitForPhase2 = false; qCDebug(UKUISMSERVER) << "sending saveyourselfphase2 to " << c->clientId(); SmsSaveYourselfPhase2(c->connection()); waitForPhase2 = true; } } if (waitForPhase2) { return; } //运行到这里说明窗管和普通客户端都完成了保存,开始保存会话信息到磁盘中 if (m_saveSession) { qCDebug(UKUISMSERVER) << "store session informantion in rcfile"; storeSession(); } //会话信息保存完毕后开始退出,杀死客户端 if (m_state == Shutdown) { m_state = WaitingForKNotify; if (m_state == WaitingForKNotify) { qCDebug(UKUISMSERVER) << "begin killint client"; startKilling(); } } } void UKUISMServer::storeSession() { KSharedConfig::Ptr config = KSharedConfig::openConfig(); config->reparseConfiguration();//更新配置文件 KConfigGroup configSessionGroup(config, m_sessionGroup); int count = configSessionGroup.readEntry("count", 0); for (int i = 1; i <= count; i++) { //读取discardcommand QStringList discardCommand = configSessionGroup.readPathEntry(QLatin1String("discardCommand") + QString::number(i), QStringList()); if (discardCommand.isEmpty()) { continue; } //这一步的目的是寻找是否有重复的discardcommand, 如果没有就直接执行discardcommand QList::iterator it = m_clients.begin(); QList::iterator const itEnd = m_clients.end(); while ((it != itEnd) && *it && (discardCommand != (*it)->discardCommand())) { ++it; } if ((it != itEnd) && *it) { continue; } qCDebug(UKUISMSERVER) << "execute discardCommand " << discardCommand; executeCommand(discardCommand); } //删除上一次保存的会话信息 config->deleteGroup(m_sessionGroup); KConfigGroup cg(config, m_sessionGroup); count = 0; //将wm移动到客户端列表的第一个 foreach (UKUISMClient *c, m_clients) { if (isWM(c)) { m_clients.removeAll(c); m_clients.prepend(c); break; } } //遍历每一个客户端,存储客户端的信息到文件中 foreach (UKUISMClient *c, m_clients) { int restartHint = c->restartStyleHint(); if (restartHint == SmRestartNever) { continue; } QString program = c->program(); QStringList restartCommand = c->restartCommand(); if (program.isEmpty() && restartCommand.isEmpty()) { continue; } count++; QString n = QString::number(count); cg.writeEntry(QStringLiteral("program") + n, program); cg.writeEntry(QStringLiteral("clientId") + n, c->clientId()); cg.writeEntry(QStringLiteral("restartCommand") + n, restartCommand); cg.writePathEntry(QStringLiteral("discardCommand") + n, c->discardCommand()); cg.writeEntry(QStringLiteral("restartStyleHint") + n, restartHint); cg.writeEntry(QStringLiteral("userId") + n, c->userId()); cg.writeEntry(QStringLiteral("wasWm") + n, isWM(c)); } cg.writeEntry( "count", count ); config->sync(); } void UKUISMServer::completeKilling() { if (m_state == Killing) { //这一段的含义是只要客户端列表中还有非窗管的客户端存在,则等待,直到客户端中只有一个窗管,则开始杀死窗管 bool wait = false; foreach (UKUISMClient *c, m_clients) { if (isWM(c)) { continue; } wait = true; } if (wait) { return; } //killWM(); //修改为不杀死窗管,直接结束会话 killingCompleted(); } } void UKUISMServer::startKilling() { if (m_state == Killing) { return; } m_state = Killing; m_kwinInterface->setState(KWinSessionState::Quitting); foreach (UKUISMClient *c, m_clients) { if (isWM(c)) {//最后再杀死窗管 continue; } qCDebug(UKUISMSERVER) << c->clientId() << "kill connection"; SmsDie(c->connection()); } completeKilling(); qCDebug(UKUISMSERVER()) << "begin killing signal timeout count"; QTimer::singleShot(2000, this, &UKUISMServer::timeoutQuit); } void UKUISMServer::killWM() { if (m_state != Killing) { return; } m_state = KillingWM; bool iswm = false; foreach (UKUISMClient *c, m_clients) { if (isWM(c)) { iswm = true; qCDebug(UKUISMSERVER) << "wm kill connection"; SmsDie(c->connection()); } } if (iswm) { completeKillingWM(); //5秒后窗管没有杀死,就直接终止程序 QTimer::singleShot(5000, this, &UKUISMServer::timeoutWMQuit); } else { killingCompleted(); } } void UKUISMServer::completeKillingWM() { if (m_state == KillingWM) { if (m_clients.isEmpty()) { killingCompleted(); } } } void UKUISMServer::killingCompleted() { //这里构造d-bus的返回值,此处返回true,说明注销过程正常完成,用来通知plasma-session的关机接口,注销保存已经完成,可以开始关机 if (m_performLogoutCall.type() == QDBusMessage::MethodCallMessage) { auto reply = m_performLogoutCall.createReply(true); qCDebug(UKUISMSERVER) << "sending D-Bus reply to plasma shutdown"; QDBusConnection::sessionBus().send(reply); m_performLogoutCall = QDBusMessage(); } //qApp->quit(); m_state = Idle; m_clientInteracting = nullptr; m_saveSession = false; m_clients.clear(); m_activeClients.clear(); // emit logoutFinished(); // //目前不清楚如果不做清理会有什么影响,看日志没有发现问题,使用上也没有区别,但为了保险还是加上 // cleanUp(); } void UKUISMServer::cancelShutdown(UKUISMClient *c) { m_clientInteracting = nullptr; foreach (UKUISMClient *c, m_clients) { qCDebug(UKUISMSERVER) << "sending cancel shutdown to client " << c->clientId(); SmsShutdownCancelled(c->connection()); if (c->m_saveYourselfDone) { QStringList discard = c->discardCommand(); if (!discard.isEmpty()) { qCDebug(UKUISMSERVER) << c->clientId() << "discard saving state, discardCommand is " << discard; executeCommand(discard); } } c->resetState(); } m_state = Idle; //取消注销会向D-Bus调用方返回值,此处返回false,说明注销被取消,保证不会被强制注销 m_kwinInterface->setState(KWinSessionState::Normal); if (m_performLogoutCall.type() == QDBusMessage::MethodCallMessage) { auto reply = m_performLogoutCall.createReply(false); QDBusConnection::sessionBus().send(reply); m_performLogoutCall = QDBusMessage(); } } KProcess *UKUISMServer::startApplication(const QStringList &command, bool wm) { if (wm) { KProcess *process = new KProcess(this); qCDebug(UKUISMSERVER) << "the wm start command is " << command; *process << command; //应该需要在此处更新m_wm,因为m_wm需要在后面用来判断应用是否是窗管 m_wm = command[0]; connect(process, &KProcess::errorOccurred, process, &KProcess::deleteLater); connect(process, static_cast(&KProcess::finished), process, &KProcess::deleteLater); process->start(); return process; } else { qCDebug(UKUISMSERVER) << "The Restart Command is :" << command; int n = command.count(); QString app = command[0]; QStringList argList; for (int i = 1; i < n; i++) { argList.append(command[i]); } //调用ukui-session的接口启动应用 QDBusInterface *sessionInterface = new QDBusInterface("org.gnome.SessionManager", "/org/gnome/SessionManager", "org.gnome.SessionManager", QDBusConnection::sessionBus(), this); if (!sessionInterface->isValid()) { qWarning() << "dbusCall: Session QDBusInterface is invalid"; return nullptr; } QList argumentList; QVariant appVar(app); QVariant arguVar(argList); argumentList.append(appVar); argumentList.append(arguVar); sessionInterface->callWithArgumentList(QDBus::CallMode::NoBlock, "startApp", argumentList); return nullptr; } } bool UKUISMServer::restoreApplication(const QStringList &command) { qCDebug(UKUISMSERVER) << "The Restart Command is :" << command; int n = command.count(); QString app = command[0]; QStringList argList; for (int i = 1; i < n; i++) { argList.append(command[i]); } //调用ukui-session的接口启动应用 QDBusInterface *sessionInterface = new QDBusInterface("org.gnome.SessionManager", "/org/gnome/SessionManager", "org.gnome.SessionManager", QDBusConnection::sessionBus(), this); if (!sessionInterface->isValid()) { qWarning() << "dbusCall: Session QDBusInterface is invalid"; return false; } QList argumentList; QVariant appVar(app); QVariant arguVar(argList); argumentList.append(appVar); argumentList.append(arguVar); //如果要使用dbus接口的返回值,则应设置为阻塞的模式 QDBusReply reply = sessionInterface->call(QDBus::CallMode::Block, "startApp", appVar, arguVar); if (!(reply.isValid())) { qCDebug(UKUISMSERVER) << "call startApp getting error " << reply.error().name(); } if (reply.value()) { qCDebug(UKUISMSERVER) << "success restore " << app << " and the reply is " << reply.value(); return true; } qCDebug(UKUISMSERVER) << "can not restore " << app; return false; } void UKUISMServer::executeCommand(const QStringList &command) { if (command.isEmpty()) { return; } KProcess::execute(command); } void UKUISMServer::handlePendingInteractions() { //该函数在保存退出阶段,第一次进入该函数时,clientInteracting一定是nullptr if (m_clientInteracting) { return; } //遍历客户端,找到第一个正在挂起的客户端,将其初始化为m_clientInteracting foreach (UKUISMClient *c, m_clients) { if (c->m_pendingInteraction) { m_clientInteracting = c; c->m_pendingInteraction = false; break; } } //向m_clientInteracting授予交互权限 if (m_clientInteracting) { endProtection(); qCDebug(UKUISMSERVER) << "sending interact to " << m_clientInteracting->clientId(); SmsInteract(m_clientInteracting->connection()); } else { qCDebug(UKUISMSERVER) << "no more client is pending"; startProtection(); } } void UKUISMServer::startProtection() { //m_protectionTimer用于在第一个客户端获得交互权限前的定时保护作用,若存在一个进程处于忙碌状态,不处理我们对其发送的保存自身信号 //则会造成服务器一直等待该进程的响应,当定时器走完的时候,我们直接将所有客户端的状态设置为保存完毕,然后进行下一阶段的保存 m_protectionTimer.setSingleShot(true); m_protectionTimer.start(5000); qCDebug(UKUISMSERVER) << "start protectionTimer"; } void UKUISMServer::endProtection() { m_protectionTimer.stop(); } void UKUISMServer::launchWM(const QList &wmStartCommands) { assert(m_state == LaunchingWM); if (!(qEnvironmentVariableIsSet("WAYLAND_DISPLAY") || qEnvironmentVariableIsSet("WAYLAND_SOCKET"))) { m_wmProcess = startApplication(wmStartCommands[0], true); connect(m_wmProcess, SIGNAL(error(QProcess::ProcessError)), SLOT(wmProcessChange())); connect(m_wmProcess, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(wmProcessChange())); } } void UKUISMServer::tryRestoreNext() { if (m_state != Restoring) { return; } m_restoreTimer.stop(); KConfigGroup config(KSharedConfig::openConfig(), m_sessionGroup); while (m_appRestored < m_appsToStart) { //最开始m_appRestored为0,而rc文件中为0的为kwin,kwin已经被处理过,所以这里将++放在前,等于从id为1开始处理 QString n = QString::number(++m_appRestored); QString clientId = config.readEntry(QLatin1String("clientId") + n, QString()); QString clientName = config.readEntry(QLatin1String("program") + n, QString()); bool alreadyStarted = false; foreach (UKUISMClient *c, m_clients) { if (QString::fromLocal8Bit(c->clientId()) == clientId) { qCDebug(UKUISMSERVER) << c->program() << " is already started"; alreadyStarted = true; break; } else if (c->program() == clientName) { qCDebug(UKUISMSERVER) << c->program() << " already started"; alreadyStarted = true; break; } } if (alreadyStarted) { continue; } QStringList restartCommand = config.readEntry(QLatin1String("restartCommand") + n, QStringList()); if (restartCommand.isEmpty() || (config.readEntry(QStringLiteral("restartStyleHint") + n, 0) == SmRestartNever)) { continue; } if (isWM(config.readEntry( QStringLiteral("program") + n, QString()))) { continue; } if (config.readEntry(QStringLiteral("wasWm") + n, false)) { continue; } if (restoreApplication(restartCommand)) { m_lastIdRestore = clientId; if (!m_lastIdRestore.isEmpty()) { m_restoreTimer.setSingleShot(true); m_restoreTimer.start(2000); return; } } else { QCoreApplication::processEvents(); continue; } } qCDebug(UKUISMSERVER) << "finish restore all clients"; m_appRestored = 0; m_lastIdRestore.clear(); m_state = Idle; } bool UKUISMServer::isWM(const UKUISMClient *client) const { return isWM(client->program()); } bool UKUISMServer::isWM(const QString &program) const { //m_wm一般情况下是个完整的二进制程序路径,此处获得程序名,如果不是完整二进制路径,获取到的也是程序名, QString wmName = m_wm.mid(m_wm.lastIndexOf(QDir::separator()) + 1); QString programName = program.mid(program.lastIndexOf(QDir::separator()) + 1); return programName == wmName; } void UKUISMServer::changeClientOrder() { //桌面和控制栏等没有实现xsmp信号保存的应用会在interect done后发过来一个保存完成的信号,然后不等server的kill connection信号 //自己退出,所以将他们从客户端列表中去掉。 //这只是一个暂时解决的方法,应该由desktop和panel做出修改,在收到服务器的退出信号后才退出进程 //经过测试,即使将桌面和任务栏放到最后杀死,任然会出现桌面和任务栏先消失,应用还在的情况,要防止这种情况 //要么在storeSession后直接调用systemd的注销接口,要么让桌面和任务栏按照xsmp规范修改。 foreach (UKUISMClient *c, m_clients) { QString programPath = c->program(); QString programName = programPath.mid(programPath.lastIndexOf(QDir::separator()) + 1); if (programName == QLatin1String("ukui-panel")) { m_clients.removeAll(c); //改为任务栏不退出 // m_clients.append(c); } else if (programName == QLatin1String("peony-qt-desktop")) { m_clients.removeAll(c); //改为桌面不退出 // m_clients.append(c); } else if (programName == QLatin1String("ukui-menu")) { m_clients.removeAll(c); m_clients.append(c); } else if (programName == QLatin1String("ukui-tablet-desktop")) { //平板桌面的进程 m_clients.removeAll(c); } else if (programName == QLatin1String("et")) { //wps表格 if (!isWPSWinActive(programName)) { m_clients.removeAll(c); } else { m_clients.removeAll(c); m_clients.prepend(c); } } else if (programName == QLatin1String("wps")) { //wps文字 if (!isWPSWinActive(programName)) { m_clients.removeAll(c); } else { m_clients.removeAll(c); m_clients.prepend(c); } } else if (programName == QLatin1String("wpp")) { //wps演示 if (!isWPSWinActive(programName)) { m_clients.removeAll(c); } else { m_clients.removeAll(c); m_clients.prepend(c); } } } } bool UKUISMServer::syncDBusEnvironment() { QString program; QStringList args = {QStringLiteral("--systemd"), QStringLiteral("--all")};; QStringList env; QProcess p; if (!QStandardPaths::findExecutable(QStringLiteral("dbus-update-activation-environment")).isEmpty()) { program = "dbus-update-activation-environment"; } p.setEnvironment(QProcess::systemEnvironment() << env); p.setProcessChannelMode(QProcess::ForwardedChannels); if (!program.isEmpty()) { p.start(program, args); } else { qWarning() << "dbus-update-activation-environment don't exist"; return false; } p.waitForFinished(-1);//等待程序执行完成 if (p.exitCode()) { qWarning() << program << args << "exited with code" << p.exitCode(); } return p.exitCode() == 0;//QProcess::NormalExit 0 QProcess::CrashExit 1 } void UKUISMServer::syncSessionEnv(const QString &key, const QString &value) { QDBusInterface *sessionInterface = new QDBusInterface("org.gnome.SessionManager", "/org/gnome/SessionManager", "org.gnome.SessionManager", QDBusConnection::sessionBus(), this); if (!sessionInterface->isValid()) { qWarning() << "dbusCall: Session QDBusInterface is invalid"; return; } QList argumentList; QVariant envKey(key); QVariant envValue(value); argumentList.append(envKey); argumentList.append(envValue); qCDebug(UKUISMSERVER) << "sync env to ukui-session"; QDBusMessage msg = sessionInterface->callWithArgumentList(QDBus::CallMode::NoBlock, "setSessionEnv", argumentList); QString error = msg.errorMessage(); if (!error.isEmpty()) { qCDebug(UKUISMSERVER) << "the error is " << error; } } bool UKUISMServer::isWPSWinActive(const QString &wpsAPP) { bool isActive = false; FILE *fp = nullptr; const char *command = nullptr; //反斜杠注意前面还要加一个反斜杠转义 //xwininfo -id `xwininfo -tree -root |grep -E "WPS表格|WPS 表格|WPS Spreadsheets|Spreadsheets"|awk '{ print $1 }'`|grep "Map\s\State"|awk '{ print $3 }' if (wpsAPP == "et") { command = "xwininfo -id `xwininfo -tree -root |grep -E \"WPS表格|WPS 表格|WPS Spreadsheets|Spreadsheets\"|awk '{ print $1 }'`|grep \"Map\\s\\State\"|awk '{ print $3 }'"; } else if (wpsAPP == "wps") { command = "xwininfo -id `xwininfo -tree -root |grep -E \"WPS文字|WPS 文字|WPS Writer|Writer\"|awk '{ print $1 }'`|grep \"Map\\s\\State\"|awk '{ print $3 }'"; } else if (wpsAPP == "wpp") { command = "xwininfo -id `xwininfo -tree -root |grep -E \"WPS演示|WPS 演示|WPS Presentation|Presentation\"|awk '{ print $1 }'`|grep \"Map\\s\\State\"|awk '{ print $3 }'"; } fp = popen(command, "r"); char c; QString str; while (!feof(fp)) { c = fgetc(fp); try { str += c; } catch (std::bad_alloc&) { str.clear(); qDebug() << "loop error"; break; }; } qCDebug(UKUISMSERVER()) << str; if (str.isEmpty()) { qCDebug(UKUISMSERVER()) << wpsAPP << "未启动"; } else if (str.contains(QString("IsUnMapped"))) { qCDebug(UKUISMSERVER()) << wpsAPP << "启动但窗口已关闭"; } else if (str.contains(QString("IsViewable"))) { qCDebug(UKUISMSERVER()) << wpsAPP << "已启动且窗口开启"; isActive = true; } pclose(fp); return isActive; } void UKUISMServer::deleteInactiveClients() { for (const auto &iter : m_activeClients) { if (iter.second == 0) { //会导致崩溃? // qCDebug(UKUISMSERVER) << "m_clients remove inactive client " << iter.first->program(); m_clients.removeAll(iter.first); } } } void UKUISMServer::bubbleNotify(QString &message) { QDBusInterface face("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", QDBusConnection::sessionBus()); QString name = QObject::tr("ukui-session"); uint id = 0; QString icon = ""; QString title = QObject::tr("Tips"); QVariantMap hints; // QString desktopFileName = QGuiApplication::desktopFileName(); // hints.insert(QStringLiteral("desktop-entry"), desktopFileName); QList argumentList; argumentList << QVariant::fromValue(name) << QVariant::fromValue(id) << QVariant::fromValue(icon) << QVariant::fromValue(title) << QVariant::fromValue(message) << QVariant::fromValue(QStringList()) << QVariant::fromValue(hints) << QVariant::fromValue(3000); QDBusPendingCall reply = face.asyncCallWithArgumentList(QStringLiteral("Notify"), argumentList); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); QObject::connect(watcher, &QDBusPendingCallWatcher::finished,[](){ qCDebug(UKUISMSERVER()) << "notify call finished"; }); } QString UKUISMServer::findLocalName(QString &name) { QString localName; QStringList desktop_paths = {"/usr/share/applications", "/etc/xdg/autostart"}; for (const QString &dirName : const_cast(desktop_paths)) { QDir dir(dirName); if (!dir.exists()) { continue; } const QFileInfoList files = dir.entryInfoList(QStringList(QLatin1String("*.desktop")), QDir::Files | QDir::Readable); for (const QFileInfo &fi : files) { XdgDesktopFile desktopFile; desktopFile.load(fi.absoluteFilePath()); //不再使用basename判断,使用命令判断 //QString base = fi.baseName(); if (desktopFile.expandExecString().isEmpty()) continue; QString command = desktopFile.expandExecString().takeFirst(); if (command.isNull() || command.isEmpty()) { continue; } QStringList list = command.split("/"); QString exec = list.last(); if (exec == name) { localName = desktopFile.localizedValue("Name").toString(); //localName有可能不存在,所以要做判断 if (!localName.isEmpty()) { return localName; } } // QString fName = fi.fileName(); // if (fName == name || fName.contains(name)) { // qCDebug(UKUISMSERVER()) << "name is " << name << " and fileName is " << fName; // XdgDesktopFile desktopFile; // desktopFile.load(fi.absoluteFilePath()); // //只有Name与进程名相同,才能证明是这个应用的desktop文件,但是某些应用的进程名和desktopfile中的Name不一样 // //例如wps // QString engName = desktopFile.value("Name").toString(); //// qCDebug(UKUISMSERVER()) << "engName is " << engName; // if (engName == name || areStringsEqualIgnoreCase(engName, name)) { // localName = desktopFile.localizedValue("Name").toString(); // //localName有可能不存在,所以要做判断 // if (!localName.isEmpty()) { // return localName; // } // } // } } } //运行到这一步,说明没找到localname,那就只能使用原来的进程名 return name; } bool UKUISMServer::areStringsEqualIgnoreCase(const QString &str1, const QString &str2) { if (str1.length() != str2.length()) { return false; } std::string lowerStr1(str1.toLocal8Bit().constData()); std::string lowerStr2(str2.toLocal8Bit().constData()); std::transform(lowerStr1.begin(), lowerStr1.end(), lowerStr1.begin(), [](unsigned char c) { return std::tolower(c); }); std::transform(lowerStr2.begin(), lowerStr2.end(), lowerStr2.begin(), [](unsigned char c) { return std::tolower(c); }); return (lowerStr1 == lowerStr2); } void UKUISMServer::removeConnection(UKUISMConnection *conn) { delete conn; } void UKUISMServer::restoreSession() { qCDebug(UKUISMSERVER) << "begin restore session"; m_appRestored = 0; m_lastIdRestore.clear(); m_state = Restoring; tryRestoreNext(); } bool UKUISMServer::isCloseSession() { qCDebug(UKUISMSERVER) << "m_state = " << m_state; return m_state >= Shutdown; } ukui-session-manager/ukuismserver/ukuismserverdebug.h0000664000175000017500000000201415252713362022241 0ustar fengfeng/* BEGIN_COMMON_COPYRIGHT_HEADER * (c)LGPL2+ * Copyright 2021 KylinSoft Co., Ltd. * * This program or library is free software; you can redistribute it * and/or modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA * * END_COMMON_COPYRIGHT_HEADER */ #ifndef UKUISMSERVERDEBUG_H #define UKUISMSERVERDEBUG_H #include Q_DECLARE_LOGGING_CATEGORY(UKUISMSERVER) #endif // UKUISMSERVERDEBUG_H ukui-session-manager/ukuismserver/ukuismserver.h0000664000175000017500000001214315252714370021236 0ustar fengfeng/***************************************************************** ukuismserver - the UKUI session management server Copyright 2000 Matthias Ettrich Copyright 2021 KylinSoft Co., Ltd. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #ifndef UKUISMSERVER_H #define UKUISMSERVER_H extern "C" { #include } #include //该头文件来自kwindowsystem,主要作用是处理和Qt的头文件一起编译时的冲突 #include #include #include #include #include class UKUISMClient; class UKUISMListener; class UKUISMConnection; class KProcess; class OrgUkuiKWinSessionInterface; class UKUISMServer : public QObject, protected QDBusContext { Q_OBJECT public: explicit UKUISMServer(const QString &windowManager = ""); ~UKUISMServer(); UKUISMClient* newClient(SmsConn conn); void deleteClient(UKUISMClient *client); //callback void clientRegistered(const char *previousId); void interactRequest(UKUISMClient *client, int dialogType); void interactDone(UKUISMClient *client, bool cancelShutdown_); void phase2Request(UKUISMClient *client); void saveYourselfDone(UKUISMClient *client, bool success); void clientSetProgram(UKUISMClient *client); // error handling void ioError(IceConn iceConn); public: void* watchConnection(IceConn iceConn ); void removeConnection(UKUISMConnection *conn ); void restoreSession(); void restoreWM(const QString &sessionName); void startDefaultSession(); void shutdown(); void performLogout(); Q_SIGNALS: void logoutFinished(); void UKUISMServerStartFinished(); public Q_SLOTS: void cleanUp();//smserver析构前的清理工作 bool closeSession(); private Q_SLOTS: void newConnection(int socket); void processData(int socket); void wmProcessChange(); void protectionTimeout(); void timeoutQuit(); void timeoutWMQuit(); private: void completeShutdownOrCheckpoint(); void storeSession(); void completeKilling(); void startKilling(); void killWM(); void completeKillingWM(); void killingCompleted(); void cancelShutdown(UKUISMClient *c); KProcess* startApplication(const QStringList &command, bool wm = false); bool restoreApplication(const QStringList &command); void executeCommand(const QStringList& command); void handlePendingInteractions(); void startProtection(); void endProtection(); void launchWM(const QList &wmStartCommands); void tryRestoreNext(); bool isWM(const UKUISMClient *client) const; bool isWM(const QString &program) const; //改变客户端的顺序 void changeClientOrder(); bool syncDBusEnvironment(); void syncSessionEnv(const QString &key, const QString &value); bool isWPSWinActive(const QString &wpsAPP); void deleteInactiveClients(); void bubbleNotify(QString &message); QString findLocalName(QString &name); bool areStringsEqualIgnoreCase(const QString &str1, const QString &str2); private: enum State { Idle, LaunchingWM, Restoring, Shutdown, Killing, KillingWM, WaitingForKNotify, // shutdown }; State m_state; bool clean; bool m_saveSession; int m_wmPhase1WaitingCount; int m_appsToStart; int m_appRestored; int m_saveType; int m_restartNum; KProcess *m_wmProcess; OrgUkuiKWinSessionInterface *m_kwinInterface; UKUISMClient *m_clientInteracting; QList m_listener; QList m_clients; std::map m_activeClients; QTimer m_restoreTimer; QTimer m_protectionTimer; QString m_wm; QString m_lastIdRestore; QString m_sessionGroup; QStringList m_wmCommands; QDBusMessage m_performLogoutCall; public: bool isCloseSession(); bool isCancelLogout() const; void setIsCancelLogout(bool isCancelLogout); bool isCancelShutdown() const; void setIsCancelShutdown(bool isCancelShutdown); bool isCancelReboot() const; void setIsCancelReboot(bool isCancelReboot); }; #endif // UKUISMSERVER_H ukui-session-manager/ukuismserver/ukuismserverdbusadaptor.h0000664000175000017500000000122515252713362023466 0ustar fengfeng#ifndef UKUISMSERVERDBUSADAPTOR_H #define UKUISMSERVERDBUSADAPTOR_H #include "ukuismserver.h" #include #include class ukuismserverdbusadaptor : public QDBusAbstractAdaptor { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.ukui.ukuismserver") public: ukuismserverdbusadaptor(UKUISMServer *server); ~ukuismserverdbusadaptor(); inline UKUISMServer *parent() const { return static_cast(QObject::parent()); } public slots: bool closeSession(); bool isCloseSession(); void restoreSession(); signals: void UKUISMServerStartFinished(); }; #endif // UKUISMSERVERDBUSADAPTOR_H ukui-session-manager/ukuismserver/org.ukui.KWin.Session.xml0000664000175000017500000000073515252713362023103 0ustar fengfeng ukui-session-manager/ukuismserver/ukuismconnection.h0000664000175000017500000000417015252713362022070 0ustar fengfeng/***************************************************************** ksmserver - the KDE session management server Copyright 2000 Matthias Ettrich Copyright 2005 Lubos Lunak Copyright 2021 KylinSoft Co., Ltd. relatively small extensions by Oswald Buddenhagen some code taken from the dcopserver (part of the KDE libraries), which is Copyright 1999 Matthias Ettrich Copyright 1999 Preston Brown Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #ifndef UKUISMCONNECTION_H #define UKUISMCONNECTION_H #include #include class UKUISMConnection : public QSocketNotifier { public: UKUISMConnection(IceConn conn) : QSocketNotifier(IceConnectionNumber(conn), QSocketNotifier::Read ) { iceConn = conn; } IceConn iceConn; }; class UKUISMListener : public QSocketNotifier { public: UKUISMListener(IceListenObj obj) : QSocketNotifier(IceGetListenConnectionNumber(obj), QSocketNotifier::Read) { listenObj = obj; } IceListenObj listenObj; }; #endif // UKUISMCONNECTION_H ukui-session-manager/translations/0000775000175000017500000000000015252714370016275 5ustar fengfengukui-session-manager/translations/bo.ts0000664000175000017500000000433715252713362017254 0ustar fengfeng MainWindow Form Suspend Switch User Log Out Restart Power Off QApplication UKUI session tools, show the shutdown dialog without any arguments. Logout this computer. Shutdown this computer. Switch the user of this computer. Restart this computer. ukui-session-manager/translations/ky.ts0000664000175000017500000004607715252714370017306 0ustar fengfeng MainWindow Switch User 切换用户 Hibernate 休眠 Suspend 睡眠 Logout 注销 Reboot 重启 Shut Down 关机 Lock Screen 锁屏 cancel 取消 confirm 确认 QApplication UKUI session tools, show the shutdown dialog without any arguments. UKUI سۉيلۅشۉۉ قۇرالى ،ەچقانداي پارامەتىر بولبوعون بەكىتىش دىيالوگ رامكاسىن كۅرسۅتۅت. ukui-session-tools ukui-جىيىن - قۇرالى Switch the user of this computer. بۇل كومپۇيوتەردىن ىشتەتۉۉچۉنۉ الماشتىرىپ بەرەبىز. Hibernate this computer. بۇل كومپىيۇتەردى ئۇخلىتىپ قويۇش Suspend this computer. بۇل كومپىيوتەردى توقتوتۇپ قويۇش Logout this computer. بۇل كومپىيۇتېردىن جانىش ، قايتىش . Restart this computer. بۇل كومپىيۇتەردى قايرا قوزعوتۇۇ Shutdown this computer. بۇل كومپىيۇتەردى بەكىتىپ جىبەرۉۉ system-monitor ساامالىق كۉزۅتكۉچ Switch User ىشتەتۉۉچۉنۉ الماشتىرۇۇ Hibernate ۇيقۇ Suspend توقتوتۇۇ Logout 注销 Reboot 重启 Log Out جانىش ، قايتىش Restart قايرا قوزعوتۇۇ Shut Down جااپ جىبەرۉۉ Lock Screen ەكىران قۇلۇپتوو UpgradeThenRboot ThenBoot نىڭ چەگىن ۅستۉرۉۉ UpgradeThenShutdown چەگىن ۅستۉرۉپ ، اندان بەكىتىش Turn off your computer, but the app stays open. When the computer is turned on, it can be restored to the state you left. كومپىيۇتەردى ەتىك، بىروق قولدونۇشچان پراگرامما اچىق ابالدا تۇرات. كومپىيۇتەر اچىلعان ۇچۇردا ، سىز ايرىلعانداقى ابالعا قايتات. The computer stays on, but consumes less power. The app stays open and can quickly wake up and revert to where you left off. كومپىيۇتەر اچىق ابالدا تۇرات، بىر وق قۇۋۋەت سەرپىياتى بىر عاچا تۅمۅن بولوت ، بۇل ئەپ اچىق ابالدا تۇرات، تەز تەزدىكتە ئويغىتىپ، سىز توقتوعون ۇچۇرداقى العاچىنا كەلتىرگەلى بولوت . The current user logs out of the system, terminates the session, and returns to the login page. گەزەكتەكى ىشتەتۉۉچۉلۅردۉ تىزىمدىكىتىن ۅچۉرۉۉ ساامالىعى ، سۉيلۅشۉۉنۉ توقتوتۇۇ، اندان تىزىمدەتىش بەتىنە قايتۇۇ گەلەت . Close all apps, turn off your computer, and then turn your computer back on. باردىق قولدونۇشچان پىروگىراممالاردى ئېتىۋېتىڭلار، كومپىيۇتەردى ەتىپ جىبەرىپ، اندان كومپىيۇتەردى قايتادان اچابىز. Close all apps, and then shut down your computer. باردىق ئەپلەرنى بەكىتىپ جىبەرىڭ، اندان كومپىيوتەرىڭىزدى ەتىپ جىبەرىڭ. Multiple users are logged in at the same time.Are you sure you want to close this system? بىر ەلە ۇباقىتتا كۅپ كەرەكتۅۅچۉ تىزىمدەتىپ كىرەت. سىز ىراس ەلە بۇل سەستىمانى توقوونۇ قالايسىزبى؟ cancel بەكەر جاسوو ،اتقارۇۇ confirm ايقىندوو (user),ukui-control-center is performing a system update or package installation. (用户),系统正在进行升级或软件包安装/卸载相关操作。 (user),yhkylin-backup-tools is performing a system backup or restore. (用户),备份还原工具正在进行备份或还原。 For system security,Reboot、Shutdown、Logout and Hibernate are temporarily unavailable. 为了系统安全,重启、关机、注销和休眠功能暂时不可用。 For system security,Reboot、Shutdown and Hibernate are temporarily unavailable. 为了系统安全,重启、关机和休眠功能暂时不可用。 UKUI Session Manager UKUI سۉيلۅشۉۉ باشقارعىچ QObject is block system 阻止系统 into sleep for reason 休眠,因为 is block system 阻止系统 into sleep for reason 睡眠,因为 Are you sure 你确定 you want to get system into sleep? 要让系统进入休眠吗? Are you sure you want to get system into sleep? 你确定要让系统进入睡眠吗? cancel بەكەر جاسوو ،اتقارۇۇ confirm ايقىندوو is block system into reboot for reason 阻止系统重启,因为 is block system into shutdown for reason 阻止系统关机,因为 Are you sure you want to reboot? 你确定要重启系统吗? Are you sure you want to shutdown? 你确定要退出系统吗? ukui-session-tools ukui-جىيىن - قۇرالى Multiple users are logged in at the same time.Are you sure you want to close this system? بىر ەلە ۇباقىتتا كۅپ كەرەكتۅۅچۉ تىزىمدەتىپ كىرەت. سىز ىراس ەلە بۇل سەستىمانى توقوونۇ قالايسىزبى؟ System update or package installation in progress,this function is temporarily unavailable. ساامالىق جاڭىلوو كۅرۉنۉشتۅرۉ ۅتۉمدۉ قاچالوو جالعاشتىرىپ جاتات،بۇل قۇربات ، جۅندۅم ۇباقتىلۇۇ ىشتەتكەلى بولبويت . System backup or restore in progress,this function is temporarily unavailable. ساامالىق زاپاستوو كۅرۉنۉشتۅرۉ العاچىنا كەلتىرۉۉ اقىرىندا بۇل قۇربات ، جۅندۅم ۇباقتىلۇۇ ىشتەتكەلى بولبويت . OK بەكىتۉۉ The following program is running to prevent the system from hibernate! ! سەستىماسىنىن تىزگىندەپ قېلىشىنىڭ الدىن الۇۇ ۉچۉن تۅمۅندۅكۉ پراگرامما اتقارماق بولۇپ جاتات The following program is running to prevent the system from suspend! ! سەستىماسىنىن توختىشىنىڭ الدىن الۇۇ ۉچۉن تۅمۅندۅكۉ پراگرامما اتقارماق قىلىنىپ جاتات The following program is running to prevent the system from logout! سەستىماسىنىن چېكىنىشىنىڭ الدىن الۇۇ ۉچۉن تۅمۅندۅكۉ پراگرامما اتقارماق بولۇپ جاتات! The following program is running to prevent the system from reboot! ! سەستىماسىنىن قايرا قوزغىلىشىنىڭ الدىن الۇۇ ۉچۉن تۅمۅندۅكۉ پراگرامما اتقارماق بولۇپ جاتات The following program is running to prevent the system from shutting down! !تۅمۅندۅكۉ پراگرامما سەستىمانىن تاقالىپ قېلىشىنىڭ الدىن الۇۇ ۉچۉن يۈگۈرۈۋاتىدۇ Still Hibernate داعى ەلە مۈگدەش ابالىندا Still Suspend داعى ەلە توقتوتۇپ قويۇلعان ابالدا Still Reboot داعى ەلە قايرا قوزغىتىۋېرىش Still Shutdown داعى ەلە بەكىتىش Cancel ارعادان قالتىرىش some applications are running and they don't want you to do this. گەەبىر قولدونۇشچان پراگرامما اتقارماق قىلىنىپ جاتات، الار سىزدىن بۇنداي قىلۇۇڭۇزدۇ خالىمايدۇ. Still to do! داعى ەلە جاسووعو تىيىشتۉۉ! give up بەل قويۇپ ۅتۉ كەچىگۉۉ cancel shutdown 取消了本次注销 canceled this operation بۇل ماشقۇلدانۇۇ ارعادان قالتىرىلدى not respond قوشۇلماسلىق ukui-session ukui- جىيناقتى The current user has logged in to the system! Currently, the system does not support more than one user to log in at the same time. Click the button below to log out. گەزەكتەكى سووداگەر ، جولووچۇ ساامالىقا كىرىپ بولدۇ ! گەزەكتە ، ساامالىق كۅپ ىشتەتكۉۉچۉنۉن بىر ەلە ۇباقىتتا كىرىشتى قولدوبويت. تۅمۅندۅكۉ كونۇپكانى چەگىپ تىزىمدىكىتىن ۅچۉرۉڭ. Tips تۉرۉ Logout Warning 注销提醒 ukui-session-manager/translations/de.ts0000664000175000017500000003311615252714370017241 0ustar fengfeng MainWindow Form Form Switch User Benutzer wechseln Hibernate Überwintern Suspend Aufhängen Logout Abmeldung Reboot Neustart Shut Down Herunterfahren Lock Screen Sperrbildschirm cancel Abbrechen confirm bestätigen <html><head/><body><p><br/></p></body></html> <html> <head/> <body> <p> <br/> </p> </body> </html> QApplication UKUI session tools, show the shutdown dialog without any arguments. UKUI-Sitzungswerkzeuge, zeigen den Dialog zum Herunterfahren ohne Argumente an. Switch the user of this computer. Wechseln Sie den Benutzer dieses Computers. Hibernate this computer. Versetzen Sie diesen Computer in den Ruhezustand. Suspend this computer. Halten Sie diesen Computer an. Logout this computer. Melden Sie sich von diesem Computer ab. Restart this computer. Starten Sie diesen Computer neu. Shutdown this computer. Fahren Sie diesen Computer herunter. system-monitor 系统监视器 Switch User Benutzer wechseln Hibernate Überwintern Suspend Aufhängen Logout Abmeldung Reboot Neustart Shut Down Herunterfahren Lock Screen Sperrbildschirm Multiple users are logged in at the same time.Are you sure you want to close this system? Mehrere Benutzer sind gleichzeitig angemeldet. Sind Sie sicher, dass Sie dieses System schließen möchten? cancel Abbrechen confirm bestätigen (user),ukui-control-center is performing a system update or package installation. (Benutzer),ukui-control-center führt ein System-Update oder eine Paketinstallation durch. (user),yhkylin-backup-tools is performing a system backup or restore. (Benutzer),yhkylin-backup-tools führt eine Systemsicherung oder -wiederherstellung durch. For system security,Reboot、Shutdown、Logout and Hibernate are temporarily unavailable. Aus Gründen der Systemsicherheit sind Neustart, Herunterfahren, Abmelden und Ruhezustand vorübergehend nicht verfügbar. For system security,Reboot、Shutdown and Hibernate are temporarily unavailable. Aus Gründen der Systemsicherheit sind Neustart, Herunterfahren und Ruhezustand vorübergehend nicht verfügbar. UKUI Session Manager UKUI-Sitzungsmanager QObject is block system 阻止系统 into sleep for reason 休眠,因为 is block system 阻止系统 into sleep for reason 睡眠,因为 Are you sure 你确定 you want to get system into sleep? 要让系统进入休眠吗? Are you sure you want to get system into sleep? 你确定要让系统进入睡眠吗? cancel Abbrechen confirm bestätigen is block system into reboot for reason 阻止系统重启,因为 is block system into shutdown for reason 阻止系统关机,因为 Are you sure you want to reboot? 你确定要重启系统吗? Are you sure you want to shutdown? 你确定要退出系统吗? Multiple users are logged in at the same time.Are you sure you want to close this system? Mehrere Benutzer sind gleichzeitig angemeldet. Sind Sie sicher, dass Sie dieses System schließen möchten? System update or package installation in progress,this function is temporarily unavailable. Systemaktualisierung oder Paketinstallation wird ausgeführt, diese Funktion ist vorübergehend nicht verfügbar. System backup or restore in progress,this function is temporarily unavailable. Systemsicherung oder -wiederherstellung wird ausgeführt, diese Funktion ist vorübergehend nicht verfügbar. OK OKAY The following program is running to prevent the system from hibernate! Das folgende Programm wird ausgeführt, um zu verhindern, dass das System in den Ruhezustand versetzt wird! The following program is running to prevent the system from suspend! Das folgende Programm wird ausgeführt, um zu verhindern, dass das System angehalten wird! The following program is running to prevent the system from logout! Das folgende Programm wird ausgeführt, um zu verhindern, dass sich das System abmeldet! The following program is running to prevent the system from reboot! Das folgende Programm wird ausgeführt, um einen Neustart des Systems zu verhindern! The following program is running to prevent the system from shutting down! Das folgende Programm wird ausgeführt, um das Herunterfahren des Systems zu verhindern! Still Hibernate Immer noch Winterschlaf Still Suspend Immer noch anhalten Still Reboot Immer noch Neustart Still Shutdown Immer noch abgeschaltet Cancel Abbrechen some applications are running and they don't want you to do this. Einige Anwendungen werden ausgeführt und möchten nicht, dass Sie dies tun. Still to do! Es gibt noch viel zu tun! give up aufgeben ukui-session-manager/translations/tr.ts0000664000175000017500000000607115252713362017276 0ustar fengfeng MainWindow Form Switch User Kullanıcı Değiştir Hebernate Hazırda Beklet Suspend Askıya Al Logout Çıkış Reboot Yeniden Başlat Shut Down Kapat Lock Screen Ekranı Kilitle QApplication UKUI session tools, show the shutdown dialog without any arguments. UKUI oturum araçları, herhangi bir argüman olmadan kapatma iletişim kutusunu gösterir. Switch the user of this computer. Bu bilgisayardaki kullanıcıyı değiştir. Hibernate this computer. Bu bilgisayarı hazırda beklet. Suspend this computer. Bu bilgisayarı askıya al. Logout this computer. Bu bilgisayardan çık. Restart this computer. Bu bilgisayarı yeniden başlat. Shutdown this computer. Bu bilgisayarı kapat. ukui-session-manager/translations/ug.ts0000664000175000017500000004545215252714370017272 0ustar fengfeng MainWindow Switch User 切换用户 Hibernate 休眠 Suspend 睡眠 Logout 注销 Reboot 重启 Shut Down 关机 Lock Screen 锁屏 cancel 取消 confirm 确认 QApplication UKUI session tools, show the shutdown dialog without any arguments. UKUI سۆزلىشىش قورالى ،ھېچقانداق پارامېتىر بولمىغان تاقاش دىئالوگ رامكىسىنى كۆرسىتىدۇ. ukui-session-tools ukui-يىغىن - قورالى Switch the user of this computer. بۇ كومپىيۇتېرنىڭ ئىشلەتكۈچىسىنى ئالماشتۇرۇپ بىرىمىز. Hibernate this computer. بۇ كومپيۇتېرنى ئۇخلىتىپ قويۇش Suspend this computer. بۇ كومپىيۇتېرنى توختىتىپ قويۇش Logout this computer. بۇ كومپىيۇتېردىن چېكىنىش. Restart this computer. بۇ كومپيۇتېرنى قايتا قوزغىتىش Shutdown this computer. بۇ كومپيۇتېرنى ئېتىۋىتىش system-monitor سىستېما كۆزەتكۈچ Switch User ئىشلەتكۈچىنى ئالماشتۇرۇش Hibernate ئۇيقۇدا Suspend ئېسىش Logout 注销 Reboot 重启 Log Out چېكىنىش Restart قايتا قوزغىتىش Shut Down تاقىۋېتىش Lock Screen ئېكران قۇلۇپلاش UpgradeThenRboot ThenBoot نىڭ دەرىجىسىنى ئۆستۈرۈش UpgradeThenShutdown دەرىجىسىنى ئۆستۈرۈپ ، ئاندىن تاقاش Turn off your computer, but the app stays open. When the computer is turned on, it can be restored to the state you left. كومپيۇتېرنى ئېتىك، لېكىن قوللىنىشچان پروگرامما ئوچۇق ھالەتتە تۇرىدۇ. كومپيۇتېر ئېچىلغان چاغدا، سىز ئايرىلغاندىكى ھالەتكە قايتىدۇ. The computer stays on, but consumes less power. The app stays open and can quickly wake up and revert to where you left off. كومپيۇتېر ئوچۇق ھالەتتە تۇرىدۇ، لېكىن قۇۋۋەت سەرپىياتى بىر قەدەر تۆۋەن بولىدۇ، بۇ ئەپ ئوچۇق ھالەتتە تۇرىدۇ، تېز سۈرئەتتە ئويغىتىپ، سىز توختىغان چاغدىكى ئەسلىگە كەلتۈرگىلى بولىدۇ. The current user logs out of the system, terminates the session, and returns to the login page. نۆۋەتتىكى ئابونېنتلارنى تىزىمدىن ئۆچۈرۈش سىستېمىسى، سۆزلىشىشنى توختىتىش، ئاندىن تىزىملىتىش بېتىگە قايتىپ كېلىدۇ. Close all apps, turn off your computer, and then turn your computer back on. بارلىق قوللىنىشچان پىروگراممىلارنى ئېتىۋېتىڭلار، كومپيۇتېرنى ئېتىۋېتىپ، ئاندىن كومپيۇتېرنى قايتىدىن ئاچىمىز. Close all apps, and then shut down your computer. بارلىق ئەپلەرنى تاقىۋېتىڭ، ئاندىن كومپيۇتېرىڭىزنى ئېتىۋېتىڭ. Multiple users are logged in at the same time.Are you sure you want to close this system? بىرلا ۋاقىتتا كۆپ ئابونت تىزىملىتىپ كىرىدۇ. سىز راستىنلا بۇ سىستېمىنى تاقاشنى خالامسىز؟ cancel ئەمەلدىن قالدۇرۇش confirm جەزىملەشتۈرمەك (user),ukui-control-center is performing a system update or package installation. (用户),系统正在进行升级或软件包安装/卸载相关操作。 (user),yhkylin-backup-tools is performing a system backup or restore. (用户),备份还原工具正在进行备份或还原。 For system security,Reboot、Shutdown、Logout and Hibernate are temporarily unavailable. 为了系统安全,重启、关机、注销和休眠功能暂时不可用。 For system security,Reboot、Shutdown and Hibernate are temporarily unavailable. 为了系统安全,重启、关机和休眠功能暂时不可用。 UKUI Session Manager UKUI سۆزلىشىش باشقۇرغۇچ QObject is block system 阻止系统 into sleep for reason 休眠,因为 is block system 阻止系统 into sleep for reason 睡眠,因为 Are you sure 你确定 you want to get system into sleep? 要让系统进入休眠吗? Are you sure you want to get system into sleep? 你确定要让系统进入睡眠吗? cancel ئەمەلدىن قالدۇرۇش confirm جەزىملەشتۈرمەك is block system into reboot for reason 阻止系统重启,因为 is block system into shutdown for reason 阻止系统关机,因为 Are you sure you want to reboot? 你确定要重启系统吗? Are you sure you want to shutdown? 你确定要退出系统吗? ukui-session-tools ukui-يىغىن - قورالى Multiple users are logged in at the same time.Are you sure you want to close this system? بىرلا ۋاقىتتا كۆپ ئابونت تىزىملىتىپ كىرىدۇ. سىز راستىنلا بۇ سىستېمىنى تاقاشنى خالامسىز؟ System update or package installation in progress,this function is temporarily unavailable. سىستېما يېڭىلاش ياكى يۈرۈشلۈك قاچىلاش داۋاملىشىۋاتىدۇ،بۇ ئىقتىدار ۋاقىتلىق ئىشلەتكىلى بولمايدۇ. System backup or restore in progress,this function is temporarily unavailable. سىستېما زاپاسلاش ياكى ئەسلىگە كەلتۈرۈش داۋامىدا بۇ ئىقتىدار ۋاقىتلىق ئىشلەتكىلى بولمايدۇ. OK ماقۇل The following program is running to prevent the system from hibernate! !سېستىمىنىڭ تىزگىنلەپ قېلىشىنىڭ ئالدىنى ئېلىش ئۈچۈن تۆۋەندىكى پروگرامما ئىجرا بولىۋاتىدۇ The following program is running to prevent the system from suspend! !سېستىمىنىڭ توختىشىنىڭ ئالدىنى ئېلىش ئۈچۈن تۆۋەندىكى پروگرامما ئىجرا قىلىنىۋاتىدۇ The following program is running to prevent the system from logout! سېستىمىنىڭ چېكىنىشىنىڭ ئالدىنى ئېلىش ئۈچۈن تۆۋەندىكى پروگرامما ئىجرا بولىۋاتىدۇ! The following program is running to prevent the system from reboot! !سېستىمىنىڭ قايتا قوزغىلىشىنىڭ ئالدىنى ئېلىش ئۈچۈن تۆۋەندىكى پروگرامما ئىجرا بولىۋاتىدۇ The following program is running to prevent the system from shutting down! !تۆۋەندىكى پروگرامما سىستېمىنىڭ تاقىلىپ قېلىشىنىڭ ئالدىنى ئېلىش ئۈچۈن يۈگۈرۈۋاتىدۇ Still Hibernate يەنىلا مۈگدەش ھالىتىدە Still Suspend يەنىلا توختىتىپ قويۇلغان ھالەتتە Still Reboot يەنىلا قايتا قوزغىتىۋېرىش Still Shutdown يەنىلا تاقاش Cancel ئەمەلدىن قالدۇرۇش some applications are running and they don't want you to do this. بەزى قوللىنىشچان پروگرامما ئىجرا قىلىنىۋاتىدۇ، ئۇلار سىزنىڭ بۇنداق قىلىشىڭىزنى خالىمايدۇ. Still to do! يەنىلا قىلىشقا تىگىشلىك! give up ۋاز كېچىش cancel shutdown 取消了本次注销 canceled this operation بۇ مەشغۇلات ئەمەلدىن قالدۇرۇلدى not respond قوشۇلماسلىق ukui-session ukui- يىغىنى The current user has logged in to the system! Currently, the system does not support more than one user to log in at the same time. Click the button below to log out. نۆۋەتتىكى خېرىدار سىستېمىغا كىرىپ بولدى! نۆۋەتتە، سىستېما كۆپ ئىشلەتكۈچىنىڭ بىرلا ۋاقىتتا كىرىشىنى قوللىمايدۇ. تۆۋەندىكى كۇنۇپكىنى چېكىپ تىزىمدىن ئۆچۈرۈڭ. Tips ئەسكەرتىش Logout Warning 注销提醒 ukui-session-manager/translations/zh_HK.ts0000664000175000017500000004100115252714370017644 0ustar fengfeng MainWindow Form 類型 Switch User 切換使用者 Hibernate 休眠 Suspend 睡眠 Logout 註銷 Reboot 重啟 Shut Down 關機 Lock Screen 鎖屏 cancel 取消 confirm 確認 <html><head/><body><p><br/></p></body></html> <html><head/><body><p><br/></p></body></html> QApplication UKUI session tools, show the shutdown dialog without any arguments. UKUI 工作階段工具,顯示不帶任何參數的關閉對話框。 ukui-session-tools ukui會話工具 Switch the user of this computer. 切換這台計算機的使用者。 UKUI session tools, show the screensave dialog Hibernate this computer. 讓這台電腦休眠。 Suspend this computer. 暫停這台電腦。 Logout this computer. 註銷這台電腦。 Restart this computer. 重啟這台電腦。 Shutdown this computer. 關閉這台電腦。 system-monitor 系統監視器 Switch User 切換使用者 Hibernate 休眠 Suspend 睡眠 Logout 註銷 Reboot 重啟 Log Out 註銷 Restart 重啟 Shut Down 關機 Lock Screen 鎖屏 UpgradeThenRboot 更新並重啟 UpgradeThenShutdown 更新並關機 Turn off your computer, but the app stays open. When the computer is turned on, it can be restored to the state you left. 關閉電腦,但是應用會一直保持打開狀態。 當打開電腦時,可以恢復到你離開的狀態。 The computer stays on, but consumes less power. The app stays open and can quickly wake up and revert to where you left off. 電腦保持開機狀態,但耗電較少。 應用會一直保持打開狀態,可快速喚醒電腦並恢復到你離開的狀態。 The current user logs out of the system, terminates the session, and returns to the login page. 當前使用者從系統中註銷,結束其會話並返回登錄介面。 Close all apps, turn off your computer, and then turn your computer back on. 關閉所有應用,關閉電腦,然後重新打開電腦。 Close all apps, and then shut down your computer. 關閉所有應用,然後關閉電腦。 Multiple users are logged in at the same time.Are you sure you want to close this system? 同時有多個使用者處於登錄狀態,你確定要退出系統嗎? cancel 取消 confirm 確認 (user),ukui-control-center is performing a system update or package installation. (使用者),系統正在進行升級或套件安裝/卸載相關操作。 (user),yhkylin-backup-tools is performing a system backup or restore. (使用者),備份還原工具正在進行備份或還原。 For system security,Reboot、Shutdown、Logout and Hibernate are temporarily unavailable. 為了系統安全,重啟、關機、註銷和休眠功能暫時不可用。 For system security,Reboot、Shutdown and Hibernate are temporarily unavailable. 為了系統安全,重啟、關機和休眠功能暫時不可用。 UKUI Session Manager UKUI 工作階段管理員 QObject is block system 阻止系统 into sleep for reason 休眠,因为 is block system 阻止系统 into sleep for reason 睡眠,因为 Are you sure 你确定 you want to get system into sleep? 要让系统进入休眠吗? Are you sure you want to get system into sleep? 你确定要让系统进入睡眠吗? cancel 取消 confirm 確認 is block system into reboot for reason 阻止系统重启,因为 is block system into shutdown for reason 阻止系统关机,因为 Are you sure you want to reboot? 你确定要重启系统吗? Are you sure you want to shutdown? 你确定要退出系统吗? ukui-session-tools ukui會話工具 Multiple users are logged in at the same time.Are you sure you want to close this system? 同時有多個使用者處於登錄狀態,你確定要退出系統嗎? System update or package installation in progress,this function is temporarily unavailable. 正在進行升級或安裝/卸載(相關操作),這個功能暫時不可用。 System backup or restore in progress,this function is temporarily unavailable. 正在進行系統備份或還原,這個功能暫時不可用。 OK 確定 The following program is running to prevent the system from hibernate! 以下程式正在運行,阻止系統進入休眠! The following program is running to prevent the system from suspend! 以下程式正在運行,阻止系統進入睡眠! The following program is running to prevent the system from logout! 以下程式正在運行,阻止系統註銷! The following program is running to prevent the system from reboot! 以下程式正在運行,阻止系統重啟! The following program is running to prevent the system from shutting down! 以下程式正在運行,阻止系統關機! Still Hibernate 仍然休眠 Still Suspend 仍然睡眠 Still Reboot 仍然重啟 Still Shutdown 仍然關機 Cancel 取消 some applications are running and they don't want you to do this. 一些程式正在運行,而且它不希望你繼續該操作。 Still to do! 仍然執行 give up 放棄 ukui-session 工作階段管理員 The current user has logged in to the system! Currently, the system does not support more than one user to log in at the same time. Click the button below to log out. 當前用戶已經在系統中登錄! 目前系統不支援同時登錄一個以上相同用戶,點擊下方按鈕退出。 canceled this operation 取消了本次操作 not respond 未回應 Tips 溫馨提示 ukui-session-manager/translations/zh_Hant.ts0000664000175000017500000003161715252714370020250 0ustar fengfeng MainWindow Form 類型 Switch User 切換使用者 Hibernate 休眠 Suspend 睡眠 Logout 註銷 Reboot 重啟 Shut Down 關機 Lock Screen 鎖屏 cancel 取消 confirm 確認 <html><head/><body><p><br/></p></body></html> <html><head/><body><p><br/></p></body></html> QApplication UKUI session tools, show the shutdown dialog without any arguments. UKUI 工作階段工具,顯示不帶任何參數的關閉對話框。 Switch the user of this computer. 切換這台計算機的使用者。 Hibernate this computer. 讓這台電腦休眠。 Suspend this computer. 暫停這台電腦。 Logout this computer. 註銷這台電腦。 Restart this computer. 重啟這台電腦。 Shutdown this computer. 關閉這台電腦。 system-monitor 系统监视器 Switch User 切換使用者 Hibernate 休眠 Suspend 睡眠 Logout 註銷 Reboot 重啟 Shut Down 關機 Lock Screen 鎖屏 Multiple users are logged in at the same time.Are you sure you want to close this system? 同時有多個使用者處於登錄狀態,你確定要退出系統嗎? cancel 取消 confirm 確認 (user),ukui-control-center is performing a system update or package installation. (使用者),系統正在進行升級或套件安裝/卸載相關操作。 (user),yhkylin-backup-tools is performing a system backup or restore. (使用者),備份還原工具正在進行備份或還原。 For system security,Reboot、Shutdown、Logout and Hibernate are temporarily unavailable. 為了系統安全,重啟、關機、註銷和休眠功能暫時不可用。 For system security,Reboot、Shutdown and Hibernate are temporarily unavailable. 為了系統安全,重啟、關機和休眠功能暫時不可用。 UKUI Session Manager UKUI 工作階段管理員 QObject is block system 阻止系统 into sleep for reason 休眠,因为 is block system 阻止系统 into sleep for reason 睡眠,因为 Are you sure 你确定 you want to get system into sleep? 要让系统进入休眠吗? Are you sure you want to get system into sleep? 你确定要让系统进入睡眠吗? cancel 取消 confirm 確認 is block system into reboot for reason 阻止系统重启,因为 is block system into shutdown for reason 阻止系统关机,因为 Are you sure you want to reboot? 你确定要重启系统吗? Are you sure you want to shutdown? 你确定要退出系统吗? Multiple users are logged in at the same time.Are you sure you want to close this system? 同時有多個使用者處於登錄狀態,你確定要退出系統嗎? System update or package installation in progress,this function is temporarily unavailable. 正在進行升級或安裝/卸載(相關操作),這個功能暫時不可用。 System backup or restore in progress,this function is temporarily unavailable. 正在進行系統備份或還原,這個功能暫時不可用。 OK 確定 The following program is running to prevent the system from hibernate! 以下程式正在運行,阻止系統進入休眠! The following program is running to prevent the system from suspend! 以下程式正在運行,阻止系統進入睡眠! The following program is running to prevent the system from logout! 以下程式正在運行,阻止系統註銷! The following program is running to prevent the system from reboot! 以下程式正在運行,阻止系統重啟! The following program is running to prevent the system from shutting down! 以下程式正在運行,阻止系統關機! Still Hibernate 仍然休眠 Still Suspend 仍然睡眠 Still Reboot 仍然重啟 Still Shutdown 仍然關機 Cancel 取消 some applications are running and they don't want you to do this. 一些程式正在運行,而且它不希望你繼續該操作。 Still to do! 仍然執行 give up 放棄 ukui-session-manager/translations/fr.ts0000664000175000017500000003315315252714370017261 0ustar fengfeng MainWindow Form Forme Switch User Changer d’utilisateur Hibernate Hiberner Suspend Suspendre Logout Déconnexion Reboot Redémarrer Shut Down Arrêter Lock Screen Écran de verrouillage cancel Annuler confirm confirmer <html><head/><body><p><br/></p></body></html> <html> <head/> <body> <p> <br/> </p> </body> </html> QApplication UKUI session tools, show the shutdown dialog without any arguments. Outils de session UKUI, affiche la boîte de dialogue d’arrêt sans aucun argument. Switch the user of this computer. Changez d’utilisateur pour cet ordinateur. Hibernate this computer. Mettez cet ordinateur en veille prolongée. Suspend this computer. Suspendez cet ordinateur. Logout this computer. Déconnectez-vous de cet ordinateur. Restart this computer. Redémarrez cet ordinateur. Shutdown this computer. Éteignez cet ordinateur. system-monitor 系统监视器 Switch User Changer d’utilisateur Hibernate Hiberner Suspend Suspendre Logout Déconnexion Reboot Redémarrer Shut Down Arrêter Lock Screen Écran de verrouillage Multiple users are logged in at the same time.Are you sure you want to close this system? Plusieurs utilisateurs sont connectés en même temps. Êtes-vous sûr de vouloir fermer ce système ? cancel Annuler confirm confirmer (user),ukui-control-center is performing a system update or package installation. (utilisateur),ukui-control-center effectue une mise à jour du système ou l’installation d’un paquet. (user),yhkylin-backup-tools is performing a system backup or restore. (utilisateur),yhkylin-backup-tools effectue une sauvegarde ou une restauration du système. For system security,Reboot、Shutdown、Logout and Hibernate are temporarily unavailable. Pour des raisons de sécurité du système, Redémarrage, Arrêt, Déconnexion et Mise en veille prolongée sont temporairement indisponibles. For system security,Reboot、Shutdown and Hibernate are temporarily unavailable. Pour la sécurité du système, Redémarrage, Arrêt et Mise en veille prolongée sont temporairement indisponibles. UKUI Session Manager Gestionnaire de session UKUI QObject is block system 阻止系统 into sleep for reason 休眠,因为 is block system 阻止系统 into sleep for reason 睡眠,因为 Are you sure 你确定 you want to get system into sleep? 要让系统进入休眠吗? Are you sure you want to get system into sleep? 你确定要让系统进入睡眠吗? cancel Annuler confirm confirmer is block system into reboot for reason 阻止系统重启,因为 is block system into shutdown for reason 阻止系统关机,因为 Are you sure you want to reboot? 你确定要重启系统吗? Are you sure you want to shutdown? 你确定要退出系统吗? Multiple users are logged in at the same time.Are you sure you want to close this system? Plusieurs utilisateurs sont connectés en même temps. Êtes-vous sûr de vouloir fermer ce système ? System update or package installation in progress,this function is temporarily unavailable. Mise à jour du système ou installation d’un package en cours, cette fonction est temporairement indisponible. System backup or restore in progress,this function is temporarily unavailable. Sauvegarde ou restauration du système en cours, cette fonction est temporairement indisponible. OK D’ACCORD The following program is running to prevent the system from hibernate! Le programme suivant est en cours d’exécution pour empêcher le système de hiberner ! The following program is running to prevent the system from suspend! Le programme suivant est en cours d’exécution pour empêcher le système de se suspendre ! The following program is running to prevent the system from logout! Le programme suivant est en cours d’exécution pour empêcher le système de se déconnecter ! The following program is running to prevent the system from reboot! Le programme suivant est en cours d’exécution pour empêcher le système de redémarrer ! The following program is running to prevent the system from shutting down! Le programme suivant est en cours d’exécution pour empêcher le système de s’arrêter ! Still Hibernate Toujours en hibernation Still Suspend Toujours en suspension Still Reboot Toujours redémarrer Still Shutdown Toujours à l’arrêt Cancel Annuler some applications are running and they don't want you to do this. Certaines applications sont en cours d’exécution et ne veulent pas que vous le fassiez. Still to do! Encore à faire ! give up abandonner ukui-session-manager/translations/ar.ts0000664000175000017500000004310315252714370017250 0ustar fengfeng MainWindow Switch User 切换用户 Hibernate 休眠 Suspend 睡眠 Logout 注销 Reboot 重启 Shut Down 关机 Lock Screen 锁屏 cancel 取消 confirm 确认 QApplication UKUI session tools, show the shutdown dialog without any arguments. أدوات جلسة UKUI ، تظهر مربع حوار إيقاف التشغيل دون أي وسيطات. ukui-session-tools أدوات جلسة UKUI Switch the user of this computer. قم بتبديل مستخدم هذا الكمبيوتر. Hibernate this computer. سبات هذا الكمبيوتر. Suspend this computer. قم بتعليق هذا الكمبيوتر. Logout this computer. قم بتسجيل الخروج من هذا الكمبيوتر. Restart this computer. أعد تشغيل هذا الكمبيوتر. Shutdown this computer. قم بإيقاف تشغيل هذا الكمبيوتر. system-monitor مراقب النظام Switch User تبديل المستخدم Hibernate السبات Suspend تعليق Logout 注销 Reboot 重启 Log Out تسجيل الخروج Restart اعاده تشغيل Shut Down إيقاف التشغيل Lock Screen قفل الشاشة UpgradeThenRboot UpgradeThenRboot UpgradeThenShutdown UpgradeThenShutdown Turn off your computer, but the app stays open. When the computer is turned on, it can be restored to the state you left. قم بإيقاف تشغيل الكمبيوتر، ولكن يظل التطبيق مفتوحا. عند تشغيل الكمبيوتر، يمكن استعادته إلى الحالة التي تركتها The computer stays on, but consumes less power. The app stays open and can quickly wake up and revert to where you left off. يظل الكمبيوتر قيد التشغيل ، لكنه يستهلك طاقة أقل. يظل التطبيق مفتوحا ويمكنه الاستيقاظ بسرعة والعودة إلى حيث توقفت. The current user logs out of the system, terminates the session, and returns to the login page. يقوم المستخدم الحالي بتسجيل الخروج من النظام وإنهاء الجلسة والعودة إلى صفحة تسجيل الدخول. Close all apps, turn off your computer, and then turn your computer back on. أغلق جميع التطبيقات، وقم بإيقاف تشغيل الكمبيوتر، ثم أعد تشغيل الكمبيوتر. Close all apps, and then shut down your computer. أغلق جميع التطبيقات، ثم قم بإيقاف تشغيل الكمبيوتر. Multiple users are logged in at the same time.Are you sure you want to close this system? يتم تسجيل دخول عدة مستخدمين في نفس الوقت. هل أنت متأكد من أنك تريد إغلاق هذا النظام؟ cancel إلغاء الأمر confirm أكد (user),ukui-control-center is performing a system update or package installation. (用户),系统正在进行升级或软件包安装/卸载相关操作。 (user),yhkylin-backup-tools is performing a system backup or restore. (用户),备份还原工具正在进行备份或还原。 For system security,Reboot、Shutdown、Logout and Hibernate are temporarily unavailable. 为了系统安全,重启、关机、注销和休眠功能暂时不可用。 For system security,Reboot、Shutdown and Hibernate are temporarily unavailable. 为了系统安全,重启、关机和休眠功能暂时不可用。 UKUI Session Manager مدير جلسة UKUI QObject is block system 阻止系统 into sleep for reason 休眠,因为 is block system 阻止系统 into sleep for reason 睡眠,因为 Are you sure 你确定 you want to get system into sleep? 要让系统进入休眠吗? Are you sure you want to get system into sleep? 你确定要让系统进入睡眠吗? cancel إلغاء الأمر confirm أكد is block system into reboot for reason 阻止系统重启,因为 is block system into shutdown for reason 阻止系统关机,因为 Are you sure you want to reboot? 你确定要重启系统吗? Are you sure you want to shutdown? 你确定要退出系统吗? ukui-session-tools أدوات جلسة UKUI Multiple users are logged in at the same time.Are you sure you want to close this system? يتم تسجيل دخول عدة مستخدمين في نفس الوقت. هل أنت متأكد من أنك تريد إغلاق هذا النظام؟ System update or package installation in progress,this function is temporarily unavailable. تحديث النظام أو تثبيت الحزمة قيد التقدم ، هذه الوظيفة غير متوفرة مؤقتا. System backup or restore in progress,this function is temporarily unavailable. النسخ الاحتياطي للنظام أو الاستعادة قيد التقدم ، هذه الوظيفة غير متوفرة مؤقتا. OK موافق The following program is running to prevent the system from hibernate! يتم تشغيل البرنامج التالي لمنع النظام من السبات! The following program is running to prevent the system from suspend! يتم تشغيل البرنامج التالي لمنع النظام من التعليق! The following program is running to prevent the system from logout! يتم تشغيل البرنامج التالي لمنع النظام من تسجيل الخروج! The following program is running to prevent the system from reboot! يتم تشغيل البرنامج التالي لمنع النظام من إعادة التشغيل! The following program is running to prevent the system from shutting down! يتم تشغيل البرنامج التالي لمنع النظام من إيقاف التشغيل! Still Hibernate لا يزال السبات Still Suspend لا يزال معلقا Still Reboot لا يزال إعادة التشغيل Still Shutdown لا يزال اغلاق Cancel إلغاء الأمر some applications are running and they don't want you to do this. بعض التطبيقات قيد التشغيل ولا يريدونك القيام بذلك. Still to do! لا يزال يتعين القيام به! give up استسلم cancel shutdown 取消了本次注销 canceled this operation ألغيت هذه العملية not respond لا تستجيب ukui-session جلسة UKUI The current user has logged in to the system! Currently, the system does not support more than one user to log in at the same time. Click the button below to log out. قام المستخدم الحالي بتسجيل الدخول إلى النظام! حاليا ، لا يدعم النظام أكثر من مستخدم واحد لتسجيل الدخول في نفس الوقت. انقر فوق الزر أدناه لتسجيل الخروج. Tips النصائح Logout Warning 注销提醒 ukui-session-manager/translations/kk.ts0000664000175000017500000004525315252714370017263 0ustar fengfeng MainWindow Switch User 切换用户 Hibernate 休眠 Suspend 睡眠 Logout 注销 Reboot 重启 Shut Down 关机 Lock Screen 锁屏 cancel 取消 confirm 确认 QApplication UKUI session tools, show the shutdown dialog without any arguments. UKUI سويلەسۋ قۇرالى ،ەشقانداي پارامەتٸر بولماعان تاقاۋ ديالوگ رامكاسىن كورسەتەدى. ukui-session-tools ukui-جيىن - قۇرالى Switch the user of this computer. نۇ كومپيۋتەرىنڭ ىستەتۋشىنى الماستٸرٸپ بەرەمىز. Hibernate this computer. نۇ كومپيۋتەردى ۇيقتاتىپ قويۋ Suspend this computer. نۇ كومپيۋتەرىن توقتاتٸپ قويۋ Logout this computer. نۇ كومپيۋتەرىنەن شەگىنۋ. Restart this computer. نۇ كومپيۋتەردى قاتە قوزعالتۋ Shutdown this computer. نۇ كومپيۋتەردى قۇلىپتاۋ system-monitor سەستيما كۇزەتۋشى Switch User تۇتٸنۋشٸنٸ سايكەستىرۋ Hibernate ۇيقى Suspend اسىۋ Logout 注销 Reboot 重启 Log Out شەگىنۋ Restart قاتە قوزعالتۋ Shut Down جابۋ Lock Screen ەكٸران قۇلپىلاۋ UpgradeThenRboot ThenBoot نىڭ دارەجەسىن ٶستٸرۋ UpgradeThenShutdown دارەجەسىن وسىرىپ ، سونان تاقاۋ Turn off your computer, but the app stays open. When the computer is turned on, it can be restored to the state you left. كومپيۋتەردى بەكتۋلى، بىراق قولدانعىش پٸروگٸرامما ايقٸن كۇيدە تۇرٸ. كومپيۋتەر اشىلعان كەزدە، ٴسىز ايىرلعانداعى قالىپقا قايتادى. The computer stays on, but consumes less power. The app stays open and can quickly wake up and revert to where you left off. كومپيۋتەر ايقٸن كۇيدە تۇرٸ، بٸراق قۋات سارىپ قىلعانى بٸر دەيىن تومەن بولادٸ، نۇ جيۋ ايقٸن كۇيدە تۇرٸ، تەز جىلدامدىقتا ئويغىتىپ، ٴسىز توقتاعان كەزدەگى قالپىنا كەلتىرگەلى بولادٸ. The current user logs out of the system, terminates the session, and returns to the login page. كەزەكتەگى ابونتتاردى تٸزٸمدەن ٴوشىرۋ سەستيماسى، سويلەسۋدى توقتاتۋ، سونان تٸزٸمدەۇ بٸرلٸككە قايتپ كەلەدى. Close all apps, turn off your computer, and then turn your computer back on. بارلٸق قولدانعىش پرٶگراممالاردى ئېتىۋېتىڭلار، كومپيۋتەردى جابىپ ەتىپ، سونان كومپيۋتەردى قايتادان اشامىز. Close all apps, and then shut down your computer. باردىق ئەپلەرنى بەكىتىپ جىبەرىڭ، اندان كومپىيوتەرىڭىزدى ەتىپ جىبەرىڭ. Multiple users are logged in at the same time.Are you sure you want to close this system? بٸرەۋ ۋاقىتتا كوپ الارمان تٸزٸمدەتٸپ كىرەدى. ٴسىز شىنىندا نۇ سەستامانى جابۋدٸ خالامٴسىز؟ cancel بوس قىلعاننڭ confirm جەزىملەشتۈرمەك (user),ukui-control-center is performing a system update or package installation. (用户),系统正在进行升级或软件包安装/卸载相关操作。 (user),yhkylin-backup-tools is performing a system backup or restore. (用户),备份还原工具正在进行备份或还原。 For system security,Reboot、Shutdown、Logout and Hibernate are temporarily unavailable. 为了系统安全,重启、关机、注销和休眠功能暂时不可用。 For system security,Reboot、Shutdown and Hibernate are temporarily unavailable. 为了系统安全,重启、关机和休眠功能暂时不可用。 UKUI Session Manager UKUI سويلەسۋ باسقارۋشى QObject is block system 阻止系统 into sleep for reason 休眠,因为 is block system 阻止系统 into sleep for reason 睡眠,因为 Are you sure 你确定 you want to get system into sleep? 要让系统进入休眠吗? Are you sure you want to get system into sleep? 你确定要让系统进入睡眠吗? cancel بوس قىلعاننڭ confirm جەزىملەشتۈرمەك is block system into reboot for reason 阻止系统重启,因为 is block system into shutdown for reason 阻止系统关机,因为 Are you sure you want to reboot? 你确定要重启系统吗? Are you sure you want to shutdown? 你确定要退出系统吗? ukui-session-tools ukui-جيىن - قۇرالى Multiple users are logged in at the same time.Are you sure you want to close this system? بٸرەۋ ۋاقىتتا كوپ الارمان تٸزٸمدەتٸپ كىرەدى. ٴسىز شىنىندا نۇ سەستامانى جابۋدٸ خالامٴسىز؟ System update or package installation in progress,this function is temporarily unavailable. سەستيما جاڭالاۋ ياكي بىر جۇرىس تۇسىرۋ جالعاسىپ جاتادى،نۇ رولٸ قەرەللىك ٸستەتكەلٸ بولمايدى. System backup or restore in progress,this function is temporarily unavailable. سەستيما زاپاستاۋ ياكي قالپىنا كەلتىرىلگەن جالعاسىدا نۇ رولٸ قەرەللىك ٸستەتكەلٸ بولمايدى. OK ماقۇل The following program is running to prevent the system from hibernate! !سەستەمانىڭ تىزگىندەپ قىلۋىنىڭ الدٸن الۋ ٷشٸن تومەندەگٸ پٸروگٸرامما اتقار بولٸپ جاتٸر The following program is running to prevent the system from suspend! ! سەستىماسىنىن توختىشىنىڭ الدىن الۇۇ ۉچۉن تۅمۅندۅكۉ پراگرامما اتقارماق قىلىنىپ جاتات The following program is running to prevent the system from logout! سەستىماسىنىن چېكىنىشىنىڭ الدىن الۇۇ ۉچۉن تۅمۅندۅكۉ پراگرامما اتقارماق بولۇپ جاتات! The following program is running to prevent the system from reboot! ! سەستىماسىنىن قايرا قوزغىلىشىنىڭ الدىن الۇۇ ۉچۉن تۅمۅندۅكۉ پراگرامما اتقارماق بولۇپ جاتات The following program is running to prevent the system from shutting down! !تومەندەگٸ پٸروگٸرامما سەستامانىڭ سەكٸرگەلٸ قىلۋىنىڭ الدٸن الۋ ٷشٸن يۈگۈرۈۋاتىدۇ Still Hibernate جانەدە مۈگدەش كۇيىندە Still Suspend جانەدە توقتاتٸپ قويىلعان كۇيدە Still Reboot جانەدە قاتە قوزغىتىۋېرىش Still Shutdown جانەدە تاقاۋ Cancel كۇشىنەن قالدىرۋ some applications are running and they don't want you to do this. بارٸ قولدانعىش پٸروگٸرامما اتقار ورىندالىپ جاتىر، ۇلار سىزدىڭ بۇنداي ورىنداۋىڭىزدى ماقۇلدامايدى. Still to do! جانەدە ىستەۋگە ٴتيٸستٸ! give up ۋاز قايتۋ cancel shutdown 取消了本次注销 canceled this operation نۇ جوبالاۋ كۇشىنەن قالدىرىلدى not respond قوسىلماستىق ukui-session ukui- جيىنى The current user has logged in to the system! Currently, the system does not support more than one user to log in at the same time. Click the button below to log out. كەزەكتەگى قاريدار سەستاماعا كىرىپ قالدى! كەزەكتە، سەستيما كوپ ٸستەتۋشٸنٸڭ بٸرەۋ ۋاقىتتا كىرۋدى قولدامايدى. تومەندەگٸ كىنوپكانى تۇرتىپ تٸزٸمدەن ٶشٸرۋدٸڭ. Tips ەسكەرتپەۋ Logout Warning 注销提醒 ukui-session-manager/translations/ms.ts0000664000175000017500000003715715252714370017301 0ustar fengfeng MainWindow Switch User 切换用户 Hibernate 休眠 Suspend 睡眠 Logout 注销 Reboot 重启 Shut Down 关机 Lock Screen 锁屏 cancel 取消 confirm 确认 QApplication UKUI session tools, show the shutdown dialog without any arguments. ukui-session-tools Switch the user of this computer. UKUI session tools, show the screensave dialog Hibernate this computer. Suspend this computer. Logout this computer. Restart this computer. Shutdown this computer. system-monitor Switch User Hibernate Suspend Logout 注销 Reboot 重启 Log Out Restart Shut Down Lock Screen UpgradeThenRboot UpgradeThenShutdown Turn off your computer, but the app stays open. When the computer is turned on, it can be restored to the state you left. The computer stays on, but consumes less power. The app stays open and can quickly wake up and revert to where you left off. The current user logs out of the system, terminates the session, and returns to the login page. Close all apps, turn off your computer, and then turn your computer back on. Close all apps, and then shut down your computer. Multiple users are logged in at the same time.Are you sure you want to close this system? cancel confirm (user),ukui-control-center is performing a system update or package installation. (用户),系统正在进行升级或软件包安装/卸载相关操作。 (user),yhkylin-backup-tools is performing a system backup or restore. (用户),备份还原工具正在进行备份或还原。 For system security,Reboot、Shutdown、Logout and Hibernate are temporarily unavailable. 为了系统安全,重启、关机、注销和休眠功能暂时不可用。 For system security,Reboot、Shutdown and Hibernate are temporarily unavailable. 为了系统安全,重启、关机和休眠功能暂时不可用。 UKUI Session Manager QObject is block system 阻止系统 into sleep for reason 休眠,因为 is block system 阻止系统 into sleep for reason 睡眠,因为 Are you sure 你确定 you want to get system into sleep? 要让系统进入休眠吗? Are you sure you want to get system into sleep? 你确定要让系统进入睡眠吗? cancel confirm is block system into reboot for reason 阻止系统重启,因为 is block system into shutdown for reason 阻止系统关机,因为 Are you sure you want to reboot? 你确定要重启系统吗? Are you sure you want to shutdown? 你确定要退出系统吗? ukui-session-tools Multiple users are logged in at the same time.Are you sure you want to close this system? System update or package installation in progress,this function is temporarily unavailable. System backup or restore in progress,this function is temporarily unavailable. OK The following program is running to prevent the system from hibernate! The following program is running to prevent the system from suspend! The following program is running to prevent the system from logout! The following program is running to prevent the system from reboot! The following program is running to prevent the system from shutting down! Still Hibernate Still Suspend Still Reboot Still Shutdown Cancel some applications are running and they don't want you to do this. Still to do! give up cancel shutdown 取消了本次注销 canceled this operation not respond ukui-session The current user has logged in to the system! Currently, the system does not support more than one user to log in at the same time. Click the button below to log out. Tips Logout Warning 注销提醒 ukui-session-manager/translations/bo_CN.ts0000664000175000017500000004500615252714370017632 0ustar fengfeng MainWindow Logout ད་ལྟ་རྩིས་ཐེམ་ནས་བསུབ་པ། Reboot བསྐྱར་སློང་། Lock Screen བརྙན་ཡོལ་ཟྭ་རྒྱག cancel ཕྱིར་འཐེན། Hebernate ངལ་གསོ། Switch User སྤྱོད་མཁན་བརྗེ་རེས། confirm གཏན་འཁེལ། Suspend གཉིད་པ། Shut Down སྒོ་རྒྱག་པ། Form རྣམ་པ། Hibernate མལ་གསོ། <html><head/><body><p><br/></p></body></html> <html> <head/> <body> <p> <br/> </p> </body> </html> QApplication (user),yhkylin-backup-tools is performing a system backup or restore. (བཀོལ་མི།)ཆིས་ལིན་གྲབས་ཉར་སླར་གསོ་ཡོ་ཆས་ཀྱིས་གྲབས་ཉར་རམ་སླར་གསོ་བྱེད་སྒང་རེད། (user),ukui-control-center is performing a system update or package installation. (བཀོལ་མི།)ཚོད་འཛིན་ངོས་པང་གིས་བརྒྱུད་ཁོངས་རིམ་སྤོར་རམ་མཉེན་ཆས་ནང་འཇུག་བྱེད་སྒང་རེད། For system security,Reboot、Shutdown、Logout and Hibernate are temporarily unavailable. བརྒྱུད་ཁོངས་བདེ་འཇགས་ལ་དམིགས་ཏེ་སྒོ་བསྐྱར་འབྱེད་དང་སྒོ་གཏན་པ། ཐོ་གསུབ་པ། ངལ་གསོ་བྱེད་པ་སོགས་ཀྱི་བྱེད་ནུས་གནས་སྐབས་རིང་བཀོལ་མི་ཐུབ། Multiple users are logged in at the same time.Are you sure you want to close this system? དུས་མཚུངས་སུ་སྤྱད་མཁན་མང་པོ་ཞིག་ཐོ་འགོད་ཀྱི་རྣམ་པར་གནས་ཡོད་པས་ཁྱོད་ཀྱིས་མ་ལག་ལས་ཕྱིར་འབུད་རྒྱ་ཡིན་པ་ཁག་ཐེག་བྱེད་ཐུབ་བམ། For system security,Reboot、Shutdown and Hibernate are temporarily unavailable. བརྒྱུད་ཁོངས་བདེ་འཇགས་ལ་དམིགས་ཏེ་སྒོ་བསྐྱར་འབྱེད་དང་སྒོ་གཏན་པ། ཐོབ་བསུབ་པ། ངལ་གསོ་བྱེད་པ་སོགས་ཀྱི་བྱེད་ནུས་གནས་སྐབས་རིང་བཀོལ་མི་ཐུབ། UKUI session tools, show the shutdown dialog without any arguments. UKUIཚོགས་འདུའི་ཡོ་བྱད་ལ་རྩོད་གླེང་ཅི་ཡང་མེད་པར་ལས་མཚམས་འཇོག་པའི་གླེང་མོལ་མངོན་པར་བྱས་ཡོད། Switch the user of this computer. རྩིས་འཁོར་འདིའི་སྤྱོད་མཁན་བརྗེ་རེས་བྱེད་དགོས། Hibernate this computer. རྩིས་འཁོར་འདི་གཉིད་དུ་བཅུག Suspend this computer. རྩིས་འཁོར་འདི་མཚམས་བཞག Logout this computer. རྩིས་འཁོར་འདི་ཐོ་འགོད་བྱེད་དགོས། Restart this computer. རྩིས་འཁོར་འདི་བསྐྱར་དུ་འགོ་བརྩམས། Shutdown this computer. གློག་ཀླད་འདི་སྒོ་རྒྱག་དགོས། Switch User གློག་སྒོ་འབྱེད་པའི་སྤྱོད་མཁན Hibernate མངལ་གནས་སུ་སྦས་པ། Suspend ལས་མཚམས་བཞག་པ། Logout དོར་བ། Reboot བསྐྱར་དུ་འཁོར་བ། Shut Down ལས་མཚམས་འཇོག Lock Screen བརྙན་ཡོལ་ཁ་རྒྱབ། cancel དོར་བ། confirm ཐག་ཆོད། UKUI Session Manager UKUIཚོགས་འདུའི་སྤྱི་གཉེར་བ། ukui-session-tools ukuiཚོགས་འདུའི་ཡོ་བྱད། system-monitor མ་ལག་ལྟ་ཞིབ་ཚད་ལེན Log Out དོར་བ Restart ཡང་བསྐྱར་འགོ་འཛུགས་ UpgradeThenRboot རིམ་པ་འཕར་བའི་མི་ UpgradeThenShutdown རིམ་པ་འཕར་བའི་དུས་ཚོད། Turn off your computer, but the app stays open. When the computer is turned on, it can be restored to the state you left. རྩིས་འཁོར་སྒོ་རྒྱག་པ་དང་། འོན་ཀྱང་ཉེར་སྤྱོད་གོ་རིམ་རྒྱུན་འཁྱོངས་བྱེད་པའི་རྣམ་པ་རྒྱུན་འཁྱོངས་བྱ་དགོས། རྩིས་འཁོར་གྱི་ཁ་ཕྱེ་སྐབས་དེས་ཁྱེད་རང་ཁ་བྲལ་བའི་རྣམ་པ་སླར་གསོ་བྱེད་ཐུབ། The computer stays on, but consumes less power. The app stays open and can quickly wake up and revert to where you left off. རྩིས་འཁོར་གྱི་ཁ་ཕྱེ་བའི་རྣམ་པ་རྒྱུན་འཁྱོངས་བྱས་མོད། འོན་ཀྱང་ཟད་གྲོན་བྱས་པའི་གློག་ཚད་ཅུང་ཉུང་། ཉེར་སྤྱོད་གོ་རིམ་འདིས་ཁ་ཕྱེ་ནས་མྱུར་དུ་གཉིད་ལས་སད་པ་མ་ཟད་ཁྱེད་རང་ཁ་བྲལ་བའི་གནས་སུ་སླར་གསོ་བྱེད་ཐུབ། The current user logs out of the system, terminates the session, and returns to the login page. མིག་སྔར་སྤྱོད་མཁན་གྱི་ཐོ་ཁོངས་ནས་སུབ་པ་དང་། ཚོགས་འདུ་གྲོལ་མཚམས་བཞག་རྗེས་ཤོག་ངོས་སུ་འགོད་དགོས། Close all apps, turn off your computer, and then turn your computer back on. བཀོལ་སྤྱོད་ཡོད་ཚད་སྒོ་རྒྱག་པ་དང་། རྩིས་འཁོར་སྒོ་རྒྱག་པ། དེ་ནས་ཡང་བསྐྱར་རྩིས་འཁོར་གྱི་ཁ་ཕྱེ་བ་རེད། Close all apps, and then shut down your computer. བཀོལ་སྤྱོད་ཡོད་ཚད་སྒོ་བརྒྱབ་ནས་རྩིས་འཁོར་སྒོ་རྒྱག་དགོས། QObject Still to do! ལག་བསྟར་བྱེད་པ། some applications are running and they dont want you to do this. བྱ་རིམ་རེ་འགའ་འཁོར་སྐྱོད་བྱེད་སྒང་ཡིན་པར་མ་ཟད། དེས་བྱ་བ་འདི་མི་བསྒྲུབ་པའི་རེ་འདོན་བྱ་བཞིག་འདུག System update or package installation in progress,this function is temporarily unavailable. རིམ་པ་འཕར་བའམ་ཡང་ན་སྒྲིག་སྦྱོར་བྱེད་བཞིན་ཡོད།(འབྲེལ་ཡོད་བཀོལ་སྤྱོད་)བྱེད་ནུས་འདི་གནས་སྐབས་སུ་བཀོལ་མི་རུང་། System backup or restore in progress,this function is temporarily unavailable. བརྒྱུད་ཁོངས་གྲབས་ཉར་རམ་སླར་གསོ་བྱེད་སྒང་ཡིན་པས། བྱེད་ནུས་འདི་གནས་སྐབས་རིང་བཀོལ་མི་ཐུབ། cancel དོར་བ། notice གསལ་བརྡ། confirm ཐག་ཆོད། give up བློས་གཏང་བ། Multiple users are logged in at the same time.Are you sure you want to close this system? དུས་མཚུངས་སུ་སྤྱད་མཁན་མང་པོ་ཞིག་ཐོ་འགོད་ཀྱི་རྣམ་པར་གནས་ཡོད་པས་ཁྱོད་ཀྱིས་མ་ལག་ལས་ཕྱིར་འབུད་རྒྱ་ཡིན་པ་ཁག་ཐེག་བྱེད་ཐུབ་བམ། OK གཏན་འཁེལ The following program is running to prevent the system from hibernate! གཤམ་གྱི་བྱ་རིམ་འཁོར་སྐྱོད་བྱེད་བཞིན་ཡོད་པས་མ་ལག་གཉིད་དུ་ཡུར་བར་བཀག་འགོག་བྱེད་བཞིན་ཡོད། The following program is running to prevent the system from suspend! གཤམ་གྱི་གོ་རིམ་ནི་མ་ལག་གནས་སྐབས་མཚམས་འཇོག་པར་བཀག་འགོག་བྱེད་པའི་ཆེད་དུ་ཡིན། The following program is running to prevent the system from logout! གཤམ་གྱི་གོ་རིམ་ནི་མ་ལག་གིས་ཐོ་འགོད་བྱེད་པར་བཀག་འགོག་བྱེད་པའི་ཆེད་དུ་ཡིན། The following program is running to prevent the system from reboot! གཤམ་གྱི་གོ་རིམ་ནི་མ་ལག་བསྐྱར་དུ་འབྱུང་བར་སྔོན་འགོག་བྱེད་ཆེད་ཡིན། The following program is running to prevent the system from shutting down! གཤམ་གྱི་གོ་རིམ་ནི་མ་ལག་གི་སྒོ་རྒྱག་པར་བཀག་འགོག་བྱེད་པའི་ཆེད་དུ་ཡིན། Still Hibernate སྔར་བཞིན་མལ་གསོ་རྒྱག་པ། Still Suspend སྔར་བཞིན་གཉིད་པ། Still Reboot སྔར་བཞིན་བསྐྱར་དུ་བྱུང་བ་རེད། Still Shutdown སྔར་བཞིན་ལས་མཚམས་བཞག་པ། Cancel མེད་པར་བཟོ་དགོས some applications are running and they don't want you to do this. བརྒྱུད་རིམ་ཁ་ཤས་འཁོར་སྐྱོད་བྱེད་བཞིན་ཡོད་པ་མ་ཟད་དེས་ཁྱོད་ཀྱིས་མུ་མཐུད་དུ་བཀོལ་སྤྱོད་བྱེད་པར་རེ་བ་མི་བྱེད། canceled this operation ཐེངས་འདིའི་བྱ་སྤྱོད་མེད་པར་བཟོས། not respond ལན་མི་འདེབས། ukui-session ཝུའུ་ཁི་ལན་གྱི་ཚོགས་འདུ། Tips སྣེ་སྟོན། ukui-session-tools ukuiཚོགས་འདུའི་ཡོ་བྱད། The current user has logged in to the system! Currently, the system does not support more than one user to log in at the same time. Click the button below to log out. མིག་སྔར་སྤྱོད་མཁན་གྱིས་མ་ལག་ཐོ་འགོད་བྱས་ཡོད། མིག་སྔར་མ་ལག་གིས་སྤྱོད་མཁན་མང་པོར་རྒྱབ་སྐྱོར་མི་བྱེད་པ་དང་དུས་མཚུངས་སུ་ཐོ་འགོད་བྱས གཤམ་གྱི་སྒྲོག་གུ་མནན་ནས་སུབ་དགོས། ukui-session-manager/translations/vi.ts0000664000175000017500000004165215252714370017273 0ustar fengfeng MainWindow Switch User 切换用户 Hibernate 休眠 Suspend 睡眠 Logout 注销 Reboot 重启 Shut Down 关机 Lock Screen 锁屏 cancel 取消 confirm 确认 QApplication UKUI session tools, show the shutdown dialog without any arguments. Công cụ phiên UKUI, hiển thị hộp thoại tắt máy mà không có bất kỳ đối số nào. ukui-session-tools ukui-session-tools Switch the user of this computer. Chuyển đổi người dùng của máy tính này. Hibernate this computer. Ngủ đông máy tính này. Suspend this computer. Tạm ngưng máy tính này. Logout this computer. Đăng xuất máy tính này. Restart this computer. Khởi động lại máy tính này. Shutdown this computer. Tắt máy tính này. system-monitor giám sát hệ thống Switch User Chuyển đổi người dùng Hibernate Ngủ đông Suspend Đình chỉ Logout 注销 Reboot 重启 Log Out Đăng xuất Restart Khởi động lại Shut Down Dừng lại Lock Screen Màn hình khóa UpgradeThenRboot UpgradeThenRboot UpgradeThenShutdown Nâng cấpSau đóTắt máy Turn off your computer, but the app stays open. When the computer is turned on, it can be restored to the state you left. Tắt máy tính của bạn nhưng ứng dụng vẫn mở. Khi máy tính được bật, nó có thể được khôi phục về trạng thái bạn đã cũ. The computer stays on, but consumes less power. The app stays open and can quickly wake up and revert to where you left off. Máy tính vẫn hoạt động, nhưng tiêu thụ ít điện năng hơn. Ứng dụng vẫn mở và có thể nhanh chóng đánh thức và hoàn nguyên về nơi bạn đã dừng lại. The current user logs out of the system, terminates the session, and returns to the login page. Người dùng hiện tại đăng xuất khỏi hệ thống, kết thúc phiên và quay lại trang đăng nhập. Close all apps, turn off your computer, and then turn your computer back on. Đóng tất cả các ứng dụng, tắt máy tính rồi bật lại máy tính. Close all apps, and then shut down your computer. Đóng tất cả các ứng dụng, sau đó tắt máy tính của bạn. Multiple users are logged in at the same time.Are you sure you want to close this system? Nhiều người dùng được đăng nhập cùng một lúc. Bạn có chắc chắn muốn đóng hệ thống này không? cancel hủy confirm xác nhận (user),ukui-control-center is performing a system update or package installation. (用户),系统正在进行升级或软件包安装/卸载相关操作。 (user),yhkylin-backup-tools is performing a system backup or restore. (用户),备份还原工具正在进行备份或还原。 For system security,Reboot、Shutdown、Logout and Hibernate are temporarily unavailable. 为了系统安全,重启、关机、注销和休眠功能暂时不可用。 For system security,Reboot、Shutdown and Hibernate are temporarily unavailable. 为了系统安全,重启、关机和休眠功能暂时不可用。 UKUI Session Manager Quản lý phiên UKUI QObject is block system 阻止系统 into sleep for reason 休眠,因为 is block system 阻止系统 into sleep for reason 睡眠,因为 Are you sure 你确定 you want to get system into sleep? 要让系统进入休眠吗? Are you sure you want to get system into sleep? 你确定要让系统进入睡眠吗? cancel hủy confirm xác nhận is block system into reboot for reason 阻止系统重启,因为 is block system into shutdown for reason 阻止系统关机,因为 Are you sure you want to reboot? 你确定要重启系统吗? Are you sure you want to shutdown? 你确定要退出系统吗? ukui-session-tools ukui-session-tools Multiple users are logged in at the same time.Are you sure you want to close this system? Nhiều người dùng được đăng nhập cùng một lúc. Bạn có chắc chắn muốn đóng hệ thống này không? System update or package installation in progress,this function is temporarily unavailable. Đang cập nhật hệ thống hoặc cài đặt gói, chức năng này tạm thời không khả dụng. System backup or restore in progress,this function is temporarily unavailable. Đang sao lưu hoặc khôi phục hệ thống, chức năng này tạm thời không khả dụng. OK Xác định The following program is running to prevent the system from hibernate! Chương trình sau đây đang chạy để ngăn hệ thống ngủ đông! The following program is running to prevent the system from suspend! Chương trình sau đây đang chạy để ngăn hệ thống bị tạm ngưng! The following program is running to prevent the system from logout! Chương trình sau đây đang chạy để ngăn hệ thống đăng xuất! The following program is running to prevent the system from reboot! Chương trình sau đang chạy để ngăn hệ thống khởi động lại! The following program is running to prevent the system from shutting down! Chương trình sau đây đang chạy để ngăn hệ thống tắt! Still Hibernate Vẫn ngủ đông Still Suspend Vẫn tạm ngưng Still Reboot Vẫn khởi động lại Still Shutdown Vẫn tắt máy Cancel Hủy some applications are running and they don't want you to do this. Một số ứng dụng đang chạy và họ không muốn bạn làm điều này. Still to do! Vẫn phải làm! give up từ cancel shutdown 取消了本次注销 canceled this operation đã hủy hoạt động này not respond không trả lời ukui-session Buổi học ukui The current user has logged in to the system! Currently, the system does not support more than one user to log in at the same time. Click the button below to log out. Người dùng hiện tại đã đăng nhập vào hệ thống! Hiện tại, hệ thống không hỗ trợ nhiều hơn một người dùng đăng nhập cùng lúc. Nhấp vào nút bên dưới để đăng xuất. Tips Mẹo Logout Warning 注销提醒 ukui-session-manager/translations/mn.ts0000664000175000017500000005650515252714370017272 0ustar fengfeng MainWindow Form ᠬᠡᠯᠪᠡᠷᠢ ᠮᠠᠶᠢᠭ Switch User ᠬᠡᠷᠡᠭᠯᠡᠭᠴᠢ᠎ᠶᠢ ᠰᠤᠯᠢᠬᠤ Hibernate ᠢᠴᠡᠬᠡᠯᠡᠬᠦ᠌ Suspend ᠤᠨᠳᠠᠬᠤ Logout ᠬᠦᠴᠦᠨ ᠦᠬᠡᠢ ᠪᠤᠯᠭᠠᠬᠤ Reboot ᠳᠠᠬᠢᠵᠤ ᠡᠬᠢᠯᠡᠬᠦᠯᠬᠦ᠌ Shut Down ᠬᠠᠭᠠᠬᠤ Lock Screen ᠳᠡᠯᠭᠡᠴᠡ ᠤᠨᠢᠰᠤᠯᠠᠬᠤ cancel ᠦᠬᠡᠢᠰᠭᠡᠬᠦ᠌ confirm ᠪᠠᠳᠤᠯᠠᠬᠤ <html><head/><body><p><br/></p></body></html> <html><head/><body><p><br/></p></body></html> QApplication UKUI session tools, show the shutdown dialog without any arguments. UKUI ᠶᠠᠷᠢᠯᠴᠠᠭᠠᠨ᠎ᠤ ᠪᠠᠭᠠᠵᠢ ᠂ ᠶᠠᠮᠠᠷ ᠴᠤ᠌ ᠫᠠᠷᠠᠮᠸᠲᠷ ᠦᠬᠡᠢ ᠬᠠᠭᠠᠭᠰᠠᠨ ᠶᠠᠷᠢᠯᠴᠠᠭᠠᠨ᠎ᠤ ᠴᠤᠩᠬᠤ᠎ᠶᠢ ᠢᠯᠡᠷᠡᠬᠦᠯᠦᠨ᠎ᠡ᠃ ukui-session-tools Ukui ᠶᠠᠷᠢᠯᠴᠠᠭ᠎ᠠ ᠵᠢᠨ ᠪᠠᠭᠠᠵᠢ Switch the user of this computer. ᠲᠤᠰ ᠺᠤᠮᠫᠢᠦᠲᠸᠷ᠎ᠤᠨ ᠬᠡᠷᠡᠭᠯᠡᠭᠴᠢ᠎ᠶᠢ ᠰᠤᠯᠢᠬᠤ᠄ Hibernate this computer. ᠲᠤᠰ ᠺᠤᠮᠫᠢᠦᠲᠸᠷ᠎ᠢ ᠢᠴᠡᠬᠡᠯᠡᠬᠦᠯᠦᠬᠡᠷᠡᠢ᠃ Suspend this computer. ᠲᠤᠰ ᠺᠤᠮᠫᠢᠦᠲᠸᠷ᠎ᠢ ᠳᠦᠷ ᠵᠤᠭᠰᠤᠭᠠᠨ᠎ᠠ᠃ Logout this computer. ᠡᠨᠡ ᠺᠤᠮᠫᠢᠦᠲᠸᠷ᠎ᠢ ᠬᠦᠴᠦᠨ ᠦᠬᠡᠢ ᠪᠤᠯᠭᠠᠨ᠎ᠠ Restart this computer. ᠡᠨᠡ ᠺᠤᠮᠫᠢᠦᠲᠸᠷ᠎ᠢ ᠳᠠᠬᠢᠵᠤ ᠡᠬᠢᠯᠡᠬᠦᠯᠦᠨ᠎ᠡ Shutdown this computer. ᠡᠨᠡ ᠺᠤᠮᠫᠢᠦᠲᠸᠷ᠎ᠢ ᠬᠠᠭᠠᠨ᠎ᠠ᠃ system-monitor ᠰᠢᠰᠲ᠋ᠧᠮ ᠤ᠋ᠨ ᠬᠢᠨᠠᠭᠤᠷ Switch User ᠬᠡᠷᠡᠭᠯᠡᠭᠴᠢ᠎ᠶᠢ ᠰᠤᠯᠢᠬᠤ Hibernate ᠢᠴᠡᠬᠡᠯᠡᠬᠦ᠌ Suspend ᠨᠤᠢᠷᠮᠤᠭᠯᠠᠬᠤ Logout ᠬᠦᠴᠦᠨ ᠦᠬᠡᠢ ᠪᠤᠯᠭᠠᠬᠤ Reboot ᠳᠠᠬᠢᠵᠤ ᠡᠬᠢᠯᠡᠬᠦᠯᠬᠦ᠌ Log Out ᠳᠠᠩᠰᠠᠨ ᠡᠴᠡ ᠬᠠᠰᠤᠬᠤ Restart ᠳᠠᠬᠢᠨ ᠡᠬᠢᠯᠡᠬᠦᠯᠬᠦ Shut Down ᠮᠠᠰᠢᠨ ᠤᠨᠳᠠᠷᠠᠭᠠᠬᠤ Lock Screen ᠳᠡᠯᠭᠡᠴᠡ ᠣᠨᠢᠰᠤᠯᠠᠬᠤ UpgradeThenRboot ᠰᠢᠨᠡᠴᠢᠯᠡᠵᠤ ᠳᠠᠬᠢᠨ ᠡᠬᠢᠯᠡᠬᠦᠯᠬᠦ UpgradeThenShutdown ᠰᠢᠨᠡᠴᠢᠯᠡᠵᠤ ᠮᠠᠰᠢᠨ ᠤᠨᠳᠠᠷᠠᠭᠠᠬᠤ Turn off your computer, but the app stays open. When the computer is turned on, it can be restored to the state you left. ᠺᠣᠮᠫᠢᠦ᠋ᠲ᠋ᠧᠷ᠎ᠢ᠋ ᠬᠠᠭᠠᠪᠠᠯ᠂ ᠭᠡᠪᠡᠴᠦ ᠬᠡᠷᠡᠭᠯᠡᠯᠲᠡ ᠨᠢ ᠨᠡᠢᠳᠡᠮ ᠬᠡᠪ᠎ᠦ᠋ᠨ ᠪᠠᠢᠳᠠᠯ᠎ᠲᠠᠢ ᠪᠣᠯᠤᠨ᠎ᠠ᠃ ᠺᠣᠮᠫᠢᠦ᠋ᠲ᠋ᠧᠷ᠎ᠢ᠋ ᠨᠡᠭᠡᠭᠡᠬᠦ ᠦᠶ᠎ᠡ᠎ᠳ᠋ᠦ᠍᠂ ᠴᠢᠨᠦ ᠰᠠᠯᠤᠭᠰᠠᠨ ᠪᠠᠢᠳᠠᠯ᠎ᠳ᠋ᠤ᠌ ᠣᠷᠣᠵᠤ ᠪᠣᠯᠤᠨ᠎ᠠ᠃ The computer stays on, but consumes less power. The app stays open and can quickly wake up and revert to where you left off. ᠺᠣᠮᠫᠢᠦ᠋ᠲ᠋ᠧᠷ ᠨᠡᠭᠡᠭᠡᠵᠦ ᠪᠠᠢᠬᠤ ᠪᠠᠢᠳᠠᠯ᠎ᠢ᠋ᠶ᠋ᠠᠨ ᠪᠠᠲᠤᠯᠠᠨ᠎ᠠ᠂ ᠭᠡᠪᠡᠴᠦ ᠴᠠᠬᠢᠯᠭᠠᠨ ᠨᠡᠯᠢᠶᠡᠳ ᠪᠠᠭ᠎ᠠ ᠵᠠᠷᠤᠴᠠᠭᠤᠯᠤᠨ᠎ᠠ᠃ ᠬᠡᠷᠡᠭᠯᠡᠬᠦ ᠨᠢ ᠨᠡᠢᠳᠡᠮ ᠨᠡᠭᠡᠭᠡᠬᠦ ᠪᠠᠢᠳᠠᠯ᠎ᠢ᠋ᠶ᠋ᠠᠨ ᠪᠠᠲᠤᠯᠠᠵᠤ ᠂ ᠺᠣᠮᠫᠢᠦ᠋ᠲ᠋ᠧᠷ᠎ᠢ᠋ ᠲᠦᠷᠭᠡᠨ ᠰᠡᠷᠡᠬᠦ᠎ᠶ᠋ᠢᠨ ᠬᠠᠮᠲᠤ ᠲᠠᠨ᠎ᠤ᠋ ᠰᠠᠯᠬᠤ ᠪᠠᠢᠳᠠᠯ᠎ᠳ᠋ᠤ᠌ ᠰᠡᠷᠭᠦᠭᠡᠨ᠎ᠡ᠃ The current user logs out of the system, terminates the session, and returns to the login page. ᠣᠳᠣᠬᠠᠨ ᠤ᠋ ᠬᠡᠷᠡᠭᠯᠡᠭᠴᠢ ᠰᠢᠰᠲ᠋ᠧᠮ ᠡᠴᠡ ᠬᠠᠰᠤᠭᠳᠠᠭᠰᠠᠨ᠂ ᠳᠡᠬᠦᠨ ᠤ᠋ ᠶᠠᠷᠢᠯᠴᠠᠭ᠎ᠠ ᠵᠢ ᠳᠠᠭᠤᠰᠬᠠᠵᠤ ᠨᠡᠪᠳᠡᠷᠡᠬᠦ ᠵᠠᠭᠠᠭ ᠭᠠᠳᠠᠷᠢᠬᠤ ᠳ᠋ᠤ᠌ ᠪᠤᠴᠠᠭᠠᠷᠠᠢ᠃ Close all apps, turn off your computer, and then turn your computer back on. ᠪᠦᠬᠦ ᠬᠡᠷᠡᠭᠯᠡᠭᠡ ᠵᠢ ᠬᠠᠭᠠᠠᠵᠤ᠂ ᠺᠣᠮᠫᠢᠦ᠋ᠲ᠋ᠧᠷ ᠢ᠋ ᠬᠠᠭᠠᠠᠵᠤ᠂ ᠳᠠᠷᠠᠭ᠎ᠠ ᠨᠢ ᠺᠣᠮᠫᠢᠦ᠋ᠲ᠋ᠧᠷ ᠢ᠋ ᠳᠠᠬᠢᠵᠤ ᠨᠡᠬᠡᠬᠡᠷᠡᠢ᠃ Close all apps, and then shut down your computer. ᠪᠦᠬᠦ ᠬᠡᠷᠡᠭᠯᠡᠭᠡ ᠵᠢ ᠬᠠᠭᠠᠠᠵᠤ᠂ ᠳᠠᠷᠠᠭ᠎ᠠ ᠨᠢ ᠺᠣᠮᠫᠢᠦ᠋ᠲ᠋ᠧᠷ ᠢ᠋ ᠬᠠᠭᠠᠭᠠᠷᠠᠢ᠃ Multiple users are logged in at the same time.Are you sure you want to close this system? ᠬᠡᠳᠦ ᠬᠡᠳᠦᠨ ᠬᠡᠷᠡᠭᠯᠡᠭᠴᠢ ᠵᠡᠷᠭᠡ ᠪᠡᠷ ᠨᠡᠪᠳᠡᠷᠡᠵᠤ ᠪᠠᠢᠬᠤ ᠳᠦᠯᠦᠪ ᠲᠠᠢ᠂ ᠲᠠ ᠱᠢᠰᠲ᠋ᠧᠮ᠎ᠡᠴᠡ ᠪᠤᠴᠠᠵᠤ ᠭᠠᠷᠬᠤ ᠤᠤ? cancel ᠦᠬᠡᠢᠰᠬᠡᠬᠦ confirm ᠪᠠᠳᠤᠯᠠᠬᠤ (user),ukui-control-center is performing a system update or package installation. ( ᠬᠡᠷᠡᠭᠯᠡᠭᠴᠢ) ᠂ ᠱᠢᠰᠲ᠋ᠧᠮ ᠶᠠᠭ ᠰᠠᠢᠬᠠᠨ ᠳᠡᠰ ᠳᠡᠪᠱᠢᠬᠦ᠌ ᠪᠤᠶᠤᠰᠤᠹᠲ᠎ᠤᠨ ᠪᠠᠭᠯᠠᠭ᠎ᠠ᠎ᠶᠢ ᠤᠭᠰᠠᠷᠠᠬᠤ/ᠪᠠᠭᠤᠯᠭᠠᠬᠤ ᠬᠠᠮᠢᠶᠠᠳᠠᠢ ᠠᠵᠢᠯᠯᠠᠬᠤᠢ᠎ᠶᠢ ᠬᠦᠢᠴᠡᠳᠭᠡᠵᠤ ᠪᠠᠢᠨ᠎ᠠ᠃ (user),yhkylin-backup-tools is performing a system backup or restore. ( ᠬᠡᠷᠡᠭᠯᠡᠭᠴᠢ) ᠂ᠬᠤᠪᠢᠯᠪᠤᠷᠢ᠎ᠶᠢ ᠬᠡᠪ᠎ᠲᠦ᠍ ᠨᠢ ᠤᠷᠤᠭᠤᠯᠬᠤ ᠪᠠᠭᠠᠵᠢ ᠶᠠᠭ ᠰᠠᠢᠬᠠᠨᠬᠠᠭᠤᠯᠤᠨ ᠬᠠᠳᠠᠭᠠᠯᠠᠬᠤ ᠪᠤᠶᠤ ᠬᠡᠪ᠎ᠲᠦ᠍ ᠨᠢ ᠤᠷᠤᠭᠤᠯᠵᠤ ᠪᠠᠢᠨ᠎ᠠ᠃ For system security,Reboot、Shutdown、Logout and Hibernate are temporarily unavailable. ᠱᠢᠰᠲ᠋ᠧᠮ᠎ᠦᠨ ᠠᠶᠤᠯᠬᠦᠢ᠎ᠶᠢᠨ ᠳᠦᠯᠦᠬᠡ ᠳᠠᠬᠢᠵᠤ ᠡᠬᠢᠯᠡᠬᠦᠯᠬᠦ᠌ ᠂ ᠬᠠᠭᠠᠬᠤ ᠂ ᠬᠦᠴᠦᠨ ᠦᠬᠡᠢ ᠪᠤᠯᠭᠠᠬᠤ ᠪᠤᠯᠤᠨ ᠢᠴᠡᠬᠡᠯᠡᠬᠦ᠌ ᠴᠢᠳᠠᠪᠬᠢ᠎ᠶᠢ ᠲᠦᠷ ᠬᠡᠷᠡᠭᠯᠡᠵᠦ᠍ ᠪᠤᠯᠬᠤ ᠦᠬᠡᠢ᠃ For system security,Reboot、Shutdown and Hibernate are temporarily unavailable. ᠱᠢᠰᠲ᠋ᠧᠮ᠎ᠦᠨ ᠠᠶᠤᠯᠬᠦᠢ᠎ᠶᠢᠨ ᠳᠦᠯᠦᠬᠡ ᠳᠠᠬᠢᠵᠤ ᠡᠬᠢᠯᠡᠬᠦᠯᠬᠦ᠌᠂ᠬᠠᠭᠠᠬᠤ ᠪᠤᠯᠤᠨ ᠢᠴᠡᠬᠡᠯᠡᠬᠦ᠌ ᠴᠢᠳᠠᠪᠬᠢ᠎ᠶᠢ ᠲᠦᠷ ᠬᠡᠷᠡᠭᠯᠡᠵᠦ᠍ ᠪᠤᠯᠬᠤ ᠦᠬᠡᠢ᠃ UKUI Session Manager ᠶᠠᠷᠢᠯᠴᠠᠭᠠᠨ᠎ᠤ ᠬᠠᠮᠢᠶᠠᠷᠤᠭᠴᠢ QObject is block system 阻止系统 into sleep for reason 休眠,因为 is block system 阻止系统 into sleep for reason 睡眠,因为 Are you sure 你确定 you want to get system into sleep? 要让系统进入休眠吗? Are you sure you want to get system into sleep? 你确定要让系统进入睡眠吗? cancel ᠦᠬᠡᠢᠰᠬᠡᠬᠦ confirm ᠪᠠᠳᠤᠯᠠᠬᠤ is block system into reboot for reason 阻止系统重启,因为 is block system into shutdown for reason 阻止系统关机,因为 Are you sure you want to reboot? 你确定要重启系统吗? Are you sure you want to shutdown? 你确定要退出系统吗? conform ᠵᠢᠷᠤᠮᠯᠠᠬᠤ ᠬᠡᠷᠡᠭᠲᠡᠶ ᠃ ukui-session-tools Ukui ᠶᠠᠷᠢᠯᠴᠠᠭ᠎ᠠ ᠵᠢᠨ ᠪᠠᠭᠠᠵᠢ Multiple users are logged in at the same time.Are you sure you want to close this system? ᠬᠡᠳᠦ ᠬᠡᠳᠦᠨ ᠬᠡᠷᠡᠭᠯᠡᠭᠴᠢ ᠵᠡᠷᠭᠡ ᠪᠡᠷ ᠨᠡᠪᠳᠡᠷᠡᠵᠤ ᠪᠠᠢᠬᠤ ᠳᠦᠯᠦᠪ ᠲᠠᠢ᠂ ᠲᠠ ᠱᠢᠰᠲ᠋ᠧᠮ᠎ᠡᠴᠡ ᠪᠤᠴᠠᠵᠤ ᠭᠠᠷᠬᠤ ᠤᠤ? System update or package installation in progress,this function is temporarily unavailable. ᠤᠳᠤ ᠶᠠᠭ ᠳᠡᠰ ᠳᠡᠪᠰᠢᠬᠦ ᠪᠤᠶᠤ ᠤᠭᠰᠠᠷᠠᠵᠤ\ ᠪᠠᠭᠤᠯᠭᠠᠵᠤ( ᠬᠠᠮᠢᠶᠠᠳᠠᠢ ᠠᠵᠢᠯᠯᠠᠬᠤᠢ) ᠪᠠᠢᠨ᠎ᠠ᠂ ᠲᠤᠰ ᠴᠢᠳᠠᠪᠬᠢ ᠵᠢ ᠲᠦᠷ ᠬᠡᠷᠡᠭᠯᠡᠵᠤ ᠪᠣᠯᠬᠤ ᠥᠬᠡᠢ᠃ System backup or restore in progress,this function is temporarily unavailable. ᠰᠢᠰᠲ᠋ᠧᠮ ᠢ᠋ ᠨᠥᠭᠡᠴᠡᠯᠡᠬᠦ ᠪᠤᠶᠤ ᠡᠬᠡᠬᠦᠯᠵᠤ ᠪᠠᠢᠨ᠎ᠠ᠂ ᠲᠤᠰ ᠴᠢᠳᠠᠪᠬᠢ ᠵᠢ ᠲᠦᠷ ᠬᠡᠷᠡᠭᠯᠡᠵᠤ ᠪᠣᠯᠬᠤ ᠥᠬᠡᠢ᠃ OK ᠪᠠᠳᠤᠯᠠᠬᠤ The following program is running to prevent the system from hibernate! ᠳᠠᠷᠠᠭᠠᠬᠢ ᠫᠠᠷᠦᠭᠷᠡᠮ ᠢᠴᠡᠬᠡᠯᠡᠬᠦ ᠵᠢ ᠬᠣᠷᠢᠭᠯᠠᠪᠠ᠂ ᠲᠠ《 ᠦᠬᠡᠢᠰᠬᠡᠬᠦ》 ᠳᠠᠷᠤᠭᠤᠯ ᠢ᠋ ᠳᠠᠷᠤᠵᠤ ᠡᠳᠡᠭᠡᠷ ᠫᠷᠣᠭ᠌ᠷᠠᠮ ᠢ᠋ ᠬᠠᠭᠠᠠᠵᠤ ᠪᠤᠯᠤᠨ᠎ᠠ! The following program is running to prevent the system from suspend! ᠳᠠᠷᠠᠭᠠᠬᠢ ᠫᠠᠷᠦᠭᠷᠡᠮ ᠨᠤᠢᠷᠮᠤᠭᠯᠠᠬᠤ ᠵᠢ ᠬᠣᠷᠢᠭᠯᠠᠪᠠ᠂ ᠲᠠ《 ᠦᠬᠡᠢᠰᠬᠡᠬᠦ》 ᠳᠠᠷᠤᠭᠤᠯ ᠢ᠋ ᠳᠠᠷᠤᠵᠤ ᠡᠳᠡᠭᠡᠷ ᠫᠷᠣᠭ᠌ᠷᠠᠮ ᠢ᠋ ᠬᠠᠭᠠᠠᠵᠤ ᠪᠤᠯᠤᠨ᠎ᠠ! The following program is running to prevent the system from logout! ᠳᠠᠷᠠᠭᠠᠬᠢ ᠫᠠᠷᠦᠭᠷᠡᠮ ᠳᠠᠩᠰᠠᠨ ᠡᠴᠡ ᠬᠠᠰᠤᠬᠤ ᠵᠢ ᠬᠣᠷᠢᠭᠯᠠᠪᠠ᠂ ᠲᠠ《 ᠦᠬᠡᠢᠰᠬᠡᠬᠦ》 ᠳᠠᠷᠤᠭᠤᠯ ᠢ᠋ ᠳᠠᠷᠤᠵᠤ ᠡᠳᠡᠭᠡᠷ ᠫᠷᠣᠭ᠌ᠷᠠᠮ ᠢ᠋ ᠬᠠᠭᠠᠠᠵᠤ ᠪᠤᠯᠤᠨ᠎ᠠ! The following program is running to prevent the system from reboot! ᠳᠠᠷᠠᠭᠠᠬᠢ ᠫᠠᠷᠦᠭᠷᠡᠮ ᠳᠠᠬᠢᠨ ᠡᠬᠢᠯᠡᠬᠦ ᠵᠢ ᠬᠣᠷᠢᠭᠯᠠᠪᠠ᠂ ᠲᠠ《 ᠦᠬᠡᠢᠰᠬᠡᠬᠦ》 ᠳᠠᠷᠤᠭᠤᠯ ᠢ᠋ ᠳᠠᠷᠤᠵᠤ ᠡᠳᠡᠭᠡᠷ ᠫᠷᠣᠭ᠌ᠷᠠᠮ ᠢ᠋ ᠬᠠᠭᠠᠠᠵᠤ ᠪᠤᠯᠤᠨ᠎ᠠ! The following program is running to prevent the system from shutting down! ᠳᠠᠷᠠᠭᠠᠬᠢ ᠫᠠᠷᠦᠭᠷᠡᠮ ᠮᠠᠰᠢᠨ ᠤᠨᠳᠠᠷᠠᠭᠠᠬᠤ ᠵᠢ ᠬᠣᠷᠢᠭᠯᠠᠪᠠ᠂ ᠲᠠ《 ᠦᠬᠡᠢᠰᠬᠡᠬᠦ》 ᠳᠠᠷᠤᠭᠤᠯ ᠢ᠋ ᠳᠠᠷᠤᠵᠤ ᠡᠳᠡᠭᠡᠷ ᠫᠷᠣᠭ᠌ᠷᠠᠮ ᠢ᠋ ᠬᠠᠭᠠᠠᠵᠤ ᠪᠤᠯᠤᠨ᠎ᠠ! Still Hibernate ᠢᠴᠡᠬᠡᠯᠡᠬᠦ Still Suspend ᠨᠤᠢᠷᠮᠤᠭᠯᠠᠬᠤ Still Reboot ᠳᠠᠬᠢᠨ ᠡᠬᠢᠯᠡᠬᠦᠯᠬᠦ Still Shutdown ᠮᠠᠰᠢᠨ ᠤᠨᠳᠠᠷᠠᠭᠠᠬᠤ Cancel ᠦᠬᠡᠢᠰᠬᠡᠬᠦ some applications are running and they don't want you to do this. ᠵᠠᠷᠢᠮ ᠫᠷᠣᠭ᠌ᠷᠠᠮ ᠢ᠋ ᠠᠵᠢᠯᠯᠠᠭᠤᠯᠵᠤ ᠪᠠᠢᠨ᠎ᠠ᠂ ᠳᠡᠷᠡ ᠨᠢ ᠲᠤᠰ ᠠᠵᠢᠯᠯᠠᠬᠤᠢ ᠵᠢ ᠦᠷᠬᠦᠯᠵᠢᠯᠡᠬᠦᠯᠬᠦ ᠵᠢ ᠬᠦᠰᠡᠬᠦ ᠥᠬᠡᠢ ᠪᠠᠢᠨ᠎ᠠ᠃ Still to do! ᠬᠦᠢᠴᠡᠳᠭᠡᠭᠰᠡᠬᠡᠷ ᠪᠠᠢᠨ᠎ᠠ! give up ᠲᠠᠶᠠᠭᠳᠠᠬᠤ canceled this operation ᠲᠤᠰ ᠤᠳᠠᠭᠠᠨ ᠤ᠋ ᠠᠵᠢᠯᠯᠠᠬᠤᠢ ᠵᠢ ᠦᠬᠡᠢᠰᠬᠡᠪᠡ not respond ᠳᠤᠰᠬᠠᠯ ᠥᠬᠡᠢ ukui-session ᠶᠠᠷᠢᠯᠴᠠᠭ᠎ᠠ ᠵᠢᠨ ᠬᠠᠮᠢᠶᠠᠷᠤᠭᠤᠷ The current user has logged in to the system! Currently, the system does not support more than one user to log in at the same time. Click the button below to log out. ᠣᠳᠣᠬᠠᠨ ᠤ᠋ ᠬᠡᠷᠡᠭᠯᠡᠭᠴᠢ ᠨᠢᠬᠡᠨᠳᠡ ᠰᠢᠰᠲ᠋ᠧᠮ ᠳ᠋ᠤ᠌ ᠨᠡᠪᠳᠡᠷᠡᠭᠰᠡᠨ ᠪᠠᠢᠨ᠎ᠠ! ᠣᠳᠣᠬᠠᠨ ᠤ᠋ ᠰᠢᠰᠲ᠋ᠧᠮ ᠨᠢ ᠨᠢᠭᠡ ᠡᠴᠡ ᠳᠡᠭᠡᠭᠰᠢ ᠬᠡᠷᠡᠭᠯᠡᠭᠴᠢ ᠵᠡᠷᠭᠡ ᠪᠡᠷ ᠨᠡᠪᠳᠡᠷᠡᠬᠦ ᠵᠢ ᠳᠡᠮᠵᠢᠬᠦ ᠥᠬᠡᠢ᠂ ᠳᠤᠤᠷᠠᠬᠢ ᠳᠠᠷᠤᠭᠤᠯ ᠢ᠋ ᠳᠠᠷᠤᠵᠤ ᠪᠤᠴᠠᠵᠤ ᠭᠠᠷᠤᠭᠠᠷᠠᠢ᠃ Tips ᠰᠠᠨᠠᠭᠤᠯᠤᠮᠵᠢ ukui-session-manager/translations/zh_CN.ts0000664000175000017500000004060715252714370017655 0ustar fengfeng MainWindow Switch User 切换用户 Hibernate 休眠 Suspend 睡眠 Logout 注销 Reboot 重启 Shut Down 关机 Lock Screen 锁屏 cancel 取消 confirm 确认 QApplication UKUI session tools, show the shutdown dialog without any arguments. ukui-session-tools UKUI会话工具 Switch the user of this computer. UKUI session tools, show the screensave dialog Hibernate this computer. Suspend this computer. Logout this computer. Restart this computer. Shutdown this computer. system-monitor 系统监视器 Switch User 切换用户 Hibernate 休眠 Suspend 睡眠 Logout 注销 Reboot 重启 Log Out 注销 Restart 重启 Shut Down 关机 Lock Screen 锁屏 UpgradeThenRboot 更新并重启 UpgradeThenShutdown 更新并关机 Turn off your computer, but the app stays open. When the computer is turned on, it can be restored to the state you left. 关闭电脑,但是应用会一直保持打开状态。当打开电脑时,可以恢复到你离开的状态。 The computer stays on, but consumes less power. The app stays open and can quickly wake up and revert to where you left off. 电脑保持开机状态,但耗电较少。应用会一直保持打开状态,可快速唤醒电脑并恢复到你离开的状态。 The current user logs out of the system, terminates the session, and returns to the login page. 当前用户从系统中注销,结束其会话并返回登录界面。 Close all apps, turn off your computer, and then turn your computer back on. 关闭所有应用,关闭电脑,然后重新打开电脑。 Close all apps, and then shut down your computer. 关闭所有应用,然后关闭电脑。 Multiple users are logged in at the same time.Are you sure you want to close this system? 同时有多个用户处于登录状态,你确定要退出系统吗? cancel 取消 confirm 确认 (user),ukui-control-center is performing a system update or package installation. (用户),系统正在进行升级或软件包安装/卸载相关操作。 (user),yhkylin-backup-tools is performing a system backup or restore. (用户),备份还原工具正在进行备份或还原。 For system security,Reboot、Shutdown、Logout and Hibernate are temporarily unavailable. 为了系统安全,重启、关机、注销和休眠功能暂时不可用。 For system security,Reboot、Shutdown and Hibernate are temporarily unavailable. 为了系统安全,重启、关机和休眠功能暂时不可用。 UKUI Session Manager QObject is block system 阻止系统 into sleep for reason 休眠,因为 is block system 阻止系统 into sleep for reason 睡眠,因为 Are you sure 你确定 you want to get system into sleep? 要让系统进入休眠吗? Are you sure you want to get system into sleep? 你确定要让系统进入睡眠吗? cancel 取消 confirm 确认 is block system into reboot for reason 阻止系统重启,因为 is block system into shutdown for reason 阻止系统关机,因为 Are you sure you want to reboot? 你确定要重启系统吗? Are you sure you want to shutdown? 你确定要退出系统吗? ukui-session-tools UKUI会话工具 Multiple users are logged in at the same time.Are you sure you want to close this system? 同时有多个用户处于登录状态,你确定要退出系统吗? System update or package installation in progress,this function is temporarily unavailable. 正在进行升级或安装/卸载(相关操作),这个功能暂时不可用。 System backup or restore in progress,this function is temporarily unavailable. 正在进行系统备份或还原,这个功能暂时不可用。 OK 确定 The following program is running to prevent the system from hibernate! 以下程序阻止休眠,您可以点击“取消”然后关闭这些程序。 The following program is running to prevent the system from suspend! 以下程序阻止睡眠,您可以点击“取消”然后关闭这些程序。 The following program is running to prevent the system from logout! 以下程序阻止注销,您可以点击“取消”然后关闭这些程序。 The following program is running to prevent the system from reboot! 以下程序阻止重启,您可以点击“取消”然后关闭这些程序。 The following program is running to prevent the system from shutting down! 以下程序阻止关机,您可以点击“取消”然后关闭这些程序。 Still Hibernate 休眠 Still Suspend 睡眠 Still Reboot 重启 Still Shutdown 关机 Cancel 取消 some applications are running and they don't want you to do this. 一些程序正在运行,而且它不希望你继续该操作。 Still to do! 仍然执行! give up 放弃 cancel shutdown 取消了本次注销 canceled this operation 取消了本次操作 not respond 未响应 ukui-session 会话管理器 The current user has logged in to the system! Currently, the system does not support more than one user to log in at the same time. Click the button below to log out. 当前用户已经在系统中登录!目前系统不支持同时登录一个以上相同用户,点击下方按钮退出。 Tips 温馨提示 Logout Warning 注销提醒 ukui-session-manager/translations/es.ts0000664000175000017500000003266515252714370017270 0ustar fengfeng MainWindow Form Forma Switch User Cambiar de usuario Hibernate Hibernar Suspend Suspender Logout Cerrar sesión Reboot Reiniciar Shut Down Apaga Lock Screen Pantalla de bloqueo cancel Cancelar confirm confirmar <html><head/><body><p><br/></p></body></html> <html> <head/> <body> <p> <br/> </p> </body> </html> QApplication UKUI session tools, show the shutdown dialog without any arguments. UKUI, muestran el cuadro de diálogo de apagado sin ningún argumento. Switch the user of this computer. Cambie el usuario de esta computadora. Hibernate this computer. Hibernar este equipo. Suspend this computer. Suspenda este equipo. Logout this computer. Cierre la sesión de este equipo. Restart this computer. Reinicie esta computadora. Shutdown this computer. Apague este equipo. system-monitor 系统监视器 Switch User Cambiar de usuario Hibernate Hibernar Suspend Suspender Logout Cerrar sesión Reboot Reiniciar Shut Down Apaga Lock Screen Pantalla de bloqueo Multiple users are logged in at the same time.Are you sure you want to close this system? Varios usuarios han iniciado sesión al mismo tiempo. ¿Estás seguro de que quieres cerrar este sistema? cancel Cancelar confirm confirmar (user),ukui-control-center is performing a system update or package installation. (usuario), ukui-control-center está realizando una actualización del sistema o la instalación de un paquete. (user),yhkylin-backup-tools is performing a system backup or restore. (usuario),yhkylin-backup-tools está realizando una copia de seguridad o restauración del sistema. For system security,Reboot、Shutdown、Logout and Hibernate are temporarily unavailable. Por seguridad del sistema, Reiniciar, Apagar, Cerrar sesión e Hibernar no están disponibles temporalmente. For system security,Reboot、Shutdown and Hibernate are temporarily unavailable. Por seguridad del sistema, Reiniciar, Apagar e Hibernar no están disponibles temporalmente. UKUI Session Manager Administrador de sesiones de UKUI QObject is block system 阻止系统 into sleep for reason 休眠,因为 is block system 阻止系统 into sleep for reason 睡眠,因为 Are you sure 你确定 you want to get system into sleep? 要让系统进入休眠吗? Are you sure you want to get system into sleep? 你确定要让系统进入睡眠吗? cancel Cancelar confirm confirmar is block system into reboot for reason 阻止系统重启,因为 is block system into shutdown for reason 阻止系统关机,因为 Are you sure you want to reboot? 你确定要重启系统吗? Are you sure you want to shutdown? 你确定要退出系统吗? Multiple users are logged in at the same time.Are you sure you want to close this system? Varios usuarios han iniciado sesión al mismo tiempo. ¿Estás seguro de que quieres cerrar este sistema? System update or package installation in progress,this function is temporarily unavailable. Actualización del sistema o instalación de paquetes en curso, esta función no está disponible temporalmente. System backup or restore in progress,this function is temporarily unavailable. Copia de seguridad o restauración del sistema en curso, esta función no está disponible temporalmente. OK De acuerdo The following program is running to prevent the system from hibernate! ¡El siguiente programa se está ejecutando para evitar que el sistema hiberne! The following program is running to prevent the system from suspend! ¡El siguiente programa se está ejecutando para evitar que el sistema se suspenda! The following program is running to prevent the system from logout! ¡El siguiente programa se está ejecutando para evitar que el sistema cierre la sesión! The following program is running to prevent the system from reboot! ¡El siguiente programa se está ejecutando para evitar que el sistema se reinicie! The following program is running to prevent the system from shutting down! ¡El siguiente programa se está ejecutando para evitar que el sistema se apague! Still Hibernate Todavía hibernar Still Suspend Todavía suspende Still Reboot Todavía reiniciar Still Shutdown Todavía apagado Cancel Cancelar some applications are running and they don't want you to do this. Algunas aplicaciones se están ejecutando y no quieren que lo hagas. Still to do! ¡Todavía queda por hacer! give up rendirse ukui-session-manager/LICENSE0000664000175000017500000005763615252713362014602 0ustar fengfeng GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS ukui-session-manager/CMakeLists.txt0000664000175000017500000000356315252714370016323 0ustar fengfengcmake_minimum_required(VERSION 3.5) project(ukui-session-manager) # Find includes in corresponding build directories set(CMAKE_INCLUDE_CURRENT_DIR ON) # Instruct CMake to run moc automatically when needed set(CMAKE_AUTOMOC ON) # Handle the Qt rcc code generator automatically. set(CMAKE_AUTORCC ON) # Create code from a list of Qt designer ui files set(CMAKE_AUTOUIC ON) set(CMAKE_CXX_STANDARD 11) include(GNUInstallDirs) # Enable function names and line numbers even for release builds add_definitions("-DQT_MESSAGELOGCONTEXT") # Find the QtWidgets library find_package(Qt6 COMPONENTS Widgets Core REQUIRED) find_package(Qt6LinguistTools) find_package(KF6IdleTime) find_package(Qt6DBus) find_package(KF6CoreAddons) find_package(KF6Config) find_package(KF6WindowSystem) # For debug: cmake -DCMAKE_BUILD_TYPE=debug set(CMAKE_CXX_FLAGS_DEBUG "-g -O0") set(CMAKE_C_FLAGS_DEBUG "-g -O0") # i18n set(UKUI_TRANSLATIONS_DIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/ukui/translations) add_definitions( -DUKUI_TRANSLATIONS_DIR="${UKUI_TRANSLATIONS_DIR}" ) if (NOT DEFINED UPDATE_TRANSLATIONS) set(UPDATE_TRANSLATIONS "No") endif() # To create a new ts file: lupdate -recursive . -target-language en_US -ts translations/en_US.ts -no-ui-lines # update ts file: lupdate -recursive . -target-language translations/bo_CN.ts -ts translations/bo_CN.ts -no-ui-lines file(GLOB TS_FILES "${CMAKE_CURRENT_SOURCE_DIR}/translations/*.ts") # cmake -DUPDATE_TRANSLATIONS=yes if (UPDATE_TRANSLATIONS) qt6_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES}) else() qt6_add_translation(QM_FILES ${TS_FILES}) endif() add_custom_target(translations ALL DEPENDS ${QM_FILES}) install(FILES ${QM_FILES} DESTINATION ${UKUI_TRANSLATIONS_DIR}/${PROJECT_NAME}) add_subdirectory(ukui-session) add_subdirectory(tools) add_subdirectory(ukuismserver) add_subdirectory(data) #add_subdirectory(tests) ukui-session-manager/man/0000775000175000017500000000000015252714370014327 5ustar fengfengukui-session-manager/man/ukui-session.10000664000175000017500000000647115252713362017057 0ustar fengfeng.\" Manual page for ukui-session .\" (C) 2000 Miguel de Icaza (miguel@helixcode.com) .\" (C) 2009-2010 Vincent Untz (vuntz@gnome.org) .\" (C) 2016, Tianjin KYLIN Information Technology Co., Ltd. .\" .TH UKUI-SESSION 1 "11 February 2016" "UKUI Desktop Environment" .\" Please adjust this date when revising the manpage. .\" .SH "NAME" ukui-session \- Start the UKUI Desktop Environment. .SH "SYNOPSIS" .B ukui-session [OPTIONS] .SH "DESCRIPTION" The \fBukui-session\fP program starts up the UKUI desktop environment. This command is typically executed by your Login/Display Manager (like GDM, LXDM, XDM, SLiM, or from your X startup scripts like .xinitrc). It will load either your saved session, or it will provide a default session for the user as defined by the system administrator (or the default UKUI installation on your system). .PP The default session is defined in the dconf keys under .BI / org / ukui / desktop / session / .br When saving a session, \fBukui-session\fP saves the currently running applications in the \fB~/.config/ukui-session/saved-session\fP directory of the users /home. .PP \fBukui-session\fP is an X11 session manager. It can manage UKUI applications as well as any other X11 SM compliant ones. .SH "OPTIONS" .SS The following options are supported: .TP \fB\-a, \-\-autostart=DIR\fR Start all applications defined in "\fBDIR\fP", instead of starting the applications defined in .BI / org / ukui / desktop / session / default\-session .br Multiple \fB\-\-autostart\fP options can be passed. .TP \fB\-f, \-\-failsafe\fR Run in fail-safe mode. User-specified applications will not be started. .TP \fB\-\-debug\fR Enable debugging code. .TP \fB\-\-display=DISPLAY\fR X display to use. .TP \fB\-\-version\fR Output version information and exit. .TP \fB\-?, \-h, \-\-help\fR Print standard command line options. .TP \fB\-\-help\-all\fR Print all command line options. .SH "ENVIRONMENT" .SS \fBukui-session\fP sets several environment variables for the use of its child processes: .PP .B "SESSION_MANAGER" .IP This variable is used by session-manager aware clients to contact ukui-session. .PP .B "DISPLAY" .IP This variable is set to the X display being used by \fBukui-session\fP. Note that if the \-\-display option is used this might be different from the setting of the environment variable when ukui-session is invoked. .SH "FILES" .PP .nf .B ~/.config/autostart .B /usr/share/autostart .B /usr/share/ukui/autostart .fi .IP The applications defined in the above directories will be started on login. \fBukui-session-properties(1)\fP can be used to easily configure them. .PP .B ~/.config/ukui-session/saved-session .IP This directory contains the list of applications of the saved session. .SH "BUGS" .SS Should you encounter any bugs, they may be reported at: https://github.com/ukui/ukui-session-manager/issues .SH "AUTHORS" .SS This Manual page was originally written for gnome-session by: .nf Miguel de Icaza (2000) Vincent Untz (2009-2010) .fi .SS It has been updated for the MATE Desktop Environment by: Adam Erdman (2014) .SS It has been updated for the UKUI Desktop Environment by: yilei (2016) .SH "SEE ALSO" .SS Further information may also be available at: http://wiki.ukui.org/ .P .BR ukui-session-properties(1), .BR ukui-session-save(1), .BR ukui-wm(1) ukui-session-manager/man/ukuismserver.10000664000175000017500000000774115252714370017166 0ustar fengfeng.\" Manual page for ukui-session .\" .\" This is free software; you may redistribute it and/or modify .\" it under the terms of the GNU General Public License as .\" published by the Free Software Foundation; either version 2, .\" or (at your option) any later version. .\" .\" This is distributed in the hope that it will be useful, but .\" WITHOUT ANY WARRANTY; without even the implied warranty of .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the .\" GNU General Public License for more details. .\" .\" You should have received a copy of the GNU General Public License along .\" with this program; if not, write to the Free Software Foundation, Inc., .\" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. .\" .\" (C) 2000 Miguel de Icaza (miguel@helixcode.com) .\" (C) 2009-2010 Vincent Untz (vuntz@gnome.org) .\" (C) 2023, KylinSoft Co., Ltd. .\" .TH UKUI-SESSION 1 "11 February 2023" "UKUI Desktop Environment" .\" Please adjust this date when revising the manpage. .\" .SH "NAME" ukui-session \- Start the UKUI Desktop Environment. .SH "SYNOPSIS" .B ukui-session [OPTIONS] .SH "DESCRIPTION" The \fBukui-session\fP program starts up the UKUI desktop environment. This command is typically executed by your Login/Display Manager (like GDM, LXDM, XDM, SLiM, or from your X startup scripts like .xinitrc). It will load either your saved session, or it will provide a default session for the user as defined by the system administrator (or the default UKUI installation on your system). .PP The default session is defined in the dconf keys under .BI / org / ukui / desktop / session / .br When saving a session, \fBukui-session\fP saves the currently running applications in the \fB~/.config/ukui-session/saved-session\fP directory of the users /home. .PP \fBukui-session\fP is an X11 session manager. It can manage UKUI applications as well as any other X11 SM compliant ones. .SH "OPTIONS" .SS The following options are supported: .TP \fB\-a, \-\-autostart=DIR\fR Start all applications defined in "\fBDIR\fP", instead of starting the applications defined in .BI / org / ukui / desktop / session / default\-session .br Multiple \fB\-\-autostart\fP options can be passed. .TP \fB\-f, \-\-failsafe\fR Run in fail-safe mode. User-specified applications will not be started. .TP \fB\-\-debug\fR Enable debugging code. .TP \fB\-\-display=DISPLAY\fR X display to use. .TP \fB\-\-version\fR Output version information and exit. .TP \fB\-?, \-h, \-\-help\fR Print standard command line options. .TP \fB\-\-help\-all\fR Print all command line options. .SH "ENVIRONMENT" .SS \fBukui-session\fP sets several environment variables for the use of its child processes: .PP .B "SESSION_MANAGER" .IP This variable is used by session-manager aware clients to contact ukui-session. .PP .B "DISPLAY" .IP This variable is set to the X display being used by \fBukui-session\fP. Note that if the \-\-display option is used this might be different from the setting of the environment variable when ukui-session is invoked. .SH "FILES" .PP .nf .B ~/.config/autostart .B /usr/share/autostart .B /usr/share/ukui/autostart .fi .IP The applications defined in the above directories will be started on login. \fBukui-session-properties(1)\fP can be used to easily configure them. .PP .B ~/.config/ukui-session/saved-session .IP This directory contains the list of applications of the saved session. .SH "BUGS" .SS Should you encounter any bugs, they may be reported at: https://github.com/ukui/ukui-session-manager/issues .SH "AUTHORS" .SS This Manual page was originally written for gnome-session by: .nf Miguel de Icaza (2000) Vincent Untz (2009-2010) .fi .SS It has been updated for the MATE Desktop Environment by: Adam Erdman (2014) .SS It has been updated for the UKUI Desktop Environment by: yilei (2016) .SH "SEE ALSO" .SS Further information may also be available at: http://wiki.ukui.org/ .P .BR ukui-session-properties(1), .BR ukui-session-save(1), .BR ukui-wm(1) ukui-session-manager/man/ukui-session-tools.10000664000175000017500000000647115252713362020215 0ustar fengfeng.\" Manual page for ukui-session .\" (C) 2000 Miguel de Icaza (miguel@helixcode.com) .\" (C) 2009-2010 Vincent Untz (vuntz@gnome.org) .\" (C) 2016, Tianjin KYLIN Information Technology Co., Ltd. .\" .TH UKUI-SESSION 1 "11 February 2016" "UKUI Desktop Environment" .\" Please adjust this date when revising the manpage. .\" .SH "NAME" ukui-session \- Start the UKUI Desktop Environment. .SH "SYNOPSIS" .B ukui-session [OPTIONS] .SH "DESCRIPTION" The \fBukui-session\fP program starts up the UKUI desktop environment. This command is typically executed by your Login/Display Manager (like GDM, LXDM, XDM, SLiM, or from your X startup scripts like .xinitrc). It will load either your saved session, or it will provide a default session for the user as defined by the system administrator (or the default UKUI installation on your system). .PP The default session is defined in the dconf keys under .BI / org / ukui / desktop / session / .br When saving a session, \fBukui-session\fP saves the currently running applications in the \fB~/.config/ukui-session/saved-session\fP directory of the users /home. .PP \fBukui-session\fP is an X11 session manager. It can manage UKUI applications as well as any other X11 SM compliant ones. .SH "OPTIONS" .SS The following options are supported: .TP \fB\-a, \-\-autostart=DIR\fR Start all applications defined in "\fBDIR\fP", instead of starting the applications defined in .BI / org / ukui / desktop / session / default\-session .br Multiple \fB\-\-autostart\fP options can be passed. .TP \fB\-f, \-\-failsafe\fR Run in fail-safe mode. User-specified applications will not be started. .TP \fB\-\-debug\fR Enable debugging code. .TP \fB\-\-display=DISPLAY\fR X display to use. .TP \fB\-\-version\fR Output version information and exit. .TP \fB\-?, \-h, \-\-help\fR Print standard command line options. .TP \fB\-\-help\-all\fR Print all command line options. .SH "ENVIRONMENT" .SS \fBukui-session\fP sets several environment variables for the use of its child processes: .PP .B "SESSION_MANAGER" .IP This variable is used by session-manager aware clients to contact ukui-session. .PP .B "DISPLAY" .IP This variable is set to the X display being used by \fBukui-session\fP. Note that if the \-\-display option is used this might be different from the setting of the environment variable when ukui-session is invoked. .SH "FILES" .PP .nf .B ~/.config/autostart .B /usr/share/autostart .B /usr/share/ukui/autostart .fi .IP The applications defined in the above directories will be started on login. \fBukui-session-properties(1)\fP can be used to easily configure them. .PP .B ~/.config/ukui-session/saved-session .IP This directory contains the list of applications of the saved session. .SH "BUGS" .SS Should you encounter any bugs, they may be reported at: https://github.com/ukui/ukui-session-manager/issues .SH "AUTHORS" .SS This Manual page was originally written for gnome-session by: .nf Miguel de Icaza (2000) Vincent Untz (2009-2010) .fi .SS It has been updated for the MATE Desktop Environment by: Adam Erdman (2014) .SS It has been updated for the UKUI Desktop Environment by: yilei (2016) .SH "SEE ALSO" .SS Further information may also be available at: http://wiki.ukui.org/ .P .BR ukui-session-properties(1), .BR ukui-session-save(1), .BR ukui-wm(1) ukui-session-manager/man/ukui-session-wayland.10000664000175000017500000000073015252714370020504 0ustar fengfeng.\" Manual page for ukui-session-wayland .\" (C) 2000 Miguel de Icaza (miguel@helixcode.com) .\" (C) 2009-2010 Vincent Untz (vuntz@gnome.org) .\" (C) 2016, Tianjin KYLIN Information Technology Co., Ltd. .\" .TH UKUI-SESSION-WAYLAND 1 "11 February 2016" "UKUI WAYLAND Desktop Environment" .SH NAME ukui-session-wayland \- UKUI session for Wayland .SH SYNOPSIS .B ukui-session-wayland .SH DESCRIPTION This manual page documents briefly the .B ukui-session-wayland command. ukui-session-manager/tests/0000775000175000017500000000000015252714370014716 5ustar fengfengukui-session-manager/tests/unit_test_systemupgrade/0000775000175000017500000000000015252714370021710 5ustar fengfengukui-session-manager/tests/unit_test_systemupgrade/CMakeLists.txt0000664000175000017500000000431715252714370024455 0ustar fengfeng# CMake 最低版本要求 cmake_minimum_required(VERSION 3.16) find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED) find_package(PkgConfig REQUIRED) pkg_check_modules(GIOUNIX2 REQUIRED gio-unix-2.0) pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0) # 包含 GTest 库和 pthread 库 find_package(GTest REQUIRED) find_package(Threads REQUIRED) find_package(KF5IdleTime) #find_package(Qt5X11Extras REQUIRED) # 设置 C++ 标准 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") file(GLOB SOURCES "../../tools/*.cpp") file(GLOB HEADERS "../../tools/*.h") set(SOURCES ../../tools/systemupgradecheck.cpp unit_test_systemupgrade.cpp ) set(HEADERS ../../tools/systemupgradecheck.h ) pkg_search_module(GSETTINGS_QT REQUIRED gsettings-qt) include_directories(${GSETTINGS_QT_INCLUDES}) pkg_check_modules(GLIB2 REQUIRED glib-2.0) pkg_check_modules(GIO2 REQUIRED gio-2.0) pkg_search_module(X11 REQUIRED x11) pkg_check_modules(KDKINFO REQUIRED kysdk-sysinfo) include_directories(${X11_INCLUDES}) include_directories(${GLIB2_INCLUDE_DIRS}) include_directories(${GIO2_INCLUDE_DIRS}) include_directories(${KDKINFO_INCLUDE_DIRS}) # 包含头文件的路径设置,对应原来的INCLUDEPATH变量 include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ) # 使用qt5_wrap_cpp生成元对象代码相关的源文件 qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) add_executable(unit_test_systemupgrade ${SOURCES} ${MOC_SOURCES}) target_link_libraries(unit_test_systemupgrade Qt5::Core Qt5::Gui Qt5::DBus KF5::IdleTime ${GSETTINGS_QT_LIBRARIES} ${X11_LIBRARIES} ${GLIB2_LIBRARIES} ${GIO2_LIBRARIES} ${KDKINFO_LIBRARIES} #Qt5::X11Extras -lX11 ) # 链接 GTest 库 target_link_libraries(unit_test_systemupgrade GTest::GTest GTest::Main Threads::Threads ) ukui-session-manager/tests/unit_test_systemupgrade/unit_test_systemupgrade.cpp0000664000175000017500000000621515252714370027412 0ustar fengfeng#include #include #include #include #include "../../tools/systemupgradecheck.h" class SystemUpgradeCheckTest : public testing::Test { protected: static void SetUpTestSuite() { // 可在此添加一些全局的设置,例如初始化一些资源 } static void TearDownTestSuite() { // 可在此清理全局的设置,例如释放资源 } void SetUp() override { // 每个测试用例开始前创建 systemUpgradeCheck 实例 systemUpgradeCheckInstance = new systemUpgradeCheck(); } void TearDown() override { // 每个测试用例结束后删除 systemUpgradeCheck 实例 delete systemUpgradeCheckInstance; systemUpgradeCheckInstance = nullptr; } systemUpgradeCheck* systemUpgradeCheckInstance; }; // 测试 systemUpgradeCheck 的构造函数 TEST_F(SystemUpgradeCheckTest, ConstructorTest) { // 创建 systemUpgradeCheck 实例 systemUpgradeCheck* check = new systemUpgradeCheck(); // 检查 isDbusActive 是否根据 QDBusInterface 的 isValid 正确设置 if (check->interface->isValid()) { EXPECT_TRUE(check->isDbusActive); } else { EXPECT_FALSE(check->isDbusActive); } delete check; } // 测试 checkSystemUpgrade 方法 TEST_F(SystemUpgradeCheckTest, CheckSystemUpgradeTest) { systemUpgradeCheck* check = new systemUpgradeCheck(); // 测试 isDbusActive 为 true 时的情况 check->isDbusActive = true; bool result = check->checkSystemUpgrade(); // 由于我们不模拟 D-Bus 响应,这里只是检查函数是否正常调用,不检查结果 EXPECT_EQ(result, false); // 测试 isDbusActive 为 false 时的情况 check->isDbusActive = false; result = check->checkSystemUpgrade(); EXPECT_EQ(result, false); delete check; } // 测试 doUpgradeThenRboot 方法 TEST_F(SystemUpgradeCheckTest, DoUpgradeThenRbootTest) { systemUpgradeCheck* check = new systemUpgradeCheck(); // 测试 isDbusActive 为 true 时的情况 check->isDbusActive = true; bool result = check->doUpgradeThenRboot(); // 由于我们不模拟 D-Bus 响应,这里只是检查函数是否正常调用,不检查结果 EXPECT_EQ(result, false); // 测试 isDbusActive 为 false 时的情况 check->isDbusActive = false; result = check->doUpgradeThenRboot(); EXPECT_EQ(result, false); delete check; } // 测试 doUpgradeThenShutdown 方法 TEST_F(SystemUpgradeCheckTest, DoUpgradeThenShutdownTest) { systemUpgradeCheck* check = new systemUpgradeCheck(); // 测试 isDbusActive 为 true 时的情况 check->isDbusActive = true; bool result = check->doUpgradeThenShutdown(); // 由于我们不模拟 D-Bus 响应,这里只是检查函数是否正常调用,不检查结果 EXPECT_EQ(result, false); // 测试 isDbusActive 为 false 时的情况 check->isDbusActive = false; result = check->doUpgradeThenShutdown(); EXPECT_EQ(result, false); delete check; } int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } ukui-session-manager/tests/CMakeLists.txt0000664000175000017500000000222515252714370017457 0ustar fengfengadd_subdirectory(unit_test_idlewatcher) add_subdirectory(unit_test_modulemanager) add_subdirectory(unit_test_lockchecker) add_subdirectory(unit_test_systemupgrade) add_subdirectory(unit_test_sessionmanagercontext) cmake_minimum_required(VERSION 3.16) # 处理打桩工具相关配置 set(TEST_UTILS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/kt-test-utils") # 收集打桩工具的头文件,递归查找符合条件的头文件 file(GLOB_RECURSE UTILS_HEADERS "${TEST_UTILS_PATH}/cpp-stub/*.h" "${TEST_UTILS_PATH}/cpp-stub/*.hpp" "${TEST_UTILS_PATH}/cpp-stub-ext/*.h" ) # 收集打桩工具的源文件,递归查找符合条件的源文件 file(GLOB_RECURSE UTILS_SOURCES "${TEST_UTILS_PATH}/cpp-stub/*.cpp" "${TEST_UTILS_PATH}/cpp-stub-ext/*.cpp" ) # 创建一个库(这里以静态库为例,可以根据需求改为共享库等)来存放打桩工具相关代码 add_library(utils_lib STATIC ${UTILS_SOURCES} ${UTILS_HEADERS}) # 将打桩工具库的头文件目录添加到包含路径,方便其他目标使用 target_include_directories(utils_lib PUBLIC "${TEST_UTILS_PATH}/cpp-stub" "${TEST_UTILS_PATH}/cpp-stub-ext" ) ukui-session-manager/tests/unit_test_modulemanager/0000775000175000017500000000000015252714370021634 5ustar fengfengukui-session-manager/tests/unit_test_modulemanager/main.cpp0000664000175000017500000000030515252714370023262 0ustar fengfeng#include #include int main(int argc, char **argv) { QGuiApplication a(argc, argv); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } ukui-session-manager/tests/unit_test_modulemanager/CMakeLists.txt0000664000175000017500000000551215252714370024377 0ustar fengfeng# CMake 最低版本要求 cmake_minimum_required(VERSION 3.16) find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED) find_package(PkgConfig REQUIRED) pkg_check_modules(GIOUNIX2 REQUIRED gio-unix-2.0) pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0) # 包含 GTest 库和 pthread 库 find_package(GTest REQUIRED) find_package(Threads REQUIRED) find_package(KF5IdleTime) #find_package(Qt5X11Extras REQUIRED) # 设置 C++ 标准 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") file(GLOB SOURCES "../../ukui-session/*.cpp") file(GLOB HEADERS "../../ukui-session/*.h") # 定义源文件列表,对应原来的SOURCES变量 set(SOURCES ../../ukui-session/modulemanager.cpp ../../ukui-session/xdgautostart.cpp ../../ukui-session/xdgdesktopfile.cpp ../../ukui-session/xdgdirs.cpp ../../ukui-session/ukuisessiondebug.cpp ../../ukui-session/ukuimodule.cpp unit_test_modulemanager.cpp main.cpp ) # 定义头文件列表,对应原来的HEADERS变量 set(HEADERS ../../ukui-session/modulemanager.h ../../ukui-session/xdgautostart.h ../../ukui-session/xdgdesktopfile.h ../../ukui-session/xdgdirs.h ../../ukui-session/ukuisessiondebug.h ../../ukui-session/ukuimodule.h ) pkg_search_module(GSETTINGS_QT REQUIRED gsettings-qt) include_directories(${GSETTINGS_QT_INCLUDES}) pkg_check_modules(GLIB2 REQUIRED glib-2.0) pkg_check_modules(GIO2 REQUIRED gio-2.0) pkg_search_module(X11 REQUIRED x11) pkg_check_modules(KDKINFO REQUIRED kysdk-sysinfo) include_directories(${X11_INCLUDES}) include_directories(${GLIB2_INCLUDE_DIRS}) include_directories(${GIO2_INCLUDE_DIRS}) include_directories(${KDKINFO_INCLUDE_DIRS}) # 包含头文件的路径设置,对应原来的INCLUDEPATH变量 include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ) # 使用qt5_wrap_cpp生成元对象代码相关的源文件 qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) # 添加可执行文件或库目标,将元对象代码源文件一起添加进去 add_executable(unit_test_modulemanager ${SOURCES} ${MOC_SOURCES}) # 链接Qt相关的库 target_link_libraries(unit_test_modulemanager Qt5::Core Qt5::Gui Qt5::DBus KF5::IdleTime ${GSETTINGS_QT_LIBRARIES} ${X11_LIBRARIES} ${GLIB2_LIBRARIES} ${GIO2_LIBRARIES} ${KDKINFO_LIBRARIES} #Qt5::X11Extras -lX11 ) # 链接 GTest 库 target_link_libraries(unit_test_modulemanager GTest::GTest GTest::Main Threads::Threads ) ukui-session-manager/tests/unit_test_modulemanager/unit_test_modulemanager.cpp0000664000175000017500000001431015252714370027255 0ustar fengfeng#include #include #include #include #include #include #include #include #include "../../ukui-session/modulemanager.h" // 测试环境设置 class ModuleManagerTest : public ::testing::Test { protected: void SetUp() override { int argc = 1; char *argv[] = {"modulemanager_test"}; // 初始化 ModuleManager moduleManager = new ModuleManager(); } void TearDown() override { delete moduleManager; } ModuleManager *moduleManager; }; TEST_F(ModuleManagerTest, Init) { moduleManager->init("test"); EXPECT_TRUE(moduleManager->quickStart()); } TEST_F(ModuleManagerTest, QuickStart) { bool ok = moduleManager->quickStart(); EXPECT_TRUE(ok); } TEST_F(ModuleManagerTest, SetUKUILIte) { bool ok = true; moduleManager->setUKUILIte("test"); EXPECT_TRUE(ok); } TEST_F(ModuleManagerTest, SetIsShutingDown) { bool ok = false; moduleManager->setIsShutingDown(ok); EXPECT_FALSE(ok); } TEST_F(ModuleManagerTest, StartUkuiSplash) { bool ok = false; moduleManager->startUkuiSplash(); EXPECT_FALSE(ok); } TEST_F(ModuleManagerTest, EndUkuiSplash) { bool ok = false; moduleManager->endUkuiSplash(); EXPECT_FALSE(ok); } TEST_F(ModuleManagerTest, AutoRestart) { XdgDesktopFile file; file.load("/home/kylin/.config/autostart/wechat-beta.desktop"); bool ok = false; moduleManager->autoRestart(file); EXPECT_FALSE(ok); } TEST_F(ModuleManagerTest, InsertStartupList) { bool ok = false; moduleManager->insertStartupList("test"); EXPECT_FALSE(ok); } TEST_F(ModuleManagerTest, WeakUp) { moduleManager->weakup(false); EXPECT_TRUE(moduleManager->quickStart()); } TEST_F(ModuleManagerTest, ConstructSpecialList) { moduleManager->constructSpecialList(); EXPECT_FALSE(moduleManager->checkIsTabletmode()); } TEST_F(ModuleManagerTest, ConstructStartupList) { moduleManager->constructStartupList(); EXPECT_FALSE(moduleManager->checkIsTabletmode()); } TEST_F(ModuleManagerTest, GetUKUILiteApps) { QSet set = moduleManager->getUKUILiteApps(); EXPECT_TRUE(set.isEmpty()); } TEST_F(ModuleManagerTest, Startupfinished) { QString str1 = "ukui-settings-daemon"; QString str2 = "ukui-kwin"; QString str3 = "ukui-panel"; QString str4 = "peony-qt-desktop"; QString str5 = "ukui-screensaver-dialog"; moduleManager->startupfinished(str1,"test"); moduleManager->startupfinished(str2,"test"); moduleManager->startupfinished(str3,"test"); moduleManager->startupfinished(str4,"test"); moduleManager->startupfinished(str5,"test"); EXPECT_EQ(str1, "ukui-settings-daemon"); EXPECT_EQ(str2, "ukui-kwin"); EXPECT_EQ(str3, "ukui-panel"); EXPECT_EQ(str4, "peony-qt-desktop"); EXPECT_EQ(str5, "ukui-screensaver-dialog"); } // 测试 checkIsTabletmode TEST_F(ModuleManagerTest, CheckIsTabletmode) { // 模拟 QDBusInterface QDBusInterface dbusService("com.kylin.statusmanager.interface", "/", "com.kylin.statusmanager.interface", QDBusConnection::sessionBus()); EXPECT_TRUE(dbusService.isValid()); // 测试平板模式 bool isTabletMode = moduleManager->checkIsTabletmode(); EXPECT_FALSE(isTabletMode); // 默认情况下,平板模式应为 false } // 测试 playBootMusic TEST_F(ModuleManagerTest, PlayBootMusic) { // 测试播放启动音乐 moduleManager->playBootMusic(true); moduleManager->playBootMusic(false); } // 测试 startup TEST_F(ModuleManagerTest, Startup) { // 模拟 XdgDesktopFile XdgDesktopFile desktopFile; desktopFile.setValue("X-UKUI-Autostart-Phase", "Initialization"); // 测试启动流程 moduleManager->startup(); } // 测试 startProcess TEST_F(ModuleManagerTest, StartProcess) { // 模拟 XdgDesktopFile XdgDesktopFile desktopFile; desktopFile.setValue("Exec", "echo Hello World"); // 测试启动进程 moduleManager->startProcess(desktopFile, true); } // 测试 sequenceStart TEST_F(ModuleManagerTest, SequenceStart) { // 模拟 XdgDesktopFileList XdgDesktopFileList fileList; XdgDesktopFile file1, file2; file1.setValue("Exec", "echo App1"); file2.setValue("Exec", "echo App2"); fileList << file1 << file2; // 测试顺序启动 moduleManager->sequenceStart(fileList); } // 测试 restartModules TEST_F(ModuleManagerTest, RestartModules) { // 模拟 UkuiModule XdgDesktopFile desktopFile; desktopFile.setValue("Exec", "echo RestartableApp"); UkuiModule *module = new UkuiModule(desktopFile, moduleManager); // 测试重启模块 moduleManager->restartModules(0, QProcess::NormalExit); module->terminate(); module->isTerminating(); module->getProcName(); delete module; module = nullptr; } // 测试 openAppWithAppManager TEST_F(ModuleManagerTest, OpenAppWithAppManager) { // 模拟 XdgDesktopFile XdgDesktopFile desktopFile; desktopFile.setValue("Exec", "echo AppManagerApp"); // 测试通过 AppManager 打开应用 bool result = moduleManager->openAppWithAppManager(desktopFile); EXPECT_TRUE(result); } // 测试 ChkScreenLockStartup TEST_F(ModuleManagerTest, ChkScreenLockStartup) { // 测试锁屏启动检查 moduleManager->ChkScreenLockStartup(); } TEST_F(ModuleManagerTest, StatusChanged) { bool ok = true; moduleManager->statusChanged(ok); EXPECT_TRUE(ok); } // 测试 onLockScrenUnlock TEST_F(ModuleManagerTest, OnLockScrenUnlock) { bool ok = true; // 测试锁屏解锁 moduleManager->onLockScrenUnlock(); EXPECT_TRUE(ok); } TEST_F(ModuleManagerTest, Dostartwm) { bool ok = true; moduleManager->dostartwm(); EXPECT_TRUE(ok); } TEST_F(ModuleManagerTest, StartNotifPhase) { bool ok = true; moduleManager->startNotifPhase(); EXPECT_TRUE(ok); } TEST_F(ModuleManagerTest, Timeup) { bool ok = true; moduleManager->timeup(); EXPECT_TRUE(ok); } TEST_F(ModuleManagerTest, StartCompsite) { bool ok = true; moduleManager->startCompsite(); EXPECT_TRUE(ok); } // 测试 onLockScrenUnlock TEST_F(ModuleManagerTest, TimerUpdate) { bool ok = true; moduleManager->timerUpdate(); EXPECT_TRUE(ok); } ukui-session-manager/tests/unit_test_ukuilockinfo/0000775000175000017500000000000015252714370021516 5ustar fengfengukui-session-manager/tests/unit_test_ukuilockinfo/main.cpp0000664000175000017500000000030515252714370023144 0ustar fengfeng#include #include int main(int argc, char **argv) { QGuiApplication a(argc, argv); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } ukui-session-manager/tests/unit_test_ukuilockinfo/CMakeLists.txt0000664000175000017500000000376215252714370024266 0ustar fengfeng# CMake 最低版本要求 cmake_minimum_required(VERSION 3.16) find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED) find_package(PkgConfig REQUIRED) pkg_check_modules(GIOUNIX2 REQUIRED gio-unix-2.0) pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0) # 包含 GTest 库和 pthread 库 find_package(GTest REQUIRED) find_package(Threads REQUIRED) find_package(KF5IdleTime) #find_package(Qt5X11Extras REQUIRED) # 设置 C++ 标准 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") # 定义源文件列表,对应原来的SOURCES变量 set(SOURCES ../../ukui-session/ukuilockinfo.cpp ../../ukui-session/xdgdesktopfile.cpp ../../ukui-session/xdgdirs.cpp ../../ukui-session/main.cpp unit_test_ukuilockinfo.cpp main.cpp ) # 定义头文件列表,对应原来的HEADERS变量 set(HEADERS ../../ukui-session/ukuilockinfo.h ../../ukui-session/xdgdesktopfile.h ../../ukui-session/xdgdirs.h ) # 包含头文件的路径设置,对应原来的INCLUDEPATH变量 include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ) # 使用qt5_wrap_cpp生成元对象代码相关的源文件 qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) # 添加可执行文件或库目标,将元对象代码源文件一起添加进去 add_executable(unit_test_ukuilockinfo ${SOURCES} ${MOC_SOURCES}) # 链接Qt相关的库 target_link_libraries(unit_test_ukuilockinfo Qt5::Core Qt5::Gui Qt5::DBus KF5::IdleTime #Qt5::X11Extras -lX11 ) # 链接 GTest 库 target_link_libraries(unit_test_ukuilockinfo GTest::GTest GTest::Main Threads::Threads ) ukui-session-manager/tests/unit_test_ukuilockinfo/unit_test_ukuilockinfo.cpp0000664000175000017500000000542515252714370027030 0ustar fengfeng#include #include #include #include "../../../ukui-session/ukuilockinfo.h" #include "stubext.h" using namespace stub_ext; class UkuilockinfoInfoTest : public testing::Test { protected: static void SetUpTestSuite() { m_ukuilockinfo = new Ukuilockinfo(); } static void TearDownTestSuite() { // delete m_ukuilockinfo; //m_ukuilockinfo = nullptr; } static Ukuilockinfo *m_ukuilockinfo; }; Ukuilockinfo *UkuilockinfoInfoTest::m_ukuilockinfo = nullptr; TEST_F(UkuilockinfoInfoTest, ListInhibitorInfo) { QVector result = m_ukuilockinfo->listInhibitorInfo(Ukuilockinfo::InhibitorType::logout); EXPECT_TRUE(result.isEmpty()); } TEST_F(UkuilockinfoInfoTest, GetCfgValue) { // switchuserBtn, // hibernateBtn, // suspendBtn, // lockscreenBtn, // logoutBtn, // rebootBtn, // shutdownBtn bool result1 = m_ukuilockinfo->getCfgValue(Ukuilockinfo::buttonType::switchuserBtn); EXPECT_TRUE(result1); bool result2 = m_ukuilockinfo->getCfgValue(Ukuilockinfo::buttonType::hibernateBtn); EXPECT_TRUE(result2); bool result3 = m_ukuilockinfo->getCfgValue(Ukuilockinfo::buttonType::suspendBtn); EXPECT_TRUE(result3); bool result4 = m_ukuilockinfo->getCfgValue(Ukuilockinfo::buttonType::lockscreenBtn); EXPECT_TRUE(result4); bool result5 = m_ukuilockinfo->getCfgValue(Ukuilockinfo::buttonType::logoutBtn); EXPECT_TRUE(result5); bool result6 = m_ukuilockinfo->getCfgValue(Ukuilockinfo::buttonType::rebootBtn); EXPECT_TRUE(result6); bool result7 = m_ukuilockinfo->getCfgValue(Ukuilockinfo::buttonType::shutdownBtn); EXPECT_TRUE(result7); } TEST_F(UkuilockinfoInfoTest, GetSystemdInhibitor) { QVector result; m_ukuilockinfo->getSystemdInhibitor(QString("sleep"),result); EXPECT_TRUE(result.isEmpty()); } TEST_F(UkuilockinfoInfoTest, operator1) { QDBusArgument argument; SystemdInhibitor::Inhibitor testInhibitor; // 方法 2:逐个提取成员并验证 QString action, name, reason, mode; uint uid, pid; argument.beginStructure(); argument >> action >> name >> reason >> mode >> uid >> pid; argument.endStructure(); // 验证提取的值是否与原始值一致 EXPECT_EQ(action, testInhibitor.action); EXPECT_EQ(name, testInhibitor.name); EXPECT_EQ(reason, testInhibitor.reason); EXPECT_EQ(mode, testInhibitor.mode); EXPECT_EQ(uid, testInhibitor.uid); EXPECT_EQ(pid, testInhibitor.pid); } TEST_F(UkuilockinfoInfoTest, GetLogoutInhibitor) { QVector result; m_ukuilockinfo->getLogoutInhibitor(result); EXPECT_TRUE(result.isEmpty()); } ukui-session-manager/tests/unit_test_sessionmanagercontext/0000775000175000017500000000000015252714370023437 5ustar fengfengukui-session-manager/tests/unit_test_sessionmanagercontext/main.cpp0000664000175000017500000000030415252714370025064 0ustar fengfeng#include #include int main(int argc, char **argv) { QGuiApplication a(argc, argv); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } ukui-session-manager/tests/unit_test_sessionmanagercontext/CMakeLists.txt0000664000175000017500000000652715252714370026211 0ustar fengfeng# CMake 最低版本要求 cmake_minimum_required(VERSION 3.16) find_package(Qt5 COMPONENTS Widgets Core Gui DBus REQUIRED) find_package(PkgConfig REQUIRED) pkg_search_module(GSETTINGS_QT REQUIRED gsettings-qt) include_directories(${GSETTINGS_QT_INCLUDES}) pkg_check_modules(GIOUNIX2 REQUIRED gio-unix-2.0) pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0) pkg_search_module(X11 REQUIRED x11) include_directories(${X11_INCLUDES}) include_directories(${GLIB2_INCLUDE_DIRS}) include_directories(${GIO2_INCLUDE_DIRS}) # 包含 GTest 库和 pthread 库 find_package(GTest REQUIRED) find_package(Threads REQUIRED) find_package(KF5IdleTime) #find_package(Qt5X11Extras REQUIRED) # 设置 C++ 标准 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") # i18n set(UKUI_TRANSLATIONS_DIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/ukui/translations) add_definitions( -DUKUI_TRANSLATIONS_DIR="${UKUI_TRANSLATIONS_DIR}" ) if (NOT DEFINED UPDATE_TRANSLATIONS) set(UPDATE_TRANSLATIONS "No") endif() file(GLOB SOURCES "../../ukui-session/*.cpp") file(GLOB HEADERS "../../ukui-session/*.h") set(SOURCES ../../ukui-session/sessionmanagercontext.cpp ../../ukui-session/modulemanager.cpp ../../tools/powerprovider.cpp ../../ukui-session/xdgautostart.cpp ../../ukui-session/xdgdesktopfile.cpp ../../ukui-session/ukuimodule.cpp ../../ukui-session/ukuisessiondebug.cpp ../../ukui-session/xdgdirs.cpp ../../ukui-session/ukuisessiondebug.cpp ../../ukui-session/ukuilockinfo.cpp ../../ukui-session/usminhibit.cpp ../kt-test-utils/cpp-stub-ext/stub-shadow.cpp unit_test_sessionmanagercontext.cpp #main.cpp ) set(HEADERS ../../tools/powerprovider.h ../../ukui-session/modulemanager.h ../../ukui-session/sessionmanagercontext.h ../../ukui-session/xdgautostart.h ../../ukui-session/xdgdesktopfile.h ../../ukui-session/idleadbusdaptor.h ../../ukui-session/ukuisessiondebug.h ../../ukui-session/sessiondbusadaptor.h ../../ukui-session/ukuimodule.h ../../ukui-session/usminhibit.h ../../ukui-session/ukuilockinfo.h ../../ukui-session/xdgdirs.h ../kt-test-utils/cpp-stub-ext/stubext.h ../kt-test-utils/cpp-stub-ext/stub-shadow.h ) # 包含头文件的路径设置,对应原来的INCLUDEPATH变量 include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ) # 使用qt5_wrap_cpp生成元对象代码相关的源文件 qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) # 添加可执行文件或库目标,将元对象代码源文件一起添加进去 add_executable(unit_test_sessionmanagercontext ${SOURCES} ${MOC_SOURCES}) # 链接Qt相关的库 target_link_libraries(unit_test_sessionmanagercontext Qt5::Core Qt5::Gui Qt5::DBus KF5::IdleTime Qt5::Widgets ${GSETTINGS_QT_LIBRARIES} #Qt5::X11Extras -lX11 ) # 链接 GTest 库 target_link_libraries(unit_test_sessionmanagercontext GTest::GTest GTest::Main Threads::Threads ) ukui-session-manager/tests/unit_test_sessionmanagercontext/unit_test_sessionmanagercontext.cpp0000664000175000017500000001461615252714370032674 0ustar fengfeng#include #include "../../ukui-session/sessionmanagercontext.h" #include "../../ukui-session/modulemanager.h" #include #include #include // 测试夹具 class SessionManagerDBusContextTest : public ::testing::Test { protected: void SetUp() override { // 初始化 QCoreApplication(需要 DBus 环境) int argc = 0; char* argv[] = {nullptr}; app = new QCoreApplication(argc, argv); // 初始化 ModuleManager 和 SessionManagerDBusContext manager = new ModuleManager(); context = new SessionManagerDBusContext(manager); } void TearDown() override { delete context; delete manager; delete app; } QCoreApplication* app; ModuleManager* manager; SessionManagerDBusContext* context; }; // 测试 startModule 方法 TEST_F(SessionManagerDBusContextTest, StartModuleTest) { QString moduleName = "test_module"; context->startModule(moduleName); // 验证是否调用了 ModuleManager 的 startProcess 方法 // 由于 startProcess 是 void 方法,我们无法直接验证其行为 // 可以通过日志或其他副作用来验证 EXPECT_TRUE(true); // 占位符,表示测试通过 } // 测试 stopModule 方法 TEST_F(SessionManagerDBusContextTest, StopModuleTest) { QString moduleName = "test_module"; context->stopModule(moduleName); // 验证是否调用了 ModuleManager 的 stopProcess 方法 // 由于 stopProcess 是 void 方法,我们无法直接验证其行为 EXPECT_TRUE(true); // 占位符,表示测试通过 } // 测试 startApp 方法 TEST_F(SessionManagerDBusContextTest, StartAppTest) { QString appName = "test_app"; QStringList args = {"--arg1", "--arg2"}; bool result = context->startApp(appName, args); // 验证 startApp 是否返回 true EXPECT_TRUE(result); } TEST_F(SessionManagerDBusContextTest, CanSwitch) { bool ok = context->canSwitch(); // 验证 startApp 是否返回 true EXPECT_TRUE(ok); } TEST_F(SessionManagerDBusContextTest, CanLockscreen) { bool ok = context->canLockscreen(); // 验证 startApp 是否返回 true EXPECT_TRUE(ok); } TEST_F(SessionManagerDBusContextTest, CanHibernate) { bool ok = context->canHibernate(); // 验证 startApp 是否返回 true EXPECT_TRUE(ok); } TEST_F(SessionManagerDBusContextTest, CanSuspend) { bool ok = context->canSuspend(); // 验证 startApp 是否返回 true EXPECT_TRUE(ok); } TEST_F(SessionManagerDBusContextTest, CanLogout) { bool ok = context->canLogout(); // 验证 startApp 是否返回 true EXPECT_TRUE(ok); } TEST_F(SessionManagerDBusContextTest, CanReboot) { bool ok = context->canReboot(); // 验证 startApp 是否返回 true EXPECT_TRUE(ok); } TEST_F(SessionManagerDBusContextTest, CanPowerOff) { bool ok = context->canPowerOff(); // 验证 startApp 是否返回 true EXPECT_TRUE(ok); } TEST_F(SessionManagerDBusContextTest, ListInhibitor) { QVector v1 = context->ListInhibitor("sleep"); QVector v2 = context->ListInhibitor("logout"); QVector v3 = context->ListInhibitor("shutdown"); // 验证 startApp 是否返回 true EXPECT_TRUE(v1.isEmpty()); EXPECT_TRUE(v2.isEmpty()); EXPECT_TRUE(v3.isEmpty()); } TEST_F(SessionManagerDBusContextTest, GetInhibitors) { QStringList list = context->GetInhibitors(); // 验证 startApp 是否返回 true EXPECT_TRUE(list.length() == 0); } TEST_F(SessionManagerDBusContextTest, ExecPro) { QStringList list; list << "clean_all_jobs.py"; context->execPro(list); // 验证 startApp 是否返回 true EXPECT_TRUE(list.length() != 0); } // 测试 IsSessionRunning 方法 TEST_F(SessionManagerDBusContextTest, IsSessionRunningTest) { bool isRunning = context->IsSessionRunning(); // 验证当前会话是否正在运行 EXPECT_FALSE(isRunning); // 假设当前会话是 UKUI } // 测试 GetSessionName 方法 TEST_F(SessionManagerDBusContextTest, GetSessionNameTest) { QString sessionName = context->GetSessionName(); // 验证返回的会话名称是否正确 EXPECT_EQ(sessionName, "ukui-session"); // 假设当前会话是 UKUI } // 测试 IsInhibited 方法 TEST_F(SessionManagerDBusContextTest, IsInhibitedTest) { quint32 flags = 1; bool isInhibited = context->IsInhibited(flags); // 验证是否被抑制 EXPECT_FALSE(isInhibited); // 假设当前没有抑制 } TEST_F(SessionManagerDBusContextTest, ListFileList) { QStringList list = context->listFileList(); EXPECT_TRUE(list.length() != 0); } TEST_F(SessionManagerDBusContextTest, ExecuteBoxadm) { bool ok = true; context->executeBoxadm(); EXPECT_TRUE(ok); } TEST_F(SessionManagerDBusContextTest, StopUkuisessionTarget) { bool ok = true; context->stopUkuisessionTarget(); EXPECT_TRUE(ok); } TEST_F(SessionManagerDBusContextTest, Uninhibit) { bool ok = true; uint i = 109; context->Uninhibit(i); EXPECT_TRUE(ok); } TEST_F(SessionManagerDBusContextTest, EmitPrepareForPhase2) { bool ok = true; context->emitPrepareForPhase2(); EXPECT_TRUE(ok); } TEST_F(SessionManagerDBusContextTest, EmitPrepareForSwitchuser) { bool ok = true; context->emitPrepareForSwitchuser(); EXPECT_TRUE(ok); } TEST_F(SessionManagerDBusContextTest, SimulateUserActivity) { bool ok = true; context->simulateUserActivity(); EXPECT_TRUE(ok); } TEST_F(SessionManagerDBusContextTest, On_serviceUnregistered) { bool ok = true; context->on_serviceUnregistered("22"); EXPECT_TRUE(ok); } TEST_F(SessionManagerDBusContextTest, Logout) { bool ok = true; context->logout(); EXPECT_TRUE(ok); } TEST_F(SessionManagerDBusContextTest, PowerOff) { bool ok = true; context->powerOff(); EXPECT_TRUE(ok); } TEST_F(SessionManagerDBusContextTest, Reboot) { bool ok = true; context->reboot(); EXPECT_TRUE(ok); } // 测试 setSessionEnv 方法 TEST_F(SessionManagerDBusContextTest, SetSessionEnvTest) { QString key = "TEST_ENV_KEY"; QString value = "TEST_ENV_VALUE"; context->setSessionEnv(key, value); // 验证环境变量是否设置成功 EXPECT_EQ(qgetenv(key.toLatin1()), value.toLatin1()); } // 主函数 int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } ukui-session-manager/tests/unit_test_idlewatcher/0000775000175000017500000000000015252714370021307 5ustar fengfengukui-session-manager/tests/unit_test_idlewatcher/main.cpp0000664000175000017500000000030515252714370022735 0ustar fengfeng#include #include int main(int argc, char **argv) { QGuiApplication a(argc, argv); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } ukui-session-manager/tests/unit_test_idlewatcher/CMakeLists.txt0000664000175000017500000000346215252714370024054 0ustar fengfeng# CMake 最低版本要求 cmake_minimum_required(VERSION 3.16) find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED) find_package(PkgConfig REQUIRED) pkg_check_modules(GIOUNIX2 REQUIRED gio-unix-2.0) pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0) # 包含 GTest 库和 pthread 库 find_package(GTest REQUIRED) find_package(Threads REQUIRED) find_package(KF5IdleTime) #find_package(Qt5X11Extras REQUIRED) # 设置 C++ 标准 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") # 定义源文件列表,对应原来的SOURCES变量 set(SOURCES ../../ukui-session/idlewatcher.cpp unit_test_idlewatcher.cpp main.cpp ) # 定义头文件列表,对应原来的HEADERS变量 set(HEADERS ../../ukui-session/idlewatcher.h ) # 包含头文件的路径设置,对应原来的INCLUDEPATH变量 include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ) # 使用qt5_wrap_cpp生成元对象代码相关的源文件 qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) # 添加可执行文件或库目标,将元对象代码源文件一起添加进去 add_executable(unit_test_idlewatcher ${SOURCES} ${MOC_SOURCES}) # 链接Qt相关的库 target_link_libraries(unit_test_idlewatcher Qt5::Core Qt5::Gui Qt5::DBus KF5::IdleTime #Qt5::X11Extras -lX11 ) # 链接 GTest 库 target_link_libraries(unit_test_idlewatcher GTest::GTest GTest::Main Threads::Threads ) ukui-session-manager/tests/unit_test_idlewatcher/unit_test_idlewatcher.cpp0000664000175000017500000000223115252714370026402 0ustar fengfeng#include #include #include "../../../ukui-session/idlewatcher.h" #include "stubext.h" using namespace stub_ext; class IdleWatcherTest : public testing::Test { protected: static void SetUpTestSuite() { m_idlewatcher = new IdleWatcher(60); } static void TearDownTestSuite() { delete m_idlewatcher; m_idlewatcher = nullptr; } static IdleWatcher *m_idlewatcher; }; IdleWatcher *IdleWatcherTest::m_idlewatcher = nullptr; TEST_F(IdleWatcherTest, isWemeetappRunning) { bool result = m_idlewatcher->isWemeetappRunning(); EXPECT_FALSE(result); } TEST_F(IdleWatcherTest, reset) { m_idlewatcher->reset(1); EXPECT_EQ(m_idlewatcher->mSecsidle,1); } TEST_F(IdleWatcherTest, ResumingFromIdle) { bool ok = true; m_idlewatcher->resumingFromIdle(); EXPECT_TRUE(ok); } TEST_F(IdleWatcherTest, WeakupFromSleep) { bool ok = true; m_idlewatcher->weakupFromSleep(false); EXPECT_TRUE(ok); } TEST_F(IdleWatcherTest, TimeoutReached) { m_idlewatcher->mSecsidle = 60; m_idlewatcher->timeoutReached(1,60); EXPECT_EQ(m_idlewatcher->mSecsidle,60); } ukui-session-manager/tests/unit_test_sessionapplication/0000775000175000017500000000000015252714370022723 5ustar fengfengukui-session-manager/tests/unit_test_sessionapplication/main.cpp0000664000175000017500000000030515252714370024351 0ustar fengfeng#include #include int main(int argc, char **argv) { QGuiApplication a(argc, argv); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } ukui-session-manager/tests/unit_test_sessionapplication/CMakeLists.txt0000664000175000017500000000700015252714370025460 0ustar fengfeng# CMake 最低版本要求 cmake_minimum_required(VERSION 3.16) find_package(Qt5 COMPONENTS Widgets Core Gui DBus REQUIRED) find_package(PkgConfig REQUIRED) pkg_check_modules(GIOUNIX2 REQUIRED gio-unix-2.0) pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0) pkg_search_module(GSETTINGS_QT REQUIRED gsettings-qt) include_directories(${GSETTINGS_QT_INCLUDES}) pkg_check_modules(GLIB2 REQUIRED glib-2.0) pkg_check_modules(GIO2 REQUIRED gio-2.0) # 包含 GTest 库和 pthread 库 find_package(GTest REQUIRED) find_package(Threads REQUIRED) find_package(KF5IdleTime) #find_package(Qt5X11Extras REQUIRED) # 设置 C++ 标准 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") # 定义源文件列表,对应原来的SOURCES变量 set(SOURCES ../../ukui-session/sessionapplication.cpp ../../ukui-session/modulemanager.cpp ../../ukui-session/idlewatcher.cpp ../../ukui-session/xdgdesktopfile.cpp ../../ukui-session/xdgautostart.cpp ../../ukui-session/xdgdirs.cpp ../../ukui-session/sessionmanagercontext.cpp ../../ukuismserver/ukuismserverdebug.cpp ../../ukui-session/usminhibit.cpp ../../ukui-session/ukuimodule.cpp ../../ukui-session/ukuisessiondebug.cpp ../../tools/powerprovider.cpp ../../tools/ukuipower.cpp ../../tools/ukuilockinfo.cpp unit_test_sessionapplication.cpp main.cpp ) # 定义头文件列表,对应原来的HEADERS变量 set(HEADERS ../../ukui-session/sessionapplication.h ../../ukui-session/modulemanager.h ../../ukui-session/idlewatcher.h ../../ukui-session/xdgautostart.h ../../ukui-session/xdgdirs.h ../../ukui-session/sessionmanagercontext.h ../../ukui-session/xdgdesktopfile.h ../../ukui-session/idleadbusdaptor.h ../../ukui-session/sessiondbusadaptor.h ../../ukui-session/usminhibit.h ../../ukuismserver/ukuismserverdebug.h ../../ukui-session/ukuimodule.h ../../tools/powerprovider.h ../../tools/ukuipower.h ../../tools/ukuilockinfo.h ../../ukui-session/ukuisessiondebug.h ) set(UKUI_TRANSLATIONS_DIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/ukui/translations) add_definitions( -DUKUI_TRANSLATIONS_DIR="${UKUI_TRANSLATIONS_DIR}" ) if (NOT DEFINED UPDATE_TRANSLATIONS) set(UPDATE_TRANSLATIONS "No") endif() # 包含头文件的路径设置,对应原来的INCLUDEPATH变量 include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ) include_directories(${GLIB2_INCLUDE_DIRS}) include_directories(${GIO2_INCLUDE_DIRS}) # 使用qt5_wrap_cpp生成元对象代码相关的源文件 qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) # 添加可执行文件或库目标,将元对象代码源文件一起添加进去 add_executable(unit_test_sessionapplication ${SOURCES} ${MOC_SOURCES}) # 链接Qt相关的库 target_link_libraries(unit_test_sessionapplication Qt5::Widgets Qt5::Core Qt5::Gui Qt5::DBus KF5::IdleTime ${GSETTINGS_QT_LIBRARIES} ${GLIB2_LIBRARIES} ${GIO2_LIBRARIES} #Qt5::X11Extras -lX11 ) # 链接 GTest 库 target_link_libraries(unit_test_sessionapplication GTest::GTest GTest::Main Threads::Threads ) ukui-session-manager/tests/unit_test_sessionapplication/unit_test_sessionapplication.cpp0000664000175000017500000000146615252714370031443 0ustar fengfeng#include #include #include "../../../ukui-session/sessionapplication.h" #include "stubext.h" using namespace stub_ext; class SessionApplicationTest: public testing::Test { protected: static void SetUpTestSuite() { int argc = 2; char* argv[] = {"test", "test"}; m_sessionapplication = new SessionApplication(argc,argv); } static void TearDownTestSuite() { delete m_sessionapplication; m_sessionapplication = nullptr; } static SessionApplication *m_sessionapplication; }; SessionApplication *SessionApplicationTest::m_sessionapplication = nullptr; TEST_F(SessionApplicationTest, InitialEnvironment) { //m_sessionapplication->initialEnvironment(); //EXPECT_TRUE(m_sessionapplication->isok); } ukui-session-manager/tests/kt-test-utils/0000775000175000017500000000000015252714370017447 5ustar fengfengukui-session-manager/tests/kt-test-utils/cpp-stub/0000775000175000017500000000000015252714370021204 5ustar fengfengukui-session-manager/tests/kt-test-utils/cpp-stub/addr_any.h0000664000175000017500000002113515252714370023140 0ustar fengfeng#ifndef __ADDR_ANY_H__ #define __ADDR_ANY_H__ //linux #include #include //c #include #include #include //c++ #include #include //project #include "elfio.hpp" class AddrAny { public: AddrAny() { m_init = get_exe_pathname(m_fullname); m_baseaddr = 0; } AddrAny(std::string libname) { m_init = get_lib_pathname_and_baseaddr(libname, m_fullname, m_baseaddr); } int get_local_func_addr_symtab(std::string func_name_regex_str, std::map& result) { return get_func_addr(SHT_SYMTAB, STB_LOCAL, func_name_regex_str, result); } int get_global_func_addr_symtab(std::string func_name_regex_str, std::map& result) { return get_func_addr(SHT_SYMTAB, STB_GLOBAL, func_name_regex_str, result); } int get_weak_func_addr_symtab(std::string func_name_regex_str, std::map& result) { return get_func_addr(SHT_SYMTAB, STB_WEAK, func_name_regex_str, result); } int get_global_func_addr_dynsym( std::string func_name_regex_str, std::map& result) { return get_func_addr(SHT_DYNSYM, STB_GLOBAL, func_name_regex_str, result); } int get_weak_func_addr_dynsym(std::string func_name_regex_str, std::map& result) { return get_func_addr(SHT_DYNSYM, STB_WEAK, func_name_regex_str, result); } private: bool demangle(std::string& s, std::string& name) { int status; char* pname = abi::__cxa_demangle(s.c_str(), 0, 0, &status); if (status != 0) { switch(status) { case -1: name = "memory allocation error"; break; case -2: name = "invalid name given"; break; case -3: name = "internal error: __cxa_demangle: invalid argument"; break; default: name = "unknown error occurred"; break; } return false; } name = pname; free(pname); return true; } bool get_exe_pathname( std::string& name) { char line[512]; FILE *fp; uintptr_t base_addr; char perm[5]; unsigned long offset; int pathname_pos; char *pathname; size_t pathname_len; int match = 0; if(NULL == (fp = fopen("/proc/self/maps", "r"))) { return false; } while(fgets(line, sizeof(line), fp)) { if(sscanf(line, "%" PRIxPTR "-%*lx %4s %lx %*x:%*x %*d%n", &base_addr, perm, &offset, &pathname_pos) != 3) continue; if(0 != offset) continue; //get pathname while(isspace(line[pathname_pos]) && pathname_pos < (int)(sizeof(line) - 1)) pathname_pos += 1; if(pathname_pos >= (int)(sizeof(line) - 1)) continue; pathname = line + pathname_pos; pathname_len = strlen(pathname); if(0 == pathname_len) continue; if(pathname[pathname_len - 1] == '\n') { pathname[pathname_len - 1] = '\0'; pathname_len -= 1; } if(0 == pathname_len) continue; if('[' == pathname[0]) continue; name = pathname; match = 1; break; } fclose(fp); if(0 == match) { return false; } else { return true; } } bool get_lib_pathname_and_baseaddr(std::string pathname_regex_str, std::string& name, unsigned long& addr) { char line[512]; FILE *fp; uintptr_t base_addr; char perm[5]; unsigned long offset; int pathname_pos; char *pathname; size_t pathname_len; int match; regex_t pathname_regex; regcomp(&pathname_regex, pathname_regex_str.c_str(), 0); if(NULL == (fp = fopen("/proc/self/maps", "r"))) { return false; } while(fgets(line, sizeof(line), fp)) { if(sscanf(line, "%" PRIxPTR "-%*lx %4s %lx %*x:%*x %*d%n", &base_addr, perm, &offset, &pathname_pos) != 3) continue; //check permission if(perm[0] != 'r') continue; if(perm[3] != 'p') continue; //do not touch the shared memory //check offset // //We are trying to find ELF header in memory. //It can only be found at the beginning of a mapped memory regions //whose offset is 0. if(0 != offset) continue; //get pathname while(isspace(line[pathname_pos]) && pathname_pos < (int)(sizeof(line) - 1)) pathname_pos += 1; if(pathname_pos >= (int)(sizeof(line) - 1)) continue; pathname = line + pathname_pos; pathname_len = strlen(pathname); if(0 == pathname_len) continue; if(pathname[pathname_len - 1] == '\n') { pathname[pathname_len - 1] = '\0'; pathname_len -= 1; } if(0 == pathname_len) continue; if('[' == pathname[0]) continue; //check pathname //if we need to hook this elf? match = 0; if(0 == regexec(&pathname_regex, pathname, 0, NULL, 0)) { match = 1; name = pathname; addr = (unsigned long)base_addr; break; } if(0 == match) continue; } fclose(fp); if(0 == match) { return false; } else { return true; } } int get_func_addr(unsigned int ttype, unsigned int stype, std::string& func_name_regex_str, std::map& result) { // Create an elfio reader ELFIO::elfio reader; int count = 0; regex_t pathname_regex; if(!m_init) { return -1; } regcomp(&pathname_regex, func_name_regex_str.c_str(), 0); // Load ELF data if(!reader.load(m_fullname.c_str())) { return -1; } ELFIO::Elf_Half sec_num = reader.sections.size(); for(int i = 0; i < sec_num; ++i) { ELFIO::section* psec = reader.sections[i]; // Check section type if(psec->get_type() == ttype) { const ELFIO::symbol_section_accessor symbols( reader, psec ); for ( unsigned int j = 0; j < symbols.get_symbols_num(); ++j ) { std::string name; std::string name_mangle; ELFIO::Elf64_Addr value; ELFIO::Elf_Xword size; unsigned char bind; unsigned char type; ELFIO::Elf_Half section_index; unsigned char other; // Read symbol properties symbols.get_symbol( j, name, value, size, bind, type, section_index, other ); if(type == STT_FUNC && bind == stype) { bool ret = demangle(name,name_mangle); if(ret == true) { if (0 == regexec(&pathname_regex, name_mangle.c_str(), 0, NULL, 0)) { result.insert ( std::pair(name_mangle,(void*)(value + m_baseaddr))); count++; } } else { if (0 == regexec(&pathname_regex, name.c_str(), 0, NULL, 0)) { result.insert ( std::pair(name,(void*)(value + m_baseaddr))); count++; } } } } break; } } return count; } private: bool m_init; std::string m_name; std::string m_fullname; unsigned long m_baseaddr; }; #endif ukui-session-manager/tests/kt-test-utils/cpp-stub/stub.h0000664000175000017500000002341115252714370022333 0ustar fengfeng#ifndef __STUB_H__ #define __STUB_H__ #ifdef _WIN32 //windows #include #include #else //linux #include #include #include #endif //c #include #include //c++ #include #define ADDR(CLASS_NAME,MEMBER_NAME) (&CLASS_NAME::MEMBER_NAME) /********************************************************** replace function **********************************************************/ #ifdef _WIN32 #define CACHEFLUSH(addr, size) FlushInstructionCache(GetCurrentProcess(), addr, size) #else #define CACHEFLUSH(addr, size) __builtin___clear_cache(addr, addr + size) #endif #if defined(__aarch64__) || defined(_M_ARM64) #define CODESIZE 16U #define CODESIZE_MIN 16U #define CODESIZE_MAX CODESIZE // ldr x9, +8 // br x9 // addr #define REPLACE_FAR(t, fn, fn_stub)\ ((uint32_t*)fn)[0] = 0x58000040 | 9;\ ((uint32_t*)fn)[1] = 0xd61f0120 | (9 << 5);\ *(long long *)(fn + 8) = (long long )fn_stub;\ CACHEFLUSH((char *)fn, CODESIZE); #define REPLACE_NEAR(t, fn, fn_stub) REPLACE_FAR(t, fn, fn_stub) #elif defined(__arm__) || defined(_M_ARM) #define CODESIZE 8U #define CODESIZE_MIN 8U #define CODESIZE_MAX CODESIZE // ldr pc, [pc, #-4] #define REPLACE_FAR(t, fn, fn_stub)\ ((uint32_t*)fn)[0] = 0xe51ff004;\ ((uint32_t*)fn)[1] = (uint32_t)fn_stub;\ CACHEFLUSH((char *)fn, CODESIZE); #define REPLACE_NEAR(t, fn, fn_stub) REPLACE_FAR(t, fn, fn_stub) #elif defined(__mips64) #define CACHEFLUSH(addr, size) __builtin___clear_cache(addr, addr + size) #define CODESIZE 80U #define CODESIZE_MIN 80U #define CODESIZE_MAX CODESIZE //mips没有PC指针,所以需要手动入栈出栈 //120000ce0: 67bdffe0 daddiu sp, sp, -32 //入栈 //120000ce4: ffbf0018 sd ra, 24(sp) //120000ce8: ffbe0010 sd s8, 16(sp) //120000cec: ffbc0008 sd gp, 8(sp) //120000cf0: 03a0f025 move s8, sp //120000d2c: 03c0e825 move sp, s8 //出栈 //120000d30: dfbf0018 ld ra, 24(sp) //120000d34: dfbe0010 ld s8, 16(sp) //120000d38: dfbc0008 ld gp, 8(sp) //120000d3c: 67bd0020 daddiu sp, sp, 32 //120000d40: 03e00008 jr ra #define REPLACE_FAR(t, fn, fn_stub)\ ((uint32_t *)fn)[0] = 0x67bdffe0;\ ((uint32_t *)fn)[1] = 0xffbf0018;\ ((uint32_t *)fn)[2] = 0xffbe0010;\ ((uint32_t *)fn)[3] = 0xffbc0008;\ ((uint32_t *)fn)[4] = 0x03a0f025;\ *(uint16_t *)(fn + 20) = (long long)fn_stub >> 32;\ *(fn + 22) = 0x19;\ *(fn + 23) = 0x24;\ ((uint32_t *)fn)[6] = 0x0019cc38;\ *(uint16_t *)(fn + 28) = (long long)fn_stub >> 16;\ *(fn + 30) = 0x39;\ *(fn + 31) = 0x37;\ ((uint32_t *)fn)[8] = 0x0019cc38;\ *(uint16_t *)(fn + 36) = (long long)fn_stub;\ *(fn + 38) = 0x39;\ *(fn + 39) = 0x37;\ ((uint32_t *)fn)[10] = 0x0320f809;\ ((uint32_t *)fn)[11] = 0x00000000;\ ((uint32_t *)fn)[12] = 0x00000000;\ ((uint32_t *)fn)[13] = 0x03c0e825;\ ((uint32_t *)fn)[14] = 0xdfbf0018;\ ((uint32_t *)fn)[15] = 0xdfbe0010;\ ((uint32_t *)fn)[16] = 0xdfbc0008;\ ((uint32_t *)fn)[17] = 0x67bd0020;\ ((uint32_t *)fn)[18] = 0x03e00008;\ ((uint32_t *)fn)[19] = 0x00000000;\ CACHEFLUSH((char *)fn, CODESIZE); #define REPLACE_NEAR(t, fn, fn_stub) REPLACE_FAR(t, fn, fn_stub) #elif defined(__thumb__) || defined(_M_THUMB) #error "Thumb is not supported" #else //__i386__ _x86_64__ #define CODESIZE 13U #define CODESIZE_MIN 5U #define CODESIZE_MAX CODESIZE //13 byte(jmp m16:64) //movabs $0x102030405060708,%r11 //jmpq *%r11 static void REPLACE_FAR(void *t, char *fn, char *fn_stub) { *fn = 0x49; *(fn + 1) = 0xbb; *(long long *)(fn + 2) = (long long)fn_stub; *(fn + 10) = 0x41; *(fn + 11) = 0xff; *(fn + 12) = 0xe3; CACHEFLUSH((char *)fn, CODESIZE); } //5 byte(jmp rel32) #define REPLACE_NEAR(t, fn, fn_stub)\ *fn = 0xE9;\ *(int *)(fn + 1) = (int)(fn_stub - fn - CODESIZE_MIN);\ CACHEFLUSH((char *)fn, CODESIZE); #endif struct func_stub { char *fn; unsigned char code_buf[CODESIZE]; bool far_jmp; }; class Stub { public: Stub() { #ifdef _WIN32 SYSTEM_INFO sys_info; GetSystemInfo(&sys_info); m_pagesize = sys_info.dwPageSize; #else m_pagesize = sysconf(_SC_PAGE_SIZE); #endif if (m_pagesize < 0) { m_pagesize = 4096; } } ~Stub() { clear(); } virtual void clear() { std::map::iterator iter; struct func_stub *pstub; for(iter=m_result.begin(); iter != m_result.end(); iter++) { pstub = iter->second; #ifdef _WIN32 DWORD lpflOldProtect; if(0 != VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READWRITE, &lpflOldProtect)) #else if (0 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_WRITE | PROT_EXEC)) #endif { if(pstub->far_jmp) { std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MAX); } else { std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MIN); } #ifdef _WIN32 VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READ, &lpflOldProtect); #else CACHEFLUSH(pstub->fn,CODESIZE); mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_EXEC); #endif } iter->second = NULL; delete pstub; } m_result.clear(); return; } template bool set(T addr, S addr_stub) { char * fn; char * fn_stub; fn = addrof(addr); fn_stub = addrof(addr_stub); struct func_stub *pstub; std::map::iterator iter = m_result.find(fn); if (iter == m_result.end()) { pstub = new func_stub; //start pstub->fn = fn; if(distanceof(fn, fn_stub)) { pstub->far_jmp = true; std::memcpy(pstub->code_buf, fn, CODESIZE_MAX); } else { pstub->far_jmp = false; std::memcpy(pstub->code_buf, fn, CODESIZE_MIN); } } else { pstub = iter->second; pstub->far_jmp = distanceof(fn, fn_stub); } #ifdef _WIN32 DWORD lpflOldProtect; if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READWRITE, &lpflOldProtect)) #else if (-1 == mprotect(pageof(pstub->fn), static_cast(m_pagesize * 2), PROT_READ | PROT_WRITE | PROT_EXEC)) #endif { throw("stub set memory protect to w+r+x failed"); return false; } if(pstub->far_jmp) { REPLACE_FAR(this, fn, fn_stub); } else { REPLACE_NEAR(this, fn, fn_stub); } #ifdef _WIN32 if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READ, &lpflOldProtect)) #else if (-1 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_EXEC)) #endif { throw("stub set memory protect to r+x failed"); return false; } m_result.insert(std::pair(fn,pstub)); return true; } template bool reset(T addr) { char * fn; fn = addrof(addr); std::map::iterator iter = m_result.find(fn); if (iter == m_result.end()) { return true; } struct func_stub *pstub; pstub = iter->second; #ifdef _WIN32 DWORD lpflOldProtect; if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READWRITE, &lpflOldProtect)) #else if (-1 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_WRITE | PROT_EXEC)) #endif { throw("stub reset memory protect to w+r+x failed"); return false; } if(pstub->far_jmp) { std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MAX); } else { std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MIN); } #ifdef _WIN32 if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READ, &lpflOldProtect)) #else CACHEFLUSH(pstub->fn,CODESIZE); if (-1 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_EXEC)) #endif { throw("stub reset memory protect to r+x failed"); return false; } m_result.erase(iter); delete pstub; return true; } protected: char *pageof(char* addr) { #ifdef _WIN32 return (char *)((unsigned long long)addr & ~(m_pagesize - 1)); #else return (char *)((unsigned long)addr & ~(m_pagesize - 1)); #endif } template char* addrof(T addr) { union { T _s; char* _d; }ut; ut._s = addr; return ut._d; } bool distanceof(char* addr, char* addr_stub) { std::ptrdiff_t diff = addr_stub >= addr ? addr_stub - addr : addr - addr_stub; if((sizeof(addr) > 4) && (((diff >> 31) - 1) > 0)) { return true; } return false; } protected: #ifdef _WIN32 //LLP64 long long m_pagesize; #else //LP64 long m_pagesize; #endif std::map m_result; }; #endif ukui-session-manager/tests/kt-test-utils/cpp-stub/elfio.hpp0000664000175000017500000045310415252714370023022 0ustar fengfeng /*** Start of inlined file: elfio_dump.hpp ***/ #ifndef ELFIO_DUMP_HPP #define ELFIO_DUMP_HPP #include #include #include #include #include /*** Start of inlined file: elfio.hpp ***/ #ifndef ELFIO_HPP #define ELFIO_HPP #ifdef _MSC_VER #pragma warning( push ) #pragma warning( disable : 4996 ) #pragma warning( disable : 4355 ) #pragma warning( disable : 4244 ) #endif #include #include #include #include #include #include #include #include /*** Start of inlined file: elf_types.hpp ***/ #ifndef ELFTYPES_H #define ELFTYPES_H #ifndef ELFIO_NO_OWN_TYPES #if !defined( ELFIO_NO_CSTDINT ) && !defined( ELFIO_NO_INTTYPES ) #include #else typedef unsigned char uint8_t; typedef signed char int8_t; typedef unsigned short uint16_t; typedef signed short int16_t; #ifdef _MSC_VER typedef unsigned __int32 uint32_t; typedef signed __int32 int32_t; typedef unsigned __int64 uint64_t; typedef signed __int64 int64_t; #else typedef unsigned int uint32_t; typedef signed int int32_t; typedef unsigned long long uint64_t; typedef signed long long int64_t; #endif // _MSC_VER #endif // ELFIO_NO_CSTDINT #endif // ELFIO_NO_OWN_TYPES namespace ELFIO { // Attention! Platform depended definitions. typedef uint16_t Elf_Half; typedef uint32_t Elf_Word; typedef int32_t Elf_Sword; typedef uint64_t Elf_Xword; typedef int64_t Elf_Sxword; typedef uint32_t Elf32_Addr; typedef uint32_t Elf32_Off; typedef uint64_t Elf64_Addr; typedef uint64_t Elf64_Off; #define Elf32_Half Elf_Half #define Elf64_Half Elf_Half #define Elf32_Word Elf_Word #define Elf64_Word Elf_Word #define Elf32_Sword Elf_Sword #define Elf64_Sword Elf_Sword /////////////////////// // ELF Header Constants // File type #define ET_NONE 0 #define ET_REL 1 #define ET_EXEC 2 #define ET_DYN 3 #define ET_CORE 4 #define ET_LOOS 0xFE00 #define ET_HIOS 0xFEFF #define ET_LOPROC 0xFF00 #define ET_HIPROC 0xFFFF #define EM_NONE 0 // No machine #define EM_M32 1 // AT&T WE 32100 #define EM_SPARC 2 // SUN SPARC #define EM_386 3 // Intel 80386 #define EM_68K 4 // Motorola m68k family #define EM_88K 5 // Motorola m88k family #define EM_486 6 // Intel 80486// Reserved for future use #define EM_860 7 // Intel 80860 #define EM_MIPS 8 // MIPS R3000 (officially, big-endian only) #define EM_S370 9 // IBM System/370 #define EM_MIPS_RS3_LE \ 10 // MIPS R3000 little-endian (Oct 4 1999 Draft) Deprecated #define EM_res011 11 // Reserved #define EM_res012 12 // Reserved #define EM_res013 13 // Reserved #define EM_res014 14 // Reserved #define EM_PARISC 15 // HPPA #define EM_res016 16 // Reserved #define EM_VPP550 17 // Fujitsu VPP500 #define EM_SPARC32PLUS 18 // Sun's "v8plus" #define EM_960 19 // Intel 80960 #define EM_PPC 20 // PowerPC #define EM_PPC64 21 // 64-bit PowerPC #define EM_S390 22 // IBM S/390 #define EM_SPU 23 // Sony/Toshiba/IBM SPU #define EM_res024 24 // Reserved #define EM_res025 25 // Reserved #define EM_res026 26 // Reserved #define EM_res027 27 // Reserved #define EM_res028 28 // Reserved #define EM_res029 29 // Reserved #define EM_res030 30 // Reserved #define EM_res031 31 // Reserved #define EM_res032 32 // Reserved #define EM_res033 33 // Reserved #define EM_res034 34 // Reserved #define EM_res035 35 // Reserved #define EM_V800 36 // NEC V800 series #define EM_FR20 37 // Fujitsu FR20 #define EM_RH32 38 // TRW RH32 #define EM_MCORE 39 // Motorola M*Core // May also be taken by Fujitsu MMA #define EM_RCE 39 // Old name for MCore #define EM_ARM 40 // ARM #define EM_OLD_ALPHA 41 // Digital Alpha #define EM_SH 42 // Renesas (formerly Hitachi) / SuperH SH #define EM_SPARCV9 43 // SPARC v9 64-bit #define EM_TRICORE 44 // Siemens Tricore embedded processor #define EM_ARC 45 // ARC Cores #define EM_H8_300 46 // Renesas (formerly Hitachi) H8/300 #define EM_H8_300H 47 // Renesas (formerly Hitachi) H8/300H #define EM_H8S 48 // Renesas (formerly Hitachi) H8S #define EM_H8_500 49 // Renesas (formerly Hitachi) H8/500 #define EM_IA_64 50 // Intel IA-64 Processor #define EM_MIPS_X 51 // Stanford MIPS-X #define EM_COLDFIRE 52 // Motorola Coldfire #define EM_68HC12 53 // Motorola M68HC12 #define EM_MMA 54 // Fujitsu Multimedia Accelerator #define EM_PCP 55 // Siemens PCP #define EM_NCPU 56 // Sony nCPU embedded RISC processor #define EM_NDR1 57 // Denso NDR1 microprocessor #define EM_STARCORE 58 // Motorola Star*Core processor #define EM_ME16 59 // Toyota ME16 processor #define EM_ST100 60 // STMicroelectronics ST100 processor #define EM_TINYJ 61 // Advanced Logic Corp. TinyJ embedded processor #define EM_X86_64 62 // Advanced Micro Devices X86-64 processor #define EM_PDSP 63 // Sony DSP Processor #define EM_PDP10 64 // Digital Equipment Corp. PDP-10 #define EM_PDP11 65 // Digital Equipment Corp. PDP-11 #define EM_FX66 66 // Siemens FX66 microcontroller #define EM_ST9PLUS 67 // STMicroelectronics ST9+ 8/16 bit microcontroller #define EM_ST7 68 // STMicroelectronics ST7 8-bit microcontroller #define EM_68HC16 69 // Motorola MC68HC16 Microcontroller #define EM_68HC11 70 // Motorola MC68HC11 Microcontroller #define EM_68HC08 71 // Motorola MC68HC08 Microcontroller #define EM_68HC05 72 // Motorola MC68HC05 Microcontroller #define EM_SVX 73 // Silicon Graphics SVx #define EM_ST19 74 // STMicroelectronics ST19 8-bit cpu #define EM_VAX 75 // Digital VAX #define EM_CRIS 76 // Axis Communications 32-bit embedded processor #define EM_JAVELIN 77 // Infineon Technologies 32-bit embedded cpu #define EM_FIREPATH 78 // Element 14 64-bit DSP processor #define EM_ZSP 79 // LSI Logic's 16-bit DSP processor #define EM_MMIX 80 // Donald Knuth's educational 64-bit processor #define EM_HUANY 81 // Harvard's machine-independent format #define EM_PRISM 82 // SiTera Prism #define EM_AVR 83 // Atmel AVR 8-bit microcontroller #define EM_FR30 84 // Fujitsu FR30 #define EM_D10V 85 // Mitsubishi D10V #define EM_D30V 86 // Mitsubishi D30V #define EM_V850 87 // NEC v850 #define EM_M32R 88 // Renesas M32R (formerly Mitsubishi M32R) #define EM_MN10300 89 // Matsushita MN10300 #define EM_MN10200 90 // Matsushita MN10200 #define EM_PJ 91 // picoJava #define EM_OPENRISC 92 // OpenRISC 32-bit embedded processor #define EM_ARC_A5 93 // ARC Cores Tangent-A5 #define EM_XTENSA 94 // Tensilica Xtensa Architecture #define EM_VIDEOCORE 95 // Alphamosaic VideoCore processor #define EM_TMM_GPP 96 // Thompson Multimedia General Purpose Processor #define EM_NS32K 97 // National Semiconductor 32000 series #define EM_TPC 98 // Tenor Network TPC processor #define EM_SNP1K 99 // Trebia SNP 1000 processor #define EM_ST200 100 // STMicroelectronics ST200 microcontroller #define EM_IP2K 101 // Ubicom IP2022 micro controller #define EM_MAX 102 // MAX Processor #define EM_CR 103 // National Semiconductor CompactRISC #define EM_F2MC16 104 // Fujitsu F2MC16 #define EM_MSP430 105 // TI msp430 micro controller #define EM_BLACKFIN 106 // ADI Blackfin #define EM_SE_C33 107 // S1C33 Family of Seiko Epson processors #define EM_SEP 108 // Sharp embedded microprocessor #define EM_ARCA 109 // Arca RISC Microprocessor #define EM_UNICORE \ 110 // Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University #define EM_EXCESS 111 // eXcess: 16/32/64-bit configurable embedded CPU #define EM_DXP 112 // Icera Semiconductor Inc. Deep Execution Processor #define EM_ALTERA_NIOS2 113 // Altera Nios II soft-core processor #define EM_CRX 114 // National Semiconductor CRX #define EM_XGATE 115 // Motorola XGATE embedded processor #define EM_C166 116 // Infineon C16x/XC16x processor #define EM_M16C 117 // Renesas M16C series microprocessors #define EM_DSPIC30F \ 118 // Microchip Technology dsPIC30F Digital Signal Controller #define EM_CE 119 // Freescale Communication Engine RISC core #define EM_M32C 120 // Renesas M32C series microprocessors #define EM_res121 121 // Reserved #define EM_res122 122 // Reserved #define EM_res123 123 // Reserved #define EM_res124 124 // Reserved #define EM_res125 125 // Reserved #define EM_res126 126 // Reserved #define EM_res127 127 // Reserved #define EM_res128 128 // Reserved #define EM_res129 129 // Reserved #define EM_res130 130 // Reserved #define EM_TSK3000 131 // Altium TSK3000 core #define EM_RS08 132 // Freescale RS08 embedded processor #define EM_res133 133 // Reserved #define EM_ECOG2 134 // Cyan Technology eCOG2 microprocessor #define EM_SCORE 135 // Sunplus Score #define EM_SCORE7 135 // Sunplus S+core7 RISC processor #define EM_DSP24 136 // New Japan Radio (NJR) 24-bit DSP Processor #define EM_VIDEOCORE3 137 // Broadcom VideoCore III processor #define EM_LATTICEMICO32 138 // RISC processor for Lattice FPGA architecture #define EM_SE_C17 139 // Seiko Epson C17 family #define EM_TI_C6000 140 // Texas Instruments TMS320C6000 DSP family #define EM_TI_C2000 141 // Texas Instruments TMS320C2000 DSP family #define EM_TI_C5500 142 // Texas Instruments TMS320C55x DSP family #define EM_res143 143 // Reserved #define EM_res144 144 // Reserved #define EM_res145 145 // Reserved #define EM_res146 146 // Reserved #define EM_res147 147 // Reserved #define EM_res148 148 // Reserved #define EM_res149 149 // Reserved #define EM_res150 150 // Reserved #define EM_res151 151 // Reserved #define EM_res152 152 // Reserved #define EM_res153 153 // Reserved #define EM_res154 154 // Reserved #define EM_res155 155 // Reserved #define EM_res156 156 // Reserved #define EM_res157 157 // Reserved #define EM_res158 158 // Reserved #define EM_res159 159 // Reserved #define EM_MMDSP_PLUS 160 // STMicroelectronics 64bit VLIW Data Signal Processor #define EM_CYPRESS_M8C 161 // Cypress M8C microprocessor #define EM_R32C 162 // Renesas R32C series microprocessors #define EM_TRIMEDIA 163 // NXP Semiconductors TriMedia architecture family #define EM_QDSP6 164 // QUALCOMM DSP6 Processor #define EM_8051 165 // Intel 8051 and variants #define EM_STXP7X 166 // STMicroelectronics STxP7x family #define EM_NDS32 \ 167 // Andes Technology compact code size embedded RISC processor family #define EM_ECOG1 168 // Cyan Technology eCOG1X family #define EM_ECOG1X 168 // Cyan Technology eCOG1X family #define EM_MAXQ30 169 // Dallas Semiconductor MAXQ30 Core Micro-controllers #define EM_XIMO16 170 // New Japan Radio (NJR) 16-bit DSP Processor #define EM_MANIK 171 // M2000 Reconfigurable RISC Microprocessor #define EM_CRAYNV2 172 // Cray Inc. NV2 vector architecture #define EM_RX 173 // Renesas RX family #define EM_METAG 174 // Imagination Technologies META processor architecture #define EM_MCST_ELBRUS 175 // MCST Elbrus general purpose hardware architecture #define EM_ECOG16 176 // Cyan Technology eCOG16 family #define EM_CR16 177 // National Semiconductor CompactRISC 16-bit processor #define EM_ETPU 178 // Freescale Extended Time Processing Unit #define EM_SLE9X 179 // Infineon Technologies SLE9X core #define EM_L1OM 180 // Intel L1OM #define EM_INTEL181 181 // Reserved by Intel #define EM_INTEL182 182 // Reserved by Intel #define EM_res183 183 // Reserved by ARM #define EM_res184 184 // Reserved by ARM #define EM_AVR32 185 // Atmel Corporation 32-bit microprocessor family #define EM_STM8 186 // STMicroeletronics STM8 8-bit microcontroller #define EM_TILE64 187 // Tilera TILE64 multicore architecture family #define EM_TILEPRO 188 // Tilera TILEPro multicore architecture family #define EM_MICROBLAZE 189 // Xilinx MicroBlaze 32-bit RISC soft processor core #define EM_CUDA 190 // NVIDIA CUDA architecture #define EM_TILEGX 191 // Tilera TILE-Gx multicore architecture family #define EM_CLOUDSHIELD 192 // CloudShield architecture family #define EM_COREA_1ST 193 // KIPO-KAIST Core-A 1st generation processor family #define EM_COREA_2ND 194 // KIPO-KAIST Core-A 2nd generation processor family #define EM_ARC_COMPACT2 195 // Synopsys ARCompact V2 #define EM_OPEN8 196 // Open8 8-bit RISC soft processor core #define EM_RL78 197 // Renesas RL78 family #define EM_VIDEOCORE5 198 // Broadcom VideoCore V processor #define EM_78KOR 199 // Renesas 78KOR family #define EM_56800EX 200 // Freescale 56800EX Digital Signal Controller (DSC) #define EM_BA1 201 // Beyond BA1 CPU architecture #define EM_BA2 202 // Beyond BA2 CPU architecture #define EM_XCORE 203 // XMOS xCORE processor family #define EM_MCHP_PIC 204 // Microchip 8-bit PIC(r) family #define EM_INTEL205 205 // Reserved by Intel #define EM_INTEL206 206 // Reserved by Intel #define EM_INTEL207 207 // Reserved by Intel #define EM_INTEL208 208 // Reserved by Intel #define EM_INTEL209 209 // Reserved by Intel #define EM_KM32 210 // KM211 KM32 32-bit processor #define EM_KMX32 211 // KM211 KMX32 32-bit processor #define EM_KMX16 212 // KM211 KMX16 16-bit processor #define EM_KMX8 213 // KM211 KMX8 8-bit processor #define EM_KVARC 214 // KM211 KVARC processor #define EM_CDP 215 // Paneve CDP architecture family #define EM_COGE 216 // Cognitive Smart Memory Processor #define EM_COOL 217 // iCelero CoolEngine #define EM_NORC 218 // Nanoradio Optimized RISC #define EM_CSR_KALIMBA 219 // CSR Kalimba architecture family #define EM_Z80 220 // Zilog Z80 #define EM_VISIUM 221 // Controls and Data Services VISIUMcore processor #define EM_FT32 222 // FTDI Chip FT32 high performance 32-bit RISC architecture #define EM_MOXIE 223 // Moxie processor family #define EM_AMDGPU 224 // AMD GPU architecture #define EM_RISCV 243 // RISC-V #define EM_LANAI 244 // Lanai processor #define EM_CEVA 245 // CEVA Processor Architecture Family #define EM_CEVA_X2 246 // CEVA X2 Processor Family #define EM_BPF 247 // Linux BPF – in-kernel virtual machine #define EM_GRAPHCORE_IPU 248 // Graphcore Intelligent Processing Unit #define EM_IMG1 249 // Imagination Technologies #define EM_NFP 250 // Netronome Flow Processor (P) #define EM_CSKY 252 // C-SKY processor family // File version #define EV_NONE 0 #define EV_CURRENT 1 // Identification index #define EI_MAG0 0 #define EI_MAG1 1 #define EI_MAG2 2 #define EI_MAG3 3 #define EI_CLASS 4 #define EI_DATA 5 #define EI_VERSION 6 #define EI_OSABI 7 #define EI_ABIVERSION 8 #define EI_PAD 9 #define EI_NIDENT 16 // Magic number #define ELFMAG0 0x7F #define ELFMAG1 'E' #define ELFMAG2 'L' #define ELFMAG3 'F' // File class #define ELFCLASSNONE 0 #define ELFCLASS32 1 #define ELFCLASS64 2 // Encoding #define ELFDATANONE 0 #define ELFDATA2LSB 1 #define ELFDATA2MSB 2 // OS extensions #define ELFOSABI_NONE 0 // No extensions or unspecified #define ELFOSABI_HPUX 1 // Hewlett-Packard HP-UX #define ELFOSABI_NETBSD 2 // NetBSD #define ELFOSABI_LINUX 3 // Linux #define ELFOSABI_SOLARIS 6 // Sun Solaris #define ELFOSABI_AIX 7 // AIX #define ELFOSABI_IRIX 8 // IRIX #define ELFOSABI_FREEBSD 9 // FreeBSD #define ELFOSABI_TRU64 10 // Compaq TRU64 UNIX #define ELFOSABI_MODESTO 11 // Novell Modesto #define ELFOSABI_OPENBSD 12 // Open BSD #define ELFOSABI_OPENVMS 13 // Open VMS #define ELFOSABI_NSK 14 // Hewlett-Packard Non-Stop Kernel #define ELFOSABI_AROS 15 // Amiga Research OS #define ELFOSABI_FENIXOS 16 // The FenixOS highly scalable multi-core OS // 64-255 Architecture-specific value range #define ELFOSABI_AMDGPU_HSA \ 64 // AMDGPU OS for HSA compatible compute // kernels. #define ELFOSABI_AMDGPU_PAL \ 65 // AMDGPU OS for AMD PAL compatible graphics // shaders and compute kernels. #define ELFOSABI_AMDGPU_MESA3D \ 66 // AMDGPU OS for Mesa3D compatible graphics // shaders and compute kernels. // AMDGPU specific e_flags #define EF_AMDGPU_MACH 0x0ff // AMDGPU processor selection mask. #define EF_AMDGPU_XNACK \ 0x100 // Indicates if the XNACK target feature is // enabled for all code contained in the ELF. // AMDGPU processors #define EF_AMDGPU_MACH_NONE 0x000 // Unspecified processor. #define EF_AMDGPU_MACH_R600_R600 0x001 #define EF_AMDGPU_MACH_R600_R630 0x002 #define EF_AMDGPU_MACH_R600_RS880 0x003 #define EF_AMDGPU_MACH_R600_RV670 0x004 #define EF_AMDGPU_MACH_R600_RV710 0x005 #define EF_AMDGPU_MACH_R600_RV730 0x006 #define EF_AMDGPU_MACH_R600_RV770 0x007 #define EF_AMDGPU_MACH_R600_CEDAR 0x008 #define EF_AMDGPU_MACH_R600_CYPRESS 0x009 #define EF_AMDGPU_MACH_R600_JUNIPER 0x00a #define EF_AMDGPU_MACH_R600_REDWOOD 0x00b #define EF_AMDGPU_MACH_R600_SUMO 0x00c #define EF_AMDGPU_MACH_R600_BARTS 0x00d #define EF_AMDGPU_MACH_R600_CAICOS 0x00e #define EF_AMDGPU_MACH_R600_CAYMAN 0x00f #define EF_AMDGPU_MACH_R600_TURKS 0x010 #define EF_AMDGPU_MACH_R600_RESERVED_FIRST 0x011 #define EF_AMDGPU_MACH_R600_RESERVED_LAST 0x01f #define EF_AMDGPU_MACH_R600_FIRST EF_AMDGPU_MACH_R600_R600 #define EF_AMDGPU_MACH_R600_LAST EF_AMDGPU_MACH_R600_TURKS #define EF_AMDGPU_MACH_AMDGCN_GFX600 0x020 #define EF_AMDGPU_MACH_AMDGCN_GFX601 0x021 #define EF_AMDGPU_MACH_AMDGCN_GFX700 0x022 #define EF_AMDGPU_MACH_AMDGCN_GFX701 0x023 #define EF_AMDGPU_MACH_AMDGCN_GFX702 0x024 #define EF_AMDGPU_MACH_AMDGCN_GFX703 0x025 #define EF_AMDGPU_MACH_AMDGCN_GFX704 0x026 #define EF_AMDGPU_MACH_AMDGCN_GFX801 0x028 #define EF_AMDGPU_MACH_AMDGCN_GFX802 0x029 #define EF_AMDGPU_MACH_AMDGCN_GFX803 0x02a #define EF_AMDGPU_MACH_AMDGCN_GFX810 0x02b #define EF_AMDGPU_MACH_AMDGCN_GFX900 0x02c #define EF_AMDGPU_MACH_AMDGCN_GFX902 0x02d #define EF_AMDGPU_MACH_AMDGCN_GFX904 0x02e #define EF_AMDGPU_MACH_AMDGCN_GFX906 0x02f #define EF_AMDGPU_MACH_AMDGCN_RESERVED0 0x027 #define EF_AMDGPU_MACH_AMDGCN_RESERVED1 0x030 #define EF_AMDGPU_MACH_AMDGCN_FIRST EF_AMDGPU_MACH_AMDGCN_GFX600 #define EF_AMDGPU_MACH_AMDGCN_LAST EF_AMDGPU_MACH_AMDGCN_GFX906 ///////////////////// // Sections constants // Section indexes #define SHN_UNDEF 0 #define SHN_LORESERVE 0xFF00 #define SHN_LOPROC 0xFF00 #define SHN_HIPROC 0xFF1F #define SHN_LOOS 0xFF20 #define SHN_HIOS 0xFF3F #define SHN_ABS 0xFFF1 #define SHN_COMMON 0xFFF2 #define SHN_XINDEX 0xFFFF #define SHN_HIRESERVE 0xFFFF // Section types #define SHT_NULL 0 #define SHT_PROGBITS 1 #define SHT_SYMTAB 2 #define SHT_STRTAB 3 #define SHT_RELA 4 #define SHT_HASH 5 #define SHT_DYNAMIC 6 #define SHT_NOTE 7 #define SHT_NOBITS 8 #define SHT_REL 9 #define SHT_SHLIB 10 #define SHT_DYNSYM 11 #define SHT_INIT_ARRAY 14 #define SHT_FINI_ARRAY 15 #define SHT_PREINIT_ARRAY 16 #define SHT_GROUP 17 #define SHT_SYMTAB_SHNDX 18 #define SHT_LOOS 0x60000000 #define SHT_HIOS 0x6fffffff #define SHT_LOPROC 0x70000000 #define SHT_HIPROC 0x7FFFFFFF #define SHT_LOUSER 0x80000000 #define SHT_HIUSER 0xFFFFFFFF // Section attribute flags #define SHF_WRITE 0x1 #define SHF_ALLOC 0x2 #define SHF_EXECINSTR 0x4 #define SHF_MERGE 0x10 #define SHF_STRINGS 0x20 #define SHF_INFO_LINK 0x40 #define SHF_LINK_ORDER 0x80 #define SHF_OS_NONCONFORMING 0x100 #define SHF_GROUP 0x200 #define SHF_TLS 0x400 #define SHF_MASKOS 0x0ff00000 #define SHF_MASKPROC 0xF0000000 // Section group flags #define GRP_COMDAT 0x1 #define GRP_MASKOS 0x0ff00000 #define GRP_MASKPROC 0xf0000000 // Symbol binding #define STB_LOCAL 0 #define STB_GLOBAL 1 #define STB_WEAK 2 #define STB_LOOS 10 #define STB_HIOS 12 #define STB_MULTIDEF 13 #define STB_LOPROC 13 #define STB_HIPROC 15 // Note types #define NT_AMDGPU_METADATA 1 #define NT_AMD_AMDGPU_HSA_METADATA 10 #define NT_AMD_AMDGPU_ISA 11 #define NT_AMD_AMDGPU_PAL_METADATA 12 // Symbol types #define STT_NOTYPE 0 #define STT_OBJECT 1 #define STT_FUNC 2 #define STT_SECTION 3 #define STT_FILE 4 #define STT_COMMON 5 #define STT_TLS 6 #define STT_LOOS 10 #define STT_AMDGPU_HSA_KERNEL 10 #define STT_HIOS 12 #define STT_LOPROC 13 #define STT_HIPROC 15 // Symbol visibility #define STV_DEFAULT 0 #define STV_INTERNAL 1 #define STV_HIDDEN 2 #define STV_PROTECTED 3 // Undefined name #define STN_UNDEF 0 // Relocation types #define R_386_NONE 0 #define R_X86_64_NONE 0 #define R_AMDGPU_NONE 0 #define R_386_32 1 #define R_X86_64_64 1 #define R_AMDGPU_ABS32_LO 1 #define R_386_PC32 2 #define R_X86_64_PC32 2 #define R_AMDGPU_ABS32_HI 2 #define R_386_GOT32 3 #define R_X86_64_GOT32 3 #define R_AMDGPU_ABS64 3 #define R_386_PLT32 4 #define R_X86_64_PLT32 4 #define R_AMDGPU_REL32 4 #define R_386_COPY 5 #define R_X86_64_COPY 5 #define R_AMDGPU_REL64 5 #define R_386_GLOB_DAT 6 #define R_X86_64_GLOB_DAT 6 #define R_AMDGPU_ABS32 6 #define R_386_JMP_SLOT 7 #define R_X86_64_JUMP_SLOT 7 #define R_AMDGPU_GOTPCREL 7 #define R_386_RELATIVE 8 #define R_X86_64_RELATIVE 8 #define R_AMDGPU_GOTPCREL32_LO 8 #define R_386_GOTOFF 9 #define R_X86_64_GOTPCREL 9 #define R_AMDGPU_GOTPCREL32_HI 9 #define R_386_GOTPC 10 #define R_X86_64_32 10 #define R_AMDGPU_REL32_LO 10 #define R_386_32PLT 11 #define R_X86_64_32S 11 #define R_AMDGPU_REL32_HI 11 #define R_X86_64_16 12 #define R_X86_64_PC16 13 #define R_AMDGPU_RELATIVE64 13 #define R_386_TLS_TPOFF 14 #define R_X86_64_8 14 #define R_386_TLS_IE 15 #define R_X86_64_PC8 15 #define R_386_TLS_GOTIE 16 #define R_X86_64_DTPMOD64 16 #define R_386_TLS_LE 17 #define R_X86_64_DTPOFF64 17 #define R_386_TLS_GD 18 #define R_X86_64_TPOFF64 18 #define R_386_TLS_LDM 19 #define R_X86_64_TLSGD 19 #define R_386_16 20 #define R_X86_64_TLSLD 20 #define R_386_PC16 21 #define R_X86_64_DTPOFF32 21 #define R_386_8 22 #define R_X86_64_GOTTPOFF 22 #define R_386_PC8 23 #define R_X86_64_TPOFF32 23 #define R_386_TLS_GD_32 24 #define R_X86_64_PC64 24 #define R_386_TLS_GD_PUSH 25 #define R_X86_64_GOTOFF64 25 #define R_386_TLS_GD_CALL 26 #define R_X86_64_GOTPC32 26 #define R_386_TLS_GD_POP 27 #define R_X86_64_GOT64 27 #define R_386_TLS_LDM_32 28 #define R_X86_64_GOTPCREL64 28 #define R_386_TLS_LDM_PUSH 29 #define R_X86_64_GOTPC64 29 #define R_386_TLS_LDM_CALL 30 #define R_X86_64_GOTPLT64 30 #define R_386_TLS_LDM_POP 31 #define R_X86_64_PLTOFF64 31 #define R_386_TLS_LDO_32 32 #define R_386_TLS_IE_32 33 #define R_386_TLS_LE_32 34 #define R_X86_64_GOTPC32_TLSDESC 34 #define R_386_TLS_DTPMOD32 35 #define R_X86_64_TLSDESC_CALL 35 #define R_386_TLS_DTPOFF32 36 #define R_X86_64_TLSDESC 36 #define R_386_TLS_TPOFF32 37 #define R_X86_64_IRELATIVE 37 #define R_386_SIZE32 38 #define R_386_TLS_GOTDESC 39 #define R_386_TLS_DESC_CALL 40 #define R_386_TLS_DESC 41 #define R_386_IRELATIVE 42 #define R_386_GOT32X 43 #define R_X86_64_GNU_VTINHERIT 250 #define R_X86_64_GNU_VTENTRY 251 // Segment types #define PT_NULL 0 #define PT_LOAD 1 #define PT_DYNAMIC 2 #define PT_INTERP 3 #define PT_NOTE 4 #define PT_SHLIB 5 #define PT_PHDR 6 #define PT_TLS 7 #define PT_LOOS 0x60000000 #define PT_HIOS 0x6fffffff #define PT_LOPROC 0x70000000 #define PT_HIPROC 0x7FFFFFFF // Segment flags #define PF_X 1 // Execute #define PF_W 2 // Write #define PF_R 4 // Read #define PF_MASKOS 0x0ff00000 // Unspecified #define PF_MASKPROC 0xf0000000 // Unspecified // Dynamic Array Tags #define DT_NULL 0 #define DT_NEEDED 1 #define DT_PLTRELSZ 2 #define DT_PLTGOT 3 #define DT_HASH 4 #define DT_STRTAB 5 #define DT_SYMTAB 6 #define DT_RELA 7 #define DT_RELASZ 8 #define DT_RELAENT 9 #define DT_STRSZ 10 #define DT_SYMENT 11 #define DT_INIT 12 #define DT_FINI 13 #define DT_SONAME 14 #define DT_RPATH 15 #define DT_SYMBOLIC 16 #define DT_REL 17 #define DT_RELSZ 18 #define DT_RELENT 19 #define DT_PLTREL 20 #define DT_DEBUG 21 #define DT_TEXTREL 22 #define DT_JMPREL 23 #define DT_BIND_NOW 24 #define DT_INIT_ARRAY 25 #define DT_FINI_ARRAY 26 #define DT_INIT_ARRAYSZ 27 #define DT_FINI_ARRAYSZ 28 #define DT_RUNPATH 29 #define DT_FLAGS 30 #define DT_ENCODING 32 #define DT_PREINIT_ARRAY 32 #define DT_PREINIT_ARRAYSZ 33 #define DT_MAXPOSTAGS 34 #define DT_LOOS 0x6000000D #define DT_HIOS 0x6ffff000 #define DT_LOPROC 0x70000000 #define DT_HIPROC 0x7FFFFFFF // DT_FLAGS values #define DF_ORIGIN 0x1 #define DF_SYMBOLIC 0x2 #define DF_TEXTREL 0x4 #define DF_BIND_NOW 0x8 #define DF_STATIC_TLS 0x10 // ELF file header struct Elf32_Ehdr { unsigned char e_ident[EI_NIDENT]; Elf_Half e_type; Elf_Half e_machine; Elf_Word e_version; Elf32_Addr e_entry; Elf32_Off e_phoff; Elf32_Off e_shoff; Elf_Word e_flags; Elf_Half e_ehsize; Elf_Half e_phentsize; Elf_Half e_phnum; Elf_Half e_shentsize; Elf_Half e_shnum; Elf_Half e_shstrndx; }; struct Elf64_Ehdr { unsigned char e_ident[EI_NIDENT]; Elf_Half e_type; Elf_Half e_machine; Elf_Word e_version; Elf64_Addr e_entry; Elf64_Off e_phoff; Elf64_Off e_shoff; Elf_Word e_flags; Elf_Half e_ehsize; Elf_Half e_phentsize; Elf_Half e_phnum; Elf_Half e_shentsize; Elf_Half e_shnum; Elf_Half e_shstrndx; }; // Section header struct Elf32_Shdr { Elf_Word sh_name; Elf_Word sh_type; Elf_Word sh_flags; Elf32_Addr sh_addr; Elf32_Off sh_offset; Elf_Word sh_size; Elf_Word sh_link; Elf_Word sh_info; Elf_Word sh_addralign; Elf_Word sh_entsize; }; struct Elf64_Shdr { Elf_Word sh_name; Elf_Word sh_type; Elf_Xword sh_flags; Elf64_Addr sh_addr; Elf64_Off sh_offset; Elf_Xword sh_size; Elf_Word sh_link; Elf_Word sh_info; Elf_Xword sh_addralign; Elf_Xword sh_entsize; }; // Segment header struct Elf32_Phdr { Elf_Word p_type; Elf32_Off p_offset; Elf32_Addr p_vaddr; Elf32_Addr p_paddr; Elf_Word p_filesz; Elf_Word p_memsz; Elf_Word p_flags; Elf_Word p_align; }; struct Elf64_Phdr { Elf_Word p_type; Elf_Word p_flags; Elf64_Off p_offset; Elf64_Addr p_vaddr; Elf64_Addr p_paddr; Elf_Xword p_filesz; Elf_Xword p_memsz; Elf_Xword p_align; }; // Symbol table entry struct Elf32_Sym { Elf_Word st_name; Elf32_Addr st_value; Elf_Word st_size; unsigned char st_info; unsigned char st_other; Elf_Half st_shndx; }; struct Elf64_Sym { Elf_Word st_name; unsigned char st_info; unsigned char st_other; Elf_Half st_shndx; Elf64_Addr st_value; Elf_Xword st_size; }; #define ELF_ST_BIND( i ) ( ( i ) >> 4 ) #define ELF_ST_TYPE( i ) ( (i)&0xf ) #define ELF_ST_INFO( b, t ) ( ( ( b ) << 4 ) + ( (t)&0xf ) ) #define ELF_ST_VISIBILITY( o ) ( (o)&0x3 ) // Relocation entries struct Elf32_Rel { Elf32_Addr r_offset; Elf_Word r_info; }; struct Elf32_Rela { Elf32_Addr r_offset; Elf_Word r_info; Elf_Sword r_addend; }; struct Elf64_Rel { Elf64_Addr r_offset; Elf_Xword r_info; }; struct Elf64_Rela { Elf64_Addr r_offset; Elf_Xword r_info; Elf_Sxword r_addend; }; #define ELF32_R_SYM( i ) ( ( i ) >> 8 ) #define ELF32_R_TYPE( i ) ( (unsigned char)( i ) ) #define ELF32_R_INFO( s, t ) ( ( ( s ) << 8 ) + (unsigned char)( t ) ) #define ELF64_R_SYM( i ) ( ( i ) >> 32 ) #define ELF64_R_TYPE( i ) ( (i)&0xffffffffL ) #define ELF64_R_INFO( s, t ) \ ( ( ( ( int64_t )( s ) ) << 32 ) + ( (t)&0xffffffffL ) ) // Dynamic structure struct Elf32_Dyn { Elf_Sword d_tag; union { Elf_Word d_val; Elf32_Addr d_ptr; } d_un; }; struct Elf64_Dyn { Elf_Sxword d_tag; union { Elf_Xword d_val; Elf64_Addr d_ptr; } d_un; }; } // namespace ELFIO #endif // ELFTYPES_H /*** End of inlined file: elf_types.hpp ***/ /*** Start of inlined file: elfio_version.hpp ***/ #define ELFIO_VERSION "3.8" /*** End of inlined file: elfio_version.hpp ***/ /*** Start of inlined file: elfio_utils.hpp ***/ #ifndef ELFIO_UTILS_HPP #define ELFIO_UTILS_HPP #define ELFIO_GET_ACCESS( TYPE, NAME, FIELD ) \ TYPE get_##NAME() const { return ( *convertor )( FIELD ); } #define ELFIO_SET_ACCESS( TYPE, NAME, FIELD ) \ void set_##NAME( TYPE value ) \ { \ FIELD = value; \ FIELD = ( *convertor )( FIELD ); \ } #define ELFIO_GET_SET_ACCESS( TYPE, NAME, FIELD ) \ TYPE get_##NAME() const { return ( *convertor )( FIELD ); } \ void set_##NAME( TYPE value ) \ { \ FIELD = value; \ FIELD = ( *convertor )( FIELD ); \ } #define ELFIO_GET_ACCESS_DECL( TYPE, NAME ) virtual TYPE get_##NAME() const = 0 #define ELFIO_SET_ACCESS_DECL( TYPE, NAME ) \ virtual void set_##NAME( TYPE value ) = 0 #define ELFIO_GET_SET_ACCESS_DECL( TYPE, NAME ) \ virtual TYPE get_##NAME() const = 0; \ virtual void set_##NAME( TYPE value ) = 0 namespace ELFIO { //------------------------------------------------------------------------------ class endianess_convertor { public: //------------------------------------------------------------------------------ endianess_convertor() { need_conversion = false; } //------------------------------------------------------------------------------ void setup( unsigned char elf_file_encoding ) { need_conversion = ( elf_file_encoding != get_host_encoding() ); } //------------------------------------------------------------------------------ uint64_t operator()( uint64_t value ) const { if ( !need_conversion ) { return value; } value = ( ( value & 0x00000000000000FFull ) << 56 ) | ( ( value & 0x000000000000FF00ull ) << 40 ) | ( ( value & 0x0000000000FF0000ull ) << 24 ) | ( ( value & 0x00000000FF000000ull ) << 8 ) | ( ( value & 0x000000FF00000000ull ) >> 8 ) | ( ( value & 0x0000FF0000000000ull ) >> 24 ) | ( ( value & 0x00FF000000000000ull ) >> 40 ) | ( ( value & 0xFF00000000000000ull ) >> 56 ); return value; } //------------------------------------------------------------------------------ int64_t operator()( int64_t value ) const { if ( !need_conversion ) { return value; } return ( int64_t )( *this )( (uint64_t)value ); } //------------------------------------------------------------------------------ uint32_t operator()( uint32_t value ) const { if ( !need_conversion ) { return value; } value = ( ( value & 0x000000FF ) << 24 ) | ( ( value & 0x0000FF00 ) << 8 ) | ( ( value & 0x00FF0000 ) >> 8 ) | ( ( value & 0xFF000000 ) >> 24 ); return value; } //------------------------------------------------------------------------------ int32_t operator()( int32_t value ) const { if ( !need_conversion ) { return value; } return ( int32_t )( *this )( (uint32_t)value ); } //------------------------------------------------------------------------------ uint16_t operator()( uint16_t value ) const { if ( !need_conversion ) { return value; } value = ( ( value & 0x00FF ) << 8 ) | ( ( value & 0xFF00 ) >> 8 ); return value; } //------------------------------------------------------------------------------ int16_t operator()( int16_t value ) const { if ( !need_conversion ) { return value; } return ( int16_t )( *this )( (uint16_t)value ); } //------------------------------------------------------------------------------ int8_t operator()( int8_t value ) const { return value; } //------------------------------------------------------------------------------ uint8_t operator()( uint8_t value ) const { return value; } //------------------------------------------------------------------------------ private: //------------------------------------------------------------------------------ unsigned char get_host_encoding() const { static const int tmp = 1; if ( 1 == *(const char*)&tmp ) { return ELFDATA2LSB; } else { return ELFDATA2MSB; } } //------------------------------------------------------------------------------ private: bool need_conversion; }; //------------------------------------------------------------------------------ inline uint32_t elf_hash( const unsigned char* name ) { uint32_t h = 0, g; while ( *name ) { h = ( h << 4 ) + *name++; g = h & 0xf0000000; if ( g != 0 ) h ^= g >> 24; h &= ~g; } return h; } } // namespace ELFIO #endif // ELFIO_UTILS_HPP /*** End of inlined file: elfio_utils.hpp ***/ /*** Start of inlined file: elfio_header.hpp ***/ #ifndef ELF_HEADER_HPP #define ELF_HEADER_HPP #include namespace ELFIO { class elf_header { public: virtual ~elf_header(){}; virtual bool load( std::istream& stream ) = 0; virtual bool save( std::ostream& stream ) const = 0; // ELF header functions ELFIO_GET_ACCESS_DECL( unsigned char, class ); ELFIO_GET_ACCESS_DECL( unsigned char, elf_version ); ELFIO_GET_ACCESS_DECL( unsigned char, encoding ); ELFIO_GET_ACCESS_DECL( Elf_Half, header_size ); ELFIO_GET_ACCESS_DECL( Elf_Half, section_entry_size ); ELFIO_GET_ACCESS_DECL( Elf_Half, segment_entry_size ); ELFIO_GET_SET_ACCESS_DECL( Elf_Word, version ); ELFIO_GET_SET_ACCESS_DECL( unsigned char, os_abi ); ELFIO_GET_SET_ACCESS_DECL( unsigned char, abi_version ); ELFIO_GET_SET_ACCESS_DECL( Elf_Half, type ); ELFIO_GET_SET_ACCESS_DECL( Elf_Half, machine ); ELFIO_GET_SET_ACCESS_DECL( Elf_Word, flags ); ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, entry ); ELFIO_GET_SET_ACCESS_DECL( Elf_Half, sections_num ); ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, sections_offset ); ELFIO_GET_SET_ACCESS_DECL( Elf_Half, segments_num ); ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, segments_offset ); ELFIO_GET_SET_ACCESS_DECL( Elf_Half, section_name_str_index ); }; template struct elf_header_impl_types; template <> struct elf_header_impl_types { typedef Elf32_Phdr Phdr_type; typedef Elf32_Shdr Shdr_type; static const unsigned char file_class = ELFCLASS32; }; template <> struct elf_header_impl_types { typedef Elf64_Phdr Phdr_type; typedef Elf64_Shdr Shdr_type; static const unsigned char file_class = ELFCLASS64; }; template class elf_header_impl : public elf_header { public: //------------------------------------------------------------------------------ elf_header_impl( endianess_convertor* convertor_, unsigned char encoding ) { convertor = convertor_; std::fill_n( reinterpret_cast( &header ), sizeof( header ), '\0' ); header.e_ident[EI_MAG0] = ELFMAG0; header.e_ident[EI_MAG1] = ELFMAG1; header.e_ident[EI_MAG2] = ELFMAG2; header.e_ident[EI_MAG3] = ELFMAG3; header.e_ident[EI_CLASS] = elf_header_impl_types::file_class; header.e_ident[EI_DATA] = encoding; header.e_ident[EI_VERSION] = EV_CURRENT; header.e_version = ( *convertor )( (Elf_Word)EV_CURRENT ); header.e_ehsize = ( sizeof( header ) ); header.e_ehsize = ( *convertor )( header.e_ehsize ); header.e_shstrndx = ( *convertor )( (Elf_Half)1 ); header.e_phentsize = sizeof( typename elf_header_impl_types::Phdr_type ); header.e_shentsize = sizeof( typename elf_header_impl_types::Shdr_type ); header.e_phentsize = ( *convertor )( header.e_phentsize ); header.e_shentsize = ( *convertor )( header.e_shentsize ); } //------------------------------------------------------------------------------ bool load( std::istream& stream ) { stream.seekg( 0 ); stream.read( reinterpret_cast( &header ), sizeof( header ) ); return ( stream.gcount() == sizeof( header ) ); } //------------------------------------------------------------------------------ bool save( std::ostream& stream ) const { stream.seekp( 0 ); stream.write( reinterpret_cast( &header ), sizeof( header ) ); return stream.good(); } //------------------------------------------------------------------------------ // ELF header functions ELFIO_GET_ACCESS( unsigned char, class, header.e_ident[EI_CLASS] ); ELFIO_GET_ACCESS( unsigned char, elf_version, header.e_ident[EI_VERSION] ); ELFIO_GET_ACCESS( unsigned char, encoding, header.e_ident[EI_DATA] ); ELFIO_GET_ACCESS( Elf_Half, header_size, header.e_ehsize ); ELFIO_GET_ACCESS( Elf_Half, section_entry_size, header.e_shentsize ); ELFIO_GET_ACCESS( Elf_Half, segment_entry_size, header.e_phentsize ); ELFIO_GET_SET_ACCESS( Elf_Word, version, header.e_version ); ELFIO_GET_SET_ACCESS( unsigned char, os_abi, header.e_ident[EI_OSABI] ); ELFIO_GET_SET_ACCESS( unsigned char, abi_version, header.e_ident[EI_ABIVERSION] ); ELFIO_GET_SET_ACCESS( Elf_Half, type, header.e_type ); ELFIO_GET_SET_ACCESS( Elf_Half, machine, header.e_machine ); ELFIO_GET_SET_ACCESS( Elf_Word, flags, header.e_flags ); ELFIO_GET_SET_ACCESS( Elf_Half, section_name_str_index, header.e_shstrndx ); ELFIO_GET_SET_ACCESS( Elf64_Addr, entry, header.e_entry ); ELFIO_GET_SET_ACCESS( Elf_Half, sections_num, header.e_shnum ); ELFIO_GET_SET_ACCESS( Elf64_Off, sections_offset, header.e_shoff ); ELFIO_GET_SET_ACCESS( Elf_Half, segments_num, header.e_phnum ); ELFIO_GET_SET_ACCESS( Elf64_Off, segments_offset, header.e_phoff ); private: T header; endianess_convertor* convertor; }; } // namespace ELFIO #endif // ELF_HEADER_HPP /*** End of inlined file: elfio_header.hpp ***/ /*** Start of inlined file: elfio_section.hpp ***/ #ifndef ELFIO_SECTION_HPP #define ELFIO_SECTION_HPP #include #include #include namespace ELFIO { class section { friend class elfio; public: virtual ~section(){}; ELFIO_GET_ACCESS_DECL( Elf_Half, index ); ELFIO_GET_SET_ACCESS_DECL( std::string, name ); ELFIO_GET_SET_ACCESS_DECL( Elf_Word, type ); ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, flags ); ELFIO_GET_SET_ACCESS_DECL( Elf_Word, info ); ELFIO_GET_SET_ACCESS_DECL( Elf_Word, link ); ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, addr_align ); ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, entry_size ); ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, address ); ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, size ); ELFIO_GET_SET_ACCESS_DECL( Elf_Word, name_string_offset ); ELFIO_GET_ACCESS_DECL( Elf64_Off, offset ); virtual const char* get_data() const = 0; virtual void set_data( const char* pData, Elf_Word size ) = 0; virtual void set_data( const std::string& data ) = 0; virtual void append_data( const char* pData, Elf_Word size ) = 0; virtual void append_data( const std::string& data ) = 0; virtual size_t get_stream_size() const = 0; virtual void set_stream_size( size_t value ) = 0; protected: ELFIO_SET_ACCESS_DECL( Elf64_Off, offset ); ELFIO_SET_ACCESS_DECL( Elf_Half, index ); virtual void load( std::istream& stream, std::streampos header_offset ) = 0; virtual void save( std::ostream& stream, std::streampos header_offset, std::streampos data_offset ) = 0; virtual bool is_address_initialized() const = 0; }; template class section_impl : public section { public: //------------------------------------------------------------------------------ section_impl( const endianess_convertor* convertor_ ) : convertor( convertor_ ) { std::fill_n( reinterpret_cast( &header ), sizeof( header ), '\0' ); is_address_set = false; data = 0; data_size = 0; index = 0; stream_size = 0; } //------------------------------------------------------------------------------ ~section_impl() { delete[] data; } //------------------------------------------------------------------------------ // Section info functions ELFIO_GET_SET_ACCESS( Elf_Word, type, header.sh_type ); ELFIO_GET_SET_ACCESS( Elf_Xword, flags, header.sh_flags ); ELFIO_GET_SET_ACCESS( Elf_Xword, size, header.sh_size ); ELFIO_GET_SET_ACCESS( Elf_Word, link, header.sh_link ); ELFIO_GET_SET_ACCESS( Elf_Word, info, header.sh_info ); ELFIO_GET_SET_ACCESS( Elf_Xword, addr_align, header.sh_addralign ); ELFIO_GET_SET_ACCESS( Elf_Xword, entry_size, header.sh_entsize ); ELFIO_GET_SET_ACCESS( Elf_Word, name_string_offset, header.sh_name ); ELFIO_GET_ACCESS( Elf64_Addr, address, header.sh_addr ); //------------------------------------------------------------------------------ Elf_Half get_index() const { return index; } //------------------------------------------------------------------------------ std::string get_name() const { return name; } //------------------------------------------------------------------------------ void set_name( std::string name_ ) { name = name_; } //------------------------------------------------------------------------------ void set_address( Elf64_Addr value ) { header.sh_addr = value; header.sh_addr = ( *convertor )( header.sh_addr ); is_address_set = true; } //------------------------------------------------------------------------------ bool is_address_initialized() const { return is_address_set; } //------------------------------------------------------------------------------ const char* get_data() const { return data; } //------------------------------------------------------------------------------ void set_data( const char* raw_data, Elf_Word size ) { if ( get_type() != SHT_NOBITS ) { delete[] data; data = new ( std::nothrow ) char[size]; if ( 0 != data && 0 != raw_data ) { data_size = size; std::copy( raw_data, raw_data + size, data ); } else { data_size = 0; } } set_size( data_size ); } //------------------------------------------------------------------------------ void set_data( const std::string& str_data ) { return set_data( str_data.c_str(), (Elf_Word)str_data.size() ); } //------------------------------------------------------------------------------ void append_data( const char* raw_data, Elf_Word size ) { if ( get_type() != SHT_NOBITS ) { if ( get_size() + size < data_size ) { std::copy( raw_data, raw_data + size, data + get_size() ); } else { data_size = 2 * ( data_size + size ); char* new_data = new ( std::nothrow ) char[data_size]; if ( 0 != new_data ) { std::copy( data, data + get_size(), new_data ); std::copy( raw_data, raw_data + size, new_data + get_size() ); delete[] data; data = new_data; } else { size = 0; } } set_size( get_size() + size ); } } //------------------------------------------------------------------------------ void append_data( const std::string& str_data ) { return append_data( str_data.c_str(), (Elf_Word)str_data.size() ); } //------------------------------------------------------------------------------ protected: //------------------------------------------------------------------------------ ELFIO_GET_SET_ACCESS( Elf64_Off, offset, header.sh_offset ); //------------------------------------------------------------------------------ void set_index( Elf_Half value ) { index = value; } //------------------------------------------------------------------------------ void load( std::istream& stream, std::streampos header_offset ) { std::fill_n( reinterpret_cast( &header ), sizeof( header ), '\0' ); stream.seekg( 0, stream.end ); set_stream_size( stream.tellg() ); stream.seekg( header_offset ); stream.read( reinterpret_cast( &header ), sizeof( header ) ); Elf_Xword size = get_size(); if ( 0 == data && SHT_NULL != get_type() && SHT_NOBITS != get_type() && size < get_stream_size() ) { data = new ( std::nothrow ) char[size + 1]; if ( ( 0 != size ) && ( 0 != data ) ) { stream.seekg( ( *convertor )( header.sh_offset ) ); stream.read( data, size ); data[size] = 0; // Ensure data is ended with 0 to avoid oob read data_size = size; } else { data_size = 0; } } } //------------------------------------------------------------------------------ void save( std::ostream& stream, std::streampos header_offset, std::streampos data_offset ) { if ( 0 != get_index() ) { header.sh_offset = data_offset; header.sh_offset = ( *convertor )( header.sh_offset ); } save_header( stream, header_offset ); if ( get_type() != SHT_NOBITS && get_type() != SHT_NULL && get_size() != 0 && data != 0 ) { save_data( stream, data_offset ); } } //------------------------------------------------------------------------------ private: //------------------------------------------------------------------------------ void save_header( std::ostream& stream, std::streampos header_offset ) const { stream.seekp( header_offset ); stream.write( reinterpret_cast( &header ), sizeof( header ) ); } //------------------------------------------------------------------------------ void save_data( std::ostream& stream, std::streampos data_offset ) const { stream.seekp( data_offset ); stream.write( get_data(), get_size() ); } //------------------------------------------------------------------------------ size_t get_stream_size() const { return stream_size; } //------------------------------------------------------------------------------ void set_stream_size( size_t value ) { stream_size = value; } //------------------------------------------------------------------------------ private: T header; Elf_Half index; std::string name; char* data; Elf_Word data_size; const endianess_convertor* convertor; bool is_address_set; size_t stream_size; }; } // namespace ELFIO #endif // ELFIO_SECTION_HPP /*** End of inlined file: elfio_section.hpp ***/ /*** Start of inlined file: elfio_segment.hpp ***/ #ifndef ELFIO_SEGMENT_HPP #define ELFIO_SEGMENT_HPP #include #include #include namespace ELFIO { class segment { friend class elfio; public: virtual ~segment(){}; ELFIO_GET_ACCESS_DECL( Elf_Half, index ); ELFIO_GET_SET_ACCESS_DECL( Elf_Word, type ); ELFIO_GET_SET_ACCESS_DECL( Elf_Word, flags ); ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, align ); ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, virtual_address ); ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, physical_address ); ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, file_size ); ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, memory_size ); ELFIO_GET_ACCESS_DECL( Elf64_Off, offset ); virtual const char* get_data() const = 0; virtual Elf_Half add_section_index( Elf_Half index, Elf_Xword addr_align ) = 0; virtual Elf_Half get_sections_num() const = 0; virtual Elf_Half get_section_index_at( Elf_Half num ) const = 0; virtual bool is_offset_initialized() const = 0; protected: ELFIO_SET_ACCESS_DECL( Elf64_Off, offset ); ELFIO_SET_ACCESS_DECL( Elf_Half, index ); virtual const std::vector& get_sections() const = 0; virtual void load( std::istream& stream, std::streampos header_offset ) = 0; virtual void save( std::ostream& stream, std::streampos header_offset, std::streampos data_offset ) = 0; }; //------------------------------------------------------------------------------ template class segment_impl : public segment { public: //------------------------------------------------------------------------------ segment_impl( endianess_convertor* convertor_ ) : stream_size( 0 ), index( 0 ), data( 0 ), convertor( convertor_ ) { is_offset_set = false; std::fill_n( reinterpret_cast( &ph ), sizeof( ph ), '\0' ); } //------------------------------------------------------------------------------ virtual ~segment_impl() { delete[] data; } //------------------------------------------------------------------------------ // Section info functions ELFIO_GET_SET_ACCESS( Elf_Word, type, ph.p_type ); ELFIO_GET_SET_ACCESS( Elf_Word, flags, ph.p_flags ); ELFIO_GET_SET_ACCESS( Elf_Xword, align, ph.p_align ); ELFIO_GET_SET_ACCESS( Elf64_Addr, virtual_address, ph.p_vaddr ); ELFIO_GET_SET_ACCESS( Elf64_Addr, physical_address, ph.p_paddr ); ELFIO_GET_SET_ACCESS( Elf_Xword, file_size, ph.p_filesz ); ELFIO_GET_SET_ACCESS( Elf_Xword, memory_size, ph.p_memsz ); ELFIO_GET_ACCESS( Elf64_Off, offset, ph.p_offset ); size_t stream_size; //------------------------------------------------------------------------------ size_t get_stream_size() const { return stream_size; } //------------------------------------------------------------------------------ void set_stream_size( size_t value ) { stream_size = value; } //------------------------------------------------------------------------------ Elf_Half get_index() const { return index; } //------------------------------------------------------------------------------ const char* get_data() const { return data; } //------------------------------------------------------------------------------ Elf_Half add_section_index( Elf_Half sec_index, Elf_Xword addr_align ) { sections.push_back( sec_index ); if ( addr_align > get_align() ) { set_align( addr_align ); } return (Elf_Half)sections.size(); } //------------------------------------------------------------------------------ Elf_Half get_sections_num() const { return (Elf_Half)sections.size(); } //------------------------------------------------------------------------------ Elf_Half get_section_index_at( Elf_Half num ) const { if ( num < sections.size() ) { return sections[num]; } return Elf_Half( -1 ); } //------------------------------------------------------------------------------ protected: //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void set_offset( Elf64_Off value ) { ph.p_offset = value; ph.p_offset = ( *convertor )( ph.p_offset ); is_offset_set = true; } //------------------------------------------------------------------------------ bool is_offset_initialized() const { return is_offset_set; } //------------------------------------------------------------------------------ const std::vector& get_sections() const { return sections; } //------------------------------------------------------------------------------ void set_index( Elf_Half value ) { index = value; } //------------------------------------------------------------------------------ void load( std::istream& stream, std::streampos header_offset ) { stream.seekg( 0, stream.end ); set_stream_size( stream.tellg() ); stream.seekg( header_offset ); stream.read( reinterpret_cast( &ph ), sizeof( ph ) ); is_offset_set = true; if ( PT_NULL != get_type() && 0 != get_file_size() ) { stream.seekg( ( *convertor )( ph.p_offset ) ); Elf_Xword size = get_file_size(); if ( size > get_stream_size() ) { data = 0; } else { data = new (std::nothrow) char[size + 1]; if ( 0 != data ) { stream.read( data, size ); data[size] = 0; } } } } //------------------------------------------------------------------------------ void save( std::ostream& stream, std::streampos header_offset, std::streampos data_offset ) { ph.p_offset = data_offset; ph.p_offset = ( *convertor )( ph.p_offset ); stream.seekp( header_offset ); stream.write( reinterpret_cast( &ph ), sizeof( ph ) ); } //------------------------------------------------------------------------------ private: T ph; Elf_Half index; char* data; std::vector sections; endianess_convertor* convertor; bool is_offset_set; }; } // namespace ELFIO #endif // ELFIO_SEGMENT_HPP /*** End of inlined file: elfio_segment.hpp ***/ /*** Start of inlined file: elfio_strings.hpp ***/ #ifndef ELFIO_STRINGS_HPP #define ELFIO_STRINGS_HPP #include #include #include namespace ELFIO { //------------------------------------------------------------------------------ template class string_section_accessor_template { public: //------------------------------------------------------------------------------ string_section_accessor_template( S* section_ ) : string_section( section_ ) { } //------------------------------------------------------------------------------ const char* get_string( Elf_Word index ) const { if ( string_section ) { if ( index < string_section->get_size() ) { const char* data = string_section->get_data(); if ( 0 != data ) { return data + index; } } } return 0; } //------------------------------------------------------------------------------ Elf_Word add_string( const char* str ) { Elf_Word current_position = 0; if ( string_section ) { // Strings are addeded to the end of the current section data current_position = (Elf_Word)string_section->get_size(); if ( current_position == 0 ) { char empty_string = '\0'; string_section->append_data( &empty_string, 1 ); current_position++; } string_section->append_data( str, (Elf_Word)std::strlen( str ) + 1 ); } return current_position; } //------------------------------------------------------------------------------ Elf_Word add_string( const std::string& str ) { return add_string( str.c_str() ); } //------------------------------------------------------------------------------ private: S* string_section; }; using string_section_accessor = string_section_accessor_template
; using const_string_section_accessor = string_section_accessor_template; } // namespace ELFIO #endif // ELFIO_STRINGS_HPP /*** End of inlined file: elfio_strings.hpp ***/ #define ELFIO_HEADER_ACCESS_GET( TYPE, FNAME ) \ TYPE get_##FNAME() const { return header ? ( header->get_##FNAME() ) : 0; } #define ELFIO_HEADER_ACCESS_GET_SET( TYPE, FNAME ) \ TYPE get_##FNAME() const \ { \ return header ? ( header->get_##FNAME() ) : 0; \ } \ void set_##FNAME( TYPE val ) \ { \ if ( header ) { \ header->set_##FNAME( val ); \ } \ } namespace ELFIO { //------------------------------------------------------------------------------ class elfio { public: //------------------------------------------------------------------------------ elfio() : sections( this ), segments( this ) { header = 0; current_file_pos = 0; create( ELFCLASS32, ELFDATA2LSB ); } //------------------------------------------------------------------------------ ~elfio() { clean(); } //------------------------------------------------------------------------------ void create( unsigned char file_class, unsigned char encoding ) { clean(); convertor.setup( encoding ); header = create_header( file_class, encoding ); create_mandatory_sections(); } //------------------------------------------------------------------------------ bool load( const std::string& file_name ) { std::ifstream stream; stream.open( file_name.c_str(), std::ios::in | std::ios::binary ); if ( !stream ) { return false; } return load( stream ); } //------------------------------------------------------------------------------ bool load( std::istream& stream ) { clean(); unsigned char e_ident[EI_NIDENT]; // Read ELF file signature stream.read( reinterpret_cast( &e_ident ), sizeof( e_ident ) ); // Is it ELF file? if ( stream.gcount() != sizeof( e_ident ) || e_ident[EI_MAG0] != ELFMAG0 || e_ident[EI_MAG1] != ELFMAG1 || e_ident[EI_MAG2] != ELFMAG2 || e_ident[EI_MAG3] != ELFMAG3 ) { return false; } if ( ( e_ident[EI_CLASS] != ELFCLASS64 ) && ( e_ident[EI_CLASS] != ELFCLASS32 ) ) { return false; } convertor.setup( e_ident[EI_DATA] ); header = create_header( e_ident[EI_CLASS], e_ident[EI_DATA] ); if ( 0 == header ) { return false; } if ( !header->load( stream ) ) { return false; } load_sections( stream ); bool is_still_good = load_segments( stream ); return is_still_good; } //------------------------------------------------------------------------------ bool save( const std::string& file_name ) { std::ofstream stream; stream.open( file_name.c_str(), std::ios::out | std::ios::binary ); if ( !stream ) { return false; } return save( stream ); } //------------------------------------------------------------------------------ bool save( std::ostream& stream ) { if ( !stream || !header ) { return false; } bool is_still_good = true; // Define layout specific header fields // The position of the segment table is fixed after the header. // The position of the section table is variable and needs to be fixed // before saving. header->set_segments_num( segments.size() ); header->set_segments_offset( segments.size() ? header->get_header_size() : 0 ); header->set_sections_num( sections.size() ); header->set_sections_offset( 0 ); // Layout the first section right after the segment table current_file_pos = header->get_header_size() + header->get_segment_entry_size() * (Elf_Xword)header->get_segments_num(); calc_segment_alignment(); is_still_good = layout_segments_and_their_sections(); is_still_good = is_still_good && layout_sections_without_segments(); is_still_good = is_still_good && layout_section_table(); is_still_good = is_still_good && save_header( stream ); is_still_good = is_still_good && save_sections( stream ); is_still_good = is_still_good && save_segments( stream ); return is_still_good; } //------------------------------------------------------------------------------ // ELF header access functions ELFIO_HEADER_ACCESS_GET( unsigned char, class ); ELFIO_HEADER_ACCESS_GET( unsigned char, elf_version ); ELFIO_HEADER_ACCESS_GET( unsigned char, encoding ); ELFIO_HEADER_ACCESS_GET( Elf_Word, version ); ELFIO_HEADER_ACCESS_GET( Elf_Half, header_size ); ELFIO_HEADER_ACCESS_GET( Elf_Half, section_entry_size ); ELFIO_HEADER_ACCESS_GET( Elf_Half, segment_entry_size ); ELFIO_HEADER_ACCESS_GET_SET( unsigned char, os_abi ); ELFIO_HEADER_ACCESS_GET_SET( unsigned char, abi_version ); ELFIO_HEADER_ACCESS_GET_SET( Elf_Half, type ); ELFIO_HEADER_ACCESS_GET_SET( Elf_Half, machine ); ELFIO_HEADER_ACCESS_GET_SET( Elf_Word, flags ); ELFIO_HEADER_ACCESS_GET_SET( Elf64_Addr, entry ); ELFIO_HEADER_ACCESS_GET_SET( Elf64_Off, sections_offset ); ELFIO_HEADER_ACCESS_GET_SET( Elf64_Off, segments_offset ); ELFIO_HEADER_ACCESS_GET_SET( Elf_Half, section_name_str_index ); //------------------------------------------------------------------------------ const endianess_convertor& get_convertor() const { return convertor; } //------------------------------------------------------------------------------ Elf_Xword get_default_entry_size( Elf_Word section_type ) const { switch ( section_type ) { case SHT_RELA: if ( header->get_class() == ELFCLASS64 ) { return sizeof( Elf64_Rela ); } else { return sizeof( Elf32_Rela ); } case SHT_REL: if ( header->get_class() == ELFCLASS64 ) { return sizeof( Elf64_Rel ); } else { return sizeof( Elf32_Rel ); } case SHT_SYMTAB: if ( header->get_class() == ELFCLASS64 ) { return sizeof( Elf64_Sym ); } else { return sizeof( Elf32_Sym ); } case SHT_DYNAMIC: if ( header->get_class() == ELFCLASS64 ) { return sizeof( Elf64_Dyn ); } else { return sizeof( Elf32_Dyn ); } default: return 0; } } //------------------------------------------------------------------------------ private: bool is_offset_in_section( Elf64_Off offset, const section* sec ) const { return ( offset >= sec->get_offset() ) && ( offset < ( sec->get_offset() + sec->get_size() ) ); } //------------------------------------------------------------------------------ public: //! returns an empty string if no problems are detected, //! or a string containing an error message if problems are found std::string validate() const { // check for overlapping sections in the file for ( int i = 0; i < sections.size(); ++i ) { for ( int j = i + 1; j < sections.size(); ++j ) { const section* a = sections[i]; const section* b = sections[j]; if ( !( a->get_type() & SHT_NOBITS ) && !( b->get_type() & SHT_NOBITS ) && ( a->get_size() > 0 ) && ( b->get_size() > 0 ) && ( a->get_offset() > 0 ) && ( b->get_offset() > 0 ) ) { if ( is_offset_in_section( a->get_offset(), b ) || is_offset_in_section( a->get_offset() + a->get_size() - 1, b ) || is_offset_in_section( b->get_offset(), a ) || is_offset_in_section( b->get_offset() + b->get_size() - 1, a ) ) { return "Sections " + a->get_name() + " and " + b->get_name() + " overlap in file"; } } } } // more checks to be added here... return ""; } //------------------------------------------------------------------------------ private: //------------------------------------------------------------------------------ void clean() { delete header; header = 0; std::vector::const_iterator it; for ( it = sections_.begin(); it != sections_.end(); ++it ) { delete *it; } sections_.clear(); std::vector::const_iterator it1; for ( it1 = segments_.begin(); it1 != segments_.end(); ++it1 ) { delete *it1; } segments_.clear(); } //------------------------------------------------------------------------------ elf_header* create_header( unsigned char file_class, unsigned char encoding ) { elf_header* new_header = 0; if ( file_class == ELFCLASS64 ) { new_header = new elf_header_impl( &convertor, encoding ); } else if ( file_class == ELFCLASS32 ) { new_header = new elf_header_impl( &convertor, encoding ); } else { return 0; } return new_header; } //------------------------------------------------------------------------------ section* create_section() { section* new_section; unsigned char file_class = get_class(); if ( file_class == ELFCLASS64 ) { new_section = new section_impl( &convertor ); } else if ( file_class == ELFCLASS32 ) { new_section = new section_impl( &convertor ); } else { return 0; } new_section->set_index( (Elf_Half)sections_.size() ); sections_.push_back( new_section ); return new_section; } //------------------------------------------------------------------------------ segment* create_segment() { segment* new_segment; unsigned char file_class = header->get_class(); if ( file_class == ELFCLASS64 ) { new_segment = new segment_impl( &convertor ); } else if ( file_class == ELFCLASS32 ) { new_segment = new segment_impl( &convertor ); } else { return 0; } new_segment->set_index( (Elf_Half)segments_.size() ); segments_.push_back( new_segment ); return new_segment; } //------------------------------------------------------------------------------ void create_mandatory_sections() { // Create null section without calling to 'add_section' as no string // section containing section names exists yet section* sec0 = create_section(); sec0->set_index( 0 ); sec0->set_name( "" ); sec0->set_name_string_offset( 0 ); set_section_name_str_index( 1 ); section* shstrtab = sections.add( ".shstrtab" ); shstrtab->set_type( SHT_STRTAB ); shstrtab->set_addr_align( 1 ); } //------------------------------------------------------------------------------ Elf_Half load_sections( std::istream& stream ) { Elf_Half entry_size = header->get_section_entry_size(); Elf_Half num = header->get_sections_num(); Elf64_Off offset = header->get_sections_offset(); for ( Elf_Half i = 0; i < num; ++i ) { section* sec = create_section(); sec->load( stream, (std::streamoff)offset + (std::streampos)i * entry_size ); sec->set_index( i ); // To mark that the section is not permitted to reassign address // during layout calculation sec->set_address( sec->get_address() ); } Elf_Half shstrndx = get_section_name_str_index(); if ( SHN_UNDEF != shstrndx ) { string_section_accessor str_reader( sections[shstrndx] ); for ( Elf_Half i = 0; i < num; ++i ) { Elf_Word section_offset = sections[i]->get_name_string_offset(); const char* p = str_reader.get_string( section_offset ); if ( p != 0 ) { sections[i]->set_name( p ); } } } return num; } //------------------------------------------------------------------------------ //! Checks whether the addresses of the section entirely fall within the given segment. //! It doesn't matter if the addresses are memory addresses, or file offsets, //! they just need to be in the same address space bool is_sect_in_seg( Elf64_Off sect_begin, Elf_Xword sect_size, Elf64_Off seg_begin, Elf64_Off seg_end ) { return ( seg_begin <= sect_begin ) && ( sect_begin + sect_size <= seg_end ) && ( sect_begin < seg_end ); // this is important criteria when sect_size == 0 // Example: seg_begin=10, seg_end=12 (-> covering the bytes 10 and 11) // sect_begin=12, sect_size=0 -> shall return false! } //------------------------------------------------------------------------------ bool load_segments( std::istream& stream ) { Elf_Half entry_size = header->get_segment_entry_size(); Elf_Half num = header->get_segments_num(); Elf64_Off offset = header->get_segments_offset(); for ( Elf_Half i = 0; i < num; ++i ) { segment* seg; unsigned char file_class = header->get_class(); if ( file_class == ELFCLASS64 ) { seg = new segment_impl( &convertor ); } else if ( file_class == ELFCLASS32 ) { seg = new segment_impl( &convertor ); } else { return false; } seg->load( stream, (std::streamoff)offset + (std::streampos)i * entry_size ); seg->set_index( i ); // Add sections to the segments (similar to readelfs algorithm) Elf64_Off segBaseOffset = seg->get_offset(); Elf64_Off segEndOffset = segBaseOffset + seg->get_file_size(); Elf64_Off segVBaseAddr = seg->get_virtual_address(); Elf64_Off segVEndAddr = segVBaseAddr + seg->get_memory_size(); for ( Elf_Half j = 0; j < sections.size(); ++j ) { const section* psec = sections[j]; // SHF_ALLOC sections are matched based on the virtual address // otherwise the file offset is matched if ( ( psec->get_flags() & SHF_ALLOC ) ? is_sect_in_seg( psec->get_address(), psec->get_size(), segVBaseAddr, segVEndAddr ) : is_sect_in_seg( psec->get_offset(), psec->get_size(), segBaseOffset, segEndOffset ) ) { // Alignment of segment shall not be updated, to preserve original value // It will be re-calculated on saving. seg->add_section_index( psec->get_index(), 0 ); } } // Add section into the segments' container segments_.push_back( seg ); } return true; } //------------------------------------------------------------------------------ bool save_header( std::ostream& stream ) { return header->save( stream ); } //------------------------------------------------------------------------------ bool save_sections( std::ostream& stream ) { for ( unsigned int i = 0; i < sections_.size(); ++i ) { section* sec = sections_.at( i ); std::streampos headerPosition = (std::streamoff)header->get_sections_offset() + (std::streampos)header->get_section_entry_size() * sec->get_index(); sec->save( stream, headerPosition, sec->get_offset() ); } return true; } //------------------------------------------------------------------------------ bool save_segments( std::ostream& stream ) { for ( unsigned int i = 0; i < segments_.size(); ++i ) { segment* seg = segments_.at( i ); std::streampos headerPosition = header->get_segments_offset() + (std::streampos)header->get_segment_entry_size() * seg->get_index(); seg->save( stream, headerPosition, seg->get_offset() ); } return true; } //------------------------------------------------------------------------------ bool is_section_without_segment( unsigned int section_index ) { bool found = false; for ( unsigned int j = 0; !found && ( j < segments.size() ); ++j ) { for ( unsigned int k = 0; !found && ( k < segments[j]->get_sections_num() ); ++k ) { found = segments[j]->get_section_index_at( k ) == section_index; } } return !found; } //------------------------------------------------------------------------------ bool is_subsequence_of( segment* seg1, segment* seg2 ) { // Return 'true' if sections of seg1 are a subset of sections in seg2 const std::vector& sections1 = seg1->get_sections(); const std::vector& sections2 = seg2->get_sections(); bool found = false; if ( sections1.size() < sections2.size() ) { found = std::includes( sections2.begin(), sections2.end(), sections1.begin(), sections1.end() ); } return found; } //------------------------------------------------------------------------------ std::vector get_ordered_segments() { std::vector res; std::deque worklist; res.reserve( segments.size() ); std::copy( segments_.begin(), segments_.end(), std::back_inserter( worklist ) ); // Bring the segments which start at address 0 to the front size_t nextSlot = 0; for ( size_t i = 0; i < worklist.size(); ++i ) { if ( i != nextSlot && worklist[i]->is_offset_initialized() && worklist[i]->get_offset() == 0 ) { if ( worklist[nextSlot]->get_offset() == 0 ) { ++nextSlot; } std::swap( worklist[i], worklist[nextSlot] ); ++nextSlot; } } while ( !worklist.empty() ) { segment* seg = worklist.front(); worklist.pop_front(); size_t i = 0; for ( ; i < worklist.size(); ++i ) { if ( is_subsequence_of( seg, worklist[i] ) ) { break; } } if ( i < worklist.size() ) worklist.push_back( seg ); else res.push_back( seg ); } return res; } //------------------------------------------------------------------------------ bool layout_sections_without_segments() { for ( unsigned int i = 0; i < sections_.size(); ++i ) { if ( is_section_without_segment( i ) ) { section* sec = sections_[i]; Elf_Xword section_align = sec->get_addr_align(); if ( section_align > 1 && current_file_pos % section_align != 0 ) { current_file_pos += section_align - current_file_pos % section_align; } if ( 0 != sec->get_index() ) sec->set_offset( current_file_pos ); if ( SHT_NOBITS != sec->get_type() && SHT_NULL != sec->get_type() ) { current_file_pos += sec->get_size(); } } } return true; } //------------------------------------------------------------------------------ void calc_segment_alignment() { for ( std::vector::iterator s = segments_.begin(); s != segments_.end(); ++s ) { segment* seg = *s; for ( int i = 0; i < seg->get_sections_num(); ++i ) { section* sect = sections_[seg->get_section_index_at( i )]; if ( sect->get_addr_align() > seg->get_align() ) { seg->set_align( sect->get_addr_align() ); } } } } //------------------------------------------------------------------------------ bool layout_segments_and_their_sections() { std::vector worklist; std::vector section_generated( sections.size(), false ); // Get segments in a order in where segments which contain a // sub sequence of other segments are located at the end worklist = get_ordered_segments(); for ( unsigned int i = 0; i < worklist.size(); ++i ) { Elf_Xword segment_memory = 0; Elf_Xword segment_filesize = 0; Elf_Xword seg_start_pos = current_file_pos; segment* seg = worklist[i]; // Special case: PHDR segment // This segment contains the program headers but no sections if ( seg->get_type() == PT_PHDR && seg->get_sections_num() == 0 ) { seg_start_pos = header->get_segments_offset(); segment_memory = segment_filesize = header->get_segment_entry_size() * (Elf_Xword)header->get_segments_num(); } // Special case: else if ( seg->is_offset_initialized() && seg->get_offset() == 0 ) { seg_start_pos = 0; if ( seg->get_sections_num() ) { segment_memory = segment_filesize = current_file_pos; } } // New segments with not generated sections // have to be aligned else if ( seg->get_sections_num() && !section_generated[seg->get_section_index_at( 0 )] ) { Elf_Xword align = seg->get_align() > 0 ? seg->get_align() : 1; Elf64_Off cur_page_alignment = current_file_pos % align; Elf64_Off req_page_alignment = seg->get_virtual_address() % align; Elf64_Off error = req_page_alignment - cur_page_alignment; current_file_pos += ( seg->get_align() + error ) % align; seg_start_pos = current_file_pos; } else if ( seg->get_sections_num() ) { seg_start_pos = sections[seg->get_section_index_at( 0 )]->get_offset(); } // Write segment's data for ( unsigned int j = 0; j < seg->get_sections_num(); ++j ) { Elf_Half index = seg->get_section_index_at( j ); section* sec = sections[index]; // The NULL section is always generated if ( SHT_NULL == sec->get_type() ) { section_generated[index] = true; continue; } Elf_Xword secAlign = 0; // Fix up the alignment if ( !section_generated[index] && sec->is_address_initialized() && SHT_NOBITS != sec->get_type() && SHT_NULL != sec->get_type() && 0 != sec->get_size() ) { // Align the sections based on the virtual addresses // when possible (this is what matters for execution) Elf64_Off req_offset = sec->get_address() - seg->get_virtual_address(); Elf64_Off cur_offset = current_file_pos - seg_start_pos; if ( req_offset < cur_offset ) { // something has gone awfully wrong, abort! // secAlign would turn out negative, seeking backwards and overwriting previous data return false; } secAlign = req_offset - cur_offset; } else if ( !section_generated[index] && !sec->is_address_initialized() ) { // If no address has been specified then only the section // alignment constraint has to be matched Elf_Xword align = sec->get_addr_align(); if ( align == 0 ) { align = 1; } Elf64_Off error = current_file_pos % align; secAlign = ( align - error ) % align; } else if ( section_generated[index] ) { // Alignment for already generated sections secAlign = sec->get_offset() - seg_start_pos - segment_filesize; } // Determine the segment file and memory sizes // Special case .tbss section (NOBITS) in non TLS segment if ( ( sec->get_flags() & SHF_ALLOC ) && !( ( sec->get_flags() & SHF_TLS ) && ( seg->get_type() != PT_TLS ) && ( SHT_NOBITS == sec->get_type() ) ) ) segment_memory += sec->get_size() + secAlign; if ( SHT_NOBITS != sec->get_type() ) segment_filesize += sec->get_size() + secAlign; // Nothing to be done when generating nested segments if ( section_generated[index] ) { continue; } current_file_pos += secAlign; // Set the section addresses when missing if ( !sec->is_address_initialized() ) sec->set_address( seg->get_virtual_address() + current_file_pos - seg_start_pos ); if ( 0 != sec->get_index() ) sec->set_offset( current_file_pos ); if ( SHT_NOBITS != sec->get_type() ) current_file_pos += sec->get_size(); section_generated[index] = true; } seg->set_file_size( segment_filesize ); // If we already have a memory size from loading an elf file (value > 0), // it must not shrink! // Memory size may be bigger than file size and it is the loader's job to do something // with the surplus bytes in memory, like initializing them with a defined value. if ( seg->get_memory_size() < segment_memory ) { seg->set_memory_size( segment_memory ); } seg->set_offset( seg_start_pos ); } return true; } //------------------------------------------------------------------------------ bool layout_section_table() { // Simply place the section table at the end for now Elf64_Off alignmentError = current_file_pos % 4; current_file_pos += ( 4 - alignmentError ) % 4; header->set_sections_offset( current_file_pos ); return true; } //------------------------------------------------------------------------------ public: friend class Sections; class Sections { public: //------------------------------------------------------------------------------ Sections( elfio* parent_ ) : parent( parent_ ) {} //------------------------------------------------------------------------------ Elf_Half size() const { return (Elf_Half)parent->sections_.size(); } //------------------------------------------------------------------------------ section* operator[]( unsigned int index ) const { section* sec = 0; if ( index < parent->sections_.size() ) { sec = parent->sections_[index]; } return sec; } //------------------------------------------------------------------------------ section* operator[]( const std::string& name ) const { section* sec = 0; std::vector::const_iterator it; for ( it = parent->sections_.begin(); it != parent->sections_.end(); ++it ) { if ( ( *it )->get_name() == name ) { sec = *it; break; } } return sec; } //------------------------------------------------------------------------------ section* add( const std::string& name ) { section* new_section = parent->create_section(); new_section->set_name( name ); Elf_Half str_index = parent->get_section_name_str_index(); section* string_table( parent->sections_[str_index] ); string_section_accessor str_writer( string_table ); Elf_Word pos = str_writer.add_string( name ); new_section->set_name_string_offset( pos ); return new_section; } //------------------------------------------------------------------------------ std::vector::iterator begin() { return parent->sections_.begin(); } //------------------------------------------------------------------------------ std::vector::iterator end() { return parent->sections_.end(); } //------------------------------------------------------------------------------ std::vector::const_iterator begin() const { return parent->sections_.cbegin(); } //------------------------------------------------------------------------------ std::vector::const_iterator end() const { return parent->sections_.cend(); } //------------------------------------------------------------------------------ private: elfio* parent; } sections; //------------------------------------------------------------------------------ public: friend class Segments; class Segments { public: //------------------------------------------------------------------------------ Segments( elfio* parent_ ) : parent( parent_ ) {} //------------------------------------------------------------------------------ Elf_Half size() const { return (Elf_Half)parent->segments_.size(); } //------------------------------------------------------------------------------ segment* operator[]( unsigned int index ) const { return parent->segments_[index]; } //------------------------------------------------------------------------------ segment* add() { return parent->create_segment(); } //------------------------------------------------------------------------------ std::vector::iterator begin() { return parent->segments_.begin(); } //------------------------------------------------------------------------------ std::vector::iterator end() { return parent->segments_.end(); } //------------------------------------------------------------------------------ std::vector::const_iterator begin() const { return parent->segments_.cbegin(); } //------------------------------------------------------------------------------ std::vector::const_iterator end() const { return parent->segments_.cend(); } //------------------------------------------------------------------------------ private: elfio* parent; } segments; //------------------------------------------------------------------------------ private: elf_header* header; std::vector sections_; std::vector segments_; endianess_convertor convertor; Elf_Xword current_file_pos; }; } // namespace ELFIO /*** Start of inlined file: elfio_symbols.hpp ***/ #ifndef ELFIO_SYMBOLS_HPP #define ELFIO_SYMBOLS_HPP namespace ELFIO { //------------------------------------------------------------------------------ template class symbol_section_accessor_template { public: //------------------------------------------------------------------------------ symbol_section_accessor_template( const elfio& elf_file_, S* symbol_section_ ) : elf_file( elf_file_ ), symbol_section( symbol_section_ ) { find_hash_section(); } //------------------------------------------------------------------------------ Elf_Xword get_symbols_num() const { Elf_Xword nRet = 0; if ( 0 != symbol_section->get_entry_size() ) { nRet = symbol_section->get_size() / symbol_section->get_entry_size(); } return nRet; } //------------------------------------------------------------------------------ bool get_symbol( Elf_Xword index, std::string& name, Elf64_Addr& value, Elf_Xword& size, unsigned char& bind, unsigned char& type, Elf_Half& section_index, unsigned char& other ) const { bool ret = false; if ( elf_file.get_class() == ELFCLASS32 ) { ret = generic_get_symbol( index, name, value, size, bind, type, section_index, other ); } else { ret = generic_get_symbol( index, name, value, size, bind, type, section_index, other ); } return ret; } //------------------------------------------------------------------------------ bool get_symbol( const std::string& name, Elf64_Addr& value, Elf_Xword& size, unsigned char& bind, unsigned char& type, Elf_Half& section_index, unsigned char& other ) const { bool ret = false; if ( 0 != get_hash_table_index() ) { Elf_Word nbucket = *(const Elf_Word*)hash_section->get_data(); Elf_Word nchain = *(const Elf_Word*)( hash_section->get_data() + sizeof( Elf_Word ) ); Elf_Word val = elf_hash( (const unsigned char*)name.c_str() ); Elf_Word y = *(const Elf_Word*)( hash_section->get_data() + ( 2 + val % nbucket ) * sizeof( Elf_Word ) ); std::string str; get_symbol( y, str, value, size, bind, type, section_index, other ); while ( str != name && STN_UNDEF != y && y < nchain ) { y = *(const Elf_Word*)( hash_section->get_data() + ( 2 + nbucket + y ) * sizeof( Elf_Word ) ); get_symbol( y, str, value, size, bind, type, section_index, other ); } if ( str == name ) { ret = true; } } else { for ( Elf_Xword i = 0; i < get_symbols_num() && !ret; i++ ) { std::string symbol_name; if ( get_symbol( i, symbol_name, value, size, bind, type, section_index, other ) ) { if ( symbol_name == name ) { ret = true; } } } } return ret; } //------------------------------------------------------------------------------ bool get_symbol( const Elf64_Addr& value, std::string& name, Elf_Xword& size, unsigned char& bind, unsigned char& type, Elf_Half& section_index, unsigned char& other ) const { const endianess_convertor& convertor = elf_file.get_convertor(); Elf_Xword idx = 0; bool match = false; Elf64_Addr v = 0; if ( elf_file.get_class() == ELFCLASS32 ) { match = generic_search_symbols( [&]( const Elf32_Sym* sym ) { return convertor( sym->st_value ) == value; }, idx ); } else { match = generic_search_symbols( [&]( const Elf64_Sym* sym ) { return convertor( sym->st_value ) == value; }, idx ); } if ( match ) { return get_symbol( idx, name, v, size, bind, type, section_index, other ); } return false; } //------------------------------------------------------------------------------ Elf_Word add_symbol( Elf_Word name, Elf64_Addr value, Elf_Xword size, unsigned char info, unsigned char other, Elf_Half shndx ) { Elf_Word nRet; if ( symbol_section->get_size() == 0 ) { if ( elf_file.get_class() == ELFCLASS32 ) { nRet = generic_add_symbol( 0, 0, 0, 0, 0, 0 ); } else { nRet = generic_add_symbol( 0, 0, 0, 0, 0, 0 ); } } if ( elf_file.get_class() == ELFCLASS32 ) { nRet = generic_add_symbol( name, value, size, info, other, shndx ); } else { nRet = generic_add_symbol( name, value, size, info, other, shndx ); } return nRet; } //------------------------------------------------------------------------------ Elf_Word add_symbol( Elf_Word name, Elf64_Addr value, Elf_Xword size, unsigned char bind, unsigned char type, unsigned char other, Elf_Half shndx ) { return add_symbol( name, value, size, ELF_ST_INFO( bind, type ), other, shndx ); } //------------------------------------------------------------------------------ Elf_Word add_symbol( string_section_accessor& pStrWriter, const char* str, Elf64_Addr value, Elf_Xword size, unsigned char info, unsigned char other, Elf_Half shndx ) { Elf_Word index = pStrWriter.add_string( str ); return add_symbol( index, value, size, info, other, shndx ); } //------------------------------------------------------------------------------ Elf_Word add_symbol( string_section_accessor& pStrWriter, const char* str, Elf64_Addr value, Elf_Xword size, unsigned char bind, unsigned char type, unsigned char other, Elf_Half shndx ) { return add_symbol( pStrWriter, str, value, size, ELF_ST_INFO( bind, type ), other, shndx ); } //------------------------------------------------------------------------------ Elf_Xword arrange_local_symbols( std::function func = nullptr ) { int nRet = 0; if ( elf_file.get_class() == ELFCLASS32 ) { nRet = generic_arrange_local_symbols( func ); } else { nRet = generic_arrange_local_symbols( func ); } return nRet; } //------------------------------------------------------------------------------ private: //------------------------------------------------------------------------------ void find_hash_section() { hash_section = 0; hash_section_index = 0; Elf_Half nSecNo = elf_file.sections.size(); for ( Elf_Half i = 0; i < nSecNo && 0 == hash_section_index; ++i ) { const section* sec = elf_file.sections[i]; if ( sec->get_link() == symbol_section->get_index() ) { hash_section = sec; hash_section_index = i; } } } //------------------------------------------------------------------------------ Elf_Half get_string_table_index() const { return (Elf_Half)symbol_section->get_link(); } //------------------------------------------------------------------------------ Elf_Half get_hash_table_index() const { return hash_section_index; } //------------------------------------------------------------------------------ template const T* generic_get_symbol_ptr( Elf_Xword index ) const { if ( 0 != symbol_section->get_data() && index < get_symbols_num() ) { const T* pSym = reinterpret_cast( symbol_section->get_data() + index * symbol_section->get_entry_size() ); return pSym; } return nullptr; } //------------------------------------------------------------------------------ template bool generic_search_symbols( std::function match, Elf_Xword& idx ) const { for ( Elf_Xword i = 0; i < get_symbols_num(); i++ ) { const T* symPtr = generic_get_symbol_ptr( i ); if ( symPtr == nullptr ) return false; if ( match( symPtr ) ) { idx = i; return true; } } return false; } //------------------------------------------------------------------------------ template bool generic_get_symbol( Elf_Xword index, std::string& name, Elf64_Addr& value, Elf_Xword& size, unsigned char& bind, unsigned char& type, Elf_Half& section_index, unsigned char& other ) const { bool ret = false; if ( 0 != symbol_section->get_data() && index < get_symbols_num() ) { const T* pSym = reinterpret_cast( symbol_section->get_data() + index * symbol_section->get_entry_size() ); const endianess_convertor& convertor = elf_file.get_convertor(); section* string_section = elf_file.sections[get_string_table_index()]; string_section_accessor str_reader( string_section ); const char* pStr = str_reader.get_string( convertor( pSym->st_name ) ); if ( 0 != pStr ) { name = pStr; } value = convertor( pSym->st_value ); size = convertor( pSym->st_size ); bind = ELF_ST_BIND( pSym->st_info ); type = ELF_ST_TYPE( pSym->st_info ); section_index = convertor( pSym->st_shndx ); other = pSym->st_other; ret = true; } return ret; } //------------------------------------------------------------------------------ template Elf_Word generic_add_symbol( Elf_Word name, Elf64_Addr value, Elf_Xword size, unsigned char info, unsigned char other, Elf_Half shndx ) { const endianess_convertor& convertor = elf_file.get_convertor(); T entry; entry.st_name = convertor( name ); entry.st_value = value; entry.st_value = convertor( entry.st_value ); entry.st_size = size; entry.st_size = convertor( entry.st_size ); entry.st_info = convertor( info ); entry.st_other = convertor( other ); entry.st_shndx = convertor( shndx ); symbol_section->append_data( reinterpret_cast( &entry ), sizeof( entry ) ); Elf_Word nRet = symbol_section->get_size() / sizeof( entry ) - 1; return nRet; } //------------------------------------------------------------------------------ template Elf_Xword generic_arrange_local_symbols( std::function func ) { const endianess_convertor& convertor = elf_file.get_convertor(); const Elf_Xword size = symbol_section->get_entry_size(); Elf_Xword first_not_local = 1; // Skip the first entry. It is always NOTYPE Elf_Xword current = 0; Elf_Xword count = get_symbols_num(); while ( true ) { T* p1 = nullptr; T* p2 = nullptr; while ( first_not_local < count ) { p1 = const_cast( generic_get_symbol_ptr( first_not_local ) ); if ( ELF_ST_BIND( convertor( p1->st_info ) ) != STB_LOCAL ) break; ++first_not_local; } current = first_not_local + 1; while ( current < count ) { p2 = const_cast( generic_get_symbol_ptr( current ) ); if ( ELF_ST_BIND( convertor( p2->st_info ) ) == STB_LOCAL ) break; ++current; } if ( first_not_local < count && current < count ) { if ( func ) func( first_not_local, current ); // Swap the symbols T tmp; std::copy( p1, p1 + 1, &tmp ); std::copy( p2, p2 + 1, p1 ); std::copy( &tmp, &tmp + 1, p2 ); } else { // Update 'info' field of the section symbol_section->set_info( first_not_local ); break; } } // Elf_Word nRet = symbol_section->get_size() / sizeof(entry) - 1; return first_not_local; } //------------------------------------------------------------------------------ private: const elfio& elf_file; S* symbol_section; Elf_Half hash_section_index; const section* hash_section; }; using symbol_section_accessor = symbol_section_accessor_template
; using const_symbol_section_accessor = symbol_section_accessor_template; } // namespace ELFIO #endif // ELFIO_SYMBOLS_HPP /*** End of inlined file: elfio_symbols.hpp ***/ /*** Start of inlined file: elfio_note.hpp ***/ #ifndef ELFIO_NOTE_HPP #define ELFIO_NOTE_HPP namespace ELFIO { //------------------------------------------------------------------------------ // There are discrepancies in documentations. SCO documentation // (http://www.sco.com/developers/gabi/latest/ch5.pheader.html#note_section) // requires 8 byte entries alignment for 64-bit ELF file, // but Oracle's definition uses the same structure // for 32-bit and 64-bit formats. // (https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-18048.html) // // It looks like EM_X86_64 Linux implementation is similar to Oracle's // definition. Therefore, the same alignment works for both formats //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ template class note_section_accessor_template { public: //------------------------------------------------------------------------------ note_section_accessor_template( const elfio& elf_file_, S* section_ ) : elf_file( elf_file_ ), note_section( section_ ) { process_section(); } //------------------------------------------------------------------------------ Elf_Word get_notes_num() const { return (Elf_Word)note_start_positions.size(); } //------------------------------------------------------------------------------ bool get_note( Elf_Word index, Elf_Word& type, std::string& name, void*& desc, Elf_Word& descSize ) const { if ( index >= note_section->get_size() ) { return false; } const char* pData = note_section->get_data() + note_start_positions[index]; int align = sizeof( Elf_Word ); const endianess_convertor& convertor = elf_file.get_convertor(); type = convertor( *(const Elf_Word*)( pData + 2 * align ) ); Elf_Word namesz = convertor( *(const Elf_Word*)( pData ) ); descSize = convertor( *(const Elf_Word*)( pData + sizeof( namesz ) ) ); Elf_Xword max_name_size = note_section->get_size() - note_start_positions[index]; if ( namesz < 1 || namesz > max_name_size || (Elf_Xword)namesz + descSize > max_name_size ) { return false; } name.assign( pData + 3 * align, namesz - 1 ); if ( 0 == descSize ) { desc = 0; } else { desc = const_cast( pData + 3 * align + ( ( namesz + align - 1 ) / align ) * align ); } return true; } //------------------------------------------------------------------------------ void add_note( Elf_Word type, const std::string& name, const void* desc, Elf_Word descSize ) { const endianess_convertor& convertor = elf_file.get_convertor(); int align = sizeof( Elf_Word ); Elf_Word nameLen = (Elf_Word)name.size() + 1; Elf_Word nameLenConv = convertor( nameLen ); std::string buffer( reinterpret_cast( &nameLenConv ), align ); Elf_Word descSizeConv = convertor( descSize ); buffer.append( reinterpret_cast( &descSizeConv ), align ); type = convertor( type ); buffer.append( reinterpret_cast( &type ), align ); buffer.append( name ); buffer.append( 1, '\x00' ); const char pad[] = { '\0', '\0', '\0', '\0' }; if ( nameLen % align != 0 ) { buffer.append( pad, align - nameLen % align ); } if ( desc != 0 && descSize != 0 ) { buffer.append( reinterpret_cast( desc ), descSize ); if ( descSize % align != 0 ) { buffer.append( pad, align - descSize % align ); } } note_start_positions.push_back( note_section->get_size() ); note_section->append_data( buffer ); } private: //------------------------------------------------------------------------------ void process_section() { const endianess_convertor& convertor = elf_file.get_convertor(); const char* data = note_section->get_data(); Elf_Xword size = note_section->get_size(); Elf_Xword current = 0; note_start_positions.clear(); // Is it empty? if ( 0 == data || 0 == size ) { return; } Elf_Word align = sizeof( Elf_Word ); while ( current + (Elf_Xword)3 * align <= size ) { note_start_positions.push_back( current ); Elf_Word namesz = convertor( *(const Elf_Word*)( data + current ) ); Elf_Word descsz = convertor( *(const Elf_Word*)( data + current + sizeof( namesz ) ) ); current += (Elf_Xword)3 * sizeof( Elf_Word ) + ( ( namesz + align - 1 ) / align ) * (Elf_Xword)align + ( ( descsz + align - 1 ) / align ) * (Elf_Xword)align; } } //------------------------------------------------------------------------------ private: const elfio& elf_file; S* note_section; std::vector note_start_positions; }; using note_section_accessor = note_section_accessor_template
; using const_note_section_accessor = note_section_accessor_template; } // namespace ELFIO #endif // ELFIO_NOTE_HPP /*** End of inlined file: elfio_note.hpp ***/ /*** Start of inlined file: elfio_relocation.hpp ***/ #ifndef ELFIO_RELOCATION_HPP #define ELFIO_RELOCATION_HPP namespace ELFIO { template struct get_sym_and_type; template <> struct get_sym_and_type { static int get_r_sym( Elf_Xword info ) { return ELF32_R_SYM( (Elf_Word)info ); } static int get_r_type( Elf_Xword info ) { return ELF32_R_TYPE( (Elf_Word)info ); } }; template <> struct get_sym_and_type { static int get_r_sym( Elf_Xword info ) { return ELF32_R_SYM( (Elf_Word)info ); } static int get_r_type( Elf_Xword info ) { return ELF32_R_TYPE( (Elf_Word)info ); } }; template <> struct get_sym_and_type { static int get_r_sym( Elf_Xword info ) { return ELF64_R_SYM( info ); } static int get_r_type( Elf_Xword info ) { return ELF64_R_TYPE( info ); } }; template <> struct get_sym_and_type { static int get_r_sym( Elf_Xword info ) { return ELF64_R_SYM( info ); } static int get_r_type( Elf_Xword info ) { return ELF64_R_TYPE( info ); } }; //------------------------------------------------------------------------------ template class relocation_section_accessor_template { public: //------------------------------------------------------------------------------ relocation_section_accessor_template( const elfio& elf_file_, S* section_ ) : elf_file( elf_file_ ), relocation_section( section_ ) { } //------------------------------------------------------------------------------ Elf_Xword get_entries_num() const { Elf_Xword nRet = 0; if ( 0 != relocation_section->get_entry_size() ) { nRet = relocation_section->get_size() / relocation_section->get_entry_size(); } return nRet; } //------------------------------------------------------------------------------ bool get_entry( Elf_Xword index, Elf64_Addr& offset, Elf_Word& symbol, Elf_Word& type, Elf_Sxword& addend ) const { if ( index >= get_entries_num() ) { // Is index valid return false; } if ( elf_file.get_class() == ELFCLASS32 ) { if ( SHT_REL == relocation_section->get_type() ) { generic_get_entry_rel( index, offset, symbol, type, addend ); } else if ( SHT_RELA == relocation_section->get_type() ) { generic_get_entry_rela( index, offset, symbol, type, addend ); } } else { if ( SHT_REL == relocation_section->get_type() ) { generic_get_entry_rel( index, offset, symbol, type, addend ); } else if ( SHT_RELA == relocation_section->get_type() ) { generic_get_entry_rela( index, offset, symbol, type, addend ); } } return true; } //------------------------------------------------------------------------------ bool get_entry( Elf_Xword index, Elf64_Addr& offset, Elf64_Addr& symbolValue, std::string& symbolName, Elf_Word& type, Elf_Sxword& addend, Elf_Sxword& calcValue ) const { // Do regular job Elf_Word symbol; bool ret = get_entry( index, offset, symbol, type, addend ); // Find the symbol Elf_Xword size; unsigned char bind; unsigned char symbolType; Elf_Half section; unsigned char other; symbol_section_accessor symbols( elf_file, elf_file.sections[get_symbol_table_index()] ); ret = ret && symbols.get_symbol( symbol, symbolName, symbolValue, size, bind, symbolType, section, other ); if ( ret ) { // Was it successful? switch ( type ) { case R_386_NONE: // none calcValue = 0; break; case R_386_32: // S + A calcValue = symbolValue + addend; break; case R_386_PC32: // S + A - P calcValue = symbolValue + addend - offset; break; case R_386_GOT32: // G + A - P calcValue = 0; break; case R_386_PLT32: // L + A - P calcValue = 0; break; case R_386_COPY: // none calcValue = 0; break; case R_386_GLOB_DAT: // S case R_386_JMP_SLOT: // S calcValue = symbolValue; break; case R_386_RELATIVE: // B + A calcValue = addend; break; case R_386_GOTOFF: // S + A - GOT calcValue = 0; break; case R_386_GOTPC: // GOT + A - P calcValue = 0; break; default: // Not recognized symbol! calcValue = 0; break; } } return ret; } //------------------------------------------------------------------------------ bool set_entry( Elf_Xword index, Elf64_Addr offset, Elf_Word symbol, Elf_Word type, Elf_Sxword addend ) { if ( index >= get_entries_num() ) { // Is index valid return false; } if ( elf_file.get_class() == ELFCLASS32 ) { if ( SHT_REL == relocation_section->get_type() ) { generic_set_entry_rel( index, offset, symbol, type, addend ); } else if ( SHT_RELA == relocation_section->get_type() ) { generic_set_entry_rela( index, offset, symbol, type, addend ); } } else { if ( SHT_REL == relocation_section->get_type() ) { generic_set_entry_rel( index, offset, symbol, type, addend ); } else if ( SHT_RELA == relocation_section->get_type() ) { generic_set_entry_rela( index, offset, symbol, type, addend ); } } return true; } //------------------------------------------------------------------------------ void add_entry( Elf64_Addr offset, Elf_Xword info ) { if ( elf_file.get_class() == ELFCLASS32 ) { generic_add_entry( offset, info ); } else { generic_add_entry( offset, info ); } } //------------------------------------------------------------------------------ void add_entry( Elf64_Addr offset, Elf_Word symbol, unsigned char type ) { Elf_Xword info; if ( elf_file.get_class() == ELFCLASS32 ) { info = ELF32_R_INFO( (Elf_Xword)symbol, type ); } else { info = ELF64_R_INFO( (Elf_Xword)symbol, type ); } add_entry( offset, info ); } //------------------------------------------------------------------------------ void add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend ) { if ( elf_file.get_class() == ELFCLASS32 ) { generic_add_entry( offset, info, addend ); } else { generic_add_entry( offset, info, addend ); } } //------------------------------------------------------------------------------ void add_entry( Elf64_Addr offset, Elf_Word symbol, unsigned char type, Elf_Sxword addend ) { Elf_Xword info; if ( elf_file.get_class() == ELFCLASS32 ) { info = ELF32_R_INFO( (Elf_Xword)symbol, type ); } else { info = ELF64_R_INFO( (Elf_Xword)symbol, type ); } add_entry( offset, info, addend ); } //------------------------------------------------------------------------------ void add_entry( string_section_accessor str_writer, const char* str, symbol_section_accessor sym_writer, Elf64_Addr value, Elf_Word size, unsigned char sym_info, unsigned char other, Elf_Half shndx, Elf64_Addr offset, unsigned char type ) { Elf_Word str_index = str_writer.add_string( str ); Elf_Word sym_index = sym_writer.add_symbol( str_index, value, size, sym_info, other, shndx ); add_entry( offset, sym_index, type ); } //------------------------------------------------------------------------------ void swap_symbols( Elf_Xword first, Elf_Xword second ) { Elf64_Addr offset; Elf_Word symbol; Elf_Word rtype; Elf_Sxword addend; for ( Elf_Word i = 0; i < get_entries_num(); i++ ) { get_entry( i, offset, symbol, rtype, addend ); if ( symbol == first ) { set_entry( i, offset, (Elf_Word)second, rtype, addend ); } if ( symbol == second ) { set_entry( i, offset, (Elf_Word)first, rtype, addend ); } } } //------------------------------------------------------------------------------ private: //------------------------------------------------------------------------------ Elf_Half get_symbol_table_index() const { return (Elf_Half)relocation_section->get_link(); } //------------------------------------------------------------------------------ template void generic_get_entry_rel( Elf_Xword index, Elf64_Addr& offset, Elf_Word& symbol, Elf_Word& type, Elf_Sxword& addend ) const { const endianess_convertor& convertor = elf_file.get_convertor(); const T* pEntry = reinterpret_cast( relocation_section->get_data() + index * relocation_section->get_entry_size() ); offset = convertor( pEntry->r_offset ); Elf_Xword tmp = convertor( pEntry->r_info ); symbol = get_sym_and_type::get_r_sym( tmp ); type = get_sym_and_type::get_r_type( tmp ); addend = 0; } //------------------------------------------------------------------------------ template void generic_get_entry_rela( Elf_Xword index, Elf64_Addr& offset, Elf_Word& symbol, Elf_Word& type, Elf_Sxword& addend ) const { const endianess_convertor& convertor = elf_file.get_convertor(); const T* pEntry = reinterpret_cast( relocation_section->get_data() + index * relocation_section->get_entry_size() ); offset = convertor( pEntry->r_offset ); Elf_Xword tmp = convertor( pEntry->r_info ); symbol = get_sym_and_type::get_r_sym( tmp ); type = get_sym_and_type::get_r_type( tmp ); addend = convertor( pEntry->r_addend ); } //------------------------------------------------------------------------------ template void generic_set_entry_rel( Elf_Xword index, Elf64_Addr offset, Elf_Word symbol, Elf_Word type, Elf_Sxword ) { const endianess_convertor& convertor = elf_file.get_convertor(); T* pEntry = const_cast( reinterpret_cast( relocation_section->get_data() + index * relocation_section->get_entry_size() ) ); if ( elf_file.get_class() == ELFCLASS32 ) { pEntry->r_info = ELF32_R_INFO( (Elf_Xword)symbol, type ); } else { pEntry->r_info = ELF64_R_INFO( (Elf_Xword)symbol, type ); } pEntry->r_offset = offset; pEntry->r_offset = convertor( pEntry->r_offset ); pEntry->r_info = convertor( pEntry->r_info ); } //------------------------------------------------------------------------------ template void generic_set_entry_rela( Elf_Xword index, Elf64_Addr offset, Elf_Word symbol, Elf_Word type, Elf_Sxword addend ) { const endianess_convertor& convertor = elf_file.get_convertor(); T* pEntry = const_cast( reinterpret_cast( relocation_section->get_data() + index * relocation_section->get_entry_size() ) ); if ( elf_file.get_class() == ELFCLASS32 ) { pEntry->r_info = ELF32_R_INFO( (Elf_Xword)symbol, type ); } else { pEntry->r_info = ELF64_R_INFO( (Elf_Xword)symbol, type ); } pEntry->r_offset = offset; pEntry->r_addend = addend; pEntry->r_offset = convertor( pEntry->r_offset ); pEntry->r_info = convertor( pEntry->r_info ); pEntry->r_addend = convertor( pEntry->r_addend ); } //------------------------------------------------------------------------------ template void generic_add_entry( Elf64_Addr offset, Elf_Xword info ) { const endianess_convertor& convertor = elf_file.get_convertor(); T entry; entry.r_offset = offset; entry.r_info = info; entry.r_offset = convertor( entry.r_offset ); entry.r_info = convertor( entry.r_info ); relocation_section->append_data( reinterpret_cast( &entry ), sizeof( entry ) ); } //------------------------------------------------------------------------------ template void generic_add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend ) { const endianess_convertor& convertor = elf_file.get_convertor(); T entry; entry.r_offset = offset; entry.r_info = info; entry.r_addend = addend; entry.r_offset = convertor( entry.r_offset ); entry.r_info = convertor( entry.r_info ); entry.r_addend = convertor( entry.r_addend ); relocation_section->append_data( reinterpret_cast( &entry ), sizeof( entry ) ); } //------------------------------------------------------------------------------ private: const elfio& elf_file; S* relocation_section; }; using relocation_section_accessor = relocation_section_accessor_template
; using const_relocation_section_accessor = relocation_section_accessor_template; } // namespace ELFIO #endif // ELFIO_RELOCATION_HPP /*** End of inlined file: elfio_relocation.hpp ***/ /*** Start of inlined file: elfio_dynamic.hpp ***/ #ifndef ELFIO_DYNAMIC_HPP #define ELFIO_DYNAMIC_HPP namespace ELFIO { //------------------------------------------------------------------------------ template class dynamic_section_accessor_template { public: //------------------------------------------------------------------------------ dynamic_section_accessor_template( const elfio& elf_file_, S* section_ ) : elf_file( elf_file_ ), dynamic_section( section_ ) { } //------------------------------------------------------------------------------ Elf_Xword get_entries_num() const { Elf_Xword nRet = 0; if ( 0 != dynamic_section->get_entry_size() ) { nRet = dynamic_section->get_size() / dynamic_section->get_entry_size(); } return nRet; } //------------------------------------------------------------------------------ bool get_entry( Elf_Xword index, Elf_Xword& tag, Elf_Xword& value, std::string& str ) const { if ( index >= get_entries_num() ) { // Is index valid return false; } if ( elf_file.get_class() == ELFCLASS32 ) { generic_get_entry_dyn( index, tag, value ); } else { generic_get_entry_dyn( index, tag, value ); } // If the tag may have a string table reference, prepare the string if ( tag == DT_NEEDED || tag == DT_SONAME || tag == DT_RPATH || tag == DT_RUNPATH ) { string_section_accessor strsec = elf_file.sections[get_string_table_index()]; const char* result = strsec.get_string( value ); if ( 0 == result ) { str.clear(); return false; } str = result; } else { str.clear(); } return true; } //------------------------------------------------------------------------------ void add_entry( Elf_Xword tag, Elf_Xword value ) { if ( elf_file.get_class() == ELFCLASS32 ) { generic_add_entry( tag, value ); } else { generic_add_entry( tag, value ); } } //------------------------------------------------------------------------------ void add_entry( Elf_Xword tag, const std::string& str ) { string_section_accessor strsec = elf_file.sections[get_string_table_index()]; Elf_Xword value = strsec.add_string( str ); add_entry( tag, value ); } //------------------------------------------------------------------------------ private: //------------------------------------------------------------------------------ Elf_Half get_string_table_index() const { return (Elf_Half)dynamic_section->get_link(); } //------------------------------------------------------------------------------ template void generic_get_entry_dyn( Elf_Xword index, Elf_Xword& tag, Elf_Xword& value ) const { const endianess_convertor& convertor = elf_file.get_convertor(); // Check unusual case when dynamic section has no data if ( dynamic_section->get_data() == 0 || ( index + 1 ) * dynamic_section->get_entry_size() > dynamic_section->get_size() ) { tag = DT_NULL; value = 0; return; } const T* pEntry = reinterpret_cast( dynamic_section->get_data() + index * dynamic_section->get_entry_size() ); tag = convertor( pEntry->d_tag ); switch ( tag ) { case DT_NULL: case DT_SYMBOLIC: case DT_TEXTREL: case DT_BIND_NOW: value = 0; break; case DT_NEEDED: case DT_PLTRELSZ: case DT_RELASZ: case DT_RELAENT: case DT_STRSZ: case DT_SYMENT: case DT_SONAME: case DT_RPATH: case DT_RELSZ: case DT_RELENT: case DT_PLTREL: case DT_INIT_ARRAYSZ: case DT_FINI_ARRAYSZ: case DT_RUNPATH: case DT_FLAGS: case DT_PREINIT_ARRAYSZ: value = convertor( pEntry->d_un.d_val ); break; case DT_PLTGOT: case DT_HASH: case DT_STRTAB: case DT_SYMTAB: case DT_RELA: case DT_INIT: case DT_FINI: case DT_REL: case DT_DEBUG: case DT_JMPREL: case DT_INIT_ARRAY: case DT_FINI_ARRAY: case DT_PREINIT_ARRAY: default: value = convertor( pEntry->d_un.d_ptr ); break; } } //------------------------------------------------------------------------------ template void generic_add_entry( Elf_Xword tag, Elf_Xword value ) { const endianess_convertor& convertor = elf_file.get_convertor(); T entry; switch ( tag ) { case DT_NULL: case DT_SYMBOLIC: case DT_TEXTREL: case DT_BIND_NOW: value = 0; case DT_NEEDED: case DT_PLTRELSZ: case DT_RELASZ: case DT_RELAENT: case DT_STRSZ: case DT_SYMENT: case DT_SONAME: case DT_RPATH: case DT_RELSZ: case DT_RELENT: case DT_PLTREL: case DT_INIT_ARRAYSZ: case DT_FINI_ARRAYSZ: case DT_RUNPATH: case DT_FLAGS: case DT_PREINIT_ARRAYSZ: entry.d_un.d_val = convertor( value ); break; case DT_PLTGOT: case DT_HASH: case DT_STRTAB: case DT_SYMTAB: case DT_RELA: case DT_INIT: case DT_FINI: case DT_REL: case DT_DEBUG: case DT_JMPREL: case DT_INIT_ARRAY: case DT_FINI_ARRAY: case DT_PREINIT_ARRAY: default: entry.d_un.d_ptr = convertor( value ); break; } entry.d_tag = convertor( tag ); dynamic_section->append_data( reinterpret_cast( &entry ), sizeof( entry ) ); } //------------------------------------------------------------------------------ private: const elfio& elf_file; S* dynamic_section; }; using dynamic_section_accessor = dynamic_section_accessor_template
; using const_dynamic_section_accessor = dynamic_section_accessor_template; } // namespace ELFIO #endif // ELFIO_DYNAMIC_HPP /*** End of inlined file: elfio_dynamic.hpp ***/ /*** Start of inlined file: elfio_modinfo.hpp ***/ #ifndef ELFIO_MODINFO_HPP #define ELFIO_MODINFO_HPP #include #include namespace ELFIO { //------------------------------------------------------------------------------ template class modinfo_section_accessor_template { public: //------------------------------------------------------------------------------ modinfo_section_accessor_template( S* section_ ) : modinfo_section( section_ ) { process_section(); } //------------------------------------------------------------------------------ Elf_Word get_attribute_num() const { return (Elf_Word)content.size(); } //------------------------------------------------------------------------------ bool get_attribute( Elf_Word no, std::string& field, std::string& value ) const { if ( no < content.size() ) { field = content[no].first; value = content[no].second; return true; } return false; } //------------------------------------------------------------------------------ bool get_attribute( std::string field_name, std::string& value ) const { for ( auto i = content.begin(); i != content.end(); i++ ) { if ( field_name == i->first ) { value = i->second; return true; } } return false; } //------------------------------------------------------------------------------ Elf_Word add_attribute( std::string field, std::string value ) { Elf_Word current_position = 0; if ( modinfo_section ) { // Strings are addeded to the end of the current section data current_position = (Elf_Word)modinfo_section->get_size(); std::string attribute = field + "=" + value; modinfo_section->append_data( attribute + '\0' ); content.push_back( std::pair( field, value ) ); } return current_position; } //------------------------------------------------------------------------------ private: void process_section() { const char* pdata = modinfo_section->get_data(); if ( pdata ) { ELFIO::Elf_Xword i = 0; while ( i < modinfo_section->get_size() ) { while ( i < modinfo_section->get_size() && !pdata[i] ) i++; if ( i < modinfo_section->get_size() ) { std::string info = pdata + i; size_t loc = info.find( '=' ); std::pair attribute( info.substr( 0, loc ), info.substr( loc + 1 ) ); content.push_back( attribute ); i += info.length(); } } } } //------------------------------------------------------------------------------ private: S* modinfo_section; std::vector> content; }; using modinfo_section_accessor = modinfo_section_accessor_template
; using const_modinfo_section_accessor = modinfo_section_accessor_template; } // namespace ELFIO #endif // ELFIO_MODINFO_HPP /*** End of inlined file: elfio_modinfo.hpp ***/ #ifdef _MSC_VER #pragma warning( pop ) #endif #endif // ELFIO_HPP /*** End of inlined file: elfio.hpp ***/ namespace ELFIO { static struct class_table_t { const char key; const char* str; } class_table[] = { { ELFCLASS32, "ELF32" }, { ELFCLASS64, "ELF64" }, }; static struct endian_table_t { const char key; const char* str; } endian_table[] = { { ELFDATANONE, "None" }, { ELFDATA2LSB, "Little endian" }, { ELFDATA2MSB, "Big endian" }, }; static struct version_table_t { const Elf64_Word key; const char* str; } version_table[] = { { EV_NONE, "None" }, { EV_CURRENT, "Current" }, }; static struct type_table_t { const Elf32_Half key; const char* str; } type_table[] = { { ET_NONE, "No file type" }, { ET_REL, "Relocatable file" }, { ET_EXEC, "Executable file" }, { ET_DYN, "Shared object file" }, { ET_CORE, "Core file" }, }; static struct machine_table_t { const Elf64_Half key; const char* str; } machine_table[] = { { EM_NONE, "No machine" }, { EM_M32, "AT&T WE 32100" }, { EM_SPARC, "SUN SPARC" }, { EM_386, "Intel 80386" }, { EM_68K, "Motorola m68k family" }, { EM_88K, "Motorola m88k family" }, { EM_486, "Intel 80486// Reserved for future use" }, { EM_860, "Intel 80860" }, { EM_MIPS, "MIPS R3000 (officially, big-endian only)" }, { EM_S370, "IBM System/370" }, { EM_MIPS_RS3_LE, "MIPS R3000 little-endian (Oct 4 1999 Draft) Deprecated" }, { EM_res011, "Reserved" }, { EM_res012, "Reserved" }, { EM_res013, "Reserved" }, { EM_res014, "Reserved" }, { EM_PARISC, "HPPA" }, { EM_res016, "Reserved" }, { EM_VPP550, "Fujitsu VPP500" }, { EM_SPARC32PLUS, "Sun's v8plus" }, { EM_960, "Intel 80960" }, { EM_PPC, "PowerPC" }, { EM_PPC64, "64-bit PowerPC" }, { EM_S390, "IBM S/390" }, { EM_SPU, "Sony/Toshiba/IBM SPU" }, { EM_res024, "Reserved" }, { EM_res025, "Reserved" }, { EM_res026, "Reserved" }, { EM_res027, "Reserved" }, { EM_res028, "Reserved" }, { EM_res029, "Reserved" }, { EM_res030, "Reserved" }, { EM_res031, "Reserved" }, { EM_res032, "Reserved" }, { EM_res033, "Reserved" }, { EM_res034, "Reserved" }, { EM_res035, "Reserved" }, { EM_V800, "NEC V800 series" }, { EM_FR20, "Fujitsu FR20" }, { EM_RH32, "TRW RH32" }, { EM_MCORE, "Motorola M*Core // May also be taken by Fujitsu MMA" }, { EM_RCE, "Old name for MCore" }, { EM_ARM, "ARM" }, { EM_OLD_ALPHA, "Digital Alpha" }, { EM_SH, "Renesas (formerly Hitachi) / SuperH SH" }, { EM_SPARCV9, "SPARC v9 64-bit" }, { EM_TRICORE, "Siemens Tricore embedded processor" }, { EM_ARC, "ARC Cores" }, { EM_H8_300, "Renesas (formerly Hitachi) H8/300" }, { EM_H8_300H, "Renesas (formerly Hitachi) H8/300H" }, { EM_H8S, "Renesas (formerly Hitachi) H8S" }, { EM_H8_500, "Renesas (formerly Hitachi) H8/500" }, { EM_IA_64, "Intel IA-64 Processor" }, { EM_MIPS_X, "Stanford MIPS-X" }, { EM_COLDFIRE, "Motorola Coldfire" }, { EM_68HC12, "Motorola M68HC12" }, { EM_MMA, "Fujitsu Multimedia Accelerator" }, { EM_PCP, "Siemens PCP" }, { EM_NCPU, "Sony nCPU embedded RISC processor" }, { EM_NDR1, "Denso NDR1 microprocessor" }, { EM_STARCORE, "Motorola Star*Core processor" }, { EM_ME16, "Toyota ME16 processor" }, { EM_ST100, "STMicroelectronics ST100 processor" }, { EM_TINYJ, "Advanced Logic Corp. TinyJ embedded processor" }, { EM_X86_64, "Advanced Micro Devices X86-64 processor" }, { EM_PDSP, "Sony DSP Processor" }, { EM_PDP10, "Digital Equipment Corp. PDP-10" }, { EM_PDP11, "Digital Equipment Corp. PDP-11" }, { EM_FX66, "Siemens FX66 microcontroller" }, { EM_ST9PLUS, "STMicroelectronics ST9+ 8/16 bit microcontroller" }, { EM_ST7, "STMicroelectronics ST7 8-bit microcontroller" }, { EM_68HC16, "Motorola MC68HC16 Microcontroller" }, { EM_68HC11, "Motorola MC68HC11 Microcontroller" }, { EM_68HC08, "Motorola MC68HC08 Microcontroller" }, { EM_68HC05, "Motorola MC68HC05 Microcontroller" }, { EM_SVX, "Silicon Graphics SVx" }, { EM_ST19, "STMicroelectronics ST19 8-bit cpu" }, { EM_VAX, "Digital VAX" }, { EM_CRIS, "Axis Communications 32-bit embedded processor" }, { EM_JAVELIN, "Infineon Technologies 32-bit embedded cpu" }, { EM_FIREPATH, "Element 14 64-bit DSP processor" }, { EM_ZSP, "LSI Logic's 16-bit DSP processor" }, { EM_MMIX, "Donald Knuth's educational 64-bit processor" }, { EM_HUANY, "Harvard's machine-independent format" }, { EM_PRISM, "SiTera Prism" }, { EM_AVR, "Atmel AVR 8-bit microcontroller" }, { EM_FR30, "Fujitsu FR30" }, { EM_D10V, "Mitsubishi D10V" }, { EM_D30V, "Mitsubishi D30V" }, { EM_V850, "NEC v850" }, { EM_M32R, "Renesas M32R (formerly Mitsubishi M32R)" }, { EM_MN10300, "Matsushita MN10300" }, { EM_MN10200, "Matsushita MN10200" }, { EM_PJ, "picoJava" }, { EM_OPENRISC, "OpenRISC 32-bit embedded processor" }, { EM_ARC_A5, "ARC Cores Tangent-A5" }, { EM_XTENSA, "Tensilica Xtensa Architecture" }, { EM_VIDEOCORE, "Alphamosaic VideoCore processor" }, { EM_TMM_GPP, "Thompson Multimedia General Purpose Processor" }, { EM_NS32K, "National Semiconductor 32000 series" }, { EM_TPC, "Tenor Network TPC processor" }, { EM_SNP1K, "Trebia SNP 1000 processor" }, { EM_ST200, "STMicroelectronics ST200 microcontroller" }, { EM_IP2K, "Ubicom IP2022 micro controller" }, { EM_MAX, "MAX Processor" }, { EM_CR, "National Semiconductor CompactRISC" }, { EM_F2MC16, "Fujitsu F2MC16" }, { EM_MSP430, "TI msp430 micro controller" }, { EM_BLACKFIN, "ADI Blackfin" }, { EM_SE_C33, "S1C33 Family of Seiko Epson processors" }, { EM_SEP, "Sharp embedded microprocessor" }, { EM_ARCA, "Arca RISC Microprocessor" }, { EM_UNICORE, "Microprocessor series from PKU-Unity Ltd. and MPRC of " "Peking University" }, { EM_EXCESS, "eXcess: 16/32/64-bit configurable embedded CPU" }, { EM_DXP, "Icera Semiconductor Inc. Deep Execution Processor" }, { EM_ALTERA_NIOS2, "Altera Nios II soft-core processor" }, { EM_CRX, "National Semiconductor CRX" }, { EM_XGATE, "Motorola XGATE embedded processor" }, { EM_C166, "Infineon C16x/XC16x processor" }, { EM_M16C, "Renesas M16C series microprocessors" }, { EM_DSPIC30F, "Microchip Technology dsPIC30F Digital Signal Controller" }, { EM_CE, "Freescale Communication Engine RISC core" }, { EM_M32C, "Renesas M32C series microprocessors" }, { EM_res121, "Reserved" }, { EM_res122, "Reserved" }, { EM_res123, "Reserved" }, { EM_res124, "Reserved" }, { EM_res125, "Reserved" }, { EM_res126, "Reserved" }, { EM_res127, "Reserved" }, { EM_res128, "Reserved" }, { EM_res129, "Reserved" }, { EM_res130, "Reserved" }, { EM_TSK3000, "Altium TSK3000 core" }, { EM_RS08, "Freescale RS08 embedded processor" }, { EM_res133, "Reserved" }, { EM_ECOG2, "Cyan Technology eCOG2 microprocessor" }, { EM_SCORE, "Sunplus Score" }, { EM_SCORE7, "Sunplus S+core7 RISC processor" }, { EM_DSP24, "New Japan Radio (NJR) 24-bit DSP Processor" }, { EM_VIDEOCORE3, "Broadcom VideoCore III processor" }, { EM_LATTICEMICO32, "RISC processor for Lattice FPGA architecture" }, { EM_SE_C17, "Seiko Epson C17 family" }, { EM_TI_C6000, "Texas Instruments TMS320C6000 DSP family" }, { EM_TI_C2000, "Texas Instruments TMS320C2000 DSP family" }, { EM_TI_C5500, "Texas Instruments TMS320C55x DSP family" }, { EM_res143, "Reserved" }, { EM_res144, "Reserved" }, { EM_res145, "Reserved" }, { EM_res146, "Reserved" }, { EM_res147, "Reserved" }, { EM_res148, "Reserved" }, { EM_res149, "Reserved" }, { EM_res150, "Reserved" }, { EM_res151, "Reserved" }, { EM_res152, "Reserved" }, { EM_res153, "Reserved" }, { EM_res154, "Reserved" }, { EM_res155, "Reserved" }, { EM_res156, "Reserved" }, { EM_res157, "Reserved" }, { EM_res158, "Reserved" }, { EM_res159, "Reserved" }, { EM_MMDSP_PLUS, "STMicroelectronics 64bit VLIW Data Signal Processor" }, { EM_CYPRESS_M8C, "Cypress M8C microprocessor" }, { EM_R32C, "Renesas R32C series microprocessors" }, { EM_TRIMEDIA, "NXP Semiconductors TriMedia architecture family" }, { EM_QDSP6, "QUALCOMM DSP6 Processor" }, { EM_8051, "Intel 8051 and variants" }, { EM_STXP7X, "STMicroelectronics STxP7x family" }, { EM_NDS32, "Andes Technology compact code size embedded RISC processor family" }, { EM_ECOG1, "Cyan Technology eCOG1X family" }, { EM_ECOG1X, "Cyan Technology eCOG1X family" }, { EM_MAXQ30, "Dallas Semiconductor MAXQ30 Core Micro-controllers" }, { EM_XIMO16, "New Japan Radio (NJR) 16-bit DSP Processor" }, { EM_MANIK, "M2000 Reconfigurable RISC Microprocessor" }, { EM_CRAYNV2, "Cray Inc. NV2 vector architecture" }, { EM_RX, "Renesas RX family" }, { EM_METAG, "Imagination Technologies META processor architecture" }, { EM_MCST_ELBRUS, "MCST Elbrus general purpose hardware architecture" }, { EM_ECOG16, "Cyan Technology eCOG16 family" }, { EM_CR16, "National Semiconductor CompactRISC 16-bit processor" }, { EM_ETPU, "Freescale Extended Time Processing Unit" }, { EM_SLE9X, "Infineon Technologies SLE9X core" }, { EM_L1OM, "Intel L1OM" }, { EM_INTEL181, "Reserved by Intel" }, { EM_INTEL182, "Reserved by Intel" }, { EM_res183, "Reserved by ARM" }, { EM_res184, "Reserved by ARM" }, { EM_AVR32, "Atmel Corporation 32-bit microprocessor family" }, { EM_STM8, "STMicroeletronics STM8 8-bit microcontroller" }, { EM_TILE64, "Tilera TILE64 multicore architecture family" }, { EM_TILEPRO, "Tilera TILEPro multicore architecture family" }, { EM_MICROBLAZE, "Xilinx MicroBlaze 32-bit RISC soft processor core" }, { EM_CUDA, "NVIDIA CUDA architecture " }, }; static struct section_type_table_t { const Elf64_Half key; const char* str; } section_type_table[] = { { SHT_NULL, "NULL" }, { SHT_PROGBITS, "PROGBITS" }, { SHT_SYMTAB, "SYMTAB" }, { SHT_STRTAB, "STRTAB" }, { SHT_RELA, "RELA" }, { SHT_HASH, "HASH" }, { SHT_DYNAMIC, "DYNAMIC" }, { SHT_NOTE, "NOTE" }, { SHT_NOBITS, "NOBITS" }, { SHT_REL, "REL" }, { SHT_SHLIB, "SHLIB" }, { SHT_DYNSYM, "DYNSYM" }, { SHT_INIT_ARRAY, "INIT_ARRAY" }, { SHT_FINI_ARRAY, "FINI_ARRAY" }, { SHT_PREINIT_ARRAY, "PREINIT_ARRAY" }, { SHT_GROUP, "GROUP" }, { SHT_SYMTAB_SHNDX, "SYMTAB_SHNDX " }, }; static struct segment_type_table_t { const Elf_Word key; const char* str; } segment_type_table[] = { { PT_NULL, "NULL" }, { PT_LOAD, "LOAD" }, { PT_DYNAMIC, "DYNAMIC" }, { PT_INTERP, "INTERP" }, { PT_NOTE, "NOTE" }, { PT_SHLIB, "SHLIB" }, { PT_PHDR, "PHDR" }, { PT_TLS, "TLS" }, }; static struct segment_flag_table_t { const Elf_Word key; const char* str; } segment_flag_table[] = { { 0, "" }, { 1, "X" }, { 2, "W" }, { 3, "WX" }, { 4, "R" }, { 5, "RX" }, { 6, "RW" }, { 7, "RWX" }, }; static struct symbol_bind_t { const Elf_Word key; const char* str; } symbol_bind_table[] = { { STB_LOCAL, "LOCAL" }, { STB_GLOBAL, "GLOBAL" }, { STB_WEAK, "WEAK" }, { STB_LOOS, "LOOS" }, { STB_HIOS, "HIOS" }, { STB_MULTIDEF, "MULTIDEF" }, { STB_LOPROC, "LOPROC" }, { STB_HIPROC, "HIPROC" }, }; static struct symbol_type_t { const Elf_Word key; const char* str; } symbol_type_table[] = { { STT_NOTYPE, "NOTYPE" }, { STT_OBJECT, "OBJECT" }, { STT_FUNC, "FUNC" }, { STT_SECTION, "SECTION" }, { STT_FILE, "FILE" }, { STT_COMMON, "COMMON" }, { STT_TLS, "TLS" }, { STT_LOOS, "LOOS" }, { STT_HIOS, "HIOS" }, { STT_LOPROC, "LOPROC" }, { STT_HIPROC, "HIPROC" }, }; static struct dynamic_tag_t { const Elf_Word key; const char* str; } dynamic_tag_table[] = { { DT_NULL, "NULL" }, { DT_NEEDED, "NEEDED" }, { DT_PLTRELSZ, "PLTRELSZ" }, { DT_PLTGOT, "PLTGOT" }, { DT_HASH, "HASH" }, { DT_STRTAB, "STRTAB" }, { DT_SYMTAB, "SYMTAB" }, { DT_RELA, "RELA" }, { DT_RELASZ, "RELASZ" }, { DT_RELAENT, "RELAENT" }, { DT_STRSZ, "STRSZ" }, { DT_SYMENT, "SYMENT" }, { DT_INIT, "INIT" }, { DT_FINI, "FINI" }, { DT_SONAME, "SONAME" }, { DT_RPATH, "RPATH" }, { DT_SYMBOLIC, "SYMBOLIC" }, { DT_REL, "REL" }, { DT_RELSZ, "RELSZ" }, { DT_RELENT, "RELENT" }, { DT_PLTREL, "PLTREL" }, { DT_DEBUG, "DEBUG" }, { DT_TEXTREL, "TEXTREL" }, { DT_JMPREL, "JMPREL" }, { DT_BIND_NOW, "BIND_NOW" }, { DT_INIT_ARRAY, "INIT_ARRAY" }, { DT_FINI_ARRAY, "FINI_ARRAY" }, { DT_INIT_ARRAYSZ, "INIT_ARRAYSZ" }, { DT_FINI_ARRAYSZ, "FINI_ARRAYSZ" }, { DT_RUNPATH, "RUNPATH" }, { DT_FLAGS, "FLAGS" }, { DT_ENCODING, "ENCODING" }, { DT_PREINIT_ARRAY, "PREINIT_ARRAY" }, { DT_PREINIT_ARRAYSZ, "PREINIT_ARRAYSZ" }, { DT_MAXPOSTAGS, "MAXPOSTAGS" }, }; static const ELFIO::Elf_Xword MAX_DATA_ENTRIES = 64; //------------------------------------------------------------------------------ class dump { #define DUMP_DEC_FORMAT( width ) \ std::setw( width ) << std::setfill( ' ' ) << std::dec << std::right #define DUMP_HEX_FORMAT( width ) \ std::setw( width ) << std::setfill( '0' ) << std::hex << std::right #define DUMP_STR_FORMAT( width ) \ std::setw( width ) << std::setfill( ' ' ) << std::hex << std::left public: //------------------------------------------------------------------------------ static void header( std::ostream& out, const elfio& reader ) { if ( !reader.get_header_size() ) { return; } out << "ELF Header" << std::endl << std::endl << " Class: " << str_class( reader.get_class() ) << std::endl << " Encoding: " << str_endian( reader.get_encoding() ) << std::endl << " ELFVersion: " << str_version( reader.get_elf_version() ) << std::endl << " Type: " << str_type( reader.get_type() ) << std::endl << " Machine: " << str_machine( reader.get_machine() ) << std::endl << " Version: " << str_version( reader.get_version() ) << std::endl << " Entry: " << "0x" << std::hex << reader.get_entry() << std::endl << " Flags: " << "0x" << std::hex << reader.get_flags() << std::endl << std::endl; } //------------------------------------------------------------------------------ static void section_headers( std::ostream& out, const elfio& reader ) { Elf_Half n = reader.sections.size(); if ( n == 0 ) { return; } out << "Section Headers:" << std::endl; if ( reader.get_class() == ELFCLASS32 ) { // Output for 32-bit out << "[ Nr ] Type Addr Size ES Flg Lk Inf " "Al Name" << std::endl; } else { // Output for 64-bit out << "[ Nr ] Type Addr Size " " ES Flg" << std::endl << " Lk Inf Al Name" << std::endl; } for ( Elf_Half i = 0; i < n; ++i ) { // For all sections section* sec = reader.sections[i]; section_header( out, i, sec, reader.get_class() ); } out << "Key to Flags: W (write), A (alloc), X (execute)\n\n" << std::endl; } //------------------------------------------------------------------------------ static void section_header( std::ostream& out, Elf_Half no, const section* sec, unsigned char elf_class ) { std::ios_base::fmtflags original_flags = out.flags(); if ( elf_class == ELFCLASS32 ) { // Output for 32-bit out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " << DUMP_STR_FORMAT( 17 ) << str_section_type( sec->get_type() ) << " " << DUMP_HEX_FORMAT( 8 ) << sec->get_address() << " " << DUMP_HEX_FORMAT( 8 ) << sec->get_size() << " " << DUMP_HEX_FORMAT( 2 ) << sec->get_entry_size() << " " << DUMP_STR_FORMAT( 3 ) << section_flags( sec->get_flags() ) << " " << DUMP_HEX_FORMAT( 2 ) << sec->get_link() << " " << DUMP_HEX_FORMAT( 3 ) << sec->get_info() << " " << DUMP_HEX_FORMAT( 2 ) << sec->get_addr_align() << " " << DUMP_STR_FORMAT( 17 ) << sec->get_name() << " " << std::endl; } else { // Output for 64-bit out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " << DUMP_STR_FORMAT( 17 ) << str_section_type( sec->get_type() ) << " " << DUMP_HEX_FORMAT( 16 ) << sec->get_address() << " " << DUMP_HEX_FORMAT( 16 ) << sec->get_size() << " " << DUMP_HEX_FORMAT( 4 ) << sec->get_entry_size() << " " << DUMP_STR_FORMAT( 3 ) << section_flags( sec->get_flags() ) << " " << std::endl << " " << DUMP_HEX_FORMAT( 4 ) << sec->get_link() << " " << DUMP_HEX_FORMAT( 4 ) << sec->get_info() << " " << DUMP_HEX_FORMAT( 4 ) << sec->get_addr_align() << " " << DUMP_STR_FORMAT( 17 ) << sec->get_name() << " " << std::endl; } out.flags( original_flags ); return; } //------------------------------------------------------------------------------ static void segment_headers( std::ostream& out, const elfio& reader ) { Elf_Half n = reader.segments.size(); if ( n == 0 ) { return; } out << "Segment headers:" << std::endl; if ( reader.get_class() == ELFCLASS32 ) { // Output for 32-bit out << "[ Nr ] Type VirtAddr PhysAddr FileSize Mem.Size " "Flags Align" << std::endl; } else { // Output for 64-bit out << "[ Nr ] Type VirtAddr PhysAddr " "Flags" << std::endl << " FileSize Mem.Size " "Align" << std::endl; } for ( Elf_Half i = 0; i < n; ++i ) { segment* seg = reader.segments[i]; segment_header( out, i, seg, reader.get_class() ); } out << std::endl; } //------------------------------------------------------------------------------ static void segment_header( std::ostream& out, Elf_Half no, const segment* seg, unsigned int elf_class ) { std::ios_base::fmtflags original_flags = out.flags(); if ( elf_class == ELFCLASS32 ) { // Output for 32-bit out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " << DUMP_STR_FORMAT( 14 ) << str_segment_type( seg->get_type() ) << " " << DUMP_HEX_FORMAT( 8 ) << seg->get_virtual_address() << " " << DUMP_HEX_FORMAT( 8 ) << seg->get_physical_address() << " " << DUMP_HEX_FORMAT( 8 ) << seg->get_file_size() << " " << DUMP_HEX_FORMAT( 8 ) << seg->get_memory_size() << " " << DUMP_STR_FORMAT( 8 ) << str_segment_flag( seg->get_flags() ) << " " << DUMP_HEX_FORMAT( 8 ) << seg->get_align() << " " << std::endl; } else { // Output for 64-bit out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " << DUMP_STR_FORMAT( 14 ) << str_segment_type( seg->get_type() ) << " " << DUMP_HEX_FORMAT( 16 ) << seg->get_virtual_address() << " " << DUMP_HEX_FORMAT( 16 ) << seg->get_physical_address() << " " << DUMP_STR_FORMAT( 16 ) << str_segment_flag( seg->get_flags() ) << " " << std::endl << " " << DUMP_HEX_FORMAT( 16 ) << seg->get_file_size() << " " << DUMP_HEX_FORMAT( 16 ) << seg->get_memory_size() << " " << DUMP_HEX_FORMAT( 16 ) << seg->get_align() << " " << std::endl; } out.flags( original_flags ); } //------------------------------------------------------------------------------ static void symbol_tables( std::ostream& out, const elfio& reader ) { Elf_Half n = reader.sections.size(); for ( Elf_Half i = 0; i < n; ++i ) { // For all sections section* sec = reader.sections[i]; if ( SHT_SYMTAB == sec->get_type() || SHT_DYNSYM == sec->get_type() ) { symbol_section_accessor symbols( reader, sec ); Elf_Xword sym_no = symbols.get_symbols_num(); if ( sym_no > 0 ) { out << "Symbol table (" << sec->get_name() << ")" << std::endl; if ( reader.get_class() == ELFCLASS32 ) { // Output for 32-bit out << "[ Nr ] Value Size Type Bind " "Sect Name" << std::endl; } else { // Output for 64-bit out << "[ Nr ] Value Size Type " " Bind Sect" << std::endl << " Name" << std::endl; } for ( Elf_Xword i = 0; i < sym_no; ++i ) { std::string name; Elf64_Addr value = 0; Elf_Xword size = 0; unsigned char bind = 0; unsigned char type = 0; Elf_Half section = 0; unsigned char other = 0; symbols.get_symbol( i, name, value, size, bind, type, section, other ); symbol_table( out, i, name, value, size, bind, type, section, reader.get_class() ); } out << std::endl; } } } } //------------------------------------------------------------------------------ static void symbol_table( std::ostream& out, Elf_Xword no, std::string& name, Elf64_Addr value, Elf_Xword size, unsigned char bind, unsigned char type, Elf_Half section, unsigned int elf_class ) { std::ios_base::fmtflags original_flags = out.flags(); if ( elf_class == ELFCLASS32 ) { // Output for 32-bit out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " << DUMP_HEX_FORMAT( 8 ) << value << " " << DUMP_HEX_FORMAT( 8 ) << size << " " << DUMP_STR_FORMAT( 7 ) << str_symbol_type( type ) << " " << DUMP_STR_FORMAT( 8 ) << str_symbol_bind( bind ) << " " << DUMP_DEC_FORMAT( 5 ) << section << " " << DUMP_STR_FORMAT( 1 ) << name << " " << std::endl; } else { // Output for 64-bit out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " << DUMP_HEX_FORMAT( 16 ) << value << " " << DUMP_HEX_FORMAT( 16 ) << size << " " << DUMP_STR_FORMAT( 7 ) << str_symbol_type( type ) << " " << DUMP_STR_FORMAT( 8 ) << str_symbol_bind( bind ) << " " << DUMP_DEC_FORMAT( 5 ) << section << " " << std::endl << " " << DUMP_STR_FORMAT( 1 ) << name << " " << std::endl; } out.flags( original_flags ); } //------------------------------------------------------------------------------ static void notes( std::ostream& out, const elfio& reader ) { Elf_Half no = reader.sections.size(); for ( Elf_Half i = 0; i < no; ++i ) { // For all sections section* sec = reader.sections[i]; if ( SHT_NOTE == sec->get_type() ) { // Look at notes note_section_accessor notes( reader, sec ); Elf_Word no_notes = notes.get_notes_num(); if ( no > 0 ) { out << "Note section (" << sec->get_name() << ")" << std::endl << " No Type Name" << std::endl; for ( Elf_Word j = 0; j < no_notes; ++j ) { // For all notes Elf_Word type; std::string name; void* desc; Elf_Word descsz; if ( notes.get_note( j, type, name, desc, descsz ) ) { // 'name' usually contains \0 at the end. Try to fix it name = name.c_str(); note( out, j, type, name ); } } out << std::endl; } } } } //------------------------------------------------------------------------------ static void modinfo( std::ostream& out, const elfio& reader ) { Elf_Half no = reader.sections.size(); for ( Elf_Half i = 0; i < no; ++i ) { // For all sections section* sec = reader.sections[i]; if ( ".modinfo" == sec->get_name() ) { // Look for the section out << "Section .modinfo" << std::endl; const_modinfo_section_accessor modinfo( sec ); for ( Elf_Word i = 0; i < modinfo.get_attribute_num(); i++ ) { std::string field; std::string value; if ( modinfo.get_attribute( i, field, value ) ) { out << " " << std::setw( 20 ) << field << std::setw( 0 ) << " = " << value << std::endl; } } out << std::endl; break; } } } //------------------------------------------------------------------------------ static void note( std::ostream& out, int no, Elf_Word type, const std::string& name ) { out << " [" << DUMP_DEC_FORMAT( 2 ) << no << "] " << DUMP_HEX_FORMAT( 8 ) << type << " " << DUMP_STR_FORMAT( 1 ) << name << std::endl; } //------------------------------------------------------------------------------ static void dynamic_tags( std::ostream& out, const elfio& reader ) { Elf_Half n = reader.sections.size(); for ( Elf_Half i = 0; i < n; ++i ) { // For all sections section* sec = reader.sections[i]; if ( SHT_DYNAMIC == sec->get_type() ) { dynamic_section_accessor dynamic( reader, sec ); Elf_Xword dyn_no = dynamic.get_entries_num(); if ( dyn_no > 0 ) { out << "Dynamic section (" << sec->get_name() << ")" << std::endl; out << "[ Nr ] Tag Name/Value" << std::endl; for ( Elf_Xword i = 0; i < dyn_no; ++i ) { Elf_Xword tag = 0; Elf_Xword value = 0; std::string str; dynamic.get_entry( i, tag, value, str ); dynamic_tag( out, i, tag, value, str, reader.get_class() ); if ( DT_NULL == tag ) { break; } } out << std::endl; } } } } //------------------------------------------------------------------------------ static void dynamic_tag( std::ostream& out, Elf_Xword no, Elf_Xword tag, Elf_Xword value, std::string str, unsigned int /*elf_class*/ ) { out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " << DUMP_STR_FORMAT( 16 ) << str_dynamic_tag( tag ) << " "; if ( str.empty() ) { out << DUMP_HEX_FORMAT( 16 ) << value << " "; } else { out << DUMP_STR_FORMAT( 32 ) << str << " "; } out << std::endl; } //------------------------------------------------------------------------------ static void section_data( std::ostream& out, const section* sec ) { std::ios_base::fmtflags original_flags = out.flags(); out << sec->get_name() << std::endl; const char* pdata = sec->get_data(); if ( pdata ) { ELFIO::Elf_Xword i; for ( i = 0; i < std::min( sec->get_size(), MAX_DATA_ENTRIES ); ++i ) { if ( i % 16 == 0 ) { out << "[" << DUMP_HEX_FORMAT( 8 ) << i << "]"; } out << " " << DUMP_HEX_FORMAT( 2 ) << ( pdata[i] & 0x000000FF ); if ( i % 16 == 15 ) { out << std::endl; } } if ( i % 16 != 0 ) { out << std::endl; } out.flags( original_flags ); } return; } //------------------------------------------------------------------------------ static void section_datas( std::ostream& out, const elfio& reader ) { Elf_Half n = reader.sections.size(); if ( n == 0 ) { return; } out << "Section Data:" << std::endl; for ( Elf_Half i = 1; i < n; ++i ) { // For all sections section* sec = reader.sections[i]; if ( sec->get_type() == SHT_NOBITS ) { continue; } section_data( out, sec ); } out << std::endl; } //------------------------------------------------------------------------------ static void segment_data( std::ostream& out, Elf_Half no, const segment* seg ) { std::ios_base::fmtflags original_flags = out.flags(); out << "Segment # " << no << std::endl; const char* pdata = seg->get_data(); if ( pdata ) { ELFIO::Elf_Xword i; for ( i = 0; i < std::min( seg->get_file_size(), MAX_DATA_ENTRIES ); ++i ) { if ( i % 16 == 0 ) { out << "[" << DUMP_HEX_FORMAT( 8 ) << i << "]"; } out << " " << DUMP_HEX_FORMAT( 2 ) << ( pdata[i] & 0x000000FF ); if ( i % 16 == 15 ) { out << std::endl; } } if ( i % 16 != 0 ) { out << std::endl; } out.flags( original_flags ); } return; } //------------------------------------------------------------------------------ static void segment_datas( std::ostream& out, const elfio& reader ) { Elf_Half n = reader.segments.size(); if ( n == 0 ) { return; } out << "Segment Data:" << std::endl; for ( Elf_Half i = 0; i < n; ++i ) { // For all sections segment* seg = reader.segments[i]; segment_data( out, i, seg ); } out << std::endl; } private: //------------------------------------------------------------------------------ template std::string static find_value_in_table( const T& table, const K& key ) { std::string res = "?"; for ( unsigned int i = 0; i < sizeof( table ) / sizeof( table[0] ); ++i ) { if ( table[i].key == key ) { res = table[i].str; break; } } return res; } //------------------------------------------------------------------------------ template static std::string format_assoc( const T& table, const K& key ) { std::string str = find_value_in_table( table, key ); if ( str == "?" ) { std::ostringstream oss; oss << str << " (0x" << std::hex << key << ")"; str = oss.str(); } return str; } //------------------------------------------------------------------------------ template static std::string format_assoc( const T& table, const char key ) { return format_assoc( table, (const int)key ); } //------------------------------------------------------------------------------ static std::string section_flags( Elf_Xword flags ) { std::string ret = ""; if ( flags & SHF_WRITE ) { ret += "W"; } if ( flags & SHF_ALLOC ) { ret += "A"; } if ( flags & SHF_EXECINSTR ) { ret += "X"; } return ret; } //------------------------------------------------------------------------------ #define STR_FUNC_TABLE( name ) \ template static std::string str_##name( const T key ) \ { \ return format_assoc( name##_table, key ); \ } STR_FUNC_TABLE( class ) STR_FUNC_TABLE( endian ) STR_FUNC_TABLE( version ) STR_FUNC_TABLE( type ) STR_FUNC_TABLE( machine ) STR_FUNC_TABLE( section_type ) STR_FUNC_TABLE( segment_type ) STR_FUNC_TABLE( segment_flag ) STR_FUNC_TABLE( symbol_bind ) STR_FUNC_TABLE( symbol_type ) STR_FUNC_TABLE( dynamic_tag ) #undef STR_FUNC_TABLE #undef DUMP_DEC_FORMAT #undef DUMP_HEX_FORMAT #undef DUMP_STR_FORMAT }; // class dump }; // namespace ELFIO #endif // ELFIO_DUMP_HPP /*** End of inlined file: elfio_dump.hpp ***/ ukui-session-manager/tests/kt-test-utils/cpp-stub/addr_pri.h0000664000175000017500000002437215252714370023151 0ustar fengfeng#ifndef __ADDR_PRI_H__ #define __ADDR_PRI_H__ #include #include //base on C++11 /********************************************************** access private function **********************************************************/ namespace std { template using enable_if_t = typename enable_if::type; template using remove_reference_t = typename remove_reference::type; } // std // Unnamed namespace is used to avoid duplicate symbols if the macros are used namespace { namespace private_access_detail { // @tparam TagType, used to declare different "get" function overloads for // different members/statistics template struct private_access { // Normal lookup cannot find in-class defined (inline) friend functions. friend PtrType get(TagType) { return PtrValue; } }; } // namespace private_access_detail } // namespace // Used macro naming conventions: // The "namespace" of this macro library is PRIVATE_ACCESS, i.e. all // macro here has this prefix. // All implementation macro, which are not meant to be used directly have the // PRIVATE_ACCESS_DETAIL prefix. // Some macros have the ABCD_IMPL form, which means they contain the // implementation details for the specific ABCD macro. #define PRIVATE_ACCESS_DETAIL_CONCATENATE_IMPL(x, y) x##y #define PRIVATE_ACCESS_DETAIL_CONCATENATE(x, y) \ PRIVATE_ACCESS_DETAIL_CONCATENATE_IMPL(x, y) // @param PtrTypeKind E.g if we have "class A", then it can be "A::*" in case of // members, or it can be "*" in case of statistics. #define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, \ PtrTypeKind) \ namespace { \ namespace private_access_detail { \ /* Tag type, used to declare different get functions for different \ * members \ */ \ struct Tag {}; \ /* Explicit instantiation */ \ template struct private_access; \ /* We can build the PtrType only with two aliases */ \ /* E.g. using PtrType = int(int) *; would be illformed */ \ using PRIVATE_ACCESS_DETAIL_CONCATENATE(Alias_, Tag) = Type; \ using PRIVATE_ACCESS_DETAIL_CONCATENATE(PtrType_, Tag) = \ PRIVATE_ACCESS_DETAIL_CONCATENATE(Alias_, Tag) PtrTypeKind; \ /* Declare the friend function, now it is visible in namespace scope. \ * Note, \ * we could declare it inside the Tag type too, in that case ADL would \ * find \ * the declaration. By choosing to declare it here, the Tag type remains \ * a \ * simple tag type, it has no other responsibilities. */ \ PRIVATE_ACCESS_DETAIL_CONCATENATE(PtrType_, Tag) get(Tag); \ } \ } #define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FIELD(Tag, Class, Type, Name) \ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, Class::*) \ namespace { \ namespace access_private_field { \ Type &Class##Name(Class &&t) { return t.*get(private_access_detail::Tag{}); } \ Type &Class##Name(Class &t) { return t.*get(private_access_detail::Tag{}); } \ /* The following usings are here to avoid duplicate const qualifier \ * warnings \ */ \ using PRIVATE_ACCESS_DETAIL_CONCATENATE(X, Tag) = Type; \ using PRIVATE_ACCESS_DETAIL_CONCATENATE(Y, Tag) = \ const PRIVATE_ACCESS_DETAIL_CONCATENATE(X, Tag); \ PRIVATE_ACCESS_DETAIL_CONCATENATE(Y, Tag) & Class##Name(const Class &t) {\ return t.*get(private_access_detail::Tag{}); \ } \ } \ } #define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FUN(Tag, Class, Type, Name) \ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, Class::*) \ namespace { \ namespace call_private_fun { \ /* We do perfect forwarding, but we want to restrict the overload set \ * only for objects which have the type Class. */ \ template , \ Class>::value> * = nullptr, \ typename... Args> \ auto Class##Name(Obj &&o, Args &&... args) -> decltype( \ (std::forward(o).* \ get(private_access_detail::Tag{}))(std::forward(args)...)) { \ return (std::forward(o).*get(private_access_detail::Tag{}))( \ std::forward(args)...); \ } \ } \ namespace get_private_fun { \ auto Class##Name() -> decltype( \ get(private_access_detail::Tag{})) { \ return (get(private_access_detail::Tag{})); \ } \ } \ } #define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FIELD(Tag, Class, Type, \ Name) \ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, *) \ namespace { \ namespace access_private_static_field { \ namespace Class { \ Type &Class##Name() { return *get(private_access_detail::Tag{}); } \ } \ } \ } #define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FUN(Tag, Class, Type, \ Name) \ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, *) \ namespace { \ namespace call_private_static_fun { \ namespace Class { \ template \ auto Class##Name(Args &&... args) -> decltype( \ get(private_access_detail::Tag{})(std::forward(args)...)) { \ return get(private_access_detail::Tag{})( \ std::forward(args)...); \ } \ } \ } \ namespace get_private_static_fun { \ namespace Class { \ auto Class##Name() -> decltype(get(private_access_detail::Tag{})) { \ return get(private_access_detail::Tag{}); \ } \ } \ } \ } #define PRIVATE_ACCESS_DETAIL_UNIQUE_TAG \ PRIVATE_ACCESS_DETAIL_CONCATENATE(PrivateAccessTag, __COUNTER__) #define ACCESS_PRIVATE_FIELD(Class, Type, Name) \ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FIELD(PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, \ Class, Type, Name) #define ACCESS_PRIVATE_FUN(Class, Type, Name) \ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FUN(PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, \ Class, Type, Name) #define ACCESS_PRIVATE_STATIC_FIELD(Class, Type, Name) \ Type Class::Name; \ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FIELD( \ PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, Class, Type, Name) #define ACCESS_PRIVATE_STATIC_FUN(Class, Type, Name) \ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FUN( \ PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, Class, Type, Name) #endif ukui-session-manager/tests/kt-test-utils/cpp-stub-ext/0000775000175000017500000000000015252714370022002 5ustar fengfengukui-session-manager/tests/kt-test-utils/cpp-stub-ext/stub-shadow.h0000664000175000017500000001143415252714370024416 0ustar fengfeng #ifndef STUBSHADOW_H #define STUBSHADOW_H /* * Author: Zhang Yu * Maintainer: Zhang Yu * * MIT License * * Copyright (c) 2020 Zhang Yu * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include #include namespace stub_ext { #define LAMDA_FUNCTION_TYPE decltype(&Lamda::operator()) class Wrapper { public: Wrapper(); virtual ~Wrapper(); }; typedef std::unordered_map WrapperMap; extern WrapperMap stub_wrappers; template class LamdaWrapper : public Wrapper { public: LamdaWrapper(Lamda func): Wrapper(),_func(func){} ~LamdaWrapper(){} Lamda _func; }; template struct VFLocator { }; template struct VFLocator { typedef Ret (*Func)(Obj*, Args...); }; template struct VFLocator { typedef Ret (*Func)(Obj*, Args...); }; template struct LamdaCaller { }; template struct LamdaCaller { template static Ret call(LamdaWrapper *wrapper, OrgArgs&&... args) { return wrapper->_func(std::forward(args)...); } }; template struct LamdaCaller { template static Ret call(LamdaWrapper *wrapper, OrgArgs&&... args) { return wrapper->_func(); } }; template struct FuncShadow { }; template struct FuncShadow { typedef Ret (*Shadow)(Args...); typedef Ret RetType; static Ret call(Args ...args) { Shadow shadow = &call; long id = (long)shadow; auto iter = stub_wrappers.find(id); assert(stub_wrappers.find(id) != stub_wrappers.end()); LamdaWrapper *wrapper = dynamic_cast *>(iter->second); return LamdaCaller::call(wrapper, args...); } }; template struct FuncShadow { typedef Ret (*Shadow)(Obj *,Args...); typedef Ret RetType; static Ret call(Obj *obj, Args ...args) { Shadow shadow = &call; long id = (long)shadow; auto iter = stub_wrappers.find(id); assert(stub_wrappers.find(id) != stub_wrappers.end()); LamdaWrapper *wrapper = dynamic_cast *>(iter->second); return LamdaCaller::call(wrapper, obj, args...); } }; template struct FuncShadow { typedef Ret (*Shadow)(Obj *,Args...); typedef Ret RetType; static Ret call(Obj *obj, Args ...args) { Shadow shadow = &call; long id = (long)shadow; auto iter = stub_wrappers.find(id); assert(stub_wrappers.find(id) != stub_wrappers.end()); LamdaWrapper *wrapper = dynamic_cast *>(iter->second); return LamdaCaller::call(wrapper, obj, args...); } }; template typename FuncShadow::Shadow depictShadow(Wrapper **wrapper, Func func, Lamda lamda) { *wrapper = new LamdaWrapper(lamda); typename FuncShadow::Shadow shadow = &FuncShadow::call; long id = (long)shadow; assert(stub_wrappers.find(id) == stub_wrappers.end()); stub_wrappers.insert(std::make_pair(id,*wrapper)); return shadow; } void freeWrapper(Wrapper *wrapper); } #endif // STUBSHADOW_H ukui-session-manager/tests/kt-test-utils/cpp-stub-ext/stub-shadow.cpp0000664000175000017500000000314715252714370024753 0ustar fengfeng/* * Author: Zhang Yu * Maintainer: Zhang Yu * * MIT License * * Copyright (c) 2020 Zhang Yu * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include "stub-shadow.h" namespace stub_ext { WrapperMap stub_wrappers; Wrapper::Wrapper() { } Wrapper::~Wrapper() { } void freeWrapper(Wrapper *wrapper) { if (!wrapper) return; for (auto iter = stub_wrappers.begin(); iter != stub_wrappers.end();) { if (iter->second == wrapper) iter = stub_wrappers.erase(iter); else ++iter; } delete wrapper; } } ukui-session-manager/tests/kt-test-utils/cpp-stub-ext/stubext.h0000664000175000017500000000734115252714370023656 0ustar fengfeng #ifndef STUBEXT_H #define STUBEXT_H /* * Author: Zhang Yu * Maintainer: Zhang Yu * * MIT License * * Copyright (c) 2020 Zhang Yu * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ //需修改Stub的私用成员函数和成员变量为保护类型 #include "stub.h" #include "stub-shadow.h" #ifdef DEBUG_STUB_INVOKE // use to make sure the stub function is invoked. # define __DBG_STUB_INVOKE__ printf("stub at %s:%d is invoked.\n", __FILE__, __LINE__); #else # define __DBG_STUB_INVOKE__ #endif #define VADDR(CLASS_NAME, MEMBER_NAME) (typename stub_ext::VFLocator::Func)(&CLASS_NAME::MEMBER_NAME) namespace stub_ext { class StubExt : public Stub { public: StubExt() : Stub() { } template bool set_lamda(T addr, Lamda lamda) { char *fn = addrof(addr); if (m_result.find(fn) != m_result.end()) reset(addr); Wrapper *wrapper = nullptr; auto addr_stub = depictShadow(&wrapper, addr, lamda); if (set(addr, addr_stub)) { m_wrappers.insert(std::make_pair(fn, wrapper)); return true; } else { freeWrapper(wrapper); } return false; } template void reset(T addr) { Stub::reset(addr); char *fn = addrof(addr); auto iter = m_wrappers.find(fn); if (iter != m_wrappers.end()) { freeWrapper(iter->second); m_wrappers.erase(iter); } } ~StubExt() { clear(); } void clear() override { Stub::clear(); for (auto iter = m_wrappers.begin(); iter != m_wrappers.end(); ++iter) { freeWrapper(iter->second); } m_wrappers.clear(); } template static void *get_ctor_addr(bool start = true) { // the start variable must be true, or the compiler will optimize out. if (start) goto Start; Call_Constructor: // This line of code will not be executed. // The purpose of the code is to allow the compiler to generate the assembly code that calls the constructor. T(); Start: // The address of the line of code T() obtained by assembly char *p = (char *)&&Call_Constructor; // https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html // CALL rel32 void *ret = 0; char pos; char call = 0xe8; do { pos = *p; if (pos == call) { ret = p + 5 + (*(int *)(p + 1)); } } while (!ret && (++p)); return ret; } protected: std::map m_wrappers; }; } #endif // STUBEXT_H ukui-session-manager/tests/unit_test_lockchecker/0000775000175000017500000000000015252714370021271 5ustar fengfengukui-session-manager/tests/unit_test_lockchecker/CMakeLists.txt0000664000175000017500000000473515252714370024042 0ustar fengfeng# CMake 最低版本要求 cmake_minimum_required(VERSION 3.16) find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED) find_package(PkgConfig REQUIRED) pkg_check_modules(GIOUNIX2 REQUIRED gio-unix-2.0) pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0) # 包含 GTest 库和 pthread 库 find_package(GTest REQUIRED) find_package(Threads REQUIRED) find_package(KF5IdleTime) #find_package(Qt5X11Extras REQUIRED) # 设置 C++ 标准 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") file(GLOB SOURCES "../../tools/*.cpp") file(GLOB HEADERS "../../tools/*.h") set(SOURCES ../../tools/lockchecker.cpp ../../tools/loginedusers.cpp ../../ukui-session/ukuilockinfo.cpp ../../ukui-session/xdgdesktopfile.cpp ../../ukui-session/xdgdirs.cpp unit_test_lockchecker.cpp ) set(HEADERS ../../tools/lockchecker.h ../../ukui-session/ukuilockinfo.h ../../ukui-session/xdgdesktopfile.h ../../ukui-session/xdgdirs.h ../../tools/loginedusers.h ) pkg_search_module(GSETTINGS_QT REQUIRED gsettings-qt) include_directories(${GSETTINGS_QT_INCLUDES}) pkg_check_modules(GLIB2 REQUIRED glib-2.0) pkg_check_modules(GIO2 REQUIRED gio-2.0) pkg_search_module(X11 REQUIRED x11) pkg_check_modules(KDKINFO REQUIRED kysdk-sysinfo) include_directories(${X11_INCLUDES}) include_directories(${GLIB2_INCLUDE_DIRS}) include_directories(${GIO2_INCLUDE_DIRS}) include_directories(${KDKINFO_INCLUDE_DIRS}) # 包含头文件的路径设置,对应原来的INCLUDEPATH变量 include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ) # 使用qt5_wrap_cpp生成元对象代码相关的源文件 qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) add_executable(unit_test_lockchecker ${SOURCES} ${MOC_SOURCES}) target_link_libraries(unit_test_lockchecker Qt5::Core Qt5::Gui Qt5::DBus KF5::IdleTime ${GSETTINGS_QT_LIBRARIES} ${X11_LIBRARIES} ${GLIB2_LIBRARIES} ${GIO2_LIBRARIES} ${KDKINFO_LIBRARIES} #Qt5::X11Extras -lX11 ) # 链接 GTest 库 target_link_libraries(unit_test_lockchecker GTest::GTest GTest::Main Threads::Threads ) ukui-session-manager/tests/unit_test_lockchecker/unit_test_lockchecker.cpp0000664000175000017500000000613315252714370026353 0ustar fengfeng#include #include #include #include #include #include "../../tools/lockchecker.h" #include "../../tools/loginedusers.h" #include "../../ukui-session/ukuilockinfo.h" #include "../../ukui-session/xdgdesktopfile.h" #include "../../ukui-session/xdgdirs.h" class LockCheckerTest : public testing::Test { protected: static void SetUpTestSuite() { // 可在此添加全局的设置,例如初始化一些资源 } static void TearDownTestSuite() { // 可在此进行全局的清理,例如释放资源 } void SetUp() override { // 每个测试用例开始前创建 LockChecker 实例 lockChecker = new LockChecker(); } void TearDown() override { // 每个测试用例结束后删除 LockChecker 实例 delete lockChecker; lockChecker = nullptr; } LockChecker* lockChecker; }; // 测试 LockChecker 的构造函数 TEST_F(LockCheckerTest, ConstructorTest) { // 创建 LockChecker 实例 LockChecker* checker = new LockChecker(); // 这里只是简单创建实例,可根据实际需求添加更多检查 delete checker; } // 测试 getLoginedUsers 方法 TEST_F(LockCheckerTest, GetLoginedUsersTest) { // 测试正常调用 QStringList users = lockChecker->getLoginedUsers(); EXPECT_TRUE(users.contains("kylin")); } // 测试 listInhibitor 方法 TEST_F(LockCheckerTest, ListInhibitorTest) { // 测试正常调用 QVector inhibitors_logout = lockChecker->listInhibitor("logout"); EXPECT_EQ(inhibitors_logout.size(), 0); QVector inhibitors_sleep = lockChecker->listInhibitor("sleep"); EXPECT_EQ(inhibitors_sleep.size(), 0); QVector inhibitors_shutdown = lockChecker->listInhibitor("shutdown"); EXPECT_EQ(inhibitors_shutdown.size(), 0); QVector inhibitors_false = lockChecker->listInhibitor("logout"); EXPECT_EQ(inhibitors_false.size(), 0); } // 测试 getName 方法 TEST_F(LockCheckerTest, GetNameTest) { // 测试文件存在的情况 QFile file("test_file"); QString name = lockChecker->getName(&file); // 测试文件不存在的情况 QFile nonExistentFile("non_existent_file"); name = lockChecker->getName(&nonExistentFile); } // 测试 getInhibitorLocal 方法 TEST_F(LockCheckerTest, GetInhibitorLocalTest) { QVector inhibitVec; // 测试不同的 type 参数 bool result = lockChecker->getInhibitorLocal(inhibitVec, "logout"); EXPECT_FALSE(result); result = lockChecker->getInhibitorLocal(inhibitVec, "sleep"); EXPECT_FALSE(result); result = lockChecker->getInhibitorLocal(inhibitVec, "shutdown"); EXPECT_FALSE(result); } // 测试 getCachedUsers 方法 TEST_F(LockCheckerTest, GetCachedUsersTest) { // 测试正常调用 int userNum = lockChecker->getCachedUsers(); EXPECT_EQ(userNum,1); } int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } ukui-session-manager/tools/0000775000175000017500000000000015252714370014714 5ustar fengfengukui-session-manager/tools/grab-x11.cpp0000664000175000017500000000654515252714370016754 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * **/ #include "grab-x11.h" #include #include #include class XServerGraber { public: XServerGraber() { xcb_connection_t *connection = nullptr; if (auto *x11Application = qApp->nativeInterface()) { connection = x11Application->connection(); } xcb_grab_server(connection); } ~XServerGraber() { xcb_connection_t *connection = nullptr; if (auto *x11Application = qApp->nativeInterface()) { connection = x11Application->connection(); } xcb_ungrab_server(connection); xcb_flush(connection); } }; static bool grabKeyboard() { Display *display = nullptr; Window window = DefaultRootWindow(display); if (auto *x11Application = qApp->nativeInterface()) { display = x11Application->display(); } int rv = XGrabKeyboard(display, window, True, GrabModeAsync, GrabModeAsync, CurrentTime); return (rv == GrabSuccess); } static bool grabMouse() { #define GRABEVENTS ButtonPressMask | ButtonReleaseMask | PointerMotionMask | \ EnterWindowMask | LeaveWindowMask | KeyPressMask | KeyReleaseMask Display *display = nullptr; Window window = DefaultRootWindow(display); if (auto *x11Application = qApp->nativeInterface()) { display = x11Application->display(); } int rv = XGrabPointer(display, window, True, GRABEVENTS, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); #undef GRABEVENTS return (rv == GrabSuccess); } bool establishGrab() { Display *display = nullptr; if (auto *x11Application = qApp->nativeInterface()) { display = x11Application->display(); } XSync(display, False); XServerGraber xserverGraber; Q_UNUSED(xserverGraber); if (!grabKeyboard()) { return false; } //不抢占鼠标事件 // if(!grabMouse()) { // XUngrabKeyboard(QX11Info::display(), CurrentTime); // XFlush(QX11Info::display()); // return false; // } return true; } bool closeGrab() { Display *display = nullptr; if (auto *x11Application = qApp->nativeInterface()) { display = x11Application->display(); } XSync(display, False); XServerGraber xserverGraber; Q_UNUSED(xserverGraber); XUngrabKeyboard(display, CurrentTime); XUngrabPointer(display, CurrentTime); XFlush(display); return true; } ukui-session-manager/tools/plasma-shell-manager.cpp0000664000175000017500000001227415252714370021420 0ustar fengfeng/* * Copyright (C) Copyright 2021 KylinSoft Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301, USA. **/ #include "plasma-shell-manager.h" #include #include #include #include #include #include static PlasmaShellManager* global_instance = nullptr; PlasmaShellManager *PlasmaShellManager::getInstance() { if (!global_instance) { global_instance = new PlasmaShellManager; qDebug() << "Here create instance..."; } qDebug() << "Return instance"; return global_instance; } bool PlasmaShellManager::setAppWindowActive() { if (!supportPlasmaWindowManagement()) return false; m_appWindow->requestActivate(); return true; } bool PlasmaShellManager::setAppWindowKeepAbove(bool keep) { if (!supportPlasmaWindowManagement()) { qDebug() << "false"; return false; } if(keep != m_appWindow->isKeepAbove()) { qDebug() << "to keep above"; m_appWindow->requestToggleKeepAbove(); } return true; } bool PlasmaShellManager::setMaximized(QWindow *window) { if (!supportShell()) return false; auto surface = KWayland::Client::Surface::fromWindow(window); if (!surface) return false; auto shellSurface = m_shell->createSurface(surface, window); if (!shellSurface) return false; shellSurface->setMaximized(); return true; } bool PlasmaShellManager::setRole(QWindow *window, KWayland::Client::PlasmaShellSurface::Role role) { if (!supportPlasmaShell()) return false; auto surface = KWayland::Client::Surface::fromWindow(window); if (!surface) return false; auto plasmaShellSurface = m_plasmaShell->createSurface(surface, window); if (!plasmaShellSurface) return false; plasmaShellSurface->setRole(role); return true; } bool PlasmaShellManager::setPos(QWindow *window, const QPoint &pos) { if (!supportPlasmaShell()) return false; auto surface = KWayland::Client::Surface::fromWindow(window); if (!surface) return false; auto plasmaShellSurface = m_plasmaShell->createSurface(surface, window); if (!plasmaShellSurface) return false; plasmaShellSurface->setPosition(pos); return true; } bool PlasmaShellManager::supportPlasmaShell() { return m_plasmaShell; } bool PlasmaShellManager::supportShell() { return m_shell; } bool PlasmaShellManager::supportPlasmaWindowManagement() { return m_windowManager && m_appWindow; } PlasmaShellManager::PlasmaShellManager(QObject *parent) : QObject(parent) { auto connection = KWayland::Client::ConnectionThread::fromApplication(qApp); auto registry = new KWayland::Client::Registry(this); registry->create(connection->display()); connect(registry, &KWayland::Client::Registry::plasmaShellAnnounced, this, [=](){ qDebug() << "plasmaShellAnnounced..."; const auto interface = registry->interface(KWayland::Client::Registry::Interface::PlasmaShell); if (interface.name != 0) { qDebug() << "createPlasmaShell..."; m_plasmaShell = registry->createPlasmaShell(interface.name, interface.version, this); } }); connect(registry, &KWayland::Client::Registry::plasmaWindowManagementAnnounced, this, [=](){ qDebug() << "plasmaWindowManagementAnnounced"; const auto interface = registry->interface(KWayland::Client::Registry::Interface::PlasmaWindowManagement); if (interface.name != 0) { qDebug() << "createPlasmaWindowManagement"; m_windowManager = registry->createPlasmaWindowManagement(interface.name, interface.version, this); } if(m_windowManager) { connect(m_windowManager, &KWayland::Client::PlasmaWindowManagement::windowCreated, [this](KWayland::Client::PlasmaWindow *window) { qDebug()<< "PlasmaWindow..."; if (window->pid() == getpid()) { if(isFirstCreate) { isFirstCreate = false; m_appWindow = window; } } }); } }); connect(registry, &KWayland::Client::Registry::shellAnnounced, this, [=](){ const auto interface = registry->interface(KWayland::Client::Registry::Interface::Shell); if (interface.name != 0) { m_shell = registry->createShell(interface.name, interface.version, this); } }); registry->setup(); connection->roundtrip(); } ukui-session-manager/tools/main.cpp0000664000175000017500000004200115252714370016341 0ustar fengfeng/* * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. * 2010-2016 LXQt team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301, USA. **/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ukuipower.h" #include "mainwindow.h" #include "loginedusers.h" #include "lockchecker.h" #include #include #include #include #include #include #include #include #include #include "plasma-shell-manager.h" #ifdef signals #undef signals #endif bool messageboxCheck() { QMessageBox msgBox; msgBox.setWindowTitle(QObject::tr("ukui-session-tools")); msgBox.setIcon(QMessageBox::Warning); msgBox.setWindowFlags(Qt::WindowStaysOnTopHint); // msgBox.setModal(false); msgBox.setText(QObject::tr("Multiple users are logged in at the same time.Are you sure you want to close this system?")); QPushButton *confirmButton = msgBox.addButton(QObject::tr("confirm"), QMessageBox::ActionRole); QPushButton *cancelButton = msgBox.addButton(QObject::tr("cancel"), QMessageBox::RejectRole); //QPushButton *confirmButton = msgBox.addButton(QObject::tr("confirm"), QMessageBox::RejectRole); msgBox.exec(); if (msgBox.clickedButton() == cancelButton) { qDebug() << "cancel!"; return false; } else if (msgBox.clickedButton() == confirmButton) { qDebug() << "confirm!"; return true; } else { return false; } } void messagecheck() { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); msgBox.setWindowFlags(Qt::WindowStaysOnTopHint); QString t1 = QObject::tr("System update or package installation in progress,this function is temporarily unavailable."); QString t2 = QObject::tr("System backup or restore in progress,this function is temporarily unavailable."); FILE *file_update = fopen("/tmp/lock/kylin-update.lock","r"); if (file_update != NULL) { msgBox.setText(t1); fclose(file_update); } FILE *file_backup = fopen("/tmp/lock/kylin-backup.lock","r"); if (file_backup != NULL) { msgBox.setText(t2); fclose(file_backup); } QPushButton *cancelButton = msgBox.addButton(QObject::tr("OK"), QMessageBox::RejectRole); msgBox.exec(); if (msgBox.clickedButton() == cancelButton) { qDebug() << "OK!"; } } bool playShutdownMusic(UkuiPower &powermanager, int num, QTimer *up_to_time) { bool play_music = false; QGSettings *gs = new QGSettings("org.ukui.session", "/org/ukui/desktop/session/"); if (num == 4) { play_music = gs->get("logout-music").toBool(); } if (num == 6 || num == 8) { play_music = gs->get("poweroff-music").toBool(); } if (num == 0 || num == 1 || num == 2) { play_music = false; } gs->set("win-key-release", false); static int action = num; if (num == 4 || num == 0) { QDBusInterface dbus("org.gnome.SessionManager", "/org/gnome/SessionManager", "org.gnome.SessionManager", QDBusConnection::sessionBus()); if (!dbus.isValid()) { qWarning() << "dbusCall: QDBusInterface is invalid"; return false; } QDBusMessage msg; if (num == 4) { msg = dbus.call("emitStartLogout"); } if (num == 0) { msg = dbus.call("emitPrepareForSwitchuser"); } if (!msg.errorName().isEmpty()) { qWarning() << "Dbus error: " << msg; } } if (play_music) { // up_to_time and soundplayer can not be define out of this if(). // otherwise run ukui-session-tools --suspend with segment error. // because they will be delete at the end of the playShutdownMusic(). QObject::connect(up_to_time, &QTimer::timeout, [&]() { powermanager.doAction(UkuiPower::Action(action)); exit(0); }); QString xdg_session_type = qgetenv("XDG_SESSION_TYPE"); if (num == 6 || num == 8) { if (xdg_session_type == "wayland") { QProcess::startDetached("paplay /usr/share/ukui/ukui-session-manager/shutdown.wav"); } else { QProcess::startDetached("aplay /usr/share/ukui/ukui-session-manager/shutdown.wav"); } up_to_time->start(5000); } else if (num == 4) { if (xdg_session_type == "wayland") { QProcess::startDetached("paplay /usr/share/ukui/ukui-session-manager/logout.wav"); } else { QProcess::startDetached("aplay /usr/share/ukui/ukui-session-manager/logout.wav"); } up_to_time->start(2000); } else { qDebug() << "error num"; return false; } } else { powermanager.doAction(UkuiPower::Action(action)); exit(0); } return false; } /** * @brief 判断当前是否处于锁屏 */ bool screensaverIsActive() { QString SS_DBUS_SERVICE = "org.ukui.ScreenSaver"; QString SS_DBUS_PATH = "/"; QString SS_DBUS_INTERFACE = "org.ukui.ScreenSaver"; QString displayNum = QString(qgetenv("DISPLAY")).replace(":", "").replace(".", "_"); qDebug() << "display = " << displayNum ; QString sessionDbus = QString("%1%2").arg(SS_DBUS_SERVICE).arg(displayNum); QDBusInterface *interface = new QDBusInterface(sessionDbus, SS_DBUS_PATH, SS_DBUS_INTERFACE); if (!interface->isValid()) { qDebug() << "interface not valid"; delete interface; interface = new QDBusInterface(SS_DBUS_SERVICE, SS_DBUS_PATH, SS_DBUS_INTERFACE); } QDBusMessage response = interface->call("GetLockState"); //判断method是否被正确返回 if (response.type() == QDBusMessage::ReplyMessage) { //从返回参数获取返回值 bool isActive = response.arguments()[0].toBool(); qDebug() << "screensaver isActive:" << isActive; return isActive; } else { qDebug() << "QDBusMessage failed!"; return false; } } int main(int argc, char* argv[]) { initUkuiLog4qt("ukui-session-tools"); #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); #endif #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); #endif QStringList homePath = QStandardPaths::standardLocations(QStandardPaths::HomeLocation); int fd = open(QString(homePath.at(0) + "/.config/ukui-session-tools%1.lock").arg(getenv("DISPLAY")).toUtf8().data(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); if (fd < 0) { exit(1); } if (lockf(fd, F_TLOCK, 0)) { qDebug() << "Can't lock single file, ukui-session-tools is already running!"; exit(0); } qunsetenv("QT_IM_MODULE"); qunsetenv("SESSION_MANAGER"); QString SS_DBUS_SERVICE = "org.ukui.ScreenSaver"; QString SS_DBUS_PATH = "/"; QString SS_DBUS_INTERFACE = "org.ukui.ScreenSaver"; QString displayNum = QString(qgetenv("DISPLAY")).replace(":", "").replace(".", "_"); QString sessionDbus = QString("%1%2").arg(SS_DBUS_SERVICE).arg(displayNum); QSharedPointer screensaverInterface( new QDBusInterface(sessionDbus, SS_DBUS_PATH, SS_DBUS_INTERFACE)); if (!screensaverInterface->isValid()) { screensaverInterface = QSharedPointer(new QDBusInterface(SS_DBUS_SERVICE, SS_DBUS_PATH, SS_DBUS_INTERFACE)); } bool m_flag = false; QDBusReply reply = screensaverInterface->call("CheckAppVersion"); if (reply.isValid()) { // use the returned value qDebug() << "CheckAppVersion is " << reply.value(); m_flag = reply.value(); } else { qDebug() << "CheckAppVersion function is not existed"; } QApplication a(argc, argv); if (m_flag) { qDebug() << "screensaverInterface valid"; QCommandLineParser parser; parser.setApplicationDescription(QApplication::tr("UKUI session tools, show the screensave dialog")); parser.addHelpOption(); parser.addVersionOption(); QCommandLineOption switchuserOption( QStringLiteral("switchuser"), QApplication::tr("Switch the user of this computer.")); parser.addOption(switchuserOption); QCommandLineOption hibernateOption(QStringLiteral("hibernate"), QApplication::tr("Hibernate this computer.")); parser.addOption(hibernateOption); QCommandLineOption suspendOption(QStringLiteral("suspend"), QApplication::tr("Suspend this computer.")); parser.addOption(suspendOption); QCommandLineOption logoutOption(QStringLiteral("logout"), QApplication::tr("Logout this computer.")); parser.addOption(logoutOption); QCommandLineOption rebootOption(QStringLiteral("reboot"), QApplication::tr("Restart this computer.")); parser.addOption(rebootOption); QCommandLineOption shutdownOption(QStringLiteral("shutdown"), QApplication::tr("Shutdown this computer.")); parser.addOption(shutdownOption); parser.process(a); bool flag1 = true; if (parser.isSet(switchuserOption)) { flag1 = false; screensaverInterface->call("SwitchUser"); } if (parser.isSet(hibernateOption)) { flag1 = false; screensaverInterface->call("Hibernate"); } if (parser.isSet(suspendOption)) { flag1 = false; screensaverInterface->call("Suspend"); } if (parser.isSet(logoutOption)) { flag1 = false; screensaverInterface->call("Logout"); } if (parser.isSet(rebootOption)) { flag1 = false; screensaverInterface->call("Reboot"); } if (parser.isSet(shutdownOption)) { flag1 = false; screensaverInterface->call("PowerOff"); } if (flag1) { screensaverInterface->call("SessionTools"); } exit(0); } qDebug() << "screensaverInterface not valed"; if (QGSettings::isSchemaInstalled("org.ukui.style")) { QGSettings *settings = new QGSettings("org.ukui.style"); if (qApp->property("noChangeSystemFontSize").isValid() && qApp->property("noChangeSystemFontSize").toBool()) { return 0; } double fontSize = settings->get("system-font-size").toString().toDouble(); QString fontType = settings->get("systemFont").toString(); if (fontSize > 0) { QFont font = QApplication::font(); font.setPointSizeF(fontSize); font.setStyleName(fontType); QApplication::setFont(font); } } // Load ts files const QString locale = QLocale::system().name(); QTranslator translator; qDebug() << "local: " << locale; qDebug() << "path: " << QStringLiteral(UKUI_TRANSLATIONS_DIR) + QStringLiteral("/ukui-session-manager"); if (translator.load(locale, QStringLiteral(UKUI_TRANSLATIONS_DIR) + QStringLiteral("/ukui-session-manager"))) { a.installTranslator(&translator); } else { qDebug() << "Load translations file failed!"; } UkuiPower powermanager(&a); bool flag = true; // define in the main() avoid scope error. QTimer *up_to_time = new QTimer(); up_to_time->setSingleShot(true); QGSettings *gs = new QGSettings("org.ukui.session", "/org/ukui/desktop/session/"); gs->set("win-key-release", true); //初始化窗口 Load qss file MainWindow *w = new MainWindow(); //KWindowSystem::setType(w->winId(), NET::Logout); QFile qss(":/powerwin.qss"); qss.open(QFile::ReadOnly); a.setStyleSheet(qss.readAll()); qss.close(); QCommandLineParser parser; parser.setApplicationDescription( QApplication::tr("UKUI session tools, show the shutdown dialog without any arguments.")); const QString VERINFO = QStringLiteral("2.0"); a.setApplicationVersion(VERINFO); a.setApplicationName(QApplication::tr("ukui-session-tools")); parser.addHelpOption(); parser.addVersionOption(); QCommandLineOption switchuserOption( QStringLiteral("switchuser"), QApplication::tr("Switch the user of this computer.")); parser.addOption(switchuserOption); QCommandLineOption hibernateOption(QStringLiteral("hibernate"), QApplication::tr("Hibernate this computer.")); parser.addOption(hibernateOption); QCommandLineOption suspendOption(QStringLiteral("suspend"), QApplication::tr("Suspend this computer.")); parser.addOption(suspendOption); QCommandLineOption logoutOption(QStringLiteral("logout"), QApplication::tr("Logout this computer.")); parser.addOption(logoutOption); QCommandLineOption rebootOption(QStringLiteral("reboot"), QApplication::tr("Restart this computer.")); parser.addOption(rebootOption); QCommandLineOption shutdownOption(QStringLiteral("shutdown"), QApplication::tr("Shutdown this computer.")); parser.addOption(shutdownOption); parser.process(a); if (parser.isSet(switchuserOption)) { flag = playShutdownMusic(powermanager, 0, up_to_time); } if (parser.isSet(hibernateOption)) { QVector res = LockChecker::listInhibitor("sleep"); if (res.isEmpty()) { flag = playShutdownMusic(powermanager, 1, up_to_time); } else { w->showInhibitWarning(res, 1); w->show(); } } if (parser.isSet(suspendOption)) { QVector res = LockChecker::listInhibitor("sleep"); if (res.isEmpty()) { flag = playShutdownMusic(powermanager, 2, up_to_time); } else { w->showInhibitWarning(res, 2); w->show(); } } if (parser.isSet(logoutOption)) { QVector res = LockChecker::listInhibitor("shutdown"); if (res.isEmpty()) { flag = playShutdownMusic(powermanager, 4, up_to_time); } else { w->showInhibitWarning(res, 4); w->show(); } } if (parser.isSet(rebootOption)) { QVector res = LockChecker::listInhibitor("shutdown"); if (res.isEmpty()) { if (LockChecker::getLoginedUsers().count() > 1) {//提醒多个用户登录的情况 if (messageboxCheck()) { flag = playShutdownMusic(powermanager, 6, up_to_time); } else { gs->set("win-key-release", false); return 0; } } else { flag = playShutdownMusic(powermanager, 6, up_to_time); } } else { w->showInhibitWarning(res, 6); w->show(); } } if (parser.isSet(shutdownOption)) { QVector res = LockChecker::listInhibitor("shutdown"); if (res.isEmpty()) { if (LockChecker::getLoginedUsers().count() > 1) {//提醒多个用户登录的情况 if (messageboxCheck()) { flag = playShutdownMusic(powermanager, 8, up_to_time); } else { gs->set("win-key-release", false); return 0; } } else { flag = playShutdownMusic(powermanager, 8, up_to_time); } } else { w->showInhibitWarning(res, 8); w->show(); } } if (screensaverIsActive()) { gs->set("win-key-release", false); exit(0); } if (flag) { w->show(); QObject::connect(w, &MainWindow::signalTostart, [&]() { // 从界面点击 切换用户、睡眠和休眠 按钮,则等待界面隐藏再执行命令 if (w->defaultnum < 3) { w->hide(); QTimer::singleShot(500, [&]() { playShutdownMusic(powermanager, w->defaultnum, up_to_time); }); } else { playShutdownMusic(powermanager, w->defaultnum, up_to_time); } }); } return a.exec(); } ukui-session-manager/tools/systemupgradecheck.cpp0000664000175000017500000000602415252714370021314 0ustar fengfeng/* * Copyright (C) Copyright 2021 KylinSoft Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301, USA. **/ #include "systemupgradecheck.h" #include #include #define DBUS_NAME "com.kylin.systemupgrade" #define DBUS_PATH "/com/kylin/systemupgrade" #define DBUS_INTERFACE "com.kylin.systemupgrade.interface" systemUpgradeCheck::systemUpgradeCheck() { interface = new QDBusInterface(DBUS_NAME, DBUS_PATH, DBUS_INTERFACE, QDBusConnection::systemBus()); if (!interface->isValid()) { qDebug() << "systemUpgrade interface not valid"; isDbusActive = false; isSystemUpgrade =false; } else { isDbusActive = true; } } bool systemUpgradeCheck::checkSystemUpgrade(){ if (!isDbusActive) return false; QDBusMessage response = interface->call("CheckInstallRequired"); if (response.type() == QDBusMessage::ReplyMessage) { int res = response.arguments()[0].toInt(); qDebug() << "CheckInstallRequired return " << res; if (res == 0) isSystemUpgrade = false; else isSystemUpgrade = true; } else { qDebug () << "call CheckInstallRequired failed;"; isSystemUpgrade = false; } return isSystemUpgrade; } bool systemUpgradeCheck::doUpgradeThenRboot(){ if (!isDbusActive) return false; bool mask = false; QDBusMessage response = interface->call("TriggerInstallOnShutdown","reboot"); if (response.type() == QDBusMessage::ReplyMessage) { int res = response.arguments()[0].toInt(); qDebug() << "TriggerInstallOnShutdown reboot return " << res; if (res == 0) mask = true; else mask = false; } else { qDebug () << "call TriggerInstallOnShutdown reboot failed;"; mask = false; } return mask; } bool systemUpgradeCheck::doUpgradeThenShutdown(){ if (!isDbusActive) return false; bool mask = false; QDBusMessage response = interface->call("TriggerInstallOnShutdown","shutdown"); if (response.type() == QDBusMessage::ReplyMessage) { int res = response.arguments()[0].toInt(); qDebug() << "TriggerInstallOnShutdown shutdown return " << res; if (res == 0) mask = true; else mask = false; } else { qDebug () << "call TriggerInstallOnShutdown shutdown failed;"; mask = false; } return mask; } ukui-session-manager/tools/mypushbutton.h0000664000175000017500000000400615252714370017646 0ustar fengfeng/* * Copyright (C) Copyright 2021 KylinSoft Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301, USA. **/ #ifndef MYPUSHBUTTON_H #define MYPUSHBUTTON_H #include #include #include #include #include #include #include #include #include #include "myiconlabel.h" class MyPushButton : public QWidget { Q_OBJECT public: MyPushButton(QString iconPath, QString buttonLable, QString objName, QWidget *parent = nullptr, int x = 0, int y = 0, int width = 140, int height = 180, int iconWidth = 48, int labelWidth = 128); ~MyPushButton(); void changeIconBackColor(bool isChoose = true, bool isKeySelect = false); MyIconLabel* getIconLabel(); bool getIsKeySelect(); bool getIsMouseSelect(); void setIsKeySelect(bool isKeySelect); void setIsMouseSelect(bool isMouseSelect); protected: public: MyIconLabel *m_iconLabel = nullptr; private: QLabel *m_buttonLabel = nullptr; QFont m_buttonLabelFont; QPixmap m_pixMap; //MyIconLabel *m_iconLabel = nullptr; bool m_isKeySelect = false;//是否通过键盘选中 bool m_isMouseSelect = false;//是否鼠标选中 protected: signals: void mouseRelase(QEvent *event, QString iconName); public slots: void iconLabelMouseEvent(QEvent *event); }; #endif // MYPUSHBUTTON_H ukui-session-manager/tools/ukuipower.cpp0000664000175000017500000001052615252714370017456 0ustar fengfeng/* BEGIN_COMMON_COPYRIGHT_HEADER * (c)LGPL2+ * Copyright: Copyright (C) Copyright 2021 KylinSoft Co., Ltd. * 2012 Razor team * Authors: * Christian Surlykke * * This program or library is free software; you can redistribute it * and/or modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA * * END_COMMON_COPYRIGHT_HEADER */ #include "ukuipower.h" #include "powerprovider.h" #include #include #include UkuiPower::UkuiPower(QObject *parent) : QObject(parent) { m_systemdProvider = new SystemdProvider(this); } UkuiPower::~UkuiPower() { } bool UkuiPower::canAction(UkuiPower::Action action) const { //以下为代码结构调整 QString command; switch (action) { case PowerSwitchUser: command = QLatin1String("canSwitch"); break; case PowerHibernate: command = QLatin1String("canHibernate"); break; case PowerSuspend: command = QLatin1String("canSuspend"); break; case PowerMonitorOff: command = QLatin1String("canLockscreen"); break; case PowerLogout: command = QLatin1String("canLogout"); break; case PowerReboot: command = QLatin1String("canReboot"); break; case PowerShutdown: command = QLatin1String("canPowerOff"); break; default: break; } QDBusInterface *sessionInterface = new QDBusInterface("org.gnome.SessionManager", "/org/gnome/SessionManager", "org.gnome.SessionManager", QDBusConnection::sessionBus()); if (!sessionInterface->isValid()) { qWarning() << "dbusCall: Session QDBusInterface is invalid"; return false; } QDBusReply testReply = sessionInterface->call(QLatin1String("canLockscreen")); if (!testReply.isValid()) { //解决老版本升级到新版本接口不兼容的问题,在session接口不存在的情况下,调用systemd的接口 QDBusError error = testReply.error(); if (error.type() == QDBusError::UnknownMethod) { qDebug() <<"updating ! old ukui-session dose not have canAction method"; if (action == PowerLogout || action == PowerMonitorOff) { return true; } return m_systemdProvider->canAction(action); } qDebug() <<"dbus error"; return false; } QDBusReply reply = sessionInterface->call(command); return reply.value(); } bool UkuiPower::doAction(UkuiPower::Action action) { QString command; switch (action) { case PowerSwitchUser: command = QLatin1String("switchUser"); break; case PowerHibernate: command = QLatin1String("hibernate"); break; case PowerSuspend: command = QLatin1String("suspend"); break; case PowerLogout: command = QLatin1String("logout"); break; case PowerReboot: command = QLatin1String("reboot"); break; case PowerShutdown: command = QLatin1String("powerOff"); break; default: break; } QDBusInterface *sessionInterface = new QDBusInterface("org.gnome.SessionManager", "/org/gnome/SessionManager", "org.gnome.SessionManager", QDBusConnection::sessionBus()); if (!sessionInterface->isValid()) { qWarning() << "dbusCall: Session QDBusInterface is invalid"; return false; } QDBusMessage mes = sessionInterface->call(command); if (!(mes.errorName().isEmpty())) { //本来应该判断错误类别,考虑到运行效率,不做该判断 return m_systemdProvider->doAction(action); } return true; } ukui-session-manager/tools/lockchecker.cpp0000664000175000017500000001472515252713362017706 0ustar fengfeng/* * Copyright (C) Copyright 2021 KylinSoft Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * **/ #include "lockchecker.h" #include "loginedusers.h" #include #include #include #include #include #include #include #define SYSTEMD_SERVICE "org.freedesktop.login1" #define SYSTEMD_PATH "/org/freedesktop/login1" #define SYSTEMD_INTERFACE "org.freedesktop.login1.Manager" //QDBusArgument &InhibitInfo::operator<<(QDBusArgument &argument, const InhibitInfo::InhibitorInfo &mystruct) //{ // argument.beginStructure(); // argument << mystruct.name << mystruct.icon; // argument.endStructure(); // return argument; //} //const QDBusArgument &InhibitInfo::operator>>(const QDBusArgument &argument, InhibitInfo::InhibitorInfo &mystruct) //{ // argument.beginStructure(); // argument >> mystruct.name >> mystruct.icon ; // argument.endStructure(); // return argument; //} LockChecker::LockChecker() { } LockChecker::~LockChecker() { } QStringList LockChecker::getLoginedUsers() { QStringList loginedUser; qRegisterMetaType("LoginedUsers"); qDBusRegisterMetaType(); QDBusInterface loginInterface(SYSTEMD_SERVICE, SYSTEMD_PATH, SYSTEMD_INTERFACE, QDBusConnection::systemBus()); if (loginInterface.isValid()) { qDebug() << "create interface success"; } QDBusMessage result = loginInterface.call("ListUsers"); QList outArgs = result.arguments(); QVariant first = outArgs.at(0); const QDBusArgument &dbusArgs = first.value(); QVector loginedUsers; dbusArgs.beginArray(); while (!dbusArgs.atEnd()) { LoginedUsers user; dbusArgs >> user; if (user.userName == "lightdm") continue;//过滤登录界面的lightdm用户 loginedUsers.push_back(user); } dbusArgs.endArray(); for (LoginedUsers user : loginedUsers) { QDBusInterface userPertyInterface("org.freedesktop.login1", user.objpath.path(), "org.freedesktop.DBus.Properties", QDBusConnection::systemBus()); QDBusReply reply = userPertyInterface.call("Get", "org.freedesktop.login1.User", "State"); if (reply.isValid()) { QString status = reply.value().toString(); if ("closing" != status) { loginedUser.append(user.userName); } } } return loginedUser; } QVector LockChecker::listInhibitor(QString type) { qDBusRegisterMetaType(); QVector resVec; QDBusInterface loginInterface("org.gnome.SessionManager", "/org/gnome/SessionManager", "org.gnome.SessionManager", QDBusConnection::sessionBus()); if (loginInterface.isValid()) { qDebug() << "create interface success"; } QDBusMessage result = loginInterface.call("ListInhibitor", QVariant(type)); if (!result.errorMessage().isEmpty()) { if (getInhibitorLocal(resVec, type)) { qDebug() << "get inhibitor information from login1"; } return resVec; } QList outArgs = result.arguments(); QVariant first = outArgs.at(0); const QDBusArgument &dbusArgs = first.value(); dbusArgs.beginArray(); while (!dbusArgs.atEnd()) { InhibitInfo::InhibitorInfo inhibtor; dbusArgs >> inhibtor; resVec.push_back(inhibtor); } dbusArgs.endArray(); return resVec; } QString LockChecker::getName(QFile *a) { QString user = getenv("USER"); if (a->exists()) { a->open(QIODevice::ReadOnly|QIODevice::Text); QTextStream fileStream(a); int k = 0; while (!fileStream.atEnd()) { QString line = fileStream.readLine(); if (k == 0) { QString a = line; qDebug() << "uid="< outArgs = ret.arguments(); QVariant first = outArgs.at(0); const QDBusArgument &dbusArgs = first.value(); QDBusObjectPath path; dbusArgs.beginArray(); int userNum = 0; while (!dbusArgs.atEnd()) { dbusArgs >> path; userNum++; } dbusArgs.endArray(); qDebug() << userNum; return userNum; } ukui-session-manager/tools/myiconlabel.h0000664000175000017500000000270215252713362017364 0ustar fengfeng/* * Copyright (C) Copyright 2021 KylinSoft Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301, USA. **/ #ifndef MYICONLABEL_H #define MYICONLABEL_H #include #include #include #include #include #include #include #include #include #include #include "pushbutton.h" class MyIconLabel : public QLabel { Q_OBJECT public: MyIconLabel(int labelWidth, int iconWidth, QString path, QWidget *parent = nullptr); ~MyIconLabel(); bool containsPoint(QPoint p); protected: bool event(QEvent *); private: PushButton *m_btnIcon = nullptr; bool m_showBackColor = false; QPoint m_point; protected: public: signals: void mouseEventSignals(QEvent *event); }; #endif // MYICONLABEL_H ukui-session-manager/tools/ukuilockinfo.h0000664000175000017500000000341215252713362017567 0ustar fengfeng#ifndef UKUILOCKINFO_H #define UKUILOCKINFO_H #include #include #include namespace InhibitInfo { struct InhibitorInfo { QString name; QString icon; }; QDBusArgument &operator<<(QDBusArgument &argument, const InhibitInfo::InhibitorInfo &mystruct); const QDBusArgument &operator>>(const QDBusArgument &argument, InhibitInfo::InhibitorInfo &mystruct); } Q_DECLARE_METATYPE(InhibitInfo::InhibitorInfo) namespace SystemdInhibitor { struct Inhibitor { QString action; QString name; QString reason; QString mode; int uid; int pid; }; QDBusArgument &operator<<(QDBusArgument &argument, const SystemdInhibitor::Inhibitor &mystruct); const QDBusArgument &operator>>(const QDBusArgument &argument, SystemdInhibitor::Inhibitor &mystruct); } Q_DECLARE_METATYPE(SystemdInhibitor::Inhibitor) class Ukuilockinfo { public: Ukuilockinfo(); ~Ukuilockinfo(); public: enum InhibitorType { logout, suspend, shutdown }; enum buttonType { switchuserBtn, hibernateBtn, suspendBtn, lockscreenBtn, logoutBtn, rebootBtn, shutdownBtn }; static QVector listInhibitorInfo(Ukuilockinfo::InhibitorType type); static bool getCfgValue(Ukuilockinfo::buttonType button); private: static void getLogoutInhibitor(QVector &inhibitorVec); static void getSystemdInhibitor(QString type, QVector &inhibitorVec); static void findNameAndIcon(QString &inhibitorName, InhibitInfo::InhibitorInfo &inhibitor); static QString getAppLocalName(QString desktopfp); }; #endif // UKUILOCKINFO_H ukui-session-manager/tools/mainwindow.h0000664000175000017500000002161115252714370017242 0ustar fengfeng/*Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301, USA. **/ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include "powerprovider.h" #include "lockchecker.h" #include "mypushbutton.h" #include "commonpushbutton.h" #include "systemupgradecheck.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include class XEventMonitor; class QListView; class QStandardItemModel; class MyListView; QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow, public QAbstractNativeEventFilter { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); /** * @brief 响应按钮事件 * @param test2 按钮名字 * @param i 按钮序号 */ void doEvent(QString test2,int i); /** * @brief 响应鼠标事件后改变按钮状态 * @param widget 指定按钮对象 * @param widget 鼠标事件 */ void changePoint(QWidget *widget ,QEvent *event); /** * @brief 调整界面显示的控件 */ void judgeboxShow(); /** * @brief 消息过滤 */ virtual bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override; /** * @brief 初始化系统监视器按钮 */ void initialSystemMonitor(); /** * @brief 初始化按钮 */ void initialBtn(); /** * @brief 初始化提示内容的控件 */ void initialJudgeWidget(); /** * @brief 初始化时间控件 */ void initialDateTimeWidget(); /** * @brief 更新时间控件 */ void updateDateTimerWidget(); /** * @brief 可以通过配置文件来控制按钮是否显示 */ void initialBtnCfg(); /** * @brief 设置layout是否显示 */ void setLayoutWidgetVisible(QLayout* layout, bool show); /** * @param btnName 指定按钮objectname * @param isEnterKey 是否通过键盘按键选中 * @brief 修改按钮样式 */ void changeBtnState(QString btnName, bool isEnterKey = false); /** * @brief 当有inhibitor存在时显示提醒界面 */ void showInhibitWarning(QVector &list, int action); private: /** * @brief 重新计算界面大小及控件位置布局 */ void ResizeEvent(); /** * @brief 画出提醒界面 */ void drawWarningWindow(QRect &rect, QVector &list, int action); /** * @brief 根据inhibitor的名称获取对应desktop文件中的应用名和icon路径 * @param allNum 共显示的按钮数 * @param lineMaxNum 一行最多显示的按钮数 * @param btn 指定按钮 */ void calculateBtnSpan(int allNum, int lineMaxNum, MyPushButton* btn, int& row, int& column); /** * @brief 计算键盘左右键对应的按钮 * @param key 按键名字 */ void calculateKeyBtn(const QString &key); /** * @brief 按钮是否可用 * @param index 按钮序号 */ bool judgeBtnIsEnable(int index); /** * @brief 匹配上下按键按钮 * @param row 行号 * @param column 列号 */ bool matchKeyBtn(int row, int column); /** * @brief 打开监视器 */ void doSystemMonitor(); /** * @brief 显示常规的按钮界面 * @param hideBtnNum 隐藏的按钮数 */ void showNormalBtnWidget(int hideBtnNum); /** * @brief 显示需要换行的按钮界面 * @param hideBtnNum 隐藏的按钮数 */ void showHasScrollBarBtnWidget(int hideBtnNum); void doLockscreen();//锁屏操作 void startUkuiSplash(); Q_SIGNALS: /** * @brief 按钮点击后的事件信号 */ void signalTostart(); /** * @brief 点击提示界面的确认按钮信号 */ void confirmButtonclicked(); private Q_SLOTS: /** * @brief 退出 */ bool exitt(); /** * @brief 按键按下事件 * @param key 键名 */ void onGlobalKeyPress(const QString &key); /** * @brief 按键弹起事件 * @param key 键名 */ void onGlobalkeyRelease(const QString &key); /** * @brief 屏幕变化 */ void screenCountChanged(); /** * @brief 点击按钮事件 */ void mouseReleaseSlots(QEvent *event, QString objName); protected: void paintEvent(QPaintEvent *e); bool eventFilter(QObject *, QEvent *); void mousePressEvent(QMouseEvent *event); public: int defaultnum = 0; private: QPixmap pix; QGSettings *gs; QWidget *lastWidget = nullptr; QHash map; QHash rowMap; QHash columMap; systemUpgradeCheck *upgradeCheck = nullptr; UkuiPower *m_power; XEventMonitor *xEventMonitor; int tableNum; bool flag = false; /// 各按钮是否隐藏 默认隐藏 bool isSwitchuserHide = true; bool isHibernateHide = true; bool isSuspendHide = true; bool isLockscreenHide = true; bool isLogoutHide = true; bool isUpgradeThenRebootHide = true; bool isRebootHide = true; bool isUpgradeThenPowerOffHide = true; bool isPowerOffHide = true; bool click_blank_space_need_to_exit = true; bool close_system_needed_to_confirm = false; bool inhibitSleep = false; bool inhibitShutdown = false; bool m_isSystemMonitorSelect = false; QHash m_btnHideMap; QString m_btnImagesPath = "/usr/share/ukui/ukui-session-manager/images"; MyPushButton *m_switchUserBtn = nullptr; MyPushButton *m_hibernateBtn = nullptr; MyPushButton *m_suspendBtn = nullptr; MyPushButton *m_lockScreenBtn = nullptr; MyPushButton *m_logoutBtn = nullptr; MyPushButton *m_upgradeThenRebootBtn = nullptr; MyPushButton *m_rebootBtn = nullptr; MyPushButton *m_upgradeThenshutDownBtn = nullptr; MyPushButton *m_shutDownBtn = nullptr; QWidget *m_systemMonitorBtn = nullptr; QLabel *m_dateLabel = nullptr; QLabel *m_timeLabel = nullptr; QLabel *m_judgeLabel = nullptr; CommonPushButton *m_cancelBtn = nullptr; CommonPushButton *m_confirmBtn = nullptr; QLabel *m_messageLabel1 = nullptr; QLabel *m_messageLabel2 = nullptr; QWidget *m_toolWidget = nullptr; QWidget *m_btnWidget = nullptr; QGridLayout *m_buttonHLayout = nullptr; QVBoxLayout *m_dateTimeLayout = nullptr; QVBoxLayout *m_judgeWidgetVLayout = nullptr; QHBoxLayout *m_judgeBtnHLayout = nullptr; QVBoxLayout *m_vBoxLayout = nullptr; QScrollArea *m_scrollArea = nullptr; QHBoxLayout *m_systemMonitorHLayout = nullptr; QLabel *m_systemMonitorIconLabel = nullptr; QLabel *m_systemMonitorLabel = nullptr; QPixmap m_systemMonitorIcon; /// 计算各按钮的行列位置 int m_switchRow = 0, m_switchColumn = 0; int m_hibernateRow = 0, m_hibernateColumn = 0; int m_suspendRow = 0, m_suspendColumn = 0; int m_lockScreenRow = 0, m_lockScreenColumn = 0; int m_logoutRow = 0, m_logoutColumn = 0; int m_upgradeThenRebootRow = 0, m_upgradeThenRebootColumn = 0; int m_rebootRow = 0, m_rebootColumn = 0; int m_upgradeThenShutdownRow = 0, m_upgradeThenShutdownColumn = 0; int m_shutDownRow = 0, m_shutDownColumn = 0; int m_lineNum = 1; QSettings *m_btnCfgSetting = nullptr; QRect m_screen; QWidget *m_showWarningArea = nullptr; /// 阻止列表 MyListView *m_inhibitAppList = nullptr; QStandardItemModel *m_inhibitDataModel = nullptr; bool m_btnWidgetNeedScrollbar = false; /// 是否需要滑动条显示 bool m_showWarningMesg = false; /// 是否显示阻止列表 QVector m_inhibitList; QWidget *m_judgeWidget = nullptr; /// 提示 int m_currentListSelect = -1; bool m_isFirstEnter = true; CommonPushButton *m_inhibitCancelBtn = nullptr; bool m_isFirstEnterInhibitList = true; bool m_isCancelBtnSelect = false; bool m_enterInhibitList = false; bool m_enterJudgeBox = false; }; #endif // MAINWINDOW_H ukui-session-manager/tools/loginedusers.cpp0000664000175000017500000000251115252713362020122 0ustar fengfeng/* * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "loginedusers.h" QDBusArgument &operator<<(QDBusArgument &argument, const LoginedUsers &mystruct) { argument.beginStructure(); argument << mystruct.uid << mystruct.userName << mystruct.objpath;//< mystruct.usergroup; argument.endStructure(); return argument; } const QDBusArgument &operator>>(const QDBusArgument &argument, LoginedUsers &mystruct) { argument.beginStructure(); argument >> mystruct.uid >> mystruct.userName >> mystruct.objpath;// >> mystruct.usergroup; argument.endStructure(); return argument; } ukui-session-manager/tools/CMakeLists.txt0000664000175000017500000000416415252714370017461 0ustar fengfengfind_package(PkgConfig) find_package(KF6Screen) find_package(KWayland) include_directories(${KF6Wayland_LIBRARIES}) #pkg_check_modules(KScreen REQUIRED kf6creen) set(tools_SRCS main.cpp ukuipower.cpp powerprovider.cpp mainwindow.h mainwindow.cpp grab-x11.cpp grab-x11.h xeventmonitor.cpp xeventmonitor.h loginedusers.h lockchecker.h lockchecker.cpp loginedusers.cpp ../ukui-session/xdgdirs.cpp ../ukui-session/xdgdesktopfile.cpp myiconlabel.cpp myiconlabel.h mypushbutton.cpp mypushbutton.h pushbutton.cpp pushbutton.h commonpushbutton.cpp commonpushbutton.h plasma-shell-manager.cpp plasma-shell-manager.h mylistview.cpp mylistview.h ukuilockinfo.h ukuilockinfo.cpp ../ukui-session/xdgdesktopfile.h ../ukui-session/xdgdesktopfile.cpp ../ukui-session/xdgdirs.h ../ukui-session/xdgdirs.cpp ../ukui-session/xdgmacros.h systemupgradecheck.cpp systemupgradecheck.h ) add_executable(ukui-session-tools ${tools_SRCS}) find_package(PkgConfig) pkg_search_module(GSETTINGS_QT REQUIRED gsettings-qt6) include_directories(${GSETTINGS_QT_INCLUDES}) pkg_check_modules(KYSDKSYSTIME_PKG kysdk-systime) target_include_directories(ukui-session-tools PRIVATE ${KYSDKSYSTIME_PKG_INCLUDE_DIRS}) target_link_directories(ukui-session-tools PRIVATE ${KYSDKSYSTIME_PKG_LIBRARY_DIRS}) pkg_check_modules(KDKINFO REQUIRED kysdk-sysinfo) include_directories(${KDKINFO_INCLUDE_DIRS}) link_directories(${KDKINFO_LIBRARY_DIRS}) pkg_check_modules(GLIB2 REQUIRED glib-2.0) pkg_check_modules(GIO2 REQUIRED gio-2.0) include_directories(${GLIB2_INCLUDE_DIRS}) include_directories(${GIO2_INCLUDE_DIRS}) target_link_libraries(ukui-session-tools Qt6::Widgets Qt6::Core Qt6::Gui Qt6::DBus ${GSETTINGS_QT_LIBRARIES} ${KYSDKSYSTIME_PKG_LIBRARIES} ${KDKINFO_LIBRARIES} ${KWayland_LIBRARIES} ${GLIB2_LIBRARIES} ${GIO2_LIBRARIES} -lxcb -lX11 -lXtst -lukui-log4qt Plasma::KWaylandClient KF6::Screen KF6::WindowSystem ) install(TARGETS ukui-session-tools DESTINATION bin) ukui-session-manager/tools/powerprovider.cpp0000664000175000017500000003451115252714370020333 0ustar fengfeng/* BEGIN_COMMON_COPYRIGHT_HEADER * (c)LGPL2+ * Copyright: Copyright (C) Copyright 2021 KylinSoft Co., Ltd. * 2012 Razor team * Authors: * Christian Surlykke * * This program or library is free software; you can redistribute it * and/or modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA * * END_COMMON_COPYRIGHT_HEADER */ #include "powerprovider.h" #include #include #include #include #include #include #include #include #include #include #include // #include "loginedusers.h" #define LIGHTDM_SERVICE "org.freedesktop.DisplayManager" #define LIGTHDM_INTERFACE "org.freedesktop.DisplayManager.Seat" #define SYSTEMD_SERVICE "org.freedesktop.login1" #define SYSTEMD_PATH "/org/freedesktop/login1" #define SYSTEMD_INTERFACE "org.freedesktop.login1.Manager" #define UKUI_SERVICE "org.gnome.SessionManager" #define UKUI_PATH "/org/gnome/SessionManager" #define UKUI_INTERFACE "org.gnome.SessionManager" #define UKUI_SCREENSAVER_SERVICE "org.ukui.ScreenSaver" #define UKUI_SCREENSAVER_PATH "/" #define UKUI_SCREENSAVER_INTERFACE "org.ukui.ScreenSaver" #define PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties" bool messageBoxCheck() { QMessageBox msgBox; // msgBox.setWindowTitle(QObject::tr("conform")); msgBox.setIcon(QMessageBox::Warning); msgBox.setWindowFlags(Qt::WindowStaysOnTopHint); // msgBox.setModal(false); msgBox.setText(QObject::tr("some applications are running and they don't want you to do this.")); QPushButton *stillButton = msgBox.addButton(QObject::tr("Still to do!"), QMessageBox::ActionRole); QPushButton *giveupButton = msgBox.addButton(QObject::tr("give up"), QMessageBox::RejectRole); // QStringList usrlist = getLoginedUsers(); // QList::Iterator it = usrlist.begin(),itend = usrlist.end(); // for(;it != itend;it++){ // qDebug()<<*it; // } msgBox.exec(); if (msgBox.clickedButton() == stillButton) { qDebug() << "Still to do!"; return true; } else if (msgBox.clickedButton() == giveupButton) { qDebug() << "give up"; return false; } else { return false; } } static bool dbusCall( const QString &service, const QString &path, const QString &interface, const QDBusConnection &connection, const QString &method) { QDBusInterface dbus(service, path, interface, connection); if (!dbus.isValid()) { qWarning() << "dbusCall: QDBusInterface is invalid" << service << path << interface << method; return false; } QDBusMessage msg = dbus.call(method); if (!msg.errorName().isEmpty()) { qWarning() << "Dbus error: " << msg; } return msg.arguments().isEmpty() || msg.arguments().constFirst().isNull() || msg.arguments().constFirst().toBool(); } static bool dbusCallSystemd( const QString &service, const QString &path, const QString &interface, const QDBusConnection &connection, const QString &method, bool needBoolArg) { QDBusInterface dbus(service, path, interface, connection); if (!dbus.isValid()) { qWarning() << "dbusCall: QDBusInterface is invalid" << service << path << interface << method; return false; } // QDBusMessage msg = dbus.call(method, needBoolArg ? QVariant(true) : QVariant()); // 在华为相关的机器上,如果调用的method没有参数,但仍传入一个空值,会调用失败 QDBusMessage msg; if (needBoolArg) { msg = dbus.call(method, QVariant(true)); } else { msg = dbus.call(method); } if (!msg.errorName().isEmpty()) { qWarning() << "Debus error: " << msg; } if (msg.arguments().isEmpty() || msg.arguments().constFirst().isNull()) { return false; } QString response = msg.arguments().constFirst().toString(); qDebug() << "systemd:" << method << "=" << response; // this need to be resolved: // while canReboot and canPoweroff return challenge,users click Reboot or shutdown, // we call logout ,then Reboot(true) and Poweroff(true) is called, // if user click cancel in the polkit messagebox,then Reboot or Poweroff is canceled, // but logout has been executed. return response == QLatin1String("yes") || response == QLatin1String("challenge"); } bool dbusGetProperty( const QString &service, const QString &path, const QString &interface, const QDBusConnection &connection, const QString &property) { QDBusInterface dbus(service, path, interface, connection); if (!dbus.isValid()) { qWarning() << "dbusGetProperty: QDBusinterface is invalid" << service << path << interface << property; return false; } // QDBusMessage msg = dbus.call("SwitchToGreeter");//QLatin1String("Get"), dbus.interface(),property // if (!msg.errorName().isEmpty()) { // qWarning() << "Dbus error: " << msg; // } // return !msg.arguments().isEmpty() && // msg.arguments().constFirst().value().variant().toBool(); QVariant canswitch = dbus.property("CanSwitch"); qDebug() << property << "=" << canswitch.toString(); return canswitch.toBool(); } PowerProvider::PowerProvider(QObject *parent) : QObject(parent) {} PowerProvider::~PowerProvider() {} /************************************************ SystemdProvider http://www.freedesktop.org/wiki/Software/systemd/logind ************************************************/ SystemdProvider::SystemdProvider(QObject *parent) : PowerProvider(parent) {} SystemdProvider::~SystemdProvider() {} bool SystemdProvider::canSwitchUser() const { QString property = "CanSwitch"; QString xdg_seat_path = qgetenv("XDG_SEAT_PATH"); if (xdg_seat_path.isEmpty()) { qWarning() << "XDG_SEAT_PATH dose not exist , make canSwitchUser return false"; return false; } return dbusGetProperty( QLatin1String(LIGHTDM_SERVICE), xdg_seat_path, QLatin1String(LIGTHDM_INTERFACE), QDBusConnection::systemBus(), property); } bool SystemdProvider::canAction(UkuiPower::Action action) const { QString command; switch (action) { case UkuiPower::PowerSwitchUser: return canSwitchUser(); case UkuiPower::PowerReboot: command = QLatin1String("CanReboot"); break; case UkuiPower::PowerShutdown: command = QLatin1String("CanPowerOff"); break; case UkuiPower::PowerSuspend: command = QLatin1String("CanSuspend"); break; case UkuiPower::PowerHibernate: command = QLatin1String("CanHibernate"); break; default: return false; } // canAction should be always silent because it can freeze // g_main_context_iteration Qt event loop in QMessageBox // on panel startup if there is no DBUS running. return dbusCallSystemd( QLatin1String(SYSTEMD_SERVICE), QLatin1String(SYSTEMD_PATH), QLatin1String(SYSTEMD_INTERFACE), QDBusConnection::systemBus(), command, false); } bool SystemdProvider::doSwitchUser() { bool isinhibited = false; QDBusInterface *interface = new QDBusInterface( "org.gnome.SessionManager", "/org/gnome/SessionManager", "org.gnome.SessionManager", QDBusConnection::sessionBus()); quint32 inhibit_switchuser = 2; QDBusReply reply = interface->call("IsInhibited", inhibit_switchuser); if (reply.isValid()) { // use the returned value qDebug() << "Is inhibit by someone: " << reply.value(); isinhibited = reply.value(); } else { qDebug() << reply.value(); } if (isinhibited == true) { isinhibited = !messageBoxCheck(); } if (isinhibited == false) { // QDBusInterface dbus("org.ukui.KWin", "/Compositor", "org.ukui.kwin.Compositing", // QDBusConnection::sessionBus()); // if (!dbus.isValid()) { // qWarning() << "dbusCall: QDBusInterface is invalid"; // return false; // } // dbus.call("suspend"); bool useScreensaver = dbusCall( QLatin1String(UKUI_SCREENSAVER_SERVICE), UKUI_SCREENSAVER_PATH, QLatin1String(UKUI_SCREENSAVER_INTERFACE), QDBusConnection::sessionBus(), "CheckAppVersion"); if (useScreensaver) { return dbusCall( QLatin1String(UKUI_SCREENSAVER_SERVICE), UKUI_SCREENSAVER_PATH, QLatin1String(UKUI_SCREENSAVER_INTERFACE), QDBusConnection::sessionBus(), "SwitchUser"); } QString command = "SwitchToGreeter"; QString xdg_seat_path = qgetenv("XDG_SEAT_PATH"); return dbusCall( QLatin1String(LIGHTDM_SERVICE), xdg_seat_path, QLatin1String(LIGTHDM_INTERFACE), QDBusConnection::systemBus(), command); } return false; } bool SystemdProvider::doAction(UkuiPower::Action action) { qDebug() << "SystemdProvider::doAction:" << action; QString command; switch (action) { case UkuiPower::PowerSwitchUser: return doSwitchUser(); case UkuiPower::PowerReboot: command = QLatin1String("Reboot"); break; case UkuiPower::PowerShutdown: command = QLatin1String("PowerOff"); break; case UkuiPower::PowerSuspend: command = QLatin1String("Suspend"); break; case UkuiPower::PowerHibernate: command = QLatin1String("Hibernate"); break; default: return false; } return dbusCallSystemd( QLatin1String(SYSTEMD_SERVICE), QLatin1String(SYSTEMD_PATH), QLatin1String(SYSTEMD_INTERFACE), QDBusConnection::systemBus(), command, true); } UKUIProvider::UKUIProvider(QObject *parent) : PowerProvider(parent) {} UKUIProvider::~UKUIProvider() {} bool UKUIProvider::canAction(UkuiPower::Action action) const { // 这里是调用ukui-session注册的d-bus检测是否有inhibitor存在 bool isinhibited = false; QDBusInterface *interface = new QDBusInterface( "org.gnome.SessionManager", "/org/gnome/SessionManager", "org.gnome.SessionManager", QDBusConnection::sessionBus()); quint32 inhibit_logout = 1; QDBusReply reply = interface->call("IsInhibited", inhibit_logout); if (reply.isValid()) { // use the returned value qDebug() << "Is inhibit by someone: " << reply.value(); isinhibited = reply.value(); } else { qDebug() << reply.value(); } if (isinhibited == true) { isinhibited = !messageBoxCheck(); } return !isinhibited; } bool UKUIProvider::doAction(UkuiPower::Action action) { QString command; switch (action) { case UkuiPower::PowerLogout: command = QLatin1String("logout"); break; case UkuiPower::PowerReboot: command = QLatin1String("reboot"); break; case UkuiPower::PowerShutdown: command = QLatin1String("powerOff"); break; default: return false; } qDebug() << "ukuipowerprovider call D-Bus session"; return dbusCall( QLatin1String(UKUI_SERVICE), QLatin1String(UKUI_PATH), QLatin1String(UKUI_INTERFACE), QDBusConnection::sessionBus(), command); } bool UKUIProvider::doLSAction(UkuiPower::Action action, QString param /* = ""*/) { qDebug() << "call LockScreen D-Bus"; QString SS_DBUS_SERVICE = "org.ukui.ScreenSaver"; QString SS_DBUS_PATH = "/"; QString SS_DBUS_INTERFACE = "org.ukui.ScreenSaver"; QString displayNum = QString(qgetenv("DISPLAY")).replace(":", "").replace(".", "_"); QString sessionDbus = QString("%1%2").arg(SS_DBUS_SERVICE).arg(displayNum); QSharedPointer screensaverInterface( new QDBusInterface(sessionDbus, SS_DBUS_PATH, SS_DBUS_INTERFACE)); if (!screensaverInterface->isValid()) { screensaverInterface = QSharedPointer(new QDBusInterface(SS_DBUS_SERVICE, SS_DBUS_PATH, SS_DBUS_INTERFACE)); } bool m_flag = false; QDBusReply reply = screensaverInterface->call("CheckAppVersion"); if (reply.isValid()) { // use the returned value m_flag = reply.value(); qDebug() << "CheckAppVersion is " << m_flag; } else { qDebug() << "CheckAppVersion function is not existed"; } if (m_flag) { switch (action) { case UkuiPower::PowerLogout: screensaverInterface->asyncCall("Logout"); break; case UkuiPower::PowerReboot: screensaverInterface->asyncCall("Reboot"); break; case UkuiPower::PowerShutdown: screensaverInterface->asyncCall("PowerOff"); break; case UkuiPower::PowerHibernate: screensaverInterface->asyncCall("Hibernate"); break; case UkuiPower::PowerSuspend: screensaverInterface->asyncCall("Suspend"); break; case UkuiPower::PowerSwitchUser: screensaverInterface->asyncCall("SwitchUser"); break; case UkuiPower::PowerSwitchToUser: screensaverInterface->asyncCall("SwitchToUser", param); break; default: return false; } return true; } else { return false; } } ukui-session-manager/tools/pushbutton.cpp0000664000175000017500000000261515252713362017637 0ustar fengfeng/* * Copyright (C) Copyright 2021 KylinSoft Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301, USA. **/ #include "pushbutton.h" #include #include #include PushButton::PushButton(QWidget *parent) :QPushButton(parent) { } PushButton::~PushButton() { } void PushButton::keyPressEvent(QKeyEvent *keyEvent) { qDebug() << "keyPressEvent..." << keyEvent->key(); return; } bool PushButton::event(QEvent *e) { if (e->type() == QEvent::FocusIn) { e->accept(); //qDebug() << "keyrelease" << static_cast(e)->key(); return true; } if (e->type() == QEvent::KeyRelease || e->type() == QEvent::KeyPress) { e->accept(); return true; } return QPushButton::event(e); } ukui-session-manager/tools/lockchecker.h0000664000175000017500000000332415252713362017344 0ustar fengfeng/* * Copyright (C) Copyright 2021 KylinSoft Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * **/ #ifndef LOCKCHECKER_H #define LOCKCHECKER_H #include "ukuilockinfo.h" #include #include //为了兼容性,要在tools中加入ukuilockinfo.h,而在该头文件中已经定义了InhibitorInfo,为了避免重复定义,注销此处定义 //namespace InhibitInfo { // struct InhibitorInfo { // QString name; // QString icon; // }; // QDBusArgument &operator<<(QDBusArgument &argument, const InhibitInfo::InhibitorInfo &mystruct); // const QDBusArgument &operator>>(const QDBusArgument &argument, InhibitInfo::InhibitorInfo &mystruct); //} //Q_DECLARE_METATYPE(InhibitInfo::InhibitorInfo) class LockChecker { public: LockChecker(); ~LockChecker(); public: static QStringList getLoginedUsers(); static QVector listInhibitor(QString type); static int getCachedUsers(); private: static QString getName(QFile *a); static bool getInhibitorLocal(QVector &inhibitVec, QString type); }; #endif // LOCKCHECKER_H ukui-session-manager/tools/powerprovider.h0000664000175000017500000000376115252714370020003 0ustar fengfeng/* BEGIN_COMMON_COPYRIGHT_HEADER * (c)LGPL2+ * Copyright: 2019 Tianjin KYLIN Information Technology Co., Ltd. * 2012 Razor team * Authors: * Christian Surlykke * * This program or library is free software; you can redistribute it * and/or modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA * * END_COMMON_COPYRIGHT_HEADER */ #ifndef POWERPROVIDER_H #define POWERPROVIDER_H #include #include "ukuipower.h" class PowerProvider : public QObject { Q_OBJECT public: explicit PowerProvider(QObject *parent = nullptr); virtual ~PowerProvider(); virtual bool canAction(UkuiPower::Action action) const = 0; public slots: virtual bool doAction(UkuiPower::Action action) = 0; }; class SystemdProvider: public PowerProvider { Q_OBJECT public: SystemdProvider(QObject *parent = nullptr); ~SystemdProvider(); bool canAction(UkuiPower::Action action) const; public slots: bool doAction(UkuiPower::Action action); private: bool canSwitchUser() const; bool doSwitchUser(); }; class UKUIProvider: public PowerProvider { Q_OBJECT public: UKUIProvider(QObject *parent = nullptr); ~UKUIProvider(); bool canAction(UkuiPower::Action action) const; public slots: bool doAction(UkuiPower::Action action); bool doLSAction(UkuiPower::Action action, QString param = ""); }; #endif // POWERPROVIDER_H ukui-session-manager/tools/mylistview.cpp0000664000175000017500000000161515252714370017637 0ustar fengfeng/* * Copyright (C) Copyright 2021 KylinSoft Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301, USA. **/ #include "mylistview.h" MyListView::MyListView(QWidget *parent) : QListView(parent) { setViewportMargins(10, 8, 10, 10); } MyListView::~MyListView() { } ukui-session-manager/tools/pushbutton.h0000664000175000017500000000213015252713362017274 0ustar fengfeng/* * Copyright (C) Copyright 2021 KylinSoft Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301, USA. **/ #ifndef PUSHBUTTON_H #define PUSHBUTTON_H #include #include class PushButton : public QPushButton { Q_OBJECT public: PushButton(QWidget *parent = nullptr); ~PushButton(); private: protected: void keyPressEvent(QKeyEvent *event); bool event(QEvent *e); public: signals: }; #endif // PUSHBUTTON_H ukui-session-manager/tools/mainwindow.cpp0000664000175000017500000021730515252714370017604 0ustar fengfeng/*Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301, USA. **/ #include "mainwindow.h" #include "commonpushbutton.h" #include "powerprovider.h" #include "mylistview.h" //#include //XTest.h/Xlib.h/XInput.h/X.h中定义了一个None,QStyleOption中也定义了None,会造成冲突,把QListView的头文件放到前面 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "grab-x11.h" #include "xeventmonitor.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "plasma-shell-manager.h" QT_BEGIN_NAMESPACE extern void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0); QT_END_NAMESPACE #define BLUR_RADIUS 300 #define BACKGROUND_SETTINGS "org.mate.background" QPixmap blurPixmap(QPixmap pixmap) { QPainter painter(&pixmap); QImage srcImg = pixmap.toImage(); qt_blurImage(&painter, srcImg, BLUR_RADIUS, false, false); //在设置Qt::WA_TranslucentBackground属性后,模糊图片会导致锁屏界面透明 //不设置上面这个属性,在wayland模式下也出现了透明 //因此这里修改image图形的alpha值为255. for (int y = 0;y < srcImg.height();++y) { QRgb *row = (QRgb*)srcImg.scanLine(y); for (int x = 0; x < srcImg.width(); ++x) { ((unsigned char*)&row[x])[3] = 255; } } painter.end(); return QPixmap::fromImage(srcImg); } QString getUserName(QFile *a) { QString user = getenv("USER"); if (a->exists()) { a->open(QIODevice::ReadOnly | QIODevice::Text); QTextStream fileStream(a); int k = 0; while (!fileStream.atEnd()) { QString line = fileStream.readLine(); if (k == 0) { QString a = line; qDebug() << "uid=" << a; struct passwd *user1; user1 = getpwuid(a.toInt()); qDebug() << "name=" << user1->pw_name << ",uid=" << user1->pw_uid; if (user1->pw_name == NULL) { return user; } user = user1->pw_name; } k++; } } return user; } MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , m_power(new UkuiPower(this)) , xEventMonitor(new XEventMonitor(this)) { const QByteArray bid(BACKGROUND_SETTINGS); if (QGSettings::isSchemaInstalled(bid)) { QGSettings *gset = new QGSettings(BACKGROUND_SETTINGS, "", this); QString fullstr = gset->get("picture-filename").toString(); qDebug() << "picture path = " << fullstr; QFileInfo fileInfo(fullstr); if (fileInfo.isFile() && pix.load(fullstr)) { //增加对pix的判断,有些图片格式qt不支持,无法读取,导致pix为null,引起程序崩溃 #bug75856 if (pix.isNull()) { pix.load(":/images/background-ukui.png"); pix = blurPixmap(pix); } else { pix = blurPixmap(pix); } } else { QString imagefile = "/usr/share/backgrounds/1-warty-final-ubuntukylin.jpg"; QFileInfo fileimage(imagefile); if (fileimage.isFile() && fileimage.exists() && pix.load(imagefile)) { pix = blurPixmap(pix); } else{ pix.load("/usr/share/ukui/ukui-session-manager/images/background-ukui.png"); pix = blurPixmap(pix); } } gset->deleteLater(); } else { pix.load("/usr/share/ukui/ukui-session-manager/images/background-ukui.png"); pix = blurPixmap(pix); } this->setObjectName("widget"); m_screen = QGuiApplication::screenAt(QCursor::pos())->geometry(); m_toolWidget = new QWidget(this); m_toolWidget->setGeometry(m_screen); qDebug() << "m_toolWidget width:" << m_toolWidget->width()<height(); m_vBoxLayout = new QVBoxLayout(); m_buttonHLayout = new QGridLayout(); m_dateTimeLayout = new QVBoxLayout(); m_timeLabel = new QLabel(); m_dateLabel = new QLabel(); m_judgeWidgetVLayout = new QVBoxLayout(); m_judgeBtnHLayout = new QHBoxLayout(); m_judgeLabel = new QLabel(); m_messageLabel1 = new QLabel(); m_messageLabel2 = new QLabel(); m_scrollArea = new QScrollArea; m_scrollArea->setObjectName("scrollArea"); m_scrollArea->removeEventFilter(this); m_btnWidget = new QWidget(); m_btnWidget->setObjectName("btnWidget"); m_judgeWidget = new QWidget(this); m_judgeWidget->setObjectName("judgeWidget"); //m_showWarningArea 作为该界面所有组件的父指针,方便排版 m_showWarningArea = new QWidget(this); m_showWarningArea->setObjectName(QString::fromUtf8("area")); initialSystemMonitor(); initialBtn(); initialJudgeWidget(); upgradeCheck = new systemUpgradeCheck(); //Make a hash-map to store tableNum-to-lastWidget if (m_power->canAction(UkuiPower::PowerHibernate)) { isHibernateHide = false; } if (m_power->canAction(UkuiPower::PowerSuspend)) { isSuspendHide = false; } if (m_power->canAction(UkuiPower::PowerLogout)) { isLogoutHide = false; } if (m_power->canAction(UkuiPower::PowerMonitorOff)) { isLockscreenHide = false; } if (m_power->canAction(UkuiPower::PowerReboot)) { isRebootHide = false; } if (m_power->canAction(UkuiPower::PowerShutdown)) { isPowerOffHide = false; } if (LockChecker::getCachedUsers() > 1 && m_power->canAction(UkuiPower::PowerSwitchUser)) { isSwitchuserHide = false; } if (upgradeCheck->checkSystemUpgrade()) { isUpgradeThenPowerOffHide = false; isUpgradeThenRebootHide = false; } //天翼云屏蔽以下按钮 QString platform = kdk_system_get_hostCloudPlatform(); if ("ctyun" == platform) { isHibernateHide=true; isSuspendHide=true; isLockscreenHide=true; isRebootHide=true; isPowerOffHide=true; isSwitchuserHide=true; } //关机界面按钮定制 QDBusInterface *setInterface = new QDBusInterface("org.ukui.SettingsDaemon", "/GlobalSignal", "org.ukui.SettingsDaemon.GlobalSignal" ,QDBusConnection::sessionBus()); if (setInterface->isValid()) { qDebug() << "usd interface valid"; QDBusReply isHide = setInterface->call("isHidePoweroffUi"); if (isHide) { exit(0); } else { QStringList hideList; QDBusReply msg = setInterface->call("getShutdownDisableOptions"); if (msg.isValid()) { hideList = msg.value(); } for (int i = 0; i < hideList.size(); ++i) { QString txt = hideList.at(i); if ("switchuser" == txt) isSwitchuserHide = true; else if ("hibernate" == txt) isHibernateHide = true; else if ("suspend" == txt) isSuspendHide = true; else if ("lockscreen" == txt) isLockscreenHide = true; else if ("logout" == txt) isLogoutHide = true; else if ("restart" == txt) isRebootHide = true; else if ("shutdown" == txt) isPowerOffHide = true; } } } m_btnHideMap.insert(m_switchUserBtn, isSwitchuserHide); m_btnHideMap.insert(m_hibernateBtn, isHibernateHide); m_btnHideMap.insert(m_suspendBtn, isSuspendHide); m_btnHideMap.insert(m_lockScreenBtn, isLockscreenHide); m_btnHideMap.insert(m_logoutBtn, isLogoutHide); m_btnHideMap.insert(m_upgradeThenRebootBtn, isUpgradeThenRebootHide); m_btnHideMap.insert(m_rebootBtn, isRebootHide); m_btnHideMap.insert(m_upgradeThenshutDownBtn, isUpgradeThenPowerOffHide); m_btnHideMap.insert(m_shutDownBtn, isPowerOffHide); // initialBtnCfg(); map.insert(0, m_switchUserBtn); map.insert(1, m_hibernateBtn); map.insert(2, m_suspendBtn); map.insert(3, m_lockScreenBtn); map.insert(4, m_logoutBtn); map.insert(5, m_upgradeThenRebootBtn); map.insert(6, m_rebootBtn); map.insert(7, m_upgradeThenshutDownBtn); map.insert(8, m_shutDownBtn); gs = new QGSettings("org.ukui.session", "/org/ukui/desktop/session/"); tableNum = -1; changeBtnState("empty"); //不知为何,sdk接口要第二次创建才能获取正确的值 //规避方案,这里先创建一次 char *user = qgetenv("USER").data(); kdk_logn_dateinfo *dateInfo = kdk_system_login_lock_dateinfo(user); //QString curTime = QString(dateInfo->time); delete dateInfo; //更新显示时间的控件 initialDateTimeWidget(); QTimer *timeWidgetUpdateTimer = new QTimer(this); connect(timeWidgetUpdateTimer, &QTimer::timeout, this, &MainWindow::updateDateTimerWidget); timeWidgetUpdateTimer->start(1000); ResizeEvent(); m_vBoxLayout->addStretch(20); m_vBoxLayout->addLayout(m_dateTimeLayout, 80); m_vBoxLayout->addStretch(120); m_vBoxLayout->addWidget(m_scrollArea, 640); m_vBoxLayout->addStretch(120); m_vBoxLayout->addWidget(m_systemMonitorBtn, 48, Qt::AlignHCenter); m_vBoxLayout->addStretch(62); m_vBoxLayout->setSpacing(0); m_vBoxLayout->setContentsMargins((m_screen.width() - m_scrollArea->width() - 20)/2,0,(m_screen.width() - m_scrollArea->width() - 20)/2,0); qDebug() << "width..........." << m_judgeLabel->width() << m_scrollArea->width() << m_messageLabel1->width() << m_messageLabel2->width(); //根据屏幕分辨率与鼠标位置重设界面 //m_screen = QApplication::desktop()->screenGeometry(QCursor::pos()); //setFixedSize(QApplication::primaryScreen()->virtualSize()); setGeometry(0, 0, QApplication::primaryScreen()->virtualSize().width(), QApplication::primaryScreen()->virtualSize().height()); move(0, 0);//设置初始位置的值 //设置窗体无边框,不可拖动拖拽拉伸;为顶层窗口,无法被切屏;不使用窗口管理器 if(QString(qgetenv("XDG_SESSION_TYPE")) == "wayland") { setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); } else if (QString(qgetenv("XDG_SESSION_TYPE")) == "x11") { setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint); setAttribute(Qt::WA_AlwaysShowToolTips); } setFocusPolicy(Qt::NoFocus); // setAttribute(Qt::WA_TranslucentBackground, true);//设定该窗口透明显示 m_toolWidget->setLayout(m_vBoxLayout); //setCentralWidget(m_toolWidget); qDebug() << "m_toolWidget...." << m_toolWidget->geometry(); qDebug() << "pos..." << QCursor::pos() << this->geometry(); qDebug() << "m_screen..." << m_screen; QString platformName = QGuiApplication::platformName(); if (QString(qgetenv("XDG_SESSION_TYPE")) == "wayland") { PlasmaShellManager::getInstance()->setAppWindowKeepAbove(true); } else { /*捕获键盘,如果捕获失败,那么模拟一次esc按键来退出菜单,如果仍捕获失败,则放弃捕获*/ if (establishGrab()) { qDebug() << "establishGrab : true"; } else { qDebug() << "establishGrab : false"; Display *display = nullptr; if (auto *x11Application = qApp->nativeInterface()) { display = x11Application->display(); } XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_Escape), True, 1); XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_Escape), False, 1); XFlush(display); sleep(1); if (!establishGrab()) { qDebug() << "establishGrab : false again!"; // exit(1); } } } // KeyPress, KeyRelease, ButtonPress, ButtonRelease and MotionNotify events has been redirected connect(xEventMonitor, SIGNAL(keyPress(const QString &)), this, SLOT(onGlobalKeyPress(const QString &))); connect(xEventMonitor, SIGNAL(keyRelease(const QString &)), this, SLOT(onGlobalkeyRelease(const QString &))); xEventMonitor->start(); //screencount changed connect(qApp, &QGuiApplication::screenAdded, this, &MainWindow::screenCountChanged); connect(qApp, &QGuiApplication::screenRemoved, this, &MainWindow::screenCountChanged); connect(qApp, &QGuiApplication::primaryScreenChanged, this, &MainWindow::screenCountChanged); qDebug() << "m_btnWidget FixedHeight000:" << m_btnWidget->width() << m_scrollArea->width(); if (platformName.startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) { //wayland interface } else { Display *display = nullptr; xcb_connection_t *connection = nullptr; bool isPlatformX11 = false; Window window = DefaultRootWindow(display); if (auto *x11Application = qApp->nativeInterface()) { display = x11Application->display(); connection = x11Application->connection(); isPlatformX11 = true; XWindowAttributes rootAttr; XGetWindowAttributes(display, window, &rootAttr); XSelectInput(display, window, SubstructureNotifyMask|rootAttr.your_event_mask); } qApp->installNativeEventFilter(this); } } MainWindow::~MainWindow() { delete m_power; delete xEventMonitor; } void MainWindow::initialSystemMonitor() { m_systemMonitorHLayout = new QHBoxLayout(); m_systemMonitorBtn = new QWidget(this); m_systemMonitorIconLabel = new QLabel(); m_systemMonitorLabel = new QLabel(m_systemMonitorBtn); m_systemMonitorBtn->setObjectName("systemMonitor"); QFont font = QApplication::font(); QFontMetrics fm(font); m_systemMonitorLabel->setText(QApplication::tr("system-monitor")); double fsize = 10; if (QGSettings::isSchemaInstalled("org.ukui.style")){ QGSettings *gset = new QGSettings("org.ukui.style"); fsize = gset->get("system-font-size").toDouble(); } fsize = fsize + 8; const QString font_size= "QLabel{font-size: " + QString::number(fsize) + "px}"; m_systemMonitorLabel->setStyleSheet(font_size + "QLabel{color: white}"); int btnWidth = fm.boundingRect(m_systemMonitorLabel->text()).width() + 60; qDebug() << "btnWidth:" << btnWidth << fontMetrics().horizontalAdvance(m_systemMonitorLabel->text()) ; m_systemMonitorBtn->setFixedSize(btnWidth, 48); QString str = "QWidget#systemMonitor{background-color: transparent;border-radius: " + QString::number(m_systemMonitorBtn->height()/2) + "px;}"; //QString str = "QWidget#systemMonitor{background-color: rgb(255,255,255,40);border-radius: " + QString::number(m_systemMonitorBtn->height()/2) + "px;}"; m_systemMonitorBtn->setStyleSheet(str); m_systemMonitorBtn->setAttribute(Qt::WA_StyledBackground); QRegion region0(m_systemMonitorBtn->x() + m_systemMonitorBtn->height()/2 + 1, m_systemMonitorBtn->y() - 1, m_systemMonitorBtn->width()-m_systemMonitorBtn->height(), m_systemMonitorBtn->height() + 2); QRegion region1(m_systemMonitorBtn->x() - 1, m_systemMonitorBtn->y() - 1, m_systemMonitorBtn->height() + 2, m_systemMonitorBtn->height() + 2, QRegion::Ellipse); QRegion region2(m_systemMonitorBtn->x() + m_systemMonitorBtn->width() - m_systemMonitorBtn->height(), m_systemMonitorBtn->y() - 1, m_systemMonitorBtn->height() + 2, m_systemMonitorBtn->height() + 2, QRegion::Ellipse); QRegion region = region0 + region1 + region2; m_systemMonitorBtn->setMask(region); m_systemMonitorLabel->setAlignment(Qt::AlignCenter); m_systemMonitorHLayout->setAlignment(Qt::AlignCenter); m_systemMonitorHLayout->addWidget(m_systemMonitorLabel,fm.boundingRect(m_systemMonitorLabel->text()).width()); m_systemMonitorBtn->setLayout(m_systemMonitorHLayout); m_systemMonitorBtn->installEventFilter(this); qDebug() << "m_systemMonitorIcon:" << m_systemMonitorIcon.width() << m_systemMonitorIcon.height() << m_systemMonitorIconLabel->width() << m_systemMonitorIconLabel->height(); qDebug() << "m_systemMonitorBtn:" << m_systemMonitorBtn->height(); } void MainWindow::initialBtn() { m_switchUserBtn = new MyPushButton(m_btnImagesPath+"/switchuser.svg", QApplication::tr("Switch User"), "switchuser", m_scrollArea); m_hibernateBtn = new MyPushButton(m_btnImagesPath+"/hibernate.svg", QApplication::tr("Hibernate"), "hibernate", m_scrollArea); m_suspendBtn = new MyPushButton(m_btnImagesPath+"/suspend.svg", QApplication::tr("Suspend"), "suspend", m_scrollArea); m_logoutBtn = new MyPushButton(m_btnImagesPath+"/logout.svg", QApplication::tr("Log Out"), "logout", m_scrollArea); m_rebootBtn = new MyPushButton(m_btnImagesPath+"/reboot.svg", QApplication::tr("Restart"), "reboot", m_scrollArea); m_shutDownBtn = new MyPushButton(m_btnImagesPath+"/shutdown.svg", QApplication::tr("Shut Down"), "shutdown", m_scrollArea); m_lockScreenBtn = new MyPushButton(m_btnImagesPath+"/lockscreen.svg", QApplication::tr("Lock Screen"), "lockscreen", m_scrollArea); m_upgradeThenRebootBtn = new MyPushButton(m_btnImagesPath+"/reboot.svg", QApplication::tr("UpgradeThenRboot"), "upgradethenreboot", m_scrollArea); m_upgradeThenshutDownBtn = new MyPushButton(m_btnImagesPath+"/shutdown.svg", QApplication::tr("UpgradeThenShutdown"), "upgradeThenShutdown", m_scrollArea); //ui->setupUi(this); m_switchUserBtn->installEventFilter(this); m_hibernateBtn->installEventFilter(this); m_suspendBtn->installEventFilter(this); m_lockScreenBtn->installEventFilter(this); m_logoutBtn->installEventFilter(this); m_rebootBtn->installEventFilter(this); m_shutDownBtn->installEventFilter(this); m_upgradeThenRebootBtn->installEventFilter(this); m_upgradeThenshutDownBtn->installEventFilter(this); m_hibernateBtn->setToolTip(QApplication::tr("Turn off your computer, but the app stays open. When the computer is turned on, it can be restored to the state you left.")); m_suspendBtn->setToolTip(QApplication::tr("The computer stays on, but consumes less power. The app stays open and can quickly wake up and revert to where you left off.")); m_logoutBtn->setToolTip(QApplication::tr("The current user logs out of the system, terminates the session, and returns to the login page.")); m_rebootBtn->setToolTip(QApplication::tr("Close all apps, turn off your computer, and then turn your computer back on.")); m_shutDownBtn->setToolTip(QApplication::tr("Close all apps, and then shut down your computer.")); connect(m_switchUserBtn, &MyPushButton::mouseRelase, this, &MainWindow::mouseReleaseSlots); connect(m_hibernateBtn, &MyPushButton::mouseRelase, this, &MainWindow::mouseReleaseSlots); connect(m_suspendBtn, &MyPushButton::mouseRelase, this, &MainWindow::mouseReleaseSlots); connect(m_lockScreenBtn, &MyPushButton::mouseRelase, this, &MainWindow::mouseReleaseSlots); connect(m_logoutBtn, &MyPushButton::mouseRelase, this, &MainWindow::mouseReleaseSlots); connect(m_rebootBtn, &MyPushButton::mouseRelase, this, &MainWindow::mouseReleaseSlots); connect(m_shutDownBtn, &MyPushButton::mouseRelase, this, &MainWindow::mouseReleaseSlots); connect(m_upgradeThenRebootBtn, &MyPushButton::mouseRelase, this, &MainWindow::mouseReleaseSlots); connect(m_upgradeThenshutDownBtn, &MyPushButton::mouseRelase, this, &MainWindow::mouseReleaseSlots); } void MainWindow::initialJudgeWidget() { QStringList userlist = LockChecker::getLoginedUsers(); if (userlist.count() > 1) { close_system_needed_to_confirm = true; } QString tips = QApplication::tr("Multiple users are logged in at the same time.Are you sure " "you want to close this system?"); m_judgeLabel->setText(tips); m_judgeLabel->setStyleSheet("color:white");//;font:12pt; m_judgeLabel->setObjectName("label"); //m_judgeLabel->setGeometry(0,0,m_screen.width(),50); //m_judgeLabel->setFixedHeight(60); qDebug() << "m_judgeLabel width:" << m_judgeLabel->width() << m_judgeLabel->height(); m_judgeLabel->setAlignment(Qt::AlignHCenter); m_judgeLabel->setWordWrap(true); m_cancelBtn = new CommonPushButton(QApplication::tr("cancel"), QString::fromUtf8("cancelButton"), 120, 48, 8); m_confirmBtn = new CommonPushButton(QApplication::tr("confirm"), QString::fromUtf8("confirmButton"), 120, 48, 8); m_judgeBtnHLayout->setAlignment(Qt::AlignHCenter); m_judgeBtnHLayout->setSpacing(0); m_judgeBtnHLayout->addWidget(m_cancelBtn); m_judgeBtnHLayout->addSpacing(24); m_judgeBtnHLayout->addWidget(m_confirmBtn); m_judgeWidgetVLayout->addSpacing(10); m_judgeWidgetVLayout->addWidget(m_judgeLabel); m_judgeWidgetVLayout->addSpacing(10); m_judgeWidgetVLayout->addLayout(m_judgeBtnHLayout); m_judgeWidgetVLayout->setAlignment(Qt::AlignCenter); m_judgeWidgetVLayout->setContentsMargins(0,0,0,0); connect(m_cancelBtn, &CommonPushButton::clicked, this, &MainWindow::exitt); connect(m_confirmBtn, &CommonPushButton::clicked, [&]() { emit confirmButtonclicked(); }); m_judgeWidget->setLayout(m_judgeWidgetVLayout); m_judgeWidget->setStyleSheet("QWidget#judgeWidget{background-color: transparent;}"); m_judgeWidget->setVisible(false); m_judgeWidget->setGeometry(m_screen.x() + (m_screen.width() - 800 * m_screen.width()/1920)/2, m_screen.y() + (m_screen.height() - 200)/2 - 10, 800 * m_screen.width()/1920, 200); } void MainWindow::initialDateTimeWidget() { char *user = qgetenv("USER").data(); kdk_logn_dateinfo *dateInfo = kdk_system_login_lock_dateinfo(user); QString curTime = QString(dateInfo->time); char *curDateLong = kdk_system_get_longformat_date(); char *curWeekLong = kdk_system_longweek(); QString currentDate = QString(curDateLong) + " " + QString(curWeekLong); qDebug() << "curDateLong is " << curDateLong << " and curWeekLong is " << curWeekLong << ",curTime=" << curTime; delete curDateLong; delete curWeekLong; delete dateInfo; // QDateTime current_date_time = QDateTime::currentDateTime(); // const QByteArray id_control("org.ukui.control-center.panel.plugins"); // QString current_time; // if (QGSettings::isSchemaInstalled(id_control)) { // QGSettings *controlSetting = new QGSettings(id_control, QByteArray(), this); // QString formate_b = controlSetting->get("hoursystem").toString(); // if (formate_b == "12") { // current_time = current_date_time.toString("A hh:mm"); // } else if (formate_b == "24") { // current_time = current_date_time.toString("hh:mm"); // } else { // current_time = current_date_time.toString("hh:mm"); // } // } else { // current_time = current_date_time.toString("hh:mm"); // } m_timeLabel->setText(curTime); m_dateLabel->setText(currentDate); // m_timeLabel->setFont(QFont("Noto Sans CJK SC", 28, 50)); // m_dateLabel->setFont(QFont("Noto Sans CJK SC", 12, 50)); m_timeLabel->setStyleSheet("color: white; font: 28pt"); m_dateLabel->setStyleSheet("color: white; font: 12pt"); m_dateLabel->setAlignment(Qt::AlignHCenter | Qt::AlignTop); m_timeLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); m_dateLabel->setObjectName("date_label"); m_timeLabel->setObjectName("time_lable"); m_dateTimeLayout->addStretch(); m_dateTimeLayout->addWidget(m_timeLabel); // m_messageVLayout->addSpacing(10); //m_dateTimeLayout->setStretch(0,1); m_dateTimeLayout->addWidget(m_dateLabel); //m_dateTimeLayout->setStretch(1,2); } void MainWindow::updateDateTimerWidget() { char *user = qgetenv("USER").data(); kdk_logn_dateinfo *dateInfo = kdk_system_login_lock_dateinfo(user); QString curTime = QString(dateInfo->time); char *curDateLong = kdk_system_get_longformat_date(); char *curWeekLong = kdk_system_longweek(); QString currentDate = QString(curDateLong) + " " + QString(curWeekLong); qDebug() << "curDateLong is " << curDateLong << " and curWeekLong is " << curWeekLong<< ",curTime=" << curTime; delete curDateLong; delete curWeekLong; delete dateInfo; // QDateTime current_date_time = QDateTime::currentDateTime(); // const QByteArray id_control("org.ukui.control-center.panel.plugins"); // QString current_time; // if (QGSettings::isSchemaInstalled(id_control)) { // QGSettings *controlSetting = new QGSettings(id_control, QByteArray(), this); // QString formate_b = controlSetting->get("hoursystem").toString(); // if (formate_b == "12") { // current_time = current_date_time.toString("A hh:mm"); // } else if (formate_b == "24") { // current_time = current_date_time.toString("hh:mm"); // } else { // current_time = current_date_time.toString("hh:mm"); // } // } else { // current_time = current_date_time.toString("hh:mm"); // } m_timeLabel->setText(curTime); m_dateLabel->setText(currentDate); } void MainWindow::initialBtnCfg() { bool newIniFile = false;//ini文件是否为新建文件 QString iniDir = "/usr/share/ukui/ukui-session-manager/config"; if(!QFile::exists(iniDir + "/btnconfig.ini")){ qDebug() << "btnconfig.ini file is not exists!!!"; QDir dir(iniDir); if(!dir.exists(iniDir)){ if(dir.mkdir(iniDir)){//目前创建不成功 没有权限 QFile iniFile(iniDir + "/btnconfig.ini"); if(iniFile.open(QIODevice::WriteOnly)){ newIniFile = true; iniFile.close(); } qDebug() << "inifile open faile!"; } else qDebug() << "create inidir faile!"; } } m_btnCfgSetting = new QSettings("/usr/share/ukui/ukui-session-manager/config/btnconfig.ini", QSettings::IniFormat); if (newIniFile) {//貌似路径下文件只可读不可写 m_btnCfgSetting->setValue("btn/SwitchUserBtnHide", false); m_btnCfgSetting->setValue("btn/HibernateBtnHide", false); m_btnCfgSetting->setValue("btn/LockScreenBtnHide", false); m_btnCfgSetting->setValue("btn/LogoutBtnHide", false); m_btnCfgSetting->setValue("btn/RebootBtnHide", false); m_btnCfgSetting->setValue("btn/ShutDownBtnHide", false); m_btnCfgSetting->setValue("btn/SuspendBtnHide", false); } m_btnCfgSetting->setValue("btn/SwitchUserBtnHide", isSwitchuserHide); m_btnCfgSetting->setValue("btn/HibernateBtnHide", isHibernateHide); m_btnCfgSetting->setValue("btn/SuspendBtnHide", isSuspendHide); m_btnCfgSetting->setValue("btn/LogoutBtnHide", isLogoutHide); m_btnCfgSetting->setValue("btn/RebootBtnHide", isRebootHide); m_btnCfgSetting->setValue("btn/ShutDownBtnHide", isPowerOffHide); qDebug() << "isHibernateHide..." << isHibernateHide; m_btnHideMap.insert(m_switchUserBtn, isSwitchuserHide); m_btnHideMap.insert(m_hibernateBtn, isHibernateHide); m_btnHideMap.insert(m_suspendBtn, isSuspendHide); m_btnHideMap.insert(m_lockScreenBtn, m_btnCfgSetting->value("btn/LockScreenBtnHide").toBool()); m_btnHideMap.insert(m_logoutBtn, isLogoutHide); m_btnHideMap.insert(m_rebootBtn, isRebootHide); m_btnHideMap.insert(m_shutDownBtn, isPowerOffHide); } void MainWindow::setLayoutWidgetVisible(QLayout* layout, bool show) { for (int i = 0;i < layout->count(); i++) { QLayoutItem*item = layout->layout()->itemAt(i); if (item->widget() != nullptr) { item->widget()->setVisible(show); } } } void MainWindow::changeBtnState(QString btnName, bool isKeySelect) { for(auto item = map.begin(); item != map.end(); item++) { if (btnName == QString("empty")) { item.value()->changeIconBackColor((item.value()->objectName() == btnName), isKeySelect); } if (isKeySelect) { item.value()->changeIconBackColor((item.value()->objectName() == btnName), isKeySelect); } else { if (item.value()->objectName() == btnName) { item.value()->changeIconBackColor((item.value()->objectName() == btnName), isKeySelect); } if (lastWidget && lastWidget->objectName() == item.value()->objectName() && lastWidget->objectName() != btnName) { item.value()->changeIconBackColor(false, isKeySelect); } } } } void MainWindow::mouseReleaseSlots(QEvent *event, QString objName) { for (auto iter = map.begin(); iter != map.end(); iter++) { if (iter.value()->getIconLabel()->objectName() == objName) { changePoint(iter.value(), event); if (event->type() == QEvent::MouseButtonRelease) { qDebug() << "mouseReleaseSlots..." << objName; doEvent(objName, iter.key()); return; } } } } void MainWindow::screenCountChanged() { int screenCount = QGuiApplication::screens().size(); m_screen = QGuiApplication::screenAt(QCursor::pos())->geometry(); int screenWidth = m_screen.width(); int screenHeight = m_screen.height(); qDebug() << "inside screenCountChanged,screenCount = " << m_screen << screenWidth << screenHeight; //setGeometry(desktop->geometry()); //updateGeometry(); //move(0,0); //setFixedSize(QApplication::primaryScreen()->virtualSize()); setGeometry(0, 0, QApplication::primaryScreen()->virtualSize().width(), QApplication::primaryScreen()->virtualSize().height()); ResizeEvent(); update(); } void MainWindow::calculateBtnSpan(int allNum, int lineMaxNum, MyPushButton *btn, int &row, int &column) { int afterHideNum = 0; for (int i = 0; i < m_btnHideMap.count(); i++) { if (map.key(btn) > i) { if (m_btnHideMap.value(map.value(i))) { afterHideNum++; } } else if(map.key(btn) == i) { column = (i - afterHideNum) % lineMaxNum; row = (i - afterHideNum) / lineMaxNum; return; } } } void MainWindow::showNormalBtnWidget(int hideNum) { int margins = 0; if (hideNum >= 8) { margins = (m_screen.width() -160 - 128 * (9 - hideNum)); } else { margins = (m_screen.width() -160 - 128 * (9 - hideNum)) / (8-hideNum); } qDebug() << "showNormalBtnWidget hideNum:" << hideNum << "margins:" << margins; m_lineNum = 1; int btnWidgetWidth = 0; if (margins > 60) { //m_buttonHLayout->addWidget(m_listView); if (hideNum == 9) { btnWidgetWidth = m_screen.width(); } else { btnWidgetWidth = (128 * (9 - hideNum) + 60 * (8 - hideNum)); } m_buttonHLayout->setHorizontalSpacing(60); } else { btnWidgetWidth = 128 * (9 - hideNum) + margins * (8 - hideNum); m_buttonHLayout->setHorizontalSpacing(margins); } m_btnWidget->setGeometry(QRect(m_btnWidget->x(),m_btnWidget->y(),btnWidgetWidth+ 24, 632 * m_screen.height()/1080)); m_btnWidget->setContentsMargins(0,0,0,100 * m_screen.height()/1080); m_scrollArea->setGeometry(QRect(m_scrollArea->x(),m_scrollArea->y(),btnWidgetWidth + 24, 632 * m_screen.height()/1080)); m_scrollArea->setContentsMargins(0,0,0,0); m_scrollArea->verticalScrollBar()->setVisible(false); m_scrollArea->verticalScrollBar()->setDisabled(true); m_scrollArea->verticalScrollBar()->setStyleSheet("QScrollBar{ background: transparent; margin-top:0px;margin-bottom:0px ; }"\ "QScrollBar:vertical{width: 0px;background: transparent;border-radius:3px;}"\ "QScrollBar::handle:vertical{width: 0px; background: rgba(255,255,255, 40); border-radius:3px;}"\ "QScrollBar::handle:vertical:hover{width: 0px; background: rgba(255,255,255, 60); border-radius:3px;}"\ "QScrollBar::add-line:vertical{width:0px;height:0px}"\ "QScrollBar::sub-line:vertical{width:0px;height:0px}"); //m_buttonHLayout->setContentsMargins(0,0,0,(m_scrollArea->height() - m_switchUserBtn->height()) * 3/5); for (int i = 0;i < m_buttonHLayout->count(); i++) { QLayoutItem*item = m_buttonHLayout->layout()->itemAt(i); if (item->widget() != nullptr) { m_buttonHLayout->removeWidget(item->widget()); } } m_buttonHLayout->addWidget(m_switchUserBtn,0,0); m_buttonHLayout->addWidget(m_hibernateBtn,0,1); m_buttonHLayout->addWidget(m_suspendBtn,0,2); m_buttonHLayout->addWidget(m_lockScreenBtn,0,3); m_buttonHLayout->addWidget(m_logoutBtn,0,4); m_buttonHLayout->addWidget(m_upgradeThenRebootBtn,0,5); m_buttonHLayout->addWidget(m_rebootBtn,0,6); m_buttonHLayout->addWidget(m_upgradeThenshutDownBtn,0,7); m_buttonHLayout->addWidget(m_shutDownBtn,0,8); m_btnWidgetNeedScrollbar = false; } void MainWindow::showHasScrollBarBtnWidget(int hideNum) { int allBtnNum = 9 - hideNum; int lineWidth = m_screen.width() - 160 - 6; int lineMaxBtnNum = (lineWidth - 128)/188 + 1; m_lineNum = allBtnNum/lineMaxBtnNum + ((allBtnNum%lineMaxBtnNum > 0) ? 1 : 0); int needHeight = (m_lineNum * 171 + (m_lineNum - 1) * 32); int btnWidgetHeight = 632; qDebug() << "showHasScrollBarBtnWidget lineWidth:" << lineWidth << "lineMaxBtnNum:" << lineMaxBtnNum << "needHeight:" << needHeight << "lineNum:" << m_lineNum<< allBtnNum/lineMaxBtnNum << allBtnNum%lineMaxBtnNum; calculateBtnSpan(allBtnNum, lineMaxBtnNum, m_switchUserBtn, m_switchRow, m_switchColumn); calculateBtnSpan(allBtnNum, lineMaxBtnNum, m_hibernateBtn, m_hibernateRow, m_hibernateColumn); calculateBtnSpan(allBtnNum, lineMaxBtnNum, m_suspendBtn, m_suspendRow, m_suspendColumn); calculateBtnSpan(allBtnNum, lineMaxBtnNum, m_lockScreenBtn, m_lockScreenRow, m_lockScreenColumn); calculateBtnSpan(allBtnNum, lineMaxBtnNum, m_logoutBtn, m_logoutRow, m_logoutColumn); calculateBtnSpan(allBtnNum, lineMaxBtnNum, m_upgradeThenRebootBtn, m_upgradeThenRebootRow, m_upgradeThenRebootColumn); calculateBtnSpan(allBtnNum, lineMaxBtnNum, m_rebootBtn, m_rebootRow, m_rebootColumn); calculateBtnSpan(allBtnNum, lineMaxBtnNum, m_upgradeThenshutDownBtn, m_upgradeThenShutdownRow, m_upgradeThenShutdownColumn); calculateBtnSpan(allBtnNum, lineMaxBtnNum, m_shutDownBtn, m_shutDownRow, m_shutDownColumn); // qDebug() << "switchRow:" << m_switchRow << m_switchColumn; // qDebug() << "hibernateRow:" << m_hibernateRow << m_hibernateColumn; // qDebug() << "suspendRow:" << m_suspendRow << m_suspendColumn; // qDebug() << "lockScreenRow:" << m_lockScreenRow << m_lockScreenColumn; // qDebug() << "logoutRow:" << m_logoutRow << m_logoutColumn; // qDebug() << "rebootRow:" << m_rebootRow << m_rebootColumn; // qDebug() << "shutDownRow:" << m_shutDownRow << m_shutDownColumn; { m_scrollArea->verticalScrollBar()->setVisible(!m_judgeLabel->isVisible()); m_scrollArea->verticalScrollBar()->setDisabled(false); m_scrollArea->verticalScrollBar()->setStyleSheet("QScrollBar{ background: transparent; margin-top:0px;margin-bottom:0px ; }"\ "QScrollBar:vertical{width: 6px;background: transparent;border-radius:3px;}"\ "QScrollBar::handle:vertical{width: 6px; background: rgba(255,255,255, 40); border-radius:3px;}"\ "QScrollBar::handle:vertical:hover{width: 6px; background: rgba(255,255,255, 60); border-radius:3px;}"\ "QScrollBar::add-line:vertical{width:0px;height:0px}"\ "QScrollBar::sub-line:vertical{width:0px;height:0px}"); qDebug() << "set bar pos..."; //m_scrollArea->verticalScrollBar()->setGeometry(QRect(lineWidth + 20, 0, 6, 100)); m_scrollArea->setContentsMargins(0,0,0,0); m_scrollArea->setGeometry(QRect(0,0,128 * lineMaxBtnNum + 60 * (lineMaxBtnNum-1) + 6, btnWidgetHeight * m_screen.height()/1080)); m_buttonHLayout->setContentsMargins(0,0,0,0);// (needHeight > 632 ? 0 : (632 - needHeight)) * m_screen.height()/1080); m_btnWidget->setGeometry(QRect(0,0,128 * lineMaxBtnNum + 60 * (lineMaxBtnNum-1), needHeight)); m_btnWidget->setContentsMargins(6,0,12,0); qDebug() << "m_btnWidget FixedHeight:" << needHeight << btnWidgetHeight << m_btnWidget->width() << m_scrollArea->width(); qDebug() << "isSwitchuserHide:" << isSwitchuserHide << "isHibernateHide:" << isHibernateHide << "isSuspendHide:" << isSuspendHide; for (int i = 0;i < m_buttonHLayout->count(); i++) { QLayoutItem*item = m_buttonHLayout->layout()->itemAt(i); if (item->widget() != nullptr) { m_buttonHLayout->removeWidget(item->widget()); } } m_buttonHLayout->addWidget(m_switchUserBtn, m_switchRow, m_switchColumn); m_buttonHLayout->addWidget(m_hibernateBtn, m_hibernateRow, m_hibernateColumn); m_buttonHLayout->addWidget(m_suspendBtn, m_suspendRow, m_suspendColumn); m_buttonHLayout->addWidget(m_lockScreenBtn, m_lockScreenRow, m_lockScreenColumn); m_buttonHLayout->addWidget(m_logoutBtn, m_logoutRow, m_logoutColumn); m_buttonHLayout->addWidget(m_upgradeThenRebootBtn, m_upgradeThenRebootRow, m_upgradeThenRebootColumn); m_buttonHLayout->addWidget(m_rebootBtn, m_rebootRow, m_rebootColumn); m_buttonHLayout->addWidget(m_upgradeThenshutDownBtn, m_upgradeThenShutdownRow, m_upgradeThenShutdownColumn); m_buttonHLayout->addWidget(m_shutDownBtn, m_shutDownRow, m_shutDownColumn); m_buttonHLayout->setHorizontalSpacing(60); m_buttonHLayout->setAlignment(Qt::AlignHCenter); m_btnWidgetNeedScrollbar = true; } } void MainWindow::ResizeEvent() { m_screen = QGuiApplication::screenAt(QCursor::pos())->geometry(); setGeometry(0, 0, QApplication::primaryScreen()->virtualSize().width(), QApplication::primaryScreen()->virtualSize().height()); //处理界面停留在阻止提醒界面时拔插屏幕出现的问题 if (m_showWarningMesg) { showInhibitWarning(m_inhibitList, defaultnum); m_toolWidget->setGeometry(m_screen); return; } m_judgeWidget->setGeometry(m_screen.x() + (m_screen.width() - 800 * m_screen.width()/1920)/2, m_screen.y() + (m_screen.height() - 200)/2 - 10,800 * m_screen.width()/1920, 200); if(m_judgeWidget->isVisible()) return; qDebug() << "ResizeEvent moveWidget m_screen:" << m_screen.width() << m_screen.height(); int hideNum = 0; for (int i = 0; i < m_btnHideMap.count(); i++) { if (m_btnHideMap.value(map.value(i))) { hideNum++; } } qDebug()<<"m_btnHideMap.count()=" << m_btnHideMap.count() <<",hideNum=" << hideNum; // Move the widget to the direction where they should be for (int i = 0; i <= 8; i++) { if (m_btnHideMap.value(map.value(i))) { map[i]->hide(); } else { map[i]->show(); } } if (hideNum >= 8 || (m_screen.width() -160 - 128 * (9 - hideNum)) / (8-hideNum) >= 16) { showNormalBtnWidget(hideNum); } else { showHasScrollBarBtnWidget(hideNum); } m_btnWidget->setStyleSheet("QWidget#btnWidget{background-color: transparent;}"); m_btnWidget->setLayout(m_buttonHLayout); m_scrollArea->horizontalScrollBar()->setVisible(false); m_scrollArea->horizontalScrollBar()->setDisabled(true); m_scrollArea->setWidget(m_btnWidget); m_scrollArea->setStyleSheet("QScrollArea#scrollArea{background-color: transparent;}"); m_scrollArea->setAlignment(Qt::AlignCenter); qDebug() << "m_scrollArea geometry:" << m_scrollArea->geometry(); qDebug() << "m_btnWidget geometry:" << m_btnWidget->geometry(); qDebug() << "m_buttonHLayout geometry:" << m_buttonHLayout->geometry(); m_vBoxLayout->setContentsMargins((m_screen.width() - m_scrollArea->width() - 20)/2,0,(m_screen.width() - m_scrollArea->width() - 20)/2,0); //m_scrollArea->adjustSize(); //m_scrollArea->setWidgetResizable(true); //行 rowMap.clear(); rowMap.insert(0, m_switchRow); rowMap.insert(1, m_hibernateRow); rowMap.insert(2, m_suspendRow); rowMap.insert(3, m_lockScreenRow); rowMap.insert(4, m_logoutRow); rowMap.insert(5,m_upgradeThenRebootRow); rowMap.insert(6, m_rebootRow); rowMap.insert(7, m_upgradeThenShutdownRow); rowMap.insert(8, m_shutDownRow); //列 columMap.clear(); columMap.insert(0, m_switchColumn); columMap.insert(1, m_hibernateColumn); columMap.insert(2, m_suspendColumn); columMap.insert(3, m_lockScreenColumn); columMap.insert(4, m_logoutColumn); columMap.insert(5, m_upgradeThenRebootColumn); columMap.insert(6, m_rebootColumn); columMap.insert(7, m_upgradeThenShutdownColumn); columMap.insert(8, m_shutDownColumn); m_toolWidget->setGeometry(m_screen); } // Paint the background picture void MainWindow::paintEvent(QPaintEvent *e) { QPainter painter(this); painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing); painter.setPen(Qt::transparent); painter.setBrush(QColor(0, 0, 0, 78)); // 178 for (QScreen *screen: QApplication::screens()) { // draw picture to every screen QRect rect = screen->geometry(); painter.drawPixmap(rect, pix.scaled(screen->size())); //drawRect可以避免在白色壁纸的情况下模糊背景造成的问题 painter.drawRect(rect); } QWidget::paintEvent(e); } //lock screen void MainWindow::doLockscreen() { QString SS_DBUS_SERVICE = "org.ukui.ScreenSaver"; QString SS_DBUS_PATH = "/"; QString SS_DBUS_INTERFACE = "org.ukui.ScreenSaver"; QString displayNum = QString(qgetenv("DISPLAY")).replace(":", "").replace(".", "_"); qDebug() << "display = " << displayNum ; QString sessionDbus = QString("%1%2").arg(SS_DBUS_SERVICE).arg(displayNum); QDBusInterface *interface = new QDBusInterface(sessionDbus, SS_DBUS_PATH, SS_DBUS_INTERFACE); if (!interface->isValid()) { qDebug() << "interface not valid"; delete interface; interface = new QDBusInterface(SS_DBUS_SERVICE, SS_DBUS_PATH, SS_DBUS_INTERFACE); } /*监听锁屏起来的信号,再执行界面退出操作,规避点击锁屏后先显示桌面再打开锁屏 QDBusConnection::sessionBus().connect(QString("org.ukui.ScreenSaver"), QString("/"), QString("org.ukui.ScreenSaver"), QString("lock"), this, SLOT(exitt()));*/ QDBusMessage msg = interface->call("Lock"); //延迟界面退出操作,规避点击锁屏后先显示桌面再打开锁屏 // QTimer::singleShot(500, this, SLOT(exitt())); exit(0); } void MainWindow::startUkuiSplash() { QProcess *splash = new QProcess(this); qDebug() << "start ukui-ksplash"; splash->startDetached("ukui-ksplash"); } void MainWindow::doSystemMonitor() { qDebug() << "doSystemMonitor...."; QProcess::startDetached("ukui-system-monitor", QStringList()); exitt(); } // handle mouse-clicked event bool MainWindow::eventFilter(QObject *obj, QEvent *event) { if (obj->objectName() == "systemMonitor") { if (event->type() == QEvent::MouseButtonRelease) { doSystemMonitor(); } else { if (event->type() == QEvent::Leave) { QString str = "QWidget#systemMonitor{background-color: transparent;border-radius: " + QString::number(m_systemMonitorBtn->height()/2) + "px;}"; m_systemMonitorBtn->setStyleSheet(str); m_systemMonitorBtn->setAttribute(Qt::WA_StyledBackground); //tableNum = -1; flag = false; changeBtnState("empty"); } else if (event->type() == QEvent::Enter) { QString str = "QWidget#systemMonitor{background-color: rgb(255,255,255,40);border-radius: " + QString::number(m_systemMonitorBtn->height()/2) + "px;}"; m_systemMonitorBtn->setStyleSheet(str); m_systemMonitorBtn->setAttribute(Qt::WA_StyledBackground); //tableNum = -1; flag = true; changeBtnState("empty"); } else if (event->type() == QEvent::MouseButtonPress) { QString str = "QWidget#systemMonitor{background-color: rgb(255,255,255,80);border-radius: " + QString::number(m_systemMonitorBtn->height()/2) + "px;}"; m_systemMonitorBtn->setStyleSheet(str); m_systemMonitorBtn->setAttribute(Qt::WA_StyledBackground); } } } if(event->type() == QEvent::WindowActivate){ if(QString(qgetenv("XDG_SESSION_TYPE")) == "wayland") { PlasmaShellManager::getInstance()->setAppWindowKeepAbove(true); } //QTimer::singleShot(20,this,&MainWindow::laterActivate); } return QWidget::eventFilter(obj, event); } void MainWindow::changePoint(QWidget *widget, QEvent *event) { if (event->type() == QEvent::Enter) { changeBtnState(widget->objectName()); } if (event->type() == QEvent::Leave) { flag = false; lastWidget = widget; } } void MainWindow::doEvent(QString test, int i) { qDebug() << "doevent... i:" << i << test << inhibitShutdown << inhibitSleep << close_system_needed_to_confirm; defaultnum = i; gs->set("win-key-release", false); QString platform = QGuiApplication::platformName(); if (platform.startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) { //wayland interface } else { if (click_blank_space_need_to_exit) { if (closeGrab()) { qDebug() << "success to close Grab"; } else { qDebug() << "failure to close Grab"; } } } switch (i) { case (1) : case (2) : { //获取inhibitor,不为空展示界面,为空直接执行动作 QVector res = LockChecker::listInhibitor("sleep"); if (res.isEmpty()) { qDebug() << "Start do action" << test << defaultnum; this->hide(); startUkuiSplash(); emit signalTostart(); } else { showInhibitWarning(res, i); } break; } case (3) : { doLockscreen(); break; } case (4) : { QVector res = LockChecker::listInhibitor("shutdown"); if (res.isEmpty()) { qDebug() << "Start do action" << test << defaultnum; this->hide(); emit signalTostart(); } else { showInhibitWarning(res, i); } break; } case (5) : { qDebug() << "Start do action " << test << defaultnum; this->hide(); upgradeCheck->doUpgradeThenRboot(); exit(0); break; } case (6) : { QVector res = LockChecker::listInhibitor("shutdown"); if (res.isEmpty()) { if (close_system_needed_to_confirm) { connect(this, &MainWindow::confirmButtonclicked, [&](){ qDebug() << "Start do action" << defaultnum; this->hide(); emit signalTostart(); }); this->judgeboxShow(); } else { qDebug() << "Start do action" << defaultnum; this->hide(); emit signalTostart(); } } else { showInhibitWarning(res, i); } break; } case (7) : { qDebug() << "Start do action" << test << defaultnum; this->hide(); upgradeCheck->doUpgradeThenShutdown(); exit(0); break; } case (8) : { QVector res = LockChecker::listInhibitor("shutdown"); if (res.isEmpty()) { if (close_system_needed_to_confirm) { connect(this, &MainWindow::confirmButtonclicked, [&](){ qDebug() << "Start do action" << defaultnum; this->hide(); emit signalTostart(); }); this->judgeboxShow(); } else { qDebug() << "Start do action" << defaultnum; this->hide(); emit signalTostart(); } } else { showInhibitWarning(res, i); } break; } default : { this->hide(); emit signalTostart(); break; } } } // handle the blank-area mousePressEvent void MainWindow::mousePressEvent(QMouseEvent *event) { if (click_blank_space_need_to_exit) { QPainterPath path; QRect rect(m_systemMonitorBtn->geometry()); const qreal radius = m_systemMonitorBtn->height()/2; path.moveTo(rect.topRight() - QPointF(radius, 0)); path.lineTo(rect.topLeft() + QPointF(radius, 0)); path.quadTo(rect.topLeft(), rect.topLeft() + QPointF(0, radius)); path.lineTo(rect.bottomLeft() + QPointF(0, -radius)); path.quadTo(rect.bottomLeft(), rect.bottomLeft() + QPointF(radius, 0)); path.lineTo(rect.bottomRight() - QPointF(radius, 0)); path.quadTo(rect.bottomRight(), rect.bottomRight() + QPointF(0, -radius)); path.lineTo(rect.topRight() + QPointF(0, radius)); path.quadTo(rect.topRight(), rect.topRight() + QPointF(-radius, -0)); qDebug() << "mousePressEvent" << m_switchUserBtn->geometry() << m_scrollArea->mapFromGlobal(event->pos()); if (!m_suspendBtn->getIconLabel()->containsPoint(m_suspendBtn->getIconLabel()->mapFromGlobal(event->pos())) && !m_hibernateBtn->getIconLabel()->containsPoint(m_hibernateBtn->getIconLabel()->mapFromGlobal(event->pos())) && !m_lockScreenBtn->getIconLabel()->containsPoint(m_lockScreenBtn->getIconLabel()->mapFromGlobal(event->pos())) && !m_switchUserBtn->getIconLabel()->containsPoint(m_switchUserBtn->getIconLabel()->mapFromGlobal(event->pos())) && !m_logoutBtn->getIconLabel()->containsPoint(m_logoutBtn->getIconLabel()->mapFromGlobal(event->pos())) && !m_upgradeThenRebootBtn->getIconLabel()->containsPoint(m_upgradeThenRebootBtn->getIconLabel()->mapFromGlobal(event->pos())) && !m_rebootBtn->getIconLabel()->containsPoint(m_rebootBtn->getIconLabel()->mapFromGlobal(event->pos())) && !m_upgradeThenshutDownBtn->getIconLabel()->containsPoint(m_upgradeThenshutDownBtn->getIconLabel()->mapFromGlobal(event->pos())) && !m_shutDownBtn->getIconLabel()->containsPoint(m_shutDownBtn->getIconLabel()->mapFromGlobal(event->pos())) && !path.contains(m_toolWidget->mapFromGlobal(event->pos()))) { exitt(); } } } bool MainWindow::exitt() { gs->set("win-key-release", false); if(QString(qgetenv("XDG_SESSION_TYPE")) == "xcb") { if (closeGrab()) { qDebug() << "success to close Grab"; } else { qDebug() << "failure to close Grab"; } } close(); exit(0); } bool MainWindow::judgeBtnIsEnable(int index) { if (!m_btnHideMap.value(map.value(index))) { return true; } return false; } bool MainWindow::matchKeyBtn(int row, int column) { for (int j = 8; j >= 0; j--) { if (rowMap.value(j) == row && columMap.value(j) == column && judgeBtnIsEnable(j)) { tableNum = j; return true; } } return false; } void MainWindow::calculateKeyBtn(const QString &key) { if (key == "Left") { if (tableNum == 0 || tableNum == -1) { for (int i = 8; i >= 0; i--) { if (judgeBtnIsEnable(i)) { tableNum = i; return; } } } else { for (int i = tableNum - 1; i >= 0; i--) { if (judgeBtnIsEnable(i)) { tableNum = i; return; } } for (int i = 8; i >= tableNum + 1; i--) { if (judgeBtnIsEnable(i)) { tableNum = i; return; } } } } else if (key == "Right") { if (tableNum == 8 || tableNum == -1) { for (int i = 0; i <= 8; i++) { if (judgeBtnIsEnable(i)) { tableNum = i; return; } } } else { for (int i = tableNum + 1; i <= 8; i++) { if (judgeBtnIsEnable(i)) { tableNum = i; return; } } for (int i = 0; i <= tableNum - 1; i++) { if (judgeBtnIsEnable(i)) { tableNum = i; return; } } } } else if (m_lineNum > 1 && key == "Up") { if (tableNum == -1) { for (int i = m_lineNum - 1; i >= 0; i--) { if(matchKeyBtn(i, 0)) return; } } int tableRow = rowMap.value(tableNum); int tableColum = columMap.value(tableNum); for (int i = 1; i < tableRow + 1; i++) { if (matchKeyBtn(tableRow - i, tableColum)) return; } for (int i = m_lineNum - 1; i > tableRow; i--) { if(matchKeyBtn(i, tableColum)) return; } } else if (m_lineNum > 1 && key == "Down") { if (tableNum == -1) { for (int i = 0; i < m_lineNum; i++) { if (matchKeyBtn(i, 0)) return; } } int tableRow = rowMap.value(tableNum); int tableColum = columMap.value(tableNum); for (int i = tableRow + 1; i < m_lineNum; i++) { if (matchKeyBtn(i, tableColum)) return; } for (int i = 0; i < tableRow + 1; i++) { if (matchKeyBtn(i, tableColum)) return; } } } void MainWindow::onGlobalKeyPress(const QString &key) { } // handle "Esc","Left","Right","Enter" keyPress event void MainWindow::onGlobalkeyRelease(const QString &key) { if(QString(qgetenv("XDG_SESSION_TYPE")) != "wayland") { return; } qDebug() << "key: " << key << "flag:" << flag << "click_blank_space_need_to_exit:" << click_blank_space_need_to_exit; if (!click_blank_space_need_to_exit && m_enterJudgeBox) { return; } /*else if (!click_blank_space_need_to_exit && m_enterInhibitList) { //处理阻止列表界面的键盘逻辑 int totalRow = m_inhibitDataModel->rowCount(); if (key == "Escape") { exitt(); } else if (key == "Tab") { if (m_isFirstEnterInhibitList) { m_inhibitAppList->setCurrentIndex(m_inhibitDataModel->index(0, 0)); m_currentListSelect = 0; m_isFirstEnterInhibitList = false; } else { if (!m_isCancelBtnSelect) { QString str = "QWidget#cancelBtn{background-color: rgb(255,255,255,80);border: 1px solid #296CD9; border-radius: " + QString::number(m_inhibitCancelBtn->height()/2) + "px;}"; m_inhibitCancelBtn->setStyleSheet(str); m_inhibitCancelBtn->setAttribute(Qt::WA_StyledBackground); m_inhibitAppList->clearSelection(); m_isCancelBtnSelect = true; } else { QString str = "QWidget#cancelBtn{background-color: rgb(255,255,255,40);border-radius: " + QString::number(m_inhibitCancelBtn->height()/2) + "px;}"; m_inhibitCancelBtn->setStyleSheet(str); m_inhibitCancelBtn->setAttribute(Qt::WA_StyledBackground); m_inhibitAppList->setCurrentIndex(m_inhibitDataModel->index(0, 0)); m_currentListSelect = 0; m_isCancelBtnSelect = false; } } } else if (key == "Down") { if (!m_isCancelBtnSelect) { m_isFirstEnterInhibitList = false; if (m_currentListSelect < totalRow - 1) { m_inhibitAppList->setCurrentIndex(m_inhibitDataModel->index(++m_currentListSelect, 0)); } else if (m_currentListSelect == totalRow - 1) { m_inhibitAppList->setCurrentIndex(m_inhibitDataModel->index(0, 0)); m_currentListSelect = 0; } } } else if (key == "Up") { if (!m_isCancelBtnSelect) { m_isFirstEnterInhibitList = false; if (m_currentListSelect > 0) { m_inhibitAppList->setCurrentIndex(m_inhibitDataModel->index(--m_currentListSelect, 0)); } else if (m_currentListSelect <= 0) { m_inhibitAppList->setCurrentIndex(m_inhibitDataModel->index(totalRow - 1, 0)); m_currentListSelect = totalRow - 1; } } } else if (key == "Return" || key == "KP_Enter") { if (m_isCancelBtnSelect) { exitt(); } } }*/ else { if (key == "Escape") { exitt(); } else if (key == "Left" || key == "Right" || key == "Up" || key == "Down") { if (!m_isSystemMonitorSelect) { m_isFirstEnter = false; int oldNum = tableNum; calculateKeyBtn(key); qDebug() << "key...." << oldNum << tableNum; if (oldNum == tableNum) return; QString button = map[tableNum]->objectName(); if (m_btnWidgetNeedScrollbar) { int currentLine = rowMap[tableNum]; QScrollBar *scrollBar = m_scrollArea->verticalScrollBar(); if (currentLine == 0) { scrollBar->setValue(0); } else { int sValue = scrollBar->maximum() - scrollBar->minimum(); float scale = (currentLine * 180 + currentLine * m_buttonHLayout->verticalSpacing() + 128) * 1.0 / (m_btnWidget->height() * 1.0); scrollBar->setValue(sValue * scale); } } changeBtnState(button, true); } } else if (key == "Return" || key == "KP_Enter") { // space,KP_Enter if (m_isSystemMonitorSelect) { doSystemMonitor(); } else { for (auto item = map.begin(); item != map.end(); item++) { if (item.value()->getIsKeySelect()) return doEvent(item.value()->objectName(), item.key()); } for (auto item = map.begin(); item != map.end(); item++) { if (item.value()->getIsMouseSelect()) { return doEvent(item.value()->objectName(), item.key()); } } } } /*else if (key == "Tab") { if (m_isFirstEnter) { tableNum = -1; calculateKeyBtn("Right"); QString button = map[tableNum]->objectName(); changeBtnState(button, true); m_isFirstEnter = false; } else { if (!m_isSystemMonitorSelect) { QString str = "QWidget#systemMonitor{background-color: rgb(255,255,255,80);border: 1px solid #296CD9; border-radius: " + QString::number(m_systemMonitorBtn->height()/2) + "px;}"; m_systemMonitorBtn->setStyleSheet(str); m_systemMonitorBtn->setAttribute(Qt::WA_StyledBackground); flag = true; changeBtnState("empty", true); m_isSystemMonitorSelect = true; } else { tableNum = -1; calculateKeyBtn("Right"); QString button = map[tableNum]->objectName(); changeBtnState(button, true); QString str = "QWidget#systemMonitor{background-color: transparent;border-radius: " + QString::number(m_systemMonitorBtn->height()/2) + "px;}"; m_systemMonitorBtn->setStyleSheet(str); m_systemMonitorBtn->setAttribute(Qt::WA_StyledBackground); flag = false; m_isSystemMonitorSelect = false; } } }*/ } } void MainWindow::showInhibitWarning(QVector &list, int action) { QRect mainScreen; QList screens = QApplication::screens(); QPoint ptf(QCursor::pos()); for (QScreen *screen : screens) { QRect rec = screen->geometry(); if (rec.contains(ptf)) { mainScreen = rec;//获取鼠标所在屏幕 } } //进入应用阻止列表后点击一些事件不会再被响应 click_blank_space_need_to_exit = false; m_enterInhibitList = true; for (int j = 0; j < 9; j++) { map[j]->hide();//隐藏界面上原有的部件 } m_systemMonitorBtn->hide(); m_scrollArea->verticalScrollBar()->setVisible(false); drawWarningWindow(mainScreen, list, action); } void MainWindow::drawWarningWindow(QRect &rect, QVector &list, int action) { int xx = rect.x(); int yy = rect.y();//用于设置相对位置 bool isEnoughBig = m_screen.height() - 266 - 467 > 0 ? true : false; m_showWarningArea->setGeometry(0, 0, isEnoughBig ? 740 : 1200 * m_screen.width()/1920, isEnoughBig ? 467 : (500 * m_screen.height()/1080)); QVBoxLayout *vBoxLayout = new QVBoxLayout(); //顶部提醒信息 QLabel *tips = new QLabel(m_showWarningArea); tips->setObjectName(QString::fromUtf8("tips")); tips->setGeometry(0, 0, isEnoughBig ? 740 : m_showWarningArea->width(), 27); tips->setWordWrap(true); QString str; //defaultnum会在doevent中初始化为按钮的编号,结合defaultnum判断可以保证sleep和shutdown都被阻止时能够正确显示信息 switch (action) { case 1 : str = QObject::tr("The following program is running to prevent the system from hibernate!"); break; case 2 : str = QObject::tr("The following program is running to prevent the system from suspend!"); break; case 4: str = QObject::tr("The following program is running to prevent the system from logout!"); break; case 6 : str = QObject::tr("The following program is running to prevent the system from reboot!"); break; case 8 : str = QObject::tr("The following program is running to prevent the system from shutting down!"); break; } tips->setText(str); tips->setAlignment(Qt::AlignCenter); tips->setContentsMargins(0,0,0,0); tips->setStyleSheet(QString::fromUtf8("color:white"));//;font:14pt; //数据模型 m_inhibitDataModel = new QStandardItemModel(this); for (auto iter = list.begin(); iter != list.end(); ++iter) { QIcon icon; QString appName = iter->name; QString iconName = iter->icon; if (!iconName.isEmpty() && QIcon::hasThemeIcon(iconName)) { icon = QIcon::fromTheme(iconName); } else if (QIcon::hasThemeIcon("application-x-desktop")) { icon = QIcon::fromTheme("application-x-desktop"); } m_inhibitDataModel->appendRow(new QStandardItem(icon, appName)); } //列表视图 m_inhibitAppList = new MyListView(m_showWarningArea); m_inhibitAppList->setObjectName(QString::fromUtf8("applist")); if (isEnoughBig) { m_inhibitAppList->setFixedSize(520 * (isEnoughBig ? 1: m_screen.width()/1920), 320 * (isEnoughBig ? 1 : m_screen.height()/1080)); } else { m_inhibitAppList->setGeometry(0,0,520 * (isEnoughBig ? 1: m_screen.width()/1920), 320 * (isEnoughBig ? 1 : m_screen.height()/1080)); } m_inhibitAppList->verticalScrollMode(); m_inhibitAppList->setStyleSheet("QListView#applist{font:10pt;color:white;background-color: rgb(255,255,255,80);border-style: outset;border-width: 0px;border-radius: 6px;}\ QListView#applist::item{height:48px;margin-top:2px;border-radius: 6px;}\ QListView#applist::item::selected {background-color: rgb(255,255,255,80);border: 1px solid #296CD9;\ height:48px;margin-top:2px;border-radius: 6px;}\ QListView#applist::item::hover {background-color: rgb(255,255,255,80);height:48px;margin-top:2px;border-radius: 6px;}"); m_inhibitAppList->setEditTriggers(QAbstractItemView::NoEditTriggers); m_inhibitAppList->setIconSize(QSize(32,32)); m_inhibitAppList->setModel(m_inhibitDataModel); m_inhibitAppList->setMinimumHeight(40); m_inhibitAppList->verticalScrollBar()->setStyleSheet("QScrollBar{ background: transparent; margin-top:3px;margin-bottom:3px ; }"\ "QScrollBar:vertical{width: 6px;background: transparent;border-radius:3px;}"\ "QScrollBar::handle:vertical{width: 6px; background: rgba(255,255,255, 40); border-radius:3px;}"\ "QScrollBar::handle:vertical:hover{width: 6px; background: rgba(255,255,255, 60); border-radius:3px;}"\ "QScrollBar::add-line:vertical{width:0px;height:0px}"\ "QScrollBar::sub-line:vertical{width:0px;height:0px}"); //继续操作按钮 QHBoxLayout *hBoxLayout = new QHBoxLayout(); QString confirBTnText; if (inhibitSleep) { if (defaultnum == 1) { confirBTnText = (QObject::tr("Still Hibernate")); } else if (defaultnum == 2) { confirBTnText = (QObject::tr("Still Suspend")); } } if (inhibitShutdown) { if (defaultnum == 6) { confirBTnText = (QObject::tr("Still Reboot")); } else if (defaultnum == 8) { confirBTnText = (QObject::tr("Still Shutdown")); } } CommonPushButton *confirmBtn = new CommonPushButton(confirBTnText, QString::fromUtf8("confirmBtn"), 120, 48, 24, m_showWarningArea); connect(confirmBtn, &CommonPushButton::clicked, [this]() { gs->set("win-key-release", false); qDebug() << "Start do action" << defaultnum; this->signalTostart(); }); //取消按钮 m_inhibitCancelBtn = new CommonPushButton(QObject::tr("Cancel"), QString::fromUtf8("cancelBtn"), 120, 48, 24, m_showWarningArea); // cancelBtn->setStyleSheet("QPushButton#cancelBtn {\ // background-color: rgb(255,255,255,80);\ // border-style: outset;\ // border-width: 0px;\ // border-radius: 24px;}"); connect(m_inhibitCancelBtn, &CommonPushButton::clicked, this, &MainWindow::exitt); qDebug() << "applist->width():" << m_inhibitAppList->width() << m_inhibitCancelBtn->width(); //hBoxLayout->setContentsMargins(0,0,0,0); //hBoxLayout->setSpacing(isEnoughBig ? 24 : 12); hBoxLayout->addStretch(); //hBoxLayout->addWidget(confirmBtn); hBoxLayout->addWidget(m_inhibitCancelBtn); hBoxLayout->addStretch(); vBoxLayout->addWidget(tips); vBoxLayout->addWidget(m_inhibitAppList, 0, Qt::AlignHCenter); vBoxLayout->addSpacing(isEnoughBig ? 32 : 0); vBoxLayout->addLayout(hBoxLayout, Qt::AlignHCenter); //移动整个区域到指定的相对位置 m_showWarningArea->move(xx + (m_screen.width() - m_showWarningArea->width()) / 2, (yy + 266 * m_screen.height()/1080) + (isEnoughBig ? 0 : 10)); // applist->move((area->width() - applist->width()) / 2, isEnoughBig ? 51 : 32); m_showWarningArea->setContentsMargins(0,0,0,0); m_showWarningArea->setLayout(vBoxLayout); m_showWarningArea->show(); m_showWarningMesg = true; m_inhibitList = list; } void MainWindow::judgeboxShow() { click_blank_space_need_to_exit = false; m_enterJudgeBox = true; for (int j = 0; j < 9; j++) { map[j]->hide(); } m_scrollArea->verticalScrollBar()->setVisible(false); setLayoutWidgetVisible(m_dateTimeLayout, false); setLayoutWidgetVisible(m_judgeWidgetVLayout, true); m_judgeWidget->setVisible(true); } bool MainWindow::nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) { if (qstrcmp(eventType, "xcb_generic_event_t") != 0) { return false; } xcb_generic_event_t *event = reinterpret_cast(message); const uint8_t responseType = event->response_type & ~0x80; Display *display = nullptr; if (auto *x11Application = qApp->nativeInterface()) { display = x11Application->display(); } Window window = DefaultRootWindow(display); if (responseType == XCB_CONFIGURE_NOTIFY) { xcb_configure_notify_event_t *xc = reinterpret_cast(event); XClassHint ch; ch.res_name = NULL; ch.res_class = NULL; XGetClassHint(display, xc->window, &ch); qDebug() << "ch name is " << ch.res_name; if (QString(ch.res_name) == "ukui-session-tools") { if (ch.res_name) { XFree(ch.res_name); } if (ch.res_class) { XFree(ch.res_class); } return false; } if (xc->event == window) { XRaiseWindow(display, this->winId()); XFlush(display); } return false; } else if (responseType == XCB_MAP_NOTIFY) { xcb_map_notify_event_t *xc = reinterpret_cast(event); XClassHint ch; ch.res_name = NULL; ch.res_class = NULL; XGetClassHint(display, xc->window, &ch); qDebug() << "ch name is " << ch.res_name; if (QString(ch.res_name) == "ukui-session-tools") { if (ch.res_name) { XFree(ch.res_name); } if (ch.res_class) { XFree(ch.res_class); } return false; } XRaiseWindow(display, this->winId()); XFlush(display); } return false; } ukui-session-manager/tools/loginedusers.h0000664000175000017500000000236115252713362017572 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef LOGINEDUSER_H #define LOGINEDUSER_H #include struct LoginedUsers { int uid; QString userName; QDBusObjectPath objpath; }; QDBusArgument &operator<<(QDBusArgument &argument, const LoginedUsers &mystruct); const QDBusArgument &operator>>(const QDBusArgument &argument, LoginedUsers &mystruct); Q_DECLARE_METATYPE(LoginedUsers) #endif // LOGINEDUSER_H ukui-session-manager/tools/commonpushbutton.cpp0000664000175000017500000000550115252713362021045 0ustar fengfeng/* * Copyright (C) Copyright 2021 KylinSoft Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301, USA. **/ #include "commonpushbutton.h" #include #include #include #include CommonPushButton::CommonPushButton(QString buttonText, QString objName, int width, int height, int radius, QWidget *parent) { m_radius = radius; m_label = new QLabel(this); m_label->setText(buttonText); this->setFixedSize(width, height); this->setObjectName(objName); m_label->setAlignment(Qt::AlignCenter); m_label->setGeometry(0, 0, width, height); m_label->setStyleSheet("color:white");//font:12pt; this->setStyleSheet("QWidget#" + this->objectName() + "{background-color: rgb(255,255,255,40);border-radius: " + QString::number(m_radius) + "px;}"); this->setAttribute(Qt::WA_StyledBackground); } CommonPushButton::~CommonPushButton() { } void CommonPushButton::setText(QString str) { m_label->setText(str); } bool CommonPushButton::event(QEvent *event) { if (event->type() == QEvent::MouseButtonPress) { QString str = "QWidget#" + this->objectName() +"{background-color: rgb(255,255,255,100);border-radius: " + QString::number(m_radius) + "px;}"; this->setStyleSheet(str); this->setAttribute(Qt::WA_StyledBackground); } else if (event->type() == QEvent::MouseButtonRelease) { QString str = "QWidget#" + this->objectName() + "{background-color: rgb(255,255,255,80);border-radius: " + QString::number(m_radius) + "px;}"; this->setStyleSheet(str); this->setAttribute(Qt::WA_StyledBackground); emit clicked(); } return QWidget::event(event); } void CommonPushButton::enterEvent(QEvent *event) { QString str = "QWidget#" + this->objectName() + "{background-color: rgb(255,255,255,80);border-radius: " + QString::number(m_radius) + "px;}"; this->setStyleSheet(str); this->setAttribute(Qt::WA_StyledBackground); } void CommonPushButton::leaveEvent(QEvent *event) { QString str = "QWidget#" + this->objectName() + "{background-color: rgb(255,255,255,40);border-radius: " + QString::number(m_radius) + "px;}"; this->setStyleSheet(str); this->setAttribute(Qt::WA_StyledBackground); } ukui-session-manager/tools/ukuipower.h0000664000175000017500000000320615252714370017120 0ustar fengfeng/* BEGIN_COMMON_COPYRIGHT_HEADER * (c)LGPL2+ * Copyright: 2019 Tianjin KYLIN Information Technology Co., Ltd. * 2012 Razor team * Authors: * Christian Surlykke * * This program or library is free software; you can redistribute it * and/or modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA * * END_COMMON_COPYRIGHT_HEADER */ #ifndef UKUIPOWER_H #define UKUIPOWER_H #include #include class PowerProvider; class UkuiPower : public QObject { Q_OBJECT public: enum Action { PowerSwitchUser, PowerHibernate, PowerSuspend, PowerMonitorOff, PowerLogout, PowerUpgradeThenRboot, PowerReboot, PowerUpgradeThenShutdown, PowerShutdown, PowerSwitchToUser, }; explicit UkuiPower(QObject *parent = nullptr); virtual ~UkuiPower(); bool canAction(Action action) const; public slots: bool doAction(Action action); private: PowerProvider *m_systemdProvider; }; #endif // UKUIPOWER_H ukui-session-manager/tools/systemupgradecheck.h0000664000175000017500000000056715252714370020767 0ustar fengfeng#ifndef SYSTEMUPGRADECHECK_H #define SYSTEMUPGRADECHECK_H #include class systemUpgradeCheck { public: systemUpgradeCheck(); QDBusInterface *interface; bool isDbusActive = false; bool isSystemUpgrade = false; bool checkSystemUpgrade(); bool doUpgradeThenRboot(); bool doUpgradeThenShutdown(); }; #endif // SYSTEMUPGRADECHECK_H ukui-session-manager/tools/xeventmonitor.cpp0000664000175000017500000001334415252713362020346 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2011 ~ 2017 Deepin, Inc. * 2011 ~ 2017 Wang Yong * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * Author: Wang Yong * Maintainer: Wang Yong * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "xeventmonitor.h" #include #include #include #include #include // Virtual button codes that are not defined by X11. #define Button1 1 #define Button2 2 #define Button3 3 #define WheelUp 4 #define WheelDown 5 #define WheelLeft 6 #define WheelRight 7 #define XButton1 8 #define XButton2 9 class XEventMonitorPrivate { public: XEventMonitorPrivate(XEventMonitor *parent); virtual ~XEventMonitorPrivate(); void run(); protected: XEventMonitor *q_ptr; bool filterWheelEvent(int detail); static void callback(XPointer trash, XRecordInterceptData* data); void handleRecordEvent(XRecordInterceptData *); void emitButtonSignal(const char *member, xEvent *event); void emitKeySignal(const char *member, xEvent *event); private: Q_DECLARE_PUBLIC(XEventMonitor) }; XEventMonitorPrivate::XEventMonitorPrivate(XEventMonitor *parent) : q_ptr(parent) { } XEventMonitorPrivate::~XEventMonitorPrivate() { } void XEventMonitorPrivate::emitButtonSignal(const char *member, xEvent *event) { int x = event->u.keyButtonPointer.rootX; int y = event->u.keyButtonPointer.rootY; QMetaObject::invokeMethod(q_ptr, member, Qt::DirectConnection, Q_ARG(int, x), Q_ARG(int, y)); } void XEventMonitorPrivate::emitKeySignal(const char *member, xEvent *event) { Display *display = XOpenDisplay(NULL); int keyCode = event->u.u.detail; KeySym keySym = XkbKeycodeToKeysym(display, event->u.u.detail, 0, 0); char *keyStr = XKeysymToString(keySym); QMetaObject::invokeMethod(q_ptr, member, Qt::AutoConnection, Q_ARG(int, keyCode)); QMetaObject::invokeMethod(q_ptr, member, Qt::AutoConnection, Q_ARG(QString, keyStr)); XCloseDisplay(display); } void XEventMonitorPrivate::run() { Display* display = XOpenDisplay(0); if (display == 0) { fprintf(stderr, "unable to open display\n"); return; } // Receive from ALL clients, including future clients. XRecordClientSpec clients = XRecordAllClients; XRecordRange* range = XRecordAllocRange(); if (range == 0) { fprintf(stderr, "unable to allocate XRecordRange\n"); return; } // Receive KeyPress, KeyRelease, ButtonPress, ButtonRelease and MotionNotify events. memset(range, 0, sizeof(XRecordRange)); range->device_events.first = KeyPress; range->device_events.last = MotionNotify; // And create the XRECORD context. XRecordContext context = XRecordCreateContext(display, 0, &clients, 1, &range, 1); if (context == 0) { fprintf(stderr, "XRecordCreateContext failed\n"); return; } XFree(range); XSync(display, True); Display* display_datalink = XOpenDisplay(0); if (display_datalink == 0) { fprintf(stderr, "unable to open second display\n"); return; } if (!XRecordEnableContext(display_datalink, context, callback, (XPointer) this)) { fprintf(stderr, "XRecordEnableContext() failed\n"); return; } } void XEventMonitorPrivate::callback(XPointer ptr, XRecordInterceptData* data) { ((XEventMonitorPrivate*)ptr)->handleRecordEvent(data); } void XEventMonitorPrivate::handleRecordEvent(XRecordInterceptData* data) { if (data->category == XRecordFromServer) { xEvent * event = (xEvent *)data->data; switch (event->u.u.type) { case ButtonPress: if (filterWheelEvent(event->u.u.detail)) emitButtonSignal("buttonPress", event); break; case MotionNotify: emitButtonSignal("buttonDrag", event); break; case ButtonRelease: if (filterWheelEvent(event->u.u.detail)) emitButtonSignal("buttonRelease", event); break; case KeyPress: emitKeySignal("keyPress", event); break; case KeyRelease: emitKeySignal("keyRelease", event); break; default: break; } } fflush(stdout); XRecordFreeData(data); } bool XEventMonitorPrivate::filterWheelEvent(int detail) { return detail != WheelUp && detail != WheelDown && detail != WheelLeft && detail != WheelRight; } XEventMonitor::XEventMonitor(QObject *parent) : QThread(parent), d_ptr(new XEventMonitorPrivate(this)) { Q_D(XEventMonitor); } XEventMonitor::~XEventMonitor() { requestInterruption(); quit(); wait(); } void XEventMonitor::run() { if (!isInterruptionRequested()) { d_ptr->run(); } } ukui-session-manager/tools/mypushbutton.cpp0000664000175000017500000001661215252714370020207 0ustar fengfeng/* * Copyright (C) Copyright 2021 KylinSoft Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301, USA. **/ #include "mypushbutton.h" #include #include #include #include #include MyPushButton::MyPushButton(QString iconPath, QString buttonLable, QString objName, QWidget *parent, int x, int y, int width, int height, int iconWidth, int labelWidth) : QWidget(parent) { this->setFixedSize(labelWidth, height); this->setObjectName(objName); QVBoxLayout *vBoxLayout = new QVBoxLayout(); vBoxLayout->setContentsMargins(0, 0, 0, 10); m_iconLabel = new MyIconLabel(labelWidth, iconWidth, iconPath); m_iconLabel->setObjectName(objName + "_button"); m_iconLabel->installEventFilter(this); QString fakeText = "·" + buttonLable; QFontMetrics fontMetric(fakeText); int fontSize = fontMetric.horizontalAdvance(fakeText); int fontHeight = fontMetric.height(); qDebug() << "objName : " << objName << " labelWidth : " << labelWidth << " fontSize : " << fontSize << " fakeText : " << fakeText; //在buttonlable的宽度大于labelWidth - 20的时候,将其省略显示,为什么不是大于labelWidth,因为在藏文的环境中,buttonLabel的宽度和 //labelWidth的宽度只差几个像素,但实际画出来的效果仍然会超出控件,所以多留点余地 QString elideLabelText = fontMetric.elidedText(buttonLable, Qt::ElideRight, labelWidth - 35 ); // if (objName == "upgradethenreboot" || objName == "upgradeThenShutdown") { // QString themeColor = "sss"; // QString themeColorRGB = "#3D6BE5"; // if (themeColor == "jamPurple") { // themeColorRGB = "#3D6BE5"; // } else if (themeColor == "magenta") { // themeColorRGB = "#EB3096"; // } else if (themeColor == "sunRed") { // themeColorRGB = "#F3222D"; // } else if (themeColor == "sunsetOrange") { // themeColorRGB = "#F68C27"; // } else if (themeColor == "dustGold") { // themeColorRGB = "#F8C53D"; // } else if (themeColor == "polarGreen") { // themeColorRGB = "#52C429"; // } else { // themeColorRGB = "#3D6BE5"; // } // elideLabelText = "·" + elideLabelText; // } m_buttonLabel = new QLabel(); m_buttonLabel->setText(elideLabelText); m_buttonLabel->setToolTip(buttonLable); double fsize = 10; if (QGSettings::isSchemaInstalled("org.ukui.style")){ QGSettings *gset = new QGSettings("org.ukui.style"); fsize = gset->get("system-font-size").toDouble(); } fsize = fsize + 8; const QString font_size= "QLabel{font-size: " + QString::number(fsize) + "px}"; m_buttonLabel->setStyleSheet(font_size + "QLabel{color: white;}"); m_buttonLabel->setAlignment(Qt::AlignCenter); //newHeight是QWidget的新高度,由icon的高度labelWidth,字体的高度fontHeight再加上一个30的余量组成 qDebug() << "height is " << height << " fontHeight is " << fontHeight; int newHeight = fontHeight + labelWidth + 30; if (newHeight > height) { //高度加大,避免某些藏文字体会出现的超出现象 this->setFixedSize(labelWidth, newHeight + 40); } vBoxLayout->addWidget(m_iconLabel, 0, Qt::AlignCenter); vBoxLayout->addWidget(m_buttonLabel, 0, Qt::AlignCenter); this->setLayout(vBoxLayout); connect(m_iconLabel, &MyIconLabel::mouseEventSignals, this, &MyPushButton::iconLabelMouseEvent); } MyPushButton::~MyPushButton() { } void MyPushButton::changeIconBackColor(bool isChoose, bool isKeySelect) { if (m_isMouseSelect && m_isKeySelect) { if ((isChoose && isKeySelect) || (isChoose && !isKeySelect)) { m_isKeySelect = true; m_isMouseSelect = true; } else if (!isChoose && !isKeySelect) { m_isKeySelect = true; m_isMouseSelect = false; } else if (!isChoose && isKeySelect) { m_isKeySelect = false; m_isMouseSelect = true; } } else if (m_isMouseSelect && !m_isKeySelect) { if ((isChoose && isKeySelect) || (!isChoose && !isKeySelect)) { m_isKeySelect = isKeySelect; m_isMouseSelect = isChoose; } else if ((isChoose && !isKeySelect) || (!isChoose && isKeySelect)) { m_isKeySelect = false; m_isMouseSelect = true; } } else if (!m_isMouseSelect && !m_isKeySelect) { if (isChoose && isKeySelect) { m_isKeySelect = true; m_isMouseSelect = false; } else if (isChoose && !isKeySelect) { m_isKeySelect = false; m_isMouseSelect = true; } else if ((!isChoose && !isKeySelect) || (!isChoose && isKeySelect)) { m_isKeySelect = false; m_isMouseSelect = false; } } else if (!m_isMouseSelect && m_isKeySelect) { if ((isChoose && isKeySelect) || (!isChoose && !isKeySelect)) { m_isKeySelect = true; m_isMouseSelect = false; } else if ((isChoose && !isKeySelect) || (!isChoose && isKeySelect)) { m_isKeySelect = !isKeySelect; m_isMouseSelect = isChoose; } } // qDebug() << "isKeySelect..." << objectName() << m_isKeySelect << m_isMouseSelect; QString str; if ((m_isKeySelect && m_isMouseSelect) || (m_isKeySelect && !m_isMouseSelect)) { str = "QLabel#" + m_iconLabel->objectName() + "{background-color: rgb(255,255,255,80);border: 1px solid #296CD9; border-radius: " + QString::number(m_iconLabel->width()/2) + "px;}"; } else if(!m_isKeySelect && m_isMouseSelect){ str = "QLabel#" + m_iconLabel->objectName() + "{background-color: rgb(255,255,255,80);border-radius: " + QString::number(m_iconLabel->width()/2) + "px;}"; } else if(!m_isKeySelect && !m_isMouseSelect){ str = "QLabel#" + m_iconLabel->objectName() + "{background-color: rgb(255,255,255,40);border: 0px; border-radius: " + QString::number(m_iconLabel->width()/2) + "px;}"; } m_iconLabel->setStyleSheet(str); m_iconLabel->setAttribute(Qt::WA_StyledBackground); } MyIconLabel* MyPushButton::getIconLabel() { return m_iconLabel; } void MyPushButton::iconLabelMouseEvent(QEvent *event) { emit mouseRelase(event, m_iconLabel->objectName()); } bool MyPushButton::getIsKeySelect() { return m_isKeySelect; } bool MyPushButton::getIsMouseSelect() { return m_isMouseSelect; } void MyPushButton::setIsKeySelect(bool isKeySelect) { if(m_isKeySelect != isKeySelect) m_isKeySelect = isKeySelect; } void MyPushButton::setIsMouseSelect(bool isMouseSelect) { if(m_isMouseSelect != isMouseSelect) m_isMouseSelect = isMouseSelect; } ukui-session-manager/tools/ukuilockinfo.cpp0000664000175000017500000002312415252714370020124 0ustar fengfeng/* * Copyright (C) Copyright 2021 KylinSoft Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301, USA. */ #include "ukuilockinfo.h" #include "../ukui-session/xdgdesktopfile.h" #include #include #include #include #include #include #include QDBusArgument &InhibitInfo::operator<<(QDBusArgument &argument, const InhibitInfo::InhibitorInfo &mystruct) { argument.beginStructure(); argument << mystruct.name << mystruct.icon; argument.endStructure(); return argument; } const QDBusArgument &InhibitInfo::operator>>(const QDBusArgument &argument, InhibitInfo::InhibitorInfo &mystruct) { argument.beginStructure(); argument >> mystruct.name >> mystruct.icon ; argument.endStructure(); return argument; } Ukuilockinfo::Ukuilockinfo() { } QVector Ukuilockinfo::listInhibitorInfo(Ukuilockinfo::InhibitorType type) { QVector result; switch (type) { case InhibitorType::logout: { getLogoutInhibitor(result); break; } case InhibitorType::suspend: { getSystemdInhibitor(QString("sleep"), result); break; } case InhibitorType::shutdown: { getSystemdInhibitor(QString("shutdown"), result); break; } } return result; } bool Ukuilockinfo::getCfgValue(Ukuilockinfo::buttonType button) { bool buttonActive = false; bool newIniFile = false;//ini文件是否为新建文件 QString iniDir = "/usr/share/ukui/ukui-session-manager/config"; if (!QFile::exists(iniDir + "/btnconfig.ini")) { qDebug() << "btnconfig.ini file is not exists!!!"; QDir dir(iniDir); if (!dir.exists(iniDir)) { if (dir.mkdir(iniDir)) {//目前创建不成功 没有权限 QFile iniFile(iniDir + "/btnconfig.ini"); if (iniFile.open(QIODevice::WriteOnly)) { newIniFile = true; iniFile.close(); } qDebug() << "inifile open failed!"; } else { qDebug() << "create inidir failed!"; } } } QSettings *cfgSettings = new QSettings("/usr/share/ukui/ukui-session-manager/config/btnconfig.ini", QSettings::IniFormat); if (newIniFile) {//貌似路径下文件只可读不可写 cfgSettings->setValue("btn/SwitchUserBtnHide", false); cfgSettings->setValue("btn/HibernateBtnHide", false); cfgSettings->setValue("btn/LockScreenBtnHide", false); cfgSettings->setValue("btn/LogoutBtnHide", false); cfgSettings->setValue("btn/RebootBtnHide", false); cfgSettings->setValue("btn/ShutDownBtnHide", false); cfgSettings->setValue("btn/SuspendBtnHide", false); } switch (button) { case switchuserBtn: buttonActive = !(cfgSettings->value("btn/SwitchUserBtnHide").toBool()); break; case hibernateBtn: buttonActive = !(cfgSettings->value("btn/HibernateBtnHide").toBool()); break; case suspendBtn: buttonActive = !(cfgSettings->value("btn/SuspendBtnHide").toBool()); break; case lockscreenBtn: buttonActive = !(cfgSettings->value("btn/LockScreenBtnHide").toBool()); break; case logoutBtn: buttonActive = !(cfgSettings->value("btn/LogoutBtnHide").toBool()); break; case rebootBtn: buttonActive = !(cfgSettings->value("btn/RebootBtnHide").toBool()); break; case shutdownBtn: buttonActive = !(cfgSettings->value("btn/ShutDownBtnHide").toBool()); break; default: break; } return buttonActive; } void Ukuilockinfo::getSystemdInhibitor(QString type, QVector &inhibitorVec) { qDBusRegisterMetaType(); QDBusInterface loginInterface("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", QDBusConnection::systemBus()); if (loginInterface.isValid()) { qDebug() << "create interface success"; } QDBusMessage result = loginInterface.call("ListInhibitors"); QList outArgs = result.arguments(); QVariant first = outArgs.at(0); const QDBusArgument &dbusArgs = first.value(); dbusArgs.beginArray(); while (!dbusArgs.atEnd()) { SystemdInhibitor::Inhibitor inhibitor; dbusArgs >> inhibitor; if (inhibitor.mode == QString("block") && inhibitor.action.contains(type)) { InhibitInfo::InhibitorInfo inhibitInfo; findNameAndIcon(inhibitor.name, inhibitInfo); if (inhibitInfo.name.isEmpty()) { inhibitInfo.name = inhibitor.name; } inhibitorVec.push_back(inhibitInfo); } } dbusArgs.endArray(); } void Ukuilockinfo::findNameAndIcon(QString &inhibitorName, InhibitInfo::InhibitorInfo &inhibitor) { QString icon; QString name; QStringList desktop_paths = { "/usr/share/applications", "/etc/xdg/autostart" }; //逻辑问题,规避文件管理器这种多个desktop中exec字段均为peony的情况 if ("peony" == inhibitorName) { XdgDesktopFile desktopFile; desktopFile.load("/usr/share/applications/peony.desktop"); icon = desktopFile.value("Icon", QVariant("application-x-desktop")).toString(); // name = getAppLocalName(fi.absoluteFilePath()); //根据系统的本地语言设置获取对应的名称,改为直接使用xdg的接口 name = desktopFile.localizedValue("Name").toString(); inhibitor.name = name; inhibitor.icon = icon; return; } for (const QString &dirName : const_cast(desktop_paths)) { QDir dir(dirName); if (!dir.exists()) { continue; } const QFileInfoList files = dir.entryInfoList(QStringList(QLatin1String("*.desktop")), QDir::Files | QDir::Readable); for (const QFileInfo &fi : files) { XdgDesktopFile desktopFile; desktopFile.load(fi.absoluteFilePath()); //不再使用basename判断,使用命令判断 //QString base = fi.baseName(); if (desktopFile.expandExecString().isEmpty()) continue; QString command = desktopFile.expandExecString().takeFirst(); QStringList list = command.split("/"); QString exec = list.last(); if (exec == inhibitorName) { icon = desktopFile.value("Icon", QVariant("application-x-desktop")).toString(); // name = getAppLocalName(fi.absoluteFilePath()); //根据系统的本地语言设置获取对应的名称,改为直接使用xdg的接口 name = desktopFile.localizedValue("Name").toString(); inhibitor.name = name; inhibitor.icon = icon; break; } } } } //QString Ukuilockinfo::getAppLocalName(QString desktopfp) //{ // GError **error = nullptr; // GKeyFileFlags flags = G_KEY_FILE_NONE; // GKeyFile *keyfile = g_key_file_new(); // QByteArray fpbyte = desktopfp.toLocal8Bit(); // char *filepath = fpbyte.data(); // g_key_file_load_from_file(keyfile, filepath, flags,error); // char *name = g_key_file_get_locale_string(keyfile, "Desktop Entry", "Name", nullptr, nullptr); // QString namestr = QString::fromLocal8Bit(name); // g_key_file_free(keyfile); // return namestr; //} void Ukuilockinfo::getLogoutInhibitor(QVector &inhibitorVec) { QDBusInterface sessionInterface("org.gnome.SessionManager", "/org/gnome/SessionManager", "org.gnome.SessionManager", QDBusConnection::sessionBus()); if (!sessionInterface.isValid()) { qDebug() << "interface not usable"; return; } QDBusMessage result = sessionInterface.call("GetInhibitors"); auto res = result.arguments().toVector(); for (auto it = res.begin(); it != res.end(); ++it) { QString info = it->toString(); if (info.isEmpty()) { continue; } QStringList infolist = info.split("/"); InhibitInfo::InhibitorInfo inhibitorInfo; inhibitorInfo.name = infolist[0]; inhibitorInfo.icon = infolist[2]; inhibitorVec.push_back(inhibitorInfo); } } QDBusArgument &SystemdInhibitor::operator<<(QDBusArgument &argument, const SystemdInhibitor::Inhibitor &mystruct) { argument.beginStructure(); argument << mystruct.action << mystruct.name << mystruct.reason << mystruct.mode << mystruct.uid << mystruct.pid; argument.endStructure(); return argument; } const QDBusArgument &SystemdInhibitor::operator>>(const QDBusArgument &argument, SystemdInhibitor::Inhibitor &mystruct) { argument.beginStructure(); argument >> mystruct.action >> mystruct.name >> mystruct.reason >> mystruct.mode >> mystruct.uid >> mystruct.pid; argument.endStructure(); return argument; } ukui-session-manager/tools/myiconlabel.cpp0000664000175000017500000000730515252713362017723 0ustar fengfeng/* * Copyright (C) Copyright 2021 KylinSoft Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301, USA. **/ #include "myiconlabel.h" #include #include #include #include #include #include #include #include MyIconLabel::MyIconLabel(int labelWidth, int iconWidth, QString path, QWidget *parent) { this->setFixedSize(labelWidth, labelWidth); this->setObjectName("iconlabel"); //iconLabel设置icon有锯齿,所以使用PushButton设置icon,同时在PushButton中将其收到的事件截断 m_btnIcon = new PushButton(this); m_btnIcon->setIcon(QIcon(path)); m_btnIcon->setIconSize(QSize(iconWidth, iconWidth)); m_btnIcon->setObjectName("btn"); m_btnIcon->setStyleSheet("QPushButton#btn{background-color: transparent;border:none;} \ QPushButton:checked { background-color: transparent;border:none;}\ QPushButton:hover { background-color: transparent;border:none;}"); m_btnIcon->setGeometry(QRect((width() - iconWidth)/2, (width() - iconWidth)/2, iconWidth, iconWidth)); m_btnIcon->setCheckable(false); m_btnIcon->setChecked(false); m_btnIcon->setGeometry(QRect((width() - iconWidth)/2, (width() - iconWidth)/2, iconWidth, iconWidth)); m_btnIcon->setAttribute(Qt::WA_TransparentForMouseEvents,true); //不再裁剪圆形窗口 //已经通过设置border-radius的方式画圆 //setMask裁剪的圆形锯齿感特别严重 //mask不要与控件一样大 锯齿明显 稍微大一点 //this->setMask(QRegion(this->x() - 1, this->y() - 1, this->width() + 2, this->height() + 2,QRegion::Ellipse)); //this->setStyleSheet("QLabel#"+ this->objectName() + "{background-color: rgb(255,255,255,40);border-radius:" + QString::number(this->width()/2) + "px;}"); //this->setPixmap(m_pixMap); this->setAlignment(Qt::AlignCenter); //setMouseTracking(true); } MyIconLabel::~MyIconLabel() { } bool MyIconLabel::event(QEvent *event) { // qDebug() << m_showBackColor << "event..." << event->type(); // if (!m_showBackColor) { // return QWidget::event(event); // } if (event->type() == QEvent::MouseButtonPress) { QString str = "QLabel{background-color: rgb(255,255,255,100);border-radius: " + QString::number(this->width()/2) + "px;}"; this->setStyleSheet(str); this->setAttribute(Qt::WA_StyledBackground); } else if (event->type() == QEvent::MouseButtonRelease) { QString str = "QLabel{background-color: rgb(255,255,255,80);border-radius: " + QString::number(this->width()/2) + "px;}"; this->setStyleSheet(str); this->setAttribute(Qt::WA_StyledBackground); emit mouseEventSignals(event); } else { emit mouseEventSignals(event); } return QWidget::event(event); } bool MyIconLabel::containsPoint(QPoint p) { QPainterPath path; path.addEllipse(QRect(0, 0, width(), height())); //qDebug() << "containsPoint..." << width() << height() << p << QRect(0,0,width(),height()); return path.contains(p); } ukui-session-manager/tools/xeventmonitor.h0000664000175000017500000000313215252713362020005 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2011 ~ 2017 Deepin, Inc. * 2011 ~ 2017 Wang Yong * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * Author: Wang Yong * Maintainer: Wang Yong * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef XEVENTMONITOR_H #define XEVENTMONITOR_H #include #include #include class XEventMonitorPrivate; class XEventMonitor : public QThread { Q_OBJECT public: XEventMonitor(QObject *parent = 0); ~XEventMonitor(); Q_SIGNALS: void buttonPress(int x, int y); void buttonDrag(int x, int y); void buttonRelease(int x, int y); void keyPress(int keyCode); void keyRelease(int keyCode); void keyPress(const QString &key); void keyRelease(const QString &key); protected: void run(); private: XEventMonitorPrivate *d_ptr; Q_DECLARE_PRIVATE(XEventMonitor) }; #endif ukui-session-manager/tools/commonpushbutton.h0000664000175000017500000000273715252713362020522 0ustar fengfeng/* * Copyright (C) Copyright 2021 KylinSoft Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301, USA. **/ #ifndef COMMONPUSHBUTTON_H #define COMMONPUSHBUTTON_H #include #include #include #include #include #include #include #include #include class CommonPushButton : public QWidget { Q_OBJECT public: CommonPushButton(QString buttonText, QString objName, int width = 120, int height = 48, int radius = 24, QWidget *parent = nullptr); ~CommonPushButton(); void setText(QString str); protected: bool event(QEvent *); void enterEvent(QEvent *event); void leaveEvent(QEvent *event); signals: void clicked(); public slots: private: QLabel *m_label = nullptr; int m_radius; }; #endif // COMMONPUSHBUTTON_H ukui-session-manager/tools/mylistview.h0000664000175000017500000000035015252713362017277 0ustar fengfeng#ifndef MYLISTVIEW_H #define MYLISTVIEW_H #include #include class MyListView : public QListView { Q_OBJECT public: MyListView(QWidget *parent = nullptr); ~MyListView(); }; #endif // MYLISTVIEW_H ukui-session-manager/tools/grab-x11.h0000664000175000017500000000145315252713362016412 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * **/ #ifndef GRABX11_H #define GRABX11_H bool establishGrab(); bool closeGrab(); #endif // GRABX11_H ukui-session-manager/tools/plasma-shell-manager.h0000664000175000017500000000205215252713362021056 0ustar fengfeng#ifndef PLASMASHELLMANAGER_H #define PLASMASHELLMANAGER_H #include #include #include #include #include class PlasmaShellManager : public QObject { Q_OBJECT public: static PlasmaShellManager *getInstance(); bool setAppWindowActive(); bool setAppWindowKeepAbove(bool keep); bool setMaximized(QWindow *window); bool setRole(QWindow *window, KWayland::Client::PlasmaShellSurface::Role role); bool setPos(QWindow *window, const QPoint &pos); bool supportPlasmaShell(); bool supportShell(); bool supportPlasmaWindowManagement(); private: explicit PlasmaShellManager(QObject *parent = nullptr); KWayland::Client::PlasmaShell *m_plasmaShell = nullptr; KWayland::Client::Shell *m_shell = nullptr; KWayland::Client::PlasmaWindowManagement *m_windowManager = nullptr; KWayland::Client::PlasmaWindow *m_appWindow = nullptr; bool isFirstCreate = true; }; #endif // PLASMASHELLMANAGER_H ukui-session-manager/data/0000775000175000017500000000000015252714370014465 5ustar fengfengukui-session-manager/data/startup.wav0000664000175000017500000447256015252713362016730 0ustar fengfengRIFFhuWAVEfmt LIST<INFOICRD2021-10-26T10:48:10+08:00ISFTLavf58.29.100datau  !%(+-0111358:;= = <83(!"!"$$')++*+'#  '3ALXafhd]VLC90)   ~{yw| 4(L.^3k:sBwHuOlV`\T^Gc;h4k.p)u(z(*/7>JT^js|}sfS@}*wneYL@4' zrlgda^\YYYw\b^Ob?h1n)t${$'0>JZhw 0ESdqz%Ed|ukaTD6) vkbZR$L)K-J1N4S9X>aAiErExDy@z9v.o!i`XNC90)  |k[J9*  "0>KWalv'H%g',-+'!#-7CzNtZofnqo}sztdSA0x l_RF<3+"xgWD2!{qh]T OK&N/V8f@{HQ\p$<Pa(nGwd~}|yvuuvy}{m^SKEBELVcrjS;" ~qcVH7&~yxxz}tcTC6+y'i'Z+H56?&JS Y[ [Y$Y:`Tjqx&64N?aHsPYcn{{pbTG6-'# 4!D%N*X6\E[UTfHw8# mM.mVBn/T ;"  }^C&*.4998757;BN^r+H1hEVcknl(j<eM_YYcSfNdIbG^GVHNMFS?Y9c3p4}8@JWeup^I7%}uqaeI\3XVW]dlwrS6 yl`XQORYfv *Kn $&1*G-X0c5j8l>kFeP_\WiOyJFEKS^kyhP7sbTKmCTC6DIQX`idqJv3x"wt oiaZVSU[fu= `(29? B%E:GIKRPUUU[McDm9y+!("6.G6Y:k9|5/#dF'lR<'k L, w d VI<3'/Hd ">^~ +6?!C9GKHTIXKWMPPGT=Y0_"ky  (8DR]g qxmQ7bJ6$jS 8  ~m^PD7*%=Zx(Gh(5?D9GOH^IfIiGjJfM^ST]Ih>z1)!#*5B/O=]HhQrV}VPH=,yV5aG1"cB "%)/2y2j/^*R&E!6( # +6F[t :X,y=LW]ab!c.a5\8X7V2V(Y]fs"+5@JV`hsx~hP4{\B+{eM0 $)}+p,d(W"K@4 ( 1Lg*Jl%9KX%bCj\nmszvv~{xkYJ9.$ &*,93F:MASJRTLbGn;z- mI%hI*uV8raPA1>` !>^+I_t (>OXZVOB5)  &3=DF$F,D5?;5B)KQZep{rN(dB# jO9! r`L8#9\*F h&@Uep x#~1:<70( # ,27)736<2F*P!Xaipy{[7tR5 zbG.xgVE4 @c?e %:K["g:pKyTWURKA9.$  &4 ?GM&P1O>PIIUB`8i+t| sO)nP8(sY@%! pXA-6Sr;_6Mdv*47952+" #.7=@B?*;65@,H!MRV]do|~]<wU9$ z`J2 yaK4-Kk@b -7@HOU\fp ~ $ ,0#4/39/B)FMV ]fsiEzY>' pXA, waI1.Kh1Qp *7BJPX \ e ow , 26):5:A:J7T0^(jvwL"dL<1*%"v"cL6$ mQ64Rq/P o#6GS^fjor!s&w&}$  (#3)<(C(J#QY`h t~T)_B* o^QD7." nV='#Bb+AXp*8DNV_hr{xx~/DWjw@[s}wpeqZ[ID30$"0vED\s}`F2 zpkhcf.hlr~^)7]q5 8Z&r;Qh?wflkp|Hs*07:>&D1K@SQZe^ZRD.qdZURlO7I<&T kjG!&@nx6[B-!!*O5@Qhdg ,ZOs !("R} *Sx*CXdhfditdAziSG+"l3pU@i0)#a5m]gIT6D"4( $7>`i50a7*q+>HMOKIHP^s&7F(U5c>uFLRZdozuaJr,T 3a'qZR0[0g=^>( 5d K/CU*fLxat& K/mQl4^N8WaqB!sQ,e)b$wJL%NLT- 6h.{TzqcWPOVfcM{9,(,$7[DZtF}Ly%B\ui L," 4Kf\$Si#"wcXXCanC 'S]B. ] V ':EaHpsh_TED1v0AOY[VJ'80#9 BJRVXZWVWY9_djqxGfCmzEPf/stP$W,;JGWh7]4Qj=e,WvwbL6   R^ Nn$a9\Jp:VZ6'hy^"+k4?O-de~<Um)Mz)+lMlMw2GUXRD/h*9'{5RKA+.\v"]) iG-4c1;O}d|a3; @O]x<\=d#;4Oe`oz[{tLk|dbace`R9Lua^J, :CR`S?p:|#`$7O.k.t8`E&Z7UuN|Et=^BzrFt @td7(No](\v#LID0)mM^1NXwo;5o!CiPv?g@e$R~O;%Q]^fklWllo q;pghX@BzB,gc'YDUR<i !s 9.SdYb:|JfQZ" ^t=Rr0 )7K fA|5vH "/R:><05oiH/sr4 2U|r8~,eBT0l0k! A9*q99@nS&=o)3l>Zt{wvywa-Mn>8:;?IRXIXN=#Jp'7a S;`uxGiG;Wha,|pukSG>(~[.uT2G $Z_D-L5P]_[QC 01EZuoE%]v8D TP'Gqf1y{"mR?/_W`+H 2gfNA)>wCM-Ziue~8xlA^QC5^#2q<Vl4JaxO 1[LsQ &i\ 3Ht"[a?"d^1~D 'LzwrZuz}%lBU2GFqVj Go$QEWxiE^Z]7_z\XM24CKzD2>Mr-i5U/}YL+PpP q+^TUPQU;Xy`kzAc'fK&^/Xt4Xx`C g{IrST.3.,/z8f=~M0-%19^b)TON|b-Hup \L,@5:?>QMke)d:k!;5LiROC3U!4'v^g!)k\4a.`3Jv(@1\r8@w[)Ox ]u>T~F|z#6Om+Cb?{uDtrpjfT)8Aqc%x~l|sdQ<"\mD D`6* zwII mslN0] @rzh]T8OcNNNJD<57?RnlE)>  -bB X^&&7S<4x @I7eA! .Twj]LULAk0?WnH)#a.i:/JToM\:I:59H_]~- gq@ UVKwT|  &rHI*!0JE[piE'O  o#(*q% c*j@2y$<O\__ZRI:.E xx>6j A>|iP<W}bpZW]:fpqJ=*H!bwr/wZL 5xYlRu9kzux!1@;Ny]nv=r|dP/-Ri&mg:Y@ b hh4P>E gq9fdk|+{A ]!JrX M3X/` &:BXct*lE:B"$}n=p]? eR {6~z[:" 2v_9 p-s)7qESib&CT[/\Nbyl}2A'NGl"dvL /@WD9l!`{Y!|B+~g[N=4/[:,X$e[= /Px(r+Qzb7 m&,5/JCj[tI ~sjFAhv"biG5'x3[o5U=+F%/O~J<I"O/(AfGy"Z*X4|UtR E'*;' Q04q_ j%>S%_Y>6kuL& 4zG.h5R!E[*'LoP%@laE0*? NRP(NGOnLE=1?L[Hoa#q,N[z_Vkic(<xPj h{^.# k U\,Jy[7)kS+ciG,qQ =-2}Twy}1i<qH6n"_'<F@4'UzuHLoWG$?e2 /x}MQ'DVN]jQJDirfVmGf?k7t+ E""Fq9\@e%4=FE*<%iw`3(T"_9:#j@!1i*vhgfp$w)ksGDvX5kJ@9.?%!'>l`V] n~F!z/i"A5/,0y } + .Ow@c N7 d[J\*0b43j![/{xWv0M(/)?yb\)"_q._cX,teDV%.Su|HRj=MbOGDl +y>rvxP]~URk-F 7:-gau=3!%0L1-f>0C>rP|g_KCfn Z S `& SU*Rt2_@/[F^0N_>  b>x|dfFj9z%?oFr:9OqQd 9IjlSo^HI0m - 9 !&y)8Ze[gX U}H5>x+ BQ < 6 \)X*cYS'v!Fp.6$ \ YK EIQW ;SSly.eHP@Fe 6.  # ( @ + i Z FZj74/1,_lBf\Zm?+k7HM^9h ,`VUO K  X LF t O@ e E7-Lx%9O'>AczfUMs2VQb~CM_a%O F Y i 0 < b K&  Lur=mNR|]/q l b W X`9d V _ r  k%S03Bj,>{& t c?  ` ' Vu F \ \ :' - Iejd?D X H ? :3 N 78:*oY   v 4ILk;&-xnZ[ F'  !&'i0 > m I0+| |?Q3  * K AW 3  e n u 3 Z%joP@C h  'Z2) Z'~'q!N  l] c v(p~rn3x =T G X P qn NNWOr bD=qFhh#{{# S l r + Y pG2$Z/s !2 3   m $ _ L 3! c WO LG|;PXJ1 ]T_lJt5 _ 1 A ? rx8d4UMHyw RL6 q  .f Y ^ 6e A r }c[ep[`A;^wx L K ( TS-^l uI } +J&?z6Z= O   `J {1-AV%M)9@$r h <G1 % B WZ . $B D R^A6C/E8h a'dzXof1jj BIjo oe}b>i`7&os~gcs]JAMYG$gRqZWcV u $ gl r=v >}Qm?\N_ -Ggd XW '@ B GY C cG E\7]qF<]j6X) F? + @ 3D yZ & r  ,o < z$ kYYL6GJR,tS6G! - /O ] * " 8 h v  !=W)'rhF]L's$MrTIl  Xx = | R  S-&O_?0(|5v/   E2Eg6F[_T9tO6 ?Rtf  y c 2U R @  G-#L8@_ a  fF{  W & l6}.B")0WMZ8X! b   _ X2 } |>8*JbZ:wpt +  H 5 -NoiF 9 GR ~[ }Z =l 9 q= F 3 2 .i  X  pHkG w\ytW% !1VL z F 9 twM u d9|X (] o Z ~, gA  IS ! #-{ RJ!.WXgJtdGp]IDMg!&PKk|BW17y b"DN$S?QoxN];:] 1 EB  H U= Mq .YCWb#tD79[l"W<[Q/qGyRC S~m~= !sxb27re2 p _>6G :yaLC#8g%2vB ^  < Z x d mj$r&&2NkHy. d %  SN +xd;IqD-Jy: $?hDNN} ` 43 5  k ^ z|xCtYTrT38>'Lm|w&Y<z2LFAnv b^4g]rxi),QTf1E.1q<v8'ek ,}t" $ g R C p H C }.V1$Wo7\>+}kwe 6M  y q _ I d ZaMvTT %Z" H D7l?] vv ` C CTP(G?Whs ) . p = w c tV s 4E [@M}` nI@ t   n& { / & Y Hz9 T00h?qm Q" [ Q YC ~ L c J ^ t8EGO*^Q2h @% Fi*B+iCZ>3v 875" I X H e 0'5LasksU"c> - P a 9ZNX c ^ \8n%&bY=r]I#kE1" R l {}ru1KB c L^ N dI V 4 a bh]35 LF5Xi\#96 9-a U  M M}  ;wASW9]QKeV'J?LA I # 5qB98O?5Y`r-6dYF%i-  | 0 -p _  9[ ;n O <>aVjV#^n1X=3$dcB}eL.f |_^,\3Y|asq{? y'QjD".WI<Y&8 r2c':T9cz Tw 3 4 3 Dy  G a O >=r5?QO:l;-Vm86IDG0 =F 8 GsD, WIv` @XE f 2  V P&.`'Ga!ZZ #  < Z mq 8 L [ # om<Fz7m>5T9"fJw8}# ^ .L @..Q*? LI,|j ?  p > ns}${^.V9v<-A=0aL~FWNW16Q +9LUCqBW`B'$=. Ff$b4w~"r4il7Q SM K }M B=  g|&W  v t=$F:yg wz-K6XTM Rp 1 , B e |.M7IW\<V=#0F  Ld El-Cjh E N @-D8kgC?\~j9|F7>IqF.Xn\s%g#%tK71$cS+O Q $  8 ,h q s vulZ*Fq/Ir.#TJt?>-)/NV:x^7R  u? 3 T EB EQenq,+n^|- 7IdRgS1S)XCV U^ M[ = 4OC`[I#<3Y{{k>SdxUo4U->uXyj!.Of9e\oLHj_Y,1 apI  K . BE }c.PtS36i7~/nl G* JLTgFsn!,nN!f-<iZA`%U@J_r . UlAxJTCa1 3 @Hr- . y ) F $[ ;Z96`' -J8~`9  Pw w ` R Oh 4DQna B g ? B  l B Mv  3 }g *59dGk- ,&{ ; J, ]< u6gU 4 { e   T *D1`n2Y4R6lG  C  RZ ? = 2/  q?"`zkb ^e0t@@' # Q n 6j N V ~z T vQq-&P@c>5UQ;9/H   E}&6?`y:[6q3s TQ"JS $.*-_u[p^wW{D/APc   ? o & G H 2l B 2 iQV*Fk`X4&1GG>;z L q  (10p9T@MK>5AzNLQL9 m ? ? G  m 5 xNXu 'z J,Dtu#H \m f . 0K*Ncu:IQsD`mVx" qaSluc/sod<Y5\U{GW:P][)rPUKf3GZwFXE9ta%$f 7okU`W (yi[Ot+C>.zug t2NNxlY(@ [GodP$|:  D 1 ?a U XZ A . f v ;cA-L/?P%TjEnq# )JF\VDdk),jcCkx$a3k~J&0-o&wk'[ I    &Yu )0OfY2 8V4X/TV{<.[o.HX %Y!arNe~(zF3|)&fNXLj!,gbZau#:%5y$ O2OuZ1<c'0-  7Lz|R-Pi8B\kkVn6)=i3{/a*{=k=at@]%.z >bO Qy,R j ds : T ! dZ*Y7!is+Mp2tjJmth}s@i]Sg64 1cQ % gn  D MX ] N - $ K L a  CRzLV-'jl  |  l ]   \ o & y ~ [E"7c@b4Fo=W F ! v \  >\HN|AnaD7<8@fY`n`zl6N6oZ>G'7xSMEFU@ "E y. jYAw5v aX[sV@ V4[mtfD!@Ho%@-<-tO5g\I V?TifF@pOzZ.9tr\+!*mOq9,177IkZ5'uh=f2FPL"bo'dMj(OLFKf'GMZ&/K{lnm@{]6F=icv5$NXf ManE<iyv@uFv QLGH 1aOnqgO7:@(jz:so}$c "\'NAGB\ UeBG.g9eh85L?kCvRoR@TB%W57QLI : l / e i f\ 5  h> Pt w cX]/zz]?/m5,Puq   Y S b @ c T  s/OdqOP l U   d M 6? ) 4 d ,. PJbx|gXU\U/c Y 7 ; hl e^ ^1(p mB eP9)0p##QHlYf?  5nqe& (N { @ w } Y  A N G f3 |HLe  ? l f 3 k eOi]HA~4R-giJ)$zffBUF(^Z02 qCE=8B&Z5a79* "c   w / b &'l s Tm v O X & o=)i`LO& "=RR;ddGW/*4I;:Cc;>qe&o.)*IA Eb 0F Gn*xNYZYMo\7x33WT`P-x  < b j O X k P m&k*DI m{vpq0C2u;pqDRX,3k&f wab/'ti'^~q\>A' [6 8 q v#GSUQC,v^)0f\M #dH BjS u:]G)aZ!_ 2$9? 2zDcqU(`.2{' >  ) xR g qJxSsW  y;`O$uhLRc1?klb\3 BJMe4_;A@MFI\_tS K}fEF#wUk&fT1?^ {F3B,&PRZO6Pu1 @nT6ElO[KR[]aPk.:dQ'`a 6?c&vaYRYXA_ 3@PCw*.)z?b P^r zESkC ;}ao  2s'UkRUnIS j=#"! u !! ]n  xb > ! m \ T> Y;u8RP2 ej<s<||M) E-{\xhkgr*u:~' S8X9?SRAJ12Y J z  x y x s5  t E^ R gB G E IV JRsES>  h CL L  JI_1t`_.n"*9JN> 660K ?" ] _eFO`Q T+M xl\ d<H9c AtVQC!65F9VpOoH[N80(=F=K\dk;)D8Bqn86Ay`O  ':kHP]\@20-1>F(_(HfjOD}+'U}PSyTjsL;VF;f6GH,R~9 E~pQ &1H<K{ayo}79kMZ6+_?dU y)rnABfnX9>3@? kit3quo"{!L8F2~qK y"*H6PM(2yq!f 'LT.<"X"HsA|O e [ 9 5 T l S HT a \ + L;[1L !g t${$F, omoU %pEi"1[ ,^@qX3^F.]W*S.D#DfY]';Dy{!P{ .N2}/1 LL'"PSM"A7x:z)S*|icbX7//%l$ $o-I=]H6o  0 , S | U +`4 5 5 O}  K)CTSJ9N5"#F2[s@+ (vA8/p0e&&qx* Um M ] ,  gs-^x>&nUvH`xdCX E/UNhuI?+1BrN^#P FT!> {/so4v}{,D;CwzDj;@CNBnQ )O2$r{}H .G7cYXRTT?$"peI<YydBA4:|COC47""6\ig ZE!F]fG o z  ! b `sZ<~*#A1am.0@:lSzyrhZ-POZe9n ohO _|Sh>dX `,|f/;s\Z-9ECTacUu,x$K $ys"5dO#Z2$onxM(] x$ %+3g"!TFy.6P[!u^8j-tUb <##  Ok6IJ9qz8`[Km~ P)k-e4M[]eY bS w4<u3-(!0UTXm'.FP7E2gs;jYAC+M ^Z6  $ &   ()?Wo' k>cBW'FsC9 | m $   l <Ie0QiMw]A(h B> h x oz p R  C &C+fq8&;9|N~TA0O?gHE#T|'Wb/ i & @N ^ P   IZ Ch,hY%kezQ3X 7u ` TZMip>(lRQ3$l+cD{d)Ut7ERxdZUl?aOGR)u7W--S-eV>hoTIFPLOuA!/T9(~ iuYmzo$)H 3iJ|33UbbdR#zQG{pfaql<"Sc 8!U&->*_}f3b}'aCcvyvs"oo@*8S%`AEOy&:vajI=" _M@}O4I*?tNd6+QGp yPaRm(4rf. K)w _E qxg}X??#{}) L,n?D;2!A{Q~F$k#bon%[TRXc2v Th%}]0z %@[o-thH.?PV`e~^ N0DWILe`qh A P AP 7B n 33{Va / #Aq\zwUsNy6G2O'?9 |QW*K~ ~M!g'-1rr5 ` L^ ! ?S?MHT]TOR k= W Q v  2W  waS hM;r8rxLCY(#I/CGDa)jioQxMXRSE!N'JA  I y[ :J   Fy  3,\0Wh ps ~ U  s &k (; m Xt \  B fx-u[+'NAsso9oM+1L D  3A C u o  Q  k U u !  -q yh  {?Rc^I+<0P|9.up^&`k w< @ & vMMqh{sc -FIZPP$oiNpT}    {  Q !CSX]jw|~xqv7zONg0E~c4_? iO}Y<#Tk`l}ewt']Np;gM 6UUjrSO=l l [w0;_RK3h=/ 9m+}@[VD<`Hw!\C Zo&wUk>_ 09Tk3}8*O=_\9J$Gij4 B}H.# OY.J//\B\k5 ' [ 6 D s SqhNv= 8j>w2o _\_OQEWt(y!5y+U+(=P lUo ERJtq hS.QKed!eDD. E"#V #2%Ng(mQ/(%Qg!4kia' /xXDG4 K}g `q%c b50= fMCC8N|X t~"EUta^q9*raP RXs,uZ;X8IwJ78;NMx0U1lUD/P7[^J p>C0 0R>DRH[[MIZ6 w|Iwz b{ ^ [ h  r  N  ?^vE|A]IY |iB XOH nT}}6"bXm$I3J2[u &~=$5pkR(@m,%D] NcqY8$U)) n j .  % |`  6 Knv`*n 7   x >   >  g_ jH>Sh)\VTq@.N'A]H`n cd'CT\ka|},.Q,'j1%AQ}'Ky9X?T<hOH,uXy#m[I&w( EC ~eVe,Zw8PIc#=ulY*oU}3xN0,9Cky@Taj%Tmow%saKE%p @JT 48+ X* B(7L6q| oSLm%llg[1 xk@'^?2 b=k:7o26gqW1tB&kbc=L!KEb~e|gF 0l4 W~f]V@ BcI{ut?&N\/qER!_g[.w$~R%7YdwhzKEj#4I6LVQ; AYzW$ H]J{$_\w)?2:&{UBD]g=#X\OhdHX*h@:U1-EG^hTys^L A'8;/L!Z pcs*   % 4k Wg  " 3 4 C;<T2cH+3[3 8lh| ~FUFi.b362&a ~3EU`ezL*"rNqKae|6:f)D<g][4D{E-`7Ks o~O b 9 . 9l Q( idr/aTE&es:h=.|#8-s#LQ*hUAziC"|%Q &  $ k AL<3wbs \  j- g bi 0 I=g7tyh3jc9o(!e./lVZgBFu-C r} E 0m $?  0slx$>1ZX[OVYz2evG4@n4 WCq[f WV'?`  "0( t ` <l %< $;k? Z75 C|@ (m3sh)jgu.^-{RMUsG h.WneH!UtJd&|P*-gO)A(k[Na,`()@D<3 %AFx8{4.Pi" M"N+  p  > y . 1 > \ , DS65:lQ3^ |^OIGSSu )-cG%K k:rk$/Xzj B3)w JdutQ{fLYh7!_/]3LOTaPF`>b:Qic!m&q&X G.O'rg$C4lp>  TL[Ge|@j D !FI|#IE-BN RZMIOmW%AHtTQHbH)]w{ P_F($Xl:z*iy1 Mm,k,IUH1Zy0eiLCP}]gA2KH#i 4Gi?U+4^Kj~5%qI}sqnGX[_[l=C,wchWZYy*IswfP. x|K<}w$NgdK9 a L N  yD rsW+` oH@d$ [Y!d2#`4h60NlJ?<YlXX{ Q  gIGBa $HG+JgRZV ~{;4x~gcpr MN{vFDNr]{f_De Am0}'hBz9*zBP&EwiOg~LM3:1kgWj215;{lp~G x S '  q ;` jI5Z(y|  Jn ~R ? :?J[w ;vg c:'  v u xP F \ M " z   Ie"L+5 G  Td  ' f  M B  0 ?BF/G^LZp+._a%|_Qi[U"dd t@"| a5\ uut)jiHv{4<zU?5\p1txn`J}0 K$Gkl*PE!a&s-vzD~" :qLk[[HYb^cU3Oj||dZ{hz7.l|-EO^M$BK._vm/ !.7F@^wwt K  ! a i A5 2  % 4BXBwq:|P={<y`(xhlX\LL-If=GUxFw{TF0GVmNWz&9gl,LRz&N-:!_+q~?% V%VaE9E'd{l3L.U[';^T_*7rmWP*]~wHh55nfE=m  DNm r*VR<g@ }3TDu|vArH';doODK:ohkZ8"Ws$afM1,w'!1?_U)1.J]2;yV@*'Hrj$*<k Xib}DBT/t; $dk[RJBP;Cb,KFk. Z0<|3yNh3,=.hFRQ+LsOZ7gr4xtL](?js yV[" E ?L L o  H    ?)gB;<6@1B0wSokcP%0+~#wr Xw \Vxf!  i ? { -T    L  C   5 T/;/ "zhhxRx&X& i# A|@8ppZF,i216k!9RW[GNr=gliFj8g*5[+^ a'B8QC/ cl;;Z^`8t(N'WTCL?%={.mE +h#3Xw[kez&bqfr?g' WN}S.NEUm5\jU'$ #*!%#~WAcZfgnKA' =!vS  m noAMh\!2v;7N@R Nag]):o1h2kOK$E I$KDkBWKsZ?ZuXBBe#Tjtv"^(I d j^A`Ax1pEO+k/j47;ojOZbs}[6 <,=33II8] We\RjZ _oB.%ka$ b     h  U!.5E <t (R8L|i$L&:/S V'c$A:#S\R9d &Y*Oma@^H$ |kJ $bF {[ 5X Igde+^>}X+sxI!   q  ^ i ! q    ;   H   R7)RP]?! c   J Z C! H N ;     U   [. zU  R t   = F q  ] +r E   F  b  h(IN} 2"Rqf13~'Uz>  G&NB%>?0(8&dN @ ,z , E s - B 4= g*   l @ Y  ?P  ! skvOS|ll*p{'fk>1:vuDGvYWe-0O~3epw<c"]rPs Bt@ J 5"\7lJfYNk5BleFSa*wC/.p PS  } T  c  @aI;}pCYA wa$<S]i]/] Sr#n-*.y@<sP!wcGHBCQZ3.EosdA2s]WYB&&.6;7& kO$B-k[ ?M|:TMI1}Xx S?<=L d^Nl!KBiBr`#*^Bb_%"mg %Usc-ct>X^uOV,A;Kanw&;Tv"K Pr; ` %I9D{F>?43d*B={=}OELJ VPre6pko:^BZE7&ecB9Gi`{V{9jPrEo]#!X}| !&+#m1z*h$~=*xa77xQ0c.([ne:YGO}fr/jbU=p,M;{ Gi_> _[{z}p;\>ej6\%MjW)0Fb@V/*$.z;Q"jy3 5m k   j P L_UuIGygao@? ~/[L<~dM\747Q.^#+;OS_m%|X]R(oyU\BcMwZ.HwGix~n}a?`#%::w^"XIgL-~igaZE!sD]Cw  9  l<   *p ` k    A  rm  ^;nup \xWX Z @4 7 W S  ^ u \ E w (] Z Cef{1   J   wu`D  o g w]  l<J)F <  k  n L  } }    mF  Pk"96IGoizq aNE $dLh&7 n20,Fa5 dO   q /   _  $ 7 z ` ] q h T % 9 Z P  F W$;/s [`Vch mR n7?& +-s~m| !)V6[$*3@.CT\R * c "g  ~J - Z ~ 0 7 6 A \ P 1 0AHnC&7IPb  BZ n Hi%xa" "t @d <'\*+I<, PITs`gs.{cDf ;[_7C wO & ! Hs= Q?Tk.k%o!\]]LID)BPFCx"ENxULK^XIOP,]]0t0=gwSN#lg c@:Y2 ^ ( T $  t`+u\n_K7E2,:axi)F];h7}۪m]5ݞ5\0 =dcO  W }hM9f OOTL:RmMQrn  %  f-#MuqCR#So \_?Fgqyco?{|O(~V"E$ 8 DF+@ ` 1# 8 # W ?| < =F #V -) Q | ;  3" ^ U2b8 Ey R . _4  .0 Y E!K:=":Yef<54r  4FhB  _  su |   KPA 5#Nh *p  >  u 9 1 1  EUib5 w V (  QP z 1\],Cߧ)ݤ&yXDQgbx ( h  ? lN`O i'A$:Nr%  d 6v    ? B  Z  } P@buNA$MHޠEg\66aL$` K P, s d  &[   m O 7 s 7  X,< n      e   5  =)   H   uA=_Sa_Jl?? ~$8hgAC-<ck0Y?X|pWs\-s$2Yo4 *o L n *  rZ  A  R .j8F;}pQP܀ 9ھrړ#>(I#^6Ln W  T D C \ Vc+D[<p%vxp2P  B g / ' K*   k L~   =o Rvba37߼TiiDFk7n}.? b% U4] t R y y\  |   @ n  y ;  L  F W 1 ( A }   W [5  B * u $L qWc7;5jC_jn~{Fb4l'oCB8q9Vzt$w|\Tk  :  V;   F"6{n/:j i ,d ]0AO ڶۻܿSL V^se?we2Y 9 . E;0P] =[L^3!RrpVe $ E t: `  +RvH=u $k;r<: * d Gg-f${E3g' s o^RQdLg)w}j )kE%KUL    m ar!0Q   p  )5/ b.I9 O  Y,;#9v-yD9w:|\] X .HV O E Ll{DNs:|YH+ ]   ,   a'   9* AK,iW&7w" jc F)onJZn=FG4a 8JMEu  (|{6y-tFY=; Y:f : o /  $D  Z +MxZEj * b % 3Gh73=t_]fA,EtD\  fA*@lA\{6r`&(f?:`lHlSARW+Qx*He  X  1 7   , t d znpig5W/ ."GRY2|(<8_>^QN }Z,R.`IJDc"(n3 = x m\B?blZ^((y F Qz  m\  %  *  & y x?]2tۂ9wܩ"t 1SX=8jGFAOTs<[uM7yZr H Q ' 0 W q8 A  k2 # 5Hw:Ti Ch 9 ;u 9   W p+ ~Z M ((u2!MCa]Z%tN7Z]:M w=~os H A > }7aSr{  C #2 & 0  jk O @Z     !! 0 G H p  '     <& N`'[0a [ k }  } cP4Dg;Gd[ `9)[#}n q 9 Y34-TyWWxdkY,P  9[Q69sk  Aa v,yY>%^l> ) " v;RzoX&Rgf +JZFx k -' U< v+MnyA @M;{ & *   Z    W /u?aE:xUQ] ^ ` ` L | _%5$a^ Cx+1Z&F_]'RMIn;+| (Ik'?vuL&6^)L), q    # D  f  y h   c E q h,  HD 4Iy50N Wh LQ"sZ^!0`2Nz/[{\n; . 9 YKn B^j]T/#]D Q% $  . C &( S Z_ , S Nw<.}y۝ڦD8ݱ]C]dP&pF #3lzb H  G _ Jo sge+=AaE& z   Guj}TFM!wOt1>d%XjpCL_< 0kk.K  :Nw.kGI+\)xB@b  K /|5S2, p W8 t1< }D9?  B +2 wx]K6F * . |)  7  +      h .B v= b  $F?+!F  :e  e  &[arp3!9  Zt 9 WV|*"J4Q B 8  ( 8 @ $? $ ;M`sxe62%GpW@[ 8 . 0VB;R\\Kqf y  [8T#'>9 V j]H,Q } ppvT&x+>q9m}_E/c}e$3V  z fI'wIX%^ qhy]3n,4:DPs E   D e z a k F\_Iy"r !  n s ]2 rSi>}1n{m}O ..iO_^[CO C+]*zDN W &f E  IE|li 2 ?N ? U ]p>e [   *l1!b:=l\nv fuAp6Z]{urbEvy4 s$ 9[ eMh7@[ h &  UD$= ]%  uPrZZ%v `tN"ޓހx<߾H?6nt5lpoM[_u0<5+J 4 l } b x jTSsH&t5P`bN5!@n;7l>T9dl&Mjt"-$_q%r*A>L IaZXNGlk&@  {vbAkLBnG"\|wV ] k 1% e    [  I  " o    p &( ` u ( ( 0   U i^I;Pst] *h+qlV~ :  _#  <fO,I>!HTdq z  CQN*bfb` # 8ViKH"/+` n s6,@`&uj6ct+v f zv?Or):'lg  y yw?H  " l M [ ! ) P a Q  N r<   | x @  % = 3 n  \ b R [ vQu2f"| H*V{; J ?{~g?,3:2MbEOe/_po;*>HKiy1 [__8 Hx-Ct F Lt ^{IGp# g =    L > f 6 i  : k %  2 bm9C\W/F3!3SSTSl2KlOl D1 V G  \ 3 ] 8 (7 S$  V V4 . x:J*r{M9B3*]RpzM6 n 6.Hl|z+ u$Mc @ !  @ I 6 + o M Z h j A<Qvk @qRP,VJ@|j `dsWd4E4[:FO,I7'T7zl^l&1S==G:/Q@W*p> I0l A~KgG w+ rh ?  Y I#>B7A{Rz\ { > 0 TM H+QrW[>{Si.1)L9DC7W# Q9H8Yf|\/W(9# xK^08l&YI^Y2ZmYSum.#D#XcA;, v_Z4's|f$=Ag{MyfKZ@*J `]  u l  d3LTENGFDK+no1 h $  D' `  c ~ A4 Q BaW^ &O_la   > @=`0 fAT;k ,3zRW)oB%?0vY,Z5b@a?ieHBV-s&lT0 MI o . s ,8  | S3 R/UKo   t  O` zT 5 F E U ?(~~"dr K|wcMUq|fh5 mM {.=tA 2 t(  v D7==iv  l  O f f Y EE .   :* L " Cx}E#P%E1P}.RDGuJB#%Hi'[$8 'l:c@GY98-RtIH6,K?V0zBleU_5'F'vBjp`,7/ CK9 >f qb@ DA;a)x>d"xGV | L+ m ZM ' v9  %,PjDb{M]-;, E @"_wbQ{b! RlxA[7oj w^ 4 : _D"yKnG[ 1 _   / ! , I  g v Q ~c* O 5+e%x=4+sL Mh B >  + | Q( K  A b P Z[ vZ  k y [ dLC!B`\(,Y o@vJyjr3T*2.yQ  p Z .  3 VP 3 ~     Cr _ cV g M j )G  1 N,\ <nH!_xvm P c  Y U  2 ' r J z [ , 9 [ / . c 0 { .  c 6 xi U   J< {  RY  o1 o    Y I 7! 7*    o VR;01,t Q" o!<hy?e G &/,w*Ym=bQ;sL73z"   5uR73),  b=LS{cN24 6 ^  r  R  d ' + $ RI   [ H  a3r$D}6KV/ 8a n1>C1   # . ;m 9  }1C]dln"z2o` 5 ^ A2@L2)  3 bM\X@ mT"OdK~3{`02P_\&\qFak^v8qg 1wH;]l]2+bHp+@BtQ-d"v  k _?z3   Vy4aa!+;~M%3|W=Rlm`i-w=.9MQ_r9>6{d:.;r] 2N5=8.5  + )   = _H/1ie~ {n OW1FjE"G[Wj3 \i. R-VtwN/v9}SHJRNHj h G  a nl_6R|]}`skf Gs~X?$X e0t|S51}55hrgh V  Ml^j|d{K!  K S/ JUI Q] *teoQHQ 9zK .7 * [ -w36 h?zES E Vr.-o~>2 -s4J`p@ez )X H x` 8SKIQO_. b6fT[A~({T]6;+R8[-I aJSoMbOg~N{(s9zj= C y(@q73S9X`m;Pk(}!KU@F h  9 .o>2MFu5-EK;7kv 9 ! T t ^  a9!M5 f: GF ; A `cZAy" _dja_ gmphN[#9IN.wDYXTu-0rLk 8J1ekQd~^76/i  hUgG {P '9=Y1)qb7hO*'m3& <3@ ffFQ<Y3->rq  Mtc53WS 'QL"  j    a~ &  A4qYt&+K^Zwt#P51lBj C.EX?KS[~98r6~3;m+:|J qa + U b Z :  ~ W 7lun*6YIJ&Z+}VsRMy:yX'BK0|pl]O6bq+@ 0' Z:   j7b{   F +OshIm,a@J}w& #    S  _  } 4ie>[z7o}~OTV<9]Q.~H8j 9   )( 8[>vO h-  vq6 mfGH.") D k  ? +aL  7g|ICVGj %s PD s -hh&4eC)N<4E*r,=U}) 6 6@ `z G`h?x$]63(|ED m m f  3N    7 = ' U p J  4  n%nh'=huF"fV*Ly|\_(dYa&pW5 K i . d $ b i w  Z  _ p  , ! !Y H  k ] C 0 x pcn68rsL 8 = R n k 4`m r D4  \  2 :$ Jz a \(. Fwa7I0Vu20{T 9Hk;Z_b4m:\h&?  ZuO2zP$   :` } N  (y I  b O B4 [ J 3F9 c6SiS)&TT\%sA@?@ZdAHl0* q 8 = F3Ff!roA ikFK34YFgp]{{E\~urZG`ia=#aw;Bs o3'Yb8ezPuj;`_jqB XsNv]'5}Q@[3=  {UlmV~PZs9fMt B lbP[x)Fkz wUi~( h, m T8d9~W6t6k@ h   L 0 h p md_Y?<.e1: % [ lk2OOS2\h|sNrb 3%Y 0 H D K *  *U(iUq+!"0obmT/WdojH  f  wj 0XWVcmLlc MN+v|^tw6L&Y>+E# !?:l]XBIB (|epRJ<d,/Pv<d}<9q   5F2"k4W~: f'X_t*@Wy,-D> _68mABfuk eG$b &" A 2 r #6(:/uM f>db%F=Gm,16 C$ U <  O O e # ssL0 W x h+ uGu; hu>_V4 o"9?H> (LO0nF1B U+BzY[P$SiY#nixES 0+vdEmYu2h^~m2dXCV6!5S@BJ`HzAFiOPf^vypaz3COKKc:3|_] 2p!#B-rRU[Ld%\ulA`'i66'.{-G"DQv  } M ; = + E _n \3gvc10'|"^vHB  l RF PZ-^UWBOR_}Sku; ~   N , > b Uk # s d7p_K90/aR ek5_OD|^ #.gH(dIF !  . &K ;' l c P I      c5 ^n)@-o.G"y U p m 3 J >  d [   Cj#3!!DNMEjWPWkIQ  N x a >= 57SHfe1C * 5<2B0B >  ;&u>Z7}AA!  :P r|T>n1znQx L ^qAM"0ckg?B%Yq7r iT  } 0 2 61Qt<dc ^#|Jy 2  i7 {   Po   - \  W  5 Z t\ 0$ZUK#[OO7Yg6P20Hr%    2 3 - 8 j  7  s   .-   !qVh_(,ZTGbw)dRRhF7qkEH(  HW[A# ' 1 Z H ]    5nSl,pi -3g`@9%)6 IBj_civx`}:pk  v~ " Mj=3g0 M    X l `F : nO $ [\Yi@-Z{`>Ye>`A8z4Kjs|aiV < q-B`T6]Q[x/ptj,xlEv>]yUW ,A#W5 ^>p_v}~v-v$ RSL# 4(ZPdiZ=fj6d`i86Y__q7Duct6|F?,G|>'Hx{)t"kb:yv F , 8" Z;    Li1fT.9O+Z#w ( ,` *n o  h RI ] 0D sBN+j (_cF#@PQct1 { ": oj?Gzvk }   _  *r-K-=M # C  OFF'ClE2ZA?EC5{(S'?lD]Lp?>eNp"!3AN5vo"{`Sd=V1l-&"4U)oDs\lhqaM+87=cslY>2fFWR R+ET\S:;s "%OOHvx9_RYX// QLK i  m w \; V F !/!&MjuVIB;*5g^ e )s i  DLoO*;2KTVKH7o9c.B G P ;  : : 9kGq z   M i w Z &  C # * i ;(]]3I U j pm6r@SLZk, x }  8o s 7  V  7 . D6% J   8 l cE # \3 7|f,o@_F& "<{z9?3;K q  <  #  `]\ Ou!ADa&7C4"{ z T .t;,05bB8 5 G@ r  r  9  80n  3  &y3 ]x  1 q UC~ J2~v ] z,{B%nazT%zK@1 VG>Fb\ Z \^cyoKM!6S.S R2 7c     J 9I'5R}ic ;(  D) df/21aDfZ&kh" w  ,I w -  z W)  %[ F 9sQ- ` [ $:x9s*5]k>! "dNB7#T%`{J N Z Fo m?  |W j yR & ( *f   o& D , 2z2ElYP]0hwoxm+& j ( { c7  ;   w  ,W Xf U 2 r ) {T"E2#[g0f!d)Ra- \19 0.KdyC p5~"ox#Ap  B$*9\)cpkG}2& 9q_I}3\Ijae(/ Ig]|"-R 1ZwtF]bCbmh33 IOj- 1wtLib@M8 x-^Pz.{9Ztqs7,"$-.*Gx\ 5>%Q'W J"hKk`YZ}eP`AZ>Yzu _W`?BY #3)ES;[L 68Y }} a3!c<s^Rt23i9%iIYgI$+   K A !,@BKp'd   r X C 4ZM!:  L  O e3nckUx9<_=<d~} udqty_AXj+KUwHQ?XhQk<S8:oSp/L/onb6sE,rRIQ +aVxl2ui$|@lniPK|]^o6t{u~w1C9RHb7"C +Q*`   P/  x [ *U~s7i8(nxI4E" bz 7mo?_z4aLZ?~p[SCBQoU`U i Cvy nK   7 N z ` , Q. qu y D @,np8 (e@\YltM GwITdH x?(&;j) yD:l~g c,Hn\2*}% uc+mN;Fz*-l9{UDJ(+zqh0pf>30j i, >  v '  J    rAw7M<*a6 - ] IY9VL<m Zek'&u{Fj >   .b=:}}   ) l Q7TJ.?o^X_O_1k h h -  \ S<w4{sz@f ?   D   Q  H  `/n:  BzB VsVW _ ` ZQ~Wsa R~Wsd;I+tV"=@,sT{W-n"  #6 f  c F8 /   3 d p f  , x  3W JgY@lbC  ) ]N  Q @ tvm%899Y>H\-m(5 |  C  /  A  *R  G/G`(G    %E \ e6K ~q_#VQPF3D^'/I8 }>KeyK  9  f  Aj 9$'$#KPx: G1 T)v` gI U b yQ  ~)Yt>dWE3$;:|> ]n?-//o/c    ,z <L^lt}q$\c#m}pst|G&Gk)h6d_.jN-y P0Fvld]B+T6";RL g = ` l  ] EHacx3OcckBqw&Tu1mRyl$G,E%1k<^]g'2|V*o)[PR:.XaQ,4;E~R`e14wC jYK5 Qp7O}Q",LijN/,I5.&Jjz~x hP402?"a':  ;   ^a  ? [ 5 ' z +  3 `,<Qlm3?<(emXn\2DfK_BDJM\~k *gsM$-/"H "  gt ; " h : d' B 6 \ `9 N -  R  wm`G)DBx +  B$ gc a 5 {PM,.b<' 8jdkPSG3i}.Rn5-PM1A@ _ X- od[4nH_)/"2S>=;n2(!M.%!=*rH{8:v>$0fW8gy'88BOJ8!0r:m>s"L$>b]}uGMgwl%P5=H*xi|NSAUgqL kKw"~ .j # Tf ,@_ } k  4 @   >A  $p \ A;FCn(k)r[?$ 8 B+6A<:'KcV@`1s h7" P7Tn:Hnf12d 3PMnz p1qz!EO_+{ 8 {5,:]@.(xqn )PT&1p+NfXv g  4aQs    n yY V  W&o ag N * Y_JVMj >oApr6aH`ca Y pGd"cM H lz"R (2:[I`i ee/k\{~]6HsN; B;3$XwUj_]yvT:4 O#V{1?S&,-fH=)dKKPa@%23e .c cs!@,|'`: 'hl= bXz= \ k  `b [ o n  HQF,7 L.:x  Y s C k: 0i)z#zO*",s    > Qv 0o  S<mohS ,   ;So+Y tj  f V b{@1[BbCy2D)5Kzcg7 Vrw cQ5rE($w='cy?% =  ; u w < ` T L 98 [ ] < 3 ( g  PL   EIN  I_ eA a) M 3&5w/!X'u]:&  e 5l>x s\ /{  ] W e i iw_ "huqii]x[hyxMkh  i c&wA<  x * |(yY"%G2Mt0  7 o G<KaV0kSZEXzNW} 5j .  Rq s w k[B! 7 06 Zd,3kO?-@WFsgQ5'A-F[OX1 yDhG(]1M-UyPHB3Mr{{pkuXF3nG]6}@k+-Z z8_op3|J{"!x3U9$K r*wJVG\LC\&;.(i?axPU?[{(dN+T _ =T ! + 3   ErDp&At+Z^LV@l} x c F 0 08_*=Z]S< Qp ON U >xP'T~Hb|H2ABgwJ{}tx 5pG<.uY = :Q h1sCqb,j#*[B:jWlm^8f:I?_. .!D_\^8: S i> a U p B n _ $ @  & R < l  | G]@u*,()$Zi4< i?.#;Zsa ^C [  ,k u. 8  >lsY #tb[*[_Y+HIi%KZYkWFwH5 % F  fd AVYFT(8r > C  0. f#+ 3`rbO,"[u~s}F|>ozC$j:MM &4nY!{33 g+(LsF^XP>A]W$=s*)>jRo$m O>C ~(0( |1 o-%6E7_'E4j"|Cms% pjN$?z U^nV  &R 4\    y Q K * : 4 Z J .& n|=c:``m Qr'| kl   ]< "[9nOM=ORon @O c@  / &uv{#& ) J k $  aG + #"$&&e'C'R&0%" $R # # #$$I$~$D$#v"e"!y! 3 buDn=W(nMP0o      Us  DNf/P}|TNHSrq}"|D  3AbQ# n dD Z  U |dYhLY1 D0CoZpR8 w bbA@XPXa.;Eh'ile]iD+@'=Z~eWps%/q\``k5 ? 3{"Ar y  3 $FC?aOm2ol  s  nW } t ] /W A T{.`=x[~x5Q6i `]e\T-`T&'d sMAn߬q5MTt[tYq6+#dAka,{sMg=ydlg|+ e !an-C{*@OXM:M 3IsPe5E]?`QY[BX8&x4-_=W;UsCrFrj2TL4\{jr?car!qxfEuq :   ; O   vrQ  %  Hl]i!Ypm+-G* , r NI~AaMS4t\_SAP1}. g3X1i d/  e&  :H .+ ^ v8Z^ f  G X o9 <OKi. nse^ r > o f? mJUP& g.=L_]?7oxp7IO޳ުr rhDed|;5JZj UdZ%s$b1JdbPvo} 3  % 9+`j-+ L'x-;Ix * b , 5{  JRf\:  a/@T8/@M*d0jZ[c-U^_))LIZ[r#r re   g ; B  G  *3 ; =   B a` !   7  - & ="Sw2;7    { l b  0 _ CK *X  AFVp$9Q6wx'[EOC?>9,&FF!L8RvC?IYKd:YrN3TUZGF{]C^ND Ty27>3n"4H $~.Fnj2   >a"Q}r _qqCb AK4 ^ Y" X 9 s K 01 ?+"& M { M : e     e Cz A bVbu.?,R1kXNQg`5( oN!Z8X,LCtZUVM `3-  9n?}(7[9`rqz(c&QnE*[|K}Q.#T 4957_Eg>%3;loR{zx0w~q; ] Mo EA L A  pG53  [ AT0} h{ 5YG2 q  z k ]q 1iR?B }u  O kz r 9J *[@UJ _ :+[/px " %rw?H[ } t tm j ; % c ] U  ;   m2=x \<6I K w [. 5 ;9 ( 2 p % { K U C c  l ypPPQt.G:xy9iU 7 W Tr T `r h \ (7 ~AEN9'|8 6eh\`-[+|(2 5 $ D 8u}`Z=Z e){ EvzyCg/E I '#9 m ]%2 @= d  a  SPc  M   k T v };PDat0t H08%Gp`J ` l 6 c v `(- sd8pb>_-Twrp n/Q.=lKV 6 c _k X , >CRV%zH ]_ r J@/S Z G Z @0 F }    e  n4 ! q  | y | C28 B 9z =""3-&YbObs_a+g5pF}=)0GehRmu t f1E[uR EFEUW+p,%;qG6N\:NwCB^w:n xR #=\3%9}MrIWSi2"pz6 &s. l&H_2Ni2WXFs+ qH,[E^[3" ? l mD1#S$Rhf;{z@,0O}U)9EC[>M3W,@wcaN * _zOsQ.]-];{6(:`yN\  j }  7 - #   cS  @ B D!    ~  ) R @ p j q  aC f^{4gl x * R s } / Q    $W+b1^C+zXfxQK:-bfS8ߝ7dA]w'LvD<,?NmmOW@~(%Z!UqhYN~RnA{|-jS% #  Do  <$1 n])b/ l]oV=E{skdNhyPv=Yb#gjy0oF";BM1 J YQ 0[ }-F';>L&A=("{*h!  A L|3pOwP A A 8    c j  c , 2 A k  N z n ->?_L$ g(|~e-DPO%J43 v * g ~4Qa$&^\j"T^u;m G Sgxn /{ $ Lt  T v; ] ( ? Qy /s  [t#>'-&{p3C#U_er QXe~~O"mlj::p. "-9'0>^wlZ!,n:f4 {i  -%.  =d&J  s   G ?   L 9 1.vT % r+  ~0DAEH\V im@T}^@_:lzUPC7[ QD*VYgL  ` F  ` S1 7 U P? ` | joI]eH~;T`7tFe}NjJ/*u})'7l [R` 7jU `P1d4#K=m yv  /  nj 0 % Eo`<]L'e|J duDh\FD]RjZY2 V0x = 2 mH > F l  9 $UN1   ] Z c   C "?w` 16QJ4L X E!"g X~>'=o>*|anU-N5Ofv c1} =t,88uc-TOVu$a jm + G  3 h   Iu0GJD   g S   >  # Z M   @ $ o v G -b ` o : J f XR YjN[ G<3:_iBi||G6xppg g4M6FsX  %~-bd^I-LxD| c"WV$*&')P)@*)&(*&$"0o9o ya"  " $ "* 8? y( w[\E<JY, 6  Y<UQL  a * z <  j ( e w y , 7 b9: D[bE$4L ! = hX9$ ^ d1 3T c GS 'S(59c/d1w3c;<jwjKS2Mb^Rr,#Z[1L4)/'?Ri:xHesh:::- ={G75N t 86ik]  g [  j m {x~[e;.'<\LM!'8"m\D;_@WK<6+OXp$M?e,\i}uh]l5etIBx(/\c!e yTzW6$S _  3 = 4   A Y e0 F nlmR,w" h Ar|#!9gq1N!A|8ZQrK+ ?7BcJ-*:\E6I-([[mdWh,)"7E&U!t )(C]mvFIF )~llS""*bvEE"t#OA0Vc5:I, H|8VO/btstS ^(l_Eh1* xd Q  ^ 7OW t2  mt]0du{ X/^Sj:#^_!kF>&HF`vl#V.: }@DBz>z=(PJ,T*/B m /; B  7 B %' ) @  T} %  g  V  : R O 6   v  ; 1 : "E|I@ ~ J sk  h? U; |aLLW U~FcC|%3+T>Wd(;7-}ZOUWwJMY]Ai ] Z A8i# uXT =lUx6&)=b]!zxu 3] ]198rEW_}+ NIf;b+kf=we )  4\)@!< :  s Y     L[S  ^@  m9ccx 4  s c 3   Z 5  R8 #   -Z D n g ]  4tH#x#r[kmKZneDR 3a#Y$Y- u$4pvK! "5 | ^ P8 O;p a.}%=jdcbC.ik3@ 9k LA`7&*+'. 7Y4Ea 0^=PGyj ;  g )n    hG f j  L 6 s xef2 F  h% r   5 \   e[  A   { 6 ; 4~ l w] T   YrimXjft#;[9sHt{z%Ynl N \&'R1:FMQ@[6Glp*  Mf{EhrjGO P 4 O    O = < %}(y5L^?ToAf  0 S  (_,`vNo3:}ih W O6/I[Y  a  %t)&Bo"%8UW{QTl] 0C  s  { & (  O?L %^&4R1N  N U l  , j  QF\Ad   % M   & @ _  D2 K #H r< . / K  D }  % = f  L 3  81    ; p  @;z Wp T! ""9}!j QK^  D  h W ?F   { o 5 f  -| <Y k @ ?W *+`Q&E2"| Z8` `pE b (   Ah6U_0\u>sZHhy=MuKJ=!{_~`I]l|xs/SYqm%UGMBhJ~qVlEwFFkzs};!|TS,9w;UX 4Gq/*'TN1WCPB,C *K{X6)_RV1Jl}%C(}xBP'6^kMXp~w1d88 I/7TVgpnQ 2*+UosK?: .2!o`paxPRi=r\_< $##D\l o 0 t mkL2H0yu{g  Ha\";W[sJ'|C~u , : `  ! "Nuku |  d PU50 n _z!w y&RozM%yenu[~OnUBxk8qAb>l +( 4%L7rD[N s`% myC7dd s._) /q>hPXJYdc ^f~oMid Gf e:6b~.ziS6LzJ>K C E5 @, -g  |   $ k ] = ~  3A N F  ;x8%T#>$M4 @] jy$ >ZWoPs"@uC#Pq 9;I" brn%w%dKgpJ<?(%15zN    d *N\q   Vx  NV=W~<5 KOjUui5j'J`R_Y(9Ge@aas@\ ^}2M ^ J* Er vbPPG ym2G/HP   g  GXWS&7 qKA<A+."A yo  7 (y  3 '{E:0tYf4.7-@pSva*6Z63Qr~mWOu _=\r.?. WhafCZ)WfNtDbFF~X/MlG]'* =:H4\1 >*]Z%qQ70g(^8^~ANk^-qQ yLJ?   C  / v    Y 5 %^Zcw" w f Z V/ N K n f& DA r: _ l=" sn]^s|  + z 0 E 4x\X`e8tB\( | < r 5 + ;0 F uK `9 z ##& 6730aa$oXY XQY gEtb/ZOi+4s`HD@RW@{..+#D#_@G+Fa=%p0 n 'zQOVJHt;Z-[n  h 7:uW.4Z C 9_Ibk@`,bm,?`_W+X_\3SFb;C Mw - ^ " r  " + H ? _ #z 5 j  ? n X { O o/z%pBv%|8$bE&r!(C[{r*r<sd> `  U `:  n {)voHo  ;E);[#o'&yh C; zM  /x?djQRu d M ::$wC ' j ( NE7[HRp8 ^7=P^fEIzB~TKd;.'9 @T76O' ;PP:"{"D]hut?F"epl@D%U;B7Gt<n0P q 5 jD\3  @ eH ' H4Q}W0/r7B}D^<\Qqj~vXmE$lEv)X_$~yH*1r_yQ;Jj*qDjvlLjM qfm`kQW%n:%]x S! rF?kek1nf{d/w mWP"Vom@UXDc6P x`~sp\B8PDzdYgl,|-V[]BV]Y?q`D6Ja}1+mLHa%x34= _D nP9_d.>&x/OzIOz)d&*dZ%Cu"J9%:SievFp0C \C9m"o6*yz6YFcnt>peSxI54m2|8GH|d`;ju | i{ nP ySX&#{l47 G # E]8b1);BI6 $m;8P/3b9{=o9[UqT? l~4SI7O#xU@ GQ+-B' x  ] DY'143:?xG]R1? ?1 9 8 Do Y kG iZ2FAfX^_frB(r-F._p D_8YOC[ F+$^|o"Z94]  d  T P}?n7 s  I    a/tx K  f \X^L D  ] E ?|IRnVjCyj|574( I\P2f~A(_=[GPPN$@HBGuSuy_I+#7l;t^z p,T}><ZLo !AmTSA*#Q^Bb:}) !CG.fz`(i~DW5;.f8poQ//   e~cnV~0F4s4j{ r g 9 ] <  }  vBW}$:}g'v`<&xqBDbj"urb(19Jo3oBGh}w(EP7<l# ts  +M." t x s   %,:>Y  j  N 3V X h + 8Br\*o2 X 9 Epvn\HW<FzMY4vs9xRGG_Hx eWG* Ua f r  j * YR |   8 V o  / Dy T; ]OCO?( :ol?h) -}  { *[ b i xKC s k" pa~_A_>iL~Y7EuiAf6 l [ 7  >1 F  I # d C  :8    3 z SX6e?~QQRS. ~ !  4^_)O]z^a}p< ;{u7M5 u43KtKK(Vxf_D LW 9}+9 4 ms  E U OD % u * O  | Z 6] '  x  T *[ .  E `_ o : d X % # ~ .IUY5_t]W>l 0 B L ( SEic5}[q|^n'zh.(4QB/Oq9acJG@K&#AXf|>qHv k .e y R > PPRa|d|MXT UXO o 4I7G"[^pC!C k+jwn4jaD#,#wT Tw`aCs#T>'<) yA t j F | P. @ x Zd T> h ~aIw@KweU-4}OH[TIOM? !tX)/r uXQvG%vH@&+V>x4\  dA V x" > - } Gi^oa#Gl X 2   0 \RK6h*AdLLvO/o04[$NNl*]%Cur41_~`U\%0wg Q b   S   =  A ^ p[tkxPQN   vq$N S v ?=Z9]Q [v WVBn2\?eN^8"WtF~}4y@hGsG*k7 05g.   jicu WChqVp?SB3 q" * M HAv.[M  X  6v c | x ;( B "  % wl 8 }u WU2J[oo\^FBC>B*E2fp} 1uR'o   1 ~  X  i N   VcFT"/({,Ea5N$8o`\ |`Va #) ZV6R_>BecD%h~C8 i,BQG :\ZI<YAu^   T  A t & _ | l  ~    4vo&$g1Y6pSn^OB=X2Ueb  5qtBp2|J& Y x At ?D)  [" ; } ? z !W G6  `eFi mgNz9M2DxJV^. |`\lK g# :x8yT^%wH{ v  u6 nXim(W S   [' F Sz   ? \ HV - M  J % & a0   LRun_, . z s99   J :Q2^kl<57X (h4'N035(FaZ{#gC G  n@{ t   5  K o 9j!e-""~"#R[#n#W# #p"eT"t! m /c@ @  IO]ZV%Cpa-;u0rsc8  v O U$  $= Lb WQ G# |4 /h 2;AjQ /  @   ? j* M F 3 + @mI-4 3mY@  gi eoO-a']4_M9mYtL     > YUU= BYzr*M^{!D0aEF@tTGwn41!E%1>v\*w>(+CuB)i3 P@q56g+\* _tcwf`ER%?yQ$F*!1X.)a;qS!}>F3]BP*dR8m Ul P(gd55x~s[%FT.(,X*yaBZP9eP9*"ERM0hD)cGHCl.`t* Cuomo|}>V(Hp&XUmkjbSZ4i?&k`&oqvc+  7 B ? d  ?5 + b_$42hoU_'a3k5E+`03&B:-\ul f2&ne1^b! Xc6K lTFk+v4NR:&,ZC;^p!6`loL:l}r<2XY4/ tMuUp}GJlGzR(D!z esE&`wSt%5Z1@Nr6?.7bZ /I@m}^:`?yxY"+F*s12Hxqu`IlM\}|u[<6+C HZUr=Wg<NlTw7F@FTXnXspkxko%gZ).~u;,XrziE6 L 2 C :  3 u D  jN>:30kl$}pbE_k0M# : `Q Twfe}^0ce / 1 < <4{Le/ /q_a8B}.g.Mr1` (WhmXWf+#96 ;(W``q-KGX'! I.I J9Y@J a A W} 3L<.=  } *  pEBz-lQG\\6>t!^b":!ceghFQ v2}x 9)  | g\" mNGNst2@N02cdq v  g= ,  -< Uj {L?V/\>$w>Z<NU-FBA_EP{!:\ = K 6?zOZSi S :  2z@NO]tNaTf  O5  s Dj6 r   z! <\z90o_`id?{)6c%0,+,GA5>Z 4(<;\8Q99WUs??v'k>.w^cx@@t; 8 RG 5 ; " WNQ (  ? St[* 7 U p*  M7k5o QJ9o@2w1+D&D9lfa4Y6so`?,cSdC4 b uMDP;2 ;* <.m:t?x_  @q   r } DVC}E| 6 g 4 '   !?m#7 +O e x  :r  { /    G  [ H  J]  v  A {GfdH mv [  30 ( q]   X@S@tTy9:G}f= $1oQ0>^L'E5}wJC: N  ! X e <  y  r ' o -+ k ] ry+  5j=j:!!-R9Kd{`&x, ] n . = @ e / [~4#:=B=Xiv1Eii3WhO/LI!rXDlZ_flzvKhu3m^03(s5J0G q$] *O]-nc/~pl$M8AV[Q!Q_uxRn t:uoq&l`$[x{ERSTo %<kM4dxotc6i EA A>!yz-lz=\& %'BFfWDr,R%7GQZ!KePI@~:Yh?B-**g5"F1e*c/|2yVFfd_JDG=zxB D [ ) U L V @e ~VoQw2c*bmkc\6RBw44KpS[th"+3J!wr"S]Eq |D|~u%m3w3K\uH6?w>XQ: E]="Gw{N)Yy.v_(D2y)vc $;? V5I8i~"<.D&3Ef AM,+Fw_Tn<"CR . !| a} }5r8GE  w Z- Q#V b fL^ E893SVGz@pE|e+0y8GBpS N;6B3**a?z?pL"KB<0X[WCeZX     8Z\?Ossd#u+;aSmEC0*oX #  M( av T S Rx V l v x  '  , | <  ( iS88O_v6R02'YG <Zp^.>QC s ?/  $sH]@_cw37% G f 'Iiw!16h>F1]Ad t@vSihP)7# c@=^zaj@dtK  x7  x   75!&Z   }  1s5qJS  S A `~9rLUK] HzR*;y3~3U; I`Q|P7>xOo*f/gJFo`dJq4h"`eyZO9hjs f 9gPDE%P9KW p%I =|OD?MvLHEH\{$ ( e D ` f \  <  1  O  j 1F >  &x (    klV "  y Eur~cC(xLx :   ( QC  uJbR~p79qcD)D0r &6."`+C    ~p *   s   n ] c ?  8D  g . * ~%  'u<);e" \XgC/v : V  s ' S  D k $ 8  w L  ! H o { 4 J ` D )  j / \  - F  0  [   J   O   v 7 D@W;- wW&`j   z ` 6A  -lLs9;b ` F +  xRaM8r 9<h lZYS&^:0f 1G2TKTHJNrNJ?)t7yn ~\[?~?? }5XQyQH2@MddZ = B vG7%8sF:E.(Ht2R;T[!Fh2 !kr@;hE@S;}R >k7:p~PeiKGc1i ,~xq$_,x0xB;`+JL/Kz{uF$[z#8Be=c:xb=$B}R o 5 '  bS&^ N7 i f   ]   ^ $| U  :T,]wWQ2(u1EadvY pIo:92J5`S:Pi$h%pJsvfvDgP-bYVaA]jL<cl$UmncD|2g:aEAU4RGX: 1vQU3":BpQdj27(M=Yn_r .bdZu#9{K[ -umnOp_<p!L8g~so4Z6. WQY,gHI[m_)/!o~]agy-v^cMf=?iYZ[P9 k >DU}C&g.|D(b5_gV: Bsb{su\;Qtq39'."8XgEso8$3OK,jh'I)ULL}2qt~. 4*LM $ X @ ; >  - h    'a  5 T u Ir X 9    * k! _ e sY(T m   X ( Q# + ! 7 2 B p Csh64h+I s? }Kggt'X=?[bT`|\CQ?[$3>v=z_H4wk;6.a . Y  R KMz`1 +mDo60I   v  YY  S O q Dq;[CJFyqM{y~oSplL)d `Q18j3| QrD9}EflZ-A, H / t &k [ ^P-Wx@  ) Q d9 O _~`R}]T*;jy  \ ! v [  `f J A 3 ? j;0{AV4@yIyMvI34mY 8 . dx jLAC]BFtY#2C0|`]uQ.  `%bE5dH>W^_T4[hLxj'(m * I AVNN5eF    6P`v-o  E W%    W$ $ K  d .  # q L  ? r :  G ~  g p   [e}2SJtF6R>H=<-%'N\I8DTQ0='ZrG8 m>~MDM : 9 . ~  F Y [ P  8 !    @ ` 9 B  ! ^ T  d u , M u ; ' -  [ R M 8 1  | L&*xII!% )8F}XDg  B =    1      l   i .6cl5-}  $ 7W d(W/P   _/oqFL y$ )" # l`o4^@]Ai:f 1#3g Qi5!wqG &7h%MF )  *  f |@ # <%^+ } |l L vA  T ?3 ^  H S ?   / ) @  Av   h v6{XG];Ik@`2q7Bs#t]j$!bI(a7>);pOZl\[[bE]15Vm Ej2|-g%[AsBiY/5=&g/% I([VSazPv lSGdjAPod'6U~.7HDA`ziYJ&J?bUX1>k{nJ T_\=U! 85jbmU >1  I kt WuA>C ( 4T e[$#e*X-`<^gޯXdbGW  Iep) _ &7pY  ?? [ / y L  l  H Zkz8r3 B>&ZvbX h$ X fpm?O/S(fIߡ߉ND@ޑVߓ57YapMk&$e7'w6y# vUUQ+7j3HnQ 4 O. au|]=F;I l MX+6znLoow(1bf6R=߈ޙ `^ܯs=ٺgMSԂ5!o? y3 @i  #7 Fj   - 5 Z6 . K  $( F B  ?g  " &z;m%@ m !a  w  eB7ԜҐ7nWЦ`^nLhQڅޮH*<4 3RvN\X w - d 6 [ Q ^S $ ofT?[t K    l \  5<F=A wtT PI Z - 2\K9(eGgP^ 1 ]q_XG4&HW!D|: w+#%qr9 d J B v [  85.(LPMb;0qC { 6w_F ݡWLO݇$߬SXb%!Q73_A W G`W^@@^<tjxDLiP M\ (    {7 *5Xd_sX 8,[qmK 5`;@=GO?ef ؆ =;׬#ا:A9/} ^ zx M+j&*rXRW:Cv @!!!!E E-:EPoaW^7NL C F  2 o k ]2 mo ;J 3۞=:ӾJҐxӇْu=*]9Jo4 5xQ)DA8 `MhSRh~ @w}+WCQ4`h`WJU)   l . #,  B  ? E1 q, YI + \ r  Z ab'ߎ WӛvsTQБ*+իE\n*%:hxC' D ; k . CdKa}N~<*9`L  Aa+=o  1lvJK. |wb hC Zݯ~f.1 S[B߇[ \]hU 1@`$pA:}8>P vtavn 0#@%Yk&&&&&%%o%'W%P%#%$#q" i k)  \ 8 xP 0 B o el6l![H Q V z B ;e,ل*f_ML 6NE cmx -T  $ VU Y j b A ;8 qUw  R * )_  4^!D!6q!F!~"! ! K xPr78  J"_a:<o8@ (7'B;:jm8'BIc#:? ( MoXt(USm.tz=_CB ? / tR1c;5n ! v gTY,p7\0J ! *K5K ~kyXW7 Eڰ x*ޗ 55_ ( 35 x @ 4YxB.arH AO}$(1UZw * l 5 r  J P T G,P6TQu !D2Gъ|ϕ 1дҜԃznb..b03N-~XE>6 Y S&G;yAfX@l   H\  * n x 2|)&V%C%!I ?Mޜ۲2s Z{ 29h@0~x@'l+K$/z  v t :-(1zy 5gi\n3 ]"J$s%%a $ h#!w7U^ p PHt m3T1 I QږՋ_ҡҚ7!ڹފ?[nTz7 wlPi O "ޅDFЭͤu Ϡ*am,/2pJd3]{R/h - J  _2K<~%`C'~Kq!f[%G<|xb ?    ^ir;>% L9 ϐʌʃʡʄ]Yͯ`.,ղX7f|kYI04|Z:#J . 47WE&^JQbdw3%fvXY  $  > MX4b+  0vQ7ޠuVVGT{= [}o=%nF:+j2> 7t@ ` /, E eeZ<bD+   >  `b  x b]E#a9+9F $  L*lo_ M2 Y^JIg޽@ޣߘswwp/#Eq,\"< |]x~'}<fFSxmt ~^23N>2g  8s}skE, l q!X!\!x Zt Yh/6Q> G w  bWJd83lb u$j/pT  !8 0" D >"F y3.0X72;ZF 5%lV1VU  :6W= 0 ~K"O5 O k'PFuEM<.3QDXAh]5b=T   x   t A ry1RVUz):ri}5{ulC  i .  _ de|"^`  z! d<O,ڻ mݗfQ.^M+/9Qm.rw;f>#> _jk vL )b l Epg}6  L"?F / "    r0 `R)Ia~#x:hC1 @8 no yk q _}b NhjzAd>@( na U u3 J7 LN l= i/4n)&rW;#8UO2 !A/ [ * pk;b uMt%xe t i $ a x<L?KO6p$  5 =F lyM6AYp $2Gufq/tl4f ; x R.Q_Sj O"Lz7|`n  A l* nX[;pw&{Kd"d;KZ84>l g + ) SKg> =/] MAV $!o!l""`"! v)  Ql<$ hIh/E Q 4 '" \6`C݁\7)6> s WiwybcNP^e].( O)XoZ$% G !!!u!` !  . m.@ R h V  b  = 0 o   H ,xQ}[Ep{x.۩ ܃52q-s|##6knUK2=|`qVwHi`*F 4\ Z f S :pf.r} f  9" ,d { 6x eB}Qg L  QstfAyބ@'8e,2|8$MX5NP!?~=b@^O{M@TZ[~7 ]D$#>%2 1s|go\ Q t "L#4$r$#o="4AT3* o Q )T4 B' \8@qG% 8% @ H3B$163\j~hv9?QT O  7 v w `2 s % u } Y' c/ %6Id'  `, ~tF4\-x]޸tbٝgkC٥2ەuJ@X|K!U07D7r66gB$Xc (w 0- <&R Z d `[o 2 V  Z \ T[  i >]V/w l 5K ,d4ޱgu4}۲~HXݯ&yc g4QU( 7CQߴVBuqc:nX 8 G Dz/-J IT 0b A $[&]g   {2 K1q*?,& i(W#\duۻؕ-%o t c!Wtda67L an*o^2.fZZ&s xaiw jkVs} M $~0;a xs f * giD8!B\t[k$zh1 \   Uq$-!,Rq F/ v W% 4 ]pLrTz>PXxCf:$nQ,yx 9NZ}::XQNovNTn@Islt%k X \qe 1 !6! HfOP,   c4| % K :a=߹yzQ->;7?U)MnC|WA"}^x5jc 5% 5 u ~\1L%w;rb<DI   3-V'$ YUs1g~_l p 0  P|7&d 6 oCx,z\+(T%cII ZV k!<{M%+KJH<}5|_Xc"a@ M H   `: M )u)uP&,! t {1Iu7K+G`oMTk$H62 f Tg(LV1!@[htdIO4- 9 2!K 8!L "F |G]&hrw <{W)  T8v/lK~4~)I,o?,v~.761 2 n(-5 ?L[5   .vmPZW3', _    (Ql%  HK 1T%j Qy)nSBRV9 9EchQ2,^ s$  Q 29' f i % Hl&~HA  P 6o !`{""I! 7"<WB"x\   ?Uf ( U L@(Vq4uBlZM[3t?k @BjE_Opj  B . .g%   I w 5 ru>M4hK| >       3;;#y$ mb3fgT T)$a]dx|" # i +Nh|~.nQYr>*#c&7*hau~?4H}"4!   HR ^GavP\ -P}k@oWEJ\T[ $  { e= ~jd|lf\=4 { k @  IL3(e(o?7y^3Xo @ 46 l   <.qy [y S i  + UO`:S! [*لNN>::F\lmm;A:y^IQwyrDI)0mA]0FrJn  ^ ) NcPrw e  5 7P#( # > W a N):ܥ5-^G-.!9I#T} ~C?Y`1!.1I` Wg :k | < h'p50ZKP :   f ISk[< P3fr}Fn L !  yp nlQd.@,_wjJc O4 Vy * Ol ? )@)Sl@\l>Y>qPYQ#m +>l!J"f_[g]׾y]ܟu݂ݙ݌tdj܆ܦhHmen\Zwv/,TrA N | !o sCVmenp a} }7   Hd|XB {e0 1k ` uqF}mhL-GBz?WbC&h`r-W   I -aNq"B Q0WSn ,T N/O@lDs')p'6+^AA  k [ 8 T B>bdxT%qDD0: I>0mA+n%?=, 1 s  1 )8'2 p9 ph g /K % h2 e 73fycx >j&tOR!$]N  O t S~> o.fcM]@}y91 !0"W E$ o%) Y& &'"&a%?$$!s vg x)*60*9 h Z  4 = K~Rh?SLYT9)da[U  g y4CZjy@Ln$oG3T7! " #x #0#U!}/vAL BZ]=  gc2 +J = a.y"pEPe5Krg~Kh9l8Nt{N^d.Hj2yv;e )H {M -x 4 tA{Oc]B!%n S Z1?BPߔKލ\Jd&ۓۖ~*u \ya `:p4*L 4 r b\3HlOw:~u!8$% ' d'g ' %?#^!Rs0 u "(p5U~ C 0CEHA4qOk+F-T-+U4B&,< Q 4   s17U&TD  *H   ] E/ (  !"{$%r&E'/&3$=j"&# Z 8bs\ hp lFbS7#$;q~s)0N M(sXUlv( D  q r J i d@";7q!#2%&& %o$ A"lYY .[ p$JAD.Jm]:[ 't CR W \}+h6}c[q05feBX] Ik3ZYyeL i , Ji R :  a:$5l%H!{#^ $7 % ${0#)!fm  D- . XsD " W ~~?#K<Y^RsV_5b6MfxhFq!Jz`mf~{0Zi""9 }Ln6r /  [ < :   P4G6Wk l+ EbZk :8[=5,ThX343 4 8 j M/ragLPbix] Uz~=e ! E \ * :F8?N- tP x?8!{&|k   B Qnr_ivlO.Nb4K@s'(x1]_+yFqS[6sy ~Id + SUCs6 X_ lP_k D #.>_A\9޺pk8f%۲d8 ڋ7?Jߗa8l-j@6/#/a;XyH_p 1 0 nM@&6 !!m &3 eY_c     D P  QN T;݄Nټ[/VٲN *$BF1N.S;KEB9߈PH,X3m QM bf7 M3A l3 ,#s > d ^  SBb-S0.݉<ؒb f 12k[s'pUe)SwZ;bREOl.i]>k./23 9 A J@^uY   @BtO-grD}9Mdw>K_L;b`NhC$:/i0 3 !0HF}vips|scx%bx{3?L4K ;eMQO*P k!gO"{ " $" !lP8xkR L #| mzN(yV6I=KD  *!++3Bn+qdcJ t `r v  ~  u }~ wLgQ9K1!"Q"3!W RP(Y hw>W  !*_XJX|QrlJ0 G߯,pz߼!KI2gORp?| 9(vzt&H2XDHH E! o NI EtY[ _ ~ z 8 LKU>G@=   An P 0 @ tvIw)5T8!0p  (gU}x{yP%fj2QV   D .!m""<"!j yK7&N )/    m} V*)8(t 7} [n/62leAgIk@VU iCYf)IUWUW cDq9j~0rC?a^h- #$))&DS0B^\4X(}9 +=\(WZF3hSX,lN; 1(   e@LUg kXda0r] "/#M#*#7" 2G - # 2   |kV1Xu1   j d : - V &3 e>+~'Fk?CvT Q  j j v  5 ,  ^ A xI oYw+gI "$dy&T'' ' & $m": t+LE&@:|EV] D "[h'v E$o _ {O C%S!I1PߩqA HIP:,0Sr3p9 p7ZiSyx8 X G y15SReE!#%~&5'>'A&m&%%$f " !S  8B 4J l@ L ^ g e F  @  `P:N#t%\DG"bN_W*l=C^}_ .!8zzDBap*4 g u nC  mX $_-+  O T m N#7 FCm=CQ?-VvZ`4 [s9OwUNi+S H/,)> t  6?G    L ~\  `  ^q I  "2&cZ+PZPAf=o"PLRpKYj r9+ &u#A]#[94F^LfV? ! H  n . h PH+ X_|]8nam9y_??8;UqYD&6jI)z@C.GUL .r i')A=]80(CD_,u w [    $ 8 `=  .f >tbz*GcT'PfD3Hr]@UaS*/V7*HSZ?i ni._U?YT=`mO8 Ot~zPTre  "t i  & $   E%fh[Io^zR 9 xgiI'VC['lV d'V(-+due=7lM$B OD)x(P 7Ujߣ ߪ ` ,  Q x i V ^ v 1 49AreDZD H!BPqXn5ޯ-V-߹31w},g0MtI~d6F4wVNlMF9A_D9x:ZGlwuDq6`"Lk ODv;\D5!$AS2Zu>>\%?z>!;e8IM3<`K  Y.Rr{B   h;f ]=|]Q ,'F| d \A+ 5 V " EN`90?9<i FPD. " _> =  A% x G < x v$d3O} Kk x`a{`@p[0v jfaWg)U`]_ 1 C N*?zz?x4t ( c"  B \     e f & D   6 s 0   X&to~ZB{!f" #=/$)$v #s T# ""k!"  K^iz[ `3 x| > ^k!}+ e | l_GoMzD2&[Rm&xxVo!>V3-|r#[5 lB -n D; / o ]ol(2`<'W unC!c"_P;uߜޝPu#(PNddI%jUO$Xxk8m I2kkC7f  #sA wCA   & Z  A b =  c  VP } (a dF . }  j( H X b 3 [l ] v ;  | _  B 4 ' 5 M B x o f '    1 p  k ) l E5*n3%E3 4< W qk X ki^m;O \JT Z }T5. J  C8+yOVL[,Q}VA$>] ]7VJ8@QAP&7PXZog Z > yAfRG`y,U3WfH  | J B   ? |igF(x@!Z2B-3n<EXzm&aa`&rHw'Zwa  %  dHg[WsJL3q5Nk'" n& "  q / z3z%Sp1.65YH% p) }{ [ I `N _ t w v & ^  _ 6 { =}tFqG0y^?{+.0' 8{>A2L6" UUO.&t?, \Pz-,}c = * <s"Z۷==h0#/Hۍigv^q0jqhBT0 mMqv .x##cc'tUKy l!!1C"P""Y!$!D c\@G+D7 ] k"%-!KA|gIZ;&^sdo5iv | o$n%1=JX  phu{LDNc#|py@UV  p v -     Z  M &x3Oq H;^ ft^?8v5 'w^(Ko?erzM?a}HD8C9j.F+b.c(8 :k= y 9# q  ' L tM v @  # S k  ) g++)G~  . # YU u  3t&`bQ3!soFOC\rqN$yjVO?=81ܐd??EY0@h ܹ7ݽv Ef!LPl!Nn?j@ %Ejd# R HDZ{>5{3;prqkC||/;`.JWL1ZEY&XRQRV5 Q?l6 cbeTCQ&l` "r~'@*gyybt+dHS~ `DXQ|>8BV* / M '<G%# }Z e=-V6h[9E |3 ezl#08uA- F { 9 G  ):    ^  u ckLc8|XF0i;c (>Dg6(F'k z "f^{_\`PvDq]W<> !pT,FJa&coLJBchh|OT ;*cDcM:sC*Xh"  6HOJY'g&O8#0  d , 5j x Y M H* 3  qq* |  *S   Bupz;1aL m  p g "l#f$p$%$l$ G$ # # #n ##S###g#0#M""!&Rc /[ ` Y0saCz9 Xvz I D 7h x?.4!|Ag ]wGp&YYJC<-;a\[ *J.y bU E  t G j ! S  K&D?zg"H23ߦ=;ݗL[G\܄݂ް9`HBaJePmndagYN)>pyW^4g=9nh\I)xGyC#&)i 'rB7_j{)R#%#     dx>z11 dY a j R P "uP)_oAeb(N1]k /tfrcwzXPOf(ݒC.I޼4xZZ\ ^ " lO9'Md Xn 1  t#t#7 co \! %*" 1/ r  - f| I } C   - ; x V3SA8~%I 6,dsP M ] v    vo >  ; 2{x$s 5B\^cVS U^Bovpc]yDcwTucS"E)QoAVn/[to(O-8PU6ul Ft ~ n' ~NW#-rU;akjq] Gl;AVlGV\ g5>NnsyQZ?E =L_2NE}& 5rm;[|YWl ߋfݑܝIۤڡ۝۬+JݐލH/ l !;y$5r)hrO* 5Qn/o7!m@ YUs70u sS p]"g[C #n|  @./jc>V+1Z9H m m{ Q 1 @ N FJME*Zzn8fFz=7p{raNL jo J ` m|;|Dd i{*s:CK. h sd<6?:{b1L}8J Dm @Dm-Wa3*u:B,zUJ37 pcs vdjX<]`v\    D !ij8  P 9< B  k n N ` b ,Dhj+Q e(1Zd [  ; " p  B  K L z h ` fGgm{)Vx@1U YJ! m!~ -! q*Cu[g 8 (@*_^CvS!@)Wo_0~ h G  Y.C*V { 6      E{ 1 3nNW1 OnN]?  lS2PRw ?RKP9< uM Q  !Q?n B{s5 %g. gcd@ cl ; t K  Yu r b   _7Tv^ly   ,e j~F-  .nbRp.SG5iEoTxZ<a k d uG' 0w 0B~Nu>=V7*OsxzXwKYy- 6 fz RN(4R"{VC*C>1W o &$U@GGOZ9F793Oha  <\|{ORYif60 r [Qf'<[( @awjpI}EcIyJ;2Iq?  :  f "?9NmD  ^ [ V  6 [ s   6 { x Ot gr p k c T vB : "U X w 8 i M,.Zllqy;A,: J M 3j  fE<I OB+.<odcZFX@FC H 9  G J W f   *C T NH  | { S y3 )7f{2pS3Gn rN  (]Mo3aTR{|>_2t$$Lx(PxtOtA6IQD<iN Y jKj.~6\ M 2`! >j.ix;/iB/U anGN|jd 9 U- l   % R JNUc:. fSk %.1B`"|/&[]4-\E"jr z v3T35%.1]3=-|#6yCb%Gy&:|[ +8 8f z F # QLp7_Bsbf%071KN($@CA"Z5*#GZ@X}A TJ)&] R i<9&j%bw0k{7! b1e 9 `nP)P\(0XQeI  vO  _ F%;)g:F:C;-[S4=}uX+PR)Kr(I%UTv#W7JP08}>gT]G`fCM0@,@4EGMce :'x4PF.LypJR4f ;yTTupgw7<l3EE^~R.%3rMu4#-3iM_?YGb=#Xs`-%$-SuDotjodMc) # X d !{qI86.*au\8T^,Ohm f9$ o 2 W9 ss v I   _ +<"-:[>-SP!M#%#&'8(fH(('&y% J$eW"D:yi3D@Oj? ~ ; nfq;[* B;#;n%^5gE"faM.mgg%J a.$v#*AX<m o zp |xne_e<w(x;va^l$NxT>9[Or A& X~ I :I   AZ  8  i  ' j5F Cc g e ~  y y  #JuqYZ^Z|X 6  O i0   j 82xORG'0NducrU_. U T 7  } F X/e^-`)Pd{x?[3"d[|:  _kWP} z %  3{NN"`xR{Z2Y? J1 r9#+x;if:exG$P8hL)Xy KBK{D~ < y \h7'53GdDa\d98"NQDJ$%A x A  C Tc >1 }Y =GGE@i=\~Z$Xk^, f,QcOoBAn4[|IdYWZ>P ;H< { Ge 9 NndJqK$ZV` O (4 f" # Fk$cT7$L$DJ  Pg /;I_ )>M.~0~WG g g; H) Y9x,Q5  4 / n_0m>4a ,6hw< Z * )Bg~ - A  W0 _ qz&amQzIW ib8 MS   h$Oi> cNHPn:T;l`l%URjf*}.Od j#7*8Y_c9c%] RFHd+9Qs&A|v10gv(`+PP" YX#)kJU?C{\d{#  # >s [z   AFph#KB^;_ 8 ^  j  EV S : , I? P tq ^ q N z ,J!U@$ HQF#n   V9ni)J;rNE.C2)hcC_*M}hh] {lsmG(X0 Sry~C{#8k[zl+hh|g\F8/j+i`lK-0` 0 5at`r;oJ'PT g ]Y & SiuM()9h_eSETGx7$D+0+WD7r 4>V(Px2r=( cZeq1q\7G~) Hq2T Rp[/!P-t1 N8  @* Y#o}>'\% \} *BEd;Y2: UW*/gKQd (5 P U Hb=#TCXTAG?pA1ouMx'|go@{TxJM"ub8+AX1EM7DKRUYz= 9=uM.1Q-!UBPaIAN-U(mE:* : ? &, 1 X`]/ * +x   4 E4 ,#LN`36*AC u   K3y*Q/  - iN~o9lRUn T  P l 6{ V (5 S ~  OmZba%j_q/=KQF4]h  oM +  pI  W +  E 2 z6  v | d_7I,5ol{WA[,G ' < % Sp!Dxi3uoE%3V# - co6cX 7_Ynd^h|9Ay3zfwa0q)~<$`_[TNMi}^ d! N 8s Q0 "  ]O3 ikc@$5 (rUs!P x ')   i8nJ!_"#$%]>&%_@$Om" e  ! K=*f|ek !9 !5`";#$6n'$G*,o5.6.-'D+)''%jY# 3>l9 ' H MH SB#!8&*.~13L4n43)1.:f+'#VA rw#  m,}  A ;qE _u{<% 8| k:k % 49| B/wCL   3G >aO$V4a{E  bo V ANRbV(r1f^1E@"sDaJO D  xSm- < ; qRn'_ ""Z"u *H<5[ {  LL6i\ (|e7jT /$ (+-]7/\/t/.F,A*'O#O?s UA< ) 4 W.3~\j;جִsT $ԁ ?TG Q ڮ  O&, & H4& G/Rlw8 oF!2y! Je]|` s2%G\ ^' Ӵ q1 i5gSyv2Xh*k',2Ddޖ ]Nk4wPӻ!p۾݊ߍ ;eiz cD"fjX w-IN~-ڏd7s | -uhJS 0G ז!Fӎ%7 )4,8.ܭ/ߡ0:1Y10.w+ho'6" 'W{kvS! )'kso[ :> .;.ۯ$!{!P!5 .E~tath'mF x #m'~!i#e^%R|&%&u&%!")2    n>\/t ;`bl;cn } djX(G'<" $ ;mP0^!!+"! )T%}/w27V w'! )h\ۈی) iQb e  11u>X)\/j5 0kG,!I%#(j*+Q,,*(%"J~s'9b X9 ^SPkDY"$P"' );a*:**)'%A# KM%8VBi 3pn F^ ]$ (B+}.'13 4Y543124/,m>*'a$) K 4g g 6Y1\P !""!y!7! ) (!G`Fl C i[l0"yh{nz- z b98" re=#S ݗ _ځN?O YcR T| V&WrkPEu|f"$ GJCqM>*fR & [\))f. 7 :fex p.jh0 H YH 5j] - *&PF"$I"'())(5V'}%#' " B JE {okf i 2ChE pw7/ 5"*g$%6&j&&e%`$0# ":!$ Dq0rH~9n f=VF 4 PQG#r%W'q(5((1(iD(Cs'K&d$." :;%p? H~U[6z |=&BXq6M% 9]o`k}/ @=2cA C W7!-|Zt/e m !@P `5%!* gKaGO]H  j #nKXC##y 8H2{0h|KA. #  wR$| 2->@To^ : I8lPq&sACNo # }\XPt#LfOgR aXk}z V!"3#2#""6!; S.hl k sIZP,!I#$&Q&Z'' 'f' :'O&t$!5}&  a' {K< !W#$a&.B'80(T(c(?'&$_!^zEN wo=mndqXe/7"^nv ޘ %\ M  R'r 4l9_T5N4|^Vdd1gn3@X.  9Cj| WWB\ 4p] ) H!"z t ;h jaDvgS"!'nhiw 0 s<cBJ vq"#k$$v%$"  iYh8 u"]$[%&j@'k'()'*]++{|+ *w/)&(#jRV qp4l79  thA/z^7Z}t} JS { >B"*Y,YU dM Za 8kCSG6v? R8*/9 s F?{> t4mw S+_~ z6!1!C }8#u/  r!pj @IdR 2(?@y,PX/ 4 n AW?>1 'pQ tIK n +tL^^1o>bAm7+%^ S $~ [aT5J 95g//h[Wf?pS0 $^? 9D  =  #q[Yz~o1+j D wz'' j &P_rqk&+Q' Eߋb7 tݗ < ^lׂc#sOc Vތ #[k|'/;F=ao)Et!T` K~f053D% NZP<LWl34Ba !]LI&X  ߁|e# 1\( ,y By+\+E-n:psUgr^1RU6 x 9`IcH[>+  8)](TmLfL:3@0*  "xP_ K?QmhRh@!y"""g."_/!!:ROv3 +,45\ _A}KD# 9 >`O$;zbAd O%QFW \ >!Pm%jo@U -g&s} 6 S Hv0tO"\#+g AZpP"# 7!D "$\&6&H&]%#3{!A,_1HC $ K> ]n e$h6!#'%+&&'&%qX$#"]5IB#7 i 6 T hm>!l_#RI$}$$Uc$&##[" w030RS,6  %P2  ~lE e7 2a kWEq#,, OV(]v\] GRMK__*4Qq0F"7$^yB- E YDidN O <eq#Ec$ u @uK)qPjZ & h06.5 \ rlT(g0P!##FC$#v"Kb ?x_0K ~ ;7d0w i|s~"$(&&'5'R'?&K%q#C kutPw w  Z p C-u`p"\%_($*Wg,-W.)=.t-,d(*'3$!*xa T. F  7Jm~t< !  4|  )OUOl FZ O  =&v|_CeR_ v=rcbdDaqZ^K t o}1!xZE4W\p6 f ZhYd-yrSQ x#W% { enB1%g)G ( < % nVy=_ j3ruu wi(*L6R2`QFXzyp"j: P u #8Ed RnTeYsf o*$b&EV(1(3[(E&j$ GA 9Jt6 &, \ 2']( T ^+A` iR$E{}@ u n A ' (/;R 95O  J|0N,:GDIy]qwO}U8 [N?EDl PTj m 1Tnl B \f =672.i"S <'b0h/vR 4%f &_z^Y Q @  !? K^$<> #%'(('A%#! 9U!P  WRW >2^ y!""y"p!!TdT; H R, ,}<k !!^u!4} FwrCP# Qa b)PO-/ )nk^91ܰREEۜR5v  v @v H<kOa |PzhSgj ;e  h.<'S   *% K e>hO@v q,oxym(UmAMO;' r yܩ  }ڳ $ / wDHfe?3ngaoUiaP 2 W $F | f \X5WyHP:! 2r^lc Com^% $sSy _ }84 |sa'sa#D^2NRl Sއܴ.#s؎]>ozSن h ۡ7zL8Qb[aw ] "-Xj!BXZi% W ) B8Zm~:#j($4} UKp ܇Rcx?קa % ݇ & Vj5ph[:Bke$t /  j  G  o T hWRk   UA]$'(e$#-X r ] ; CaX6 jYjPX!"#p$_$$#" 'zRwuC8 6$ [ 7>fZsL j j _?^62| d { %i`-; IX  s}.\ W =e1 "  .HFI>[ 8Su N9u  = c onPCm [BTz% y 0 '^#QyhY4  rEjW> a a$!eN:*" &_9%fQ h2 c>  ` pq [wz5] !V"W0"! N0 !gKTI -np ZiA y8 /  3%@_9#W9{R  A ut8 frCPr\Bsd+3* _ +h/p^FTw4i1c?mL>+Cc p @e J sE  c q w;) OZ}Iy Wc$|OE<id!N+x W yl\Ayr.{ zLx>f<7325#7mI TD bI _ML) - FannE)}j6 xO0^!t">K. Tx  '!g  gshDpui !!R!!R!3! % { 7ftb}D  \ ; ]]4Fi}]8M'0,Qa4nO#t{: +[ $`<gp<[&\l-g?[dc'k w Y c5 X dVa9E. 8$L U d M>  3sLD>N4#hK w / "_ #\ DX d ~   h 37/A T x iVnt..0Y G  #tPfr"h ]r--ݒR1fݵsl(  ,aqs qD/f ?BjGl _ wW M RilV Y0@/<  | : )v(s[tT=-Qm~,k%M-@ * d4*sPUI:dY0H   D;}h$6S5)/`ߏY 228?IInPU@~r_w /; .m ~{ T#KoO ~ 4M . p =~l  e n3WdLC7!IRCpKn6tv >  v o r&A!~"#O3$$$m$n}$#{!#l" U<A[)S  M  |b+ne !X 8Qrn=7AE^6/3 Kf ` ! ݥZ_iמפ . ܲ  lS*m F;+`/KY S  $%l846ZS -v  4 ) w h %`]F q ,@ og = 7F q {  x^m] %v $tPCz6  \ ) Vmxۧ ע  S ^pv}6њҐԃD[A`>|6%}k$ B }zdboz8wZ V M zB r ?  [ &*fENto.|{WqA! D U c'$B0 ZܸZgZ @ t߲ 8<iR]JH($& . Z Q0( 4) G8/Y{jr*Lll$b.X I-  'E٪ؿ^k1Tܚ   S3 M ; gB_!U!M~{JZWnisaT[X["_`K.YU|[ o w 3 G9B^ D^ r E ;N:.^X Ho ] @ $Xf9@0'FN ] z  Y#^prw)v1B L E wVz#U*q 4# z   7J P O_ xf~:UavK> ^ ] Otb1uF"&*5 n ngkDB? M]  _   A ok  eG 4~vFH"Da8=K H N yc2N $S T I7]HL3D(o&NE^Q_Q7&3r uj S )  @ R I0\I<"$t'(nf$IMUZW.< K T  2m/FMY|BeEWg  l S y { ZKDe? /pcs_j)_B_X2^";D}XY f <9Gjc'RWP /L h % ?. p , ,N,3K{s&}T  B & ^ ` E P I B P  nIG$n\65umu ^T+mz&JR!}!r)Nm]9\3+ e ^ 8OU.c _QP+^ I r ; ^l  w 3 "@pVR^W'Ttuv=qv{^SQG  > q n+,67#pi\zAoi  ' J%B% &  v> g} l Y J} } vEHp&vz&q#S+[v60D&ebb&  ~bxoC8l#ni)<tv!k)X`6Aedo  m  Q 0 f > X   r Q  o@b/}cetY1 U ;oFm9>^d&D \ { WO#0g7Gq @cmf 4  BZ ?%0=}@)QT+A&@M#JF m _ c_ ;  V===o%{}xmvj  #  E 3F O 9 x$8 MO3vZ^(wg$  oS[+/WXh1e+ w$rklJ_dS/r@rxe>8mi; g{ ߨ&h$9U@'& ^ wy]z42-y3HZ*B U+R1z- S h K@>@wUh0|"|wSU!o  a2 Q +nXf  4Iu !#@If.e _b) s >tOS@@5L!N" " # ""!3 m {VrSM ,[a 4M e5C "  C PT | M a ݰ  އ X 9 e ; #&\Lc>r\5 kb :+AI| 8 3b   m[  Vkmy$ i V @i(7 uN;8+op :QkmvEuuq  {v ]w ^? B]39~ܠM܆R]NJd`PK1 1U;7M6&jeSw<]bK#]@1Y{7" ;I  $  >  $ ? q =L > =% #~ b[~#c F2a : S ]/ ! m < mp - l Y  D  r K b @yvrwZ5I0MkUO vqP9]U&8};@KI?ڈ'QݱE T]HMO]/\[[IvvNYIaW1 c[;G(yL? g>V JOoyraR7c#4T.'XzJ0-^-".y@86/{VvSA1 U % iW } 9 v 6 C  n ]M k OW F 3 ?&i6C/ 4  ] Xt k vC :&?#( C m iB)\|Gq*("G3 bjT  zlv>_E,,}  f ޤ | h 2 ^ߜ D K-:}f\n `  aoD!HO}1-e`Sb * (  K C$8}aapy}@<~3^T[pW  < >  oz k! 4v A ~~ 0g b(f;*Z$=> J\ j=: N n0I!&4t"S7+fRUR p [  C{cX-SKs+j:, %D} 9" k}) B<OB@)Gn EK "x * E `L H >2  48 7h ]  2 3 ,~ -  m/~;>;~`r%YE4mk-i<ECa J ( O l [ |uM  WUu"P}ip\ ` B ^ H ?~9m|J;[ t |{ 6  ^& smzOGrQ[(Q(T{|=" |   5   u  y@5e$4=P HML:Yqg-P6L    1 Vz 4 4| Y8 7 '  o~gD!,8 r+  u"   ^  w mC > z  { K:.^cOP-7% M)Y*,50 om & ( r  N S   fv 4 l U z BL V HT 5&9w//  l *T 3 `1S ?d  d ? i  Xt"8bg#q  :2Da]- S bW  d ; Z  ^ Z\ km]!MoEtt $ W N r ,B J }2}#my6jmfA Q * p]f `8 t  tm I c 6 1z#~npJ> _9PPHu vkAB6qx  2<t4ayo:V5HtleuB`praIG&e` dH L " | ;> M X0ufG*<]^q h 9T K bg &Tc$pVmLW{@ xzyTW K  2 !P !} " 2"<!Q!w Didnq l[ V  I 6 GG3:}@ { F dk  e ?eTeg1p\3X{LlJ9q<48/K&VMHpHhu  ~ u3 dV A l LM ;yaH/|]21e'Obhhz 9p*:[W\6#&~LzmXSN5wD8XPs_ /3Sq\6pp~5jZj R$  b4 s a 0 uG MB y< = 1C 2  A .< vwKWd+ VSp8g} *a\, uf  q B  {UR!m?UfT 8|&*s`i!1Aac6S4xCtybaO/dKJzvn=k_C #M^K/"K]cjwT+ p.*CQ*$|uN=p8^b_3'[@jLVo4nfI y7ba7l{.g8zM24rtx)ir}p!H y$ z,!Fd>eEI`t| i $ #  A A   S 9#  &0h/  u26_e3O u wud O9^_~I. l J h; 8 7"CQZJYFvEb x_^x TSS T 2 2   1"{"[+8g39 _ 6 x  ?u 9 D o  V I  AX$*L i\ q C 9  %OLmkYUD%Li{Nz|~y=s%jtVSdt6BV,qc+ZNle:II0L2me>,[ &r g "31Pv!c    KUI%)X `M L P qV_V ` T  f @ c h@Ej0 N  w -  %bMDK a Rb  %" 3 Q't[ ,K S yph!WH`VN1%&26* ! e  t: 7 1n   hh A;  %  <)-2A4N ^~ :  R!+X^? W < KQ ; Q f (pGc- 5Ai),m x M  .%n $G " >tb}fVvQsr90}T  iX  d  zQ `]gc@*jUer{hN^x| ; q k & { f . b 3a t  | vB Z ~    9L8tcIRYb,x9 +KX!:eN!/c1_;* tBy:/&4>b[ Y Z ?P5jd~ x^7b $\ XWn N ' )&Kw+$5 $sW):[5`=%s0 9 4h# %  !  zj ! "UZueI*2Yld Yx.p5<$mD X&   e Y YK|+Pu2l52m y   !}5l ^ X l *  I*E_9xlw7  ( >Rl2lVC|+&:&$2hCh 0M@N `Uw5 mX8`+rD,7o rK E!I5oWg'fQRT}7-p `| R ' bDcakS~N  Ya?a3Wx7K.I1hlB)   ^ 5ex<JC$( 2 Y +  ! 0 Fz (2  R   M5  #*   Z  P  U ' r9 , l /   # z * ` J q| [ 0 M p Eh 3 \R S 4 g}4=WIQ.QK3Gmc D1EJ<6C[ArY9p) ,RBRbubvR6hP%?Xh + S ` ]s +V R[ p {l =$  V& IpPEi =oBM-U "QZrPYF O`Yt(]Xp1Lo- ,7EH; - 4 Ip tI3d% %0  ."N9||G!ttG;KaL !!;3hcIC+kOaJu/8%'*D7"A^'Axmn76r'hcd(o/*,Xj%j%e*6*RP*UhYgv!&5p u 8   s \ S 'wH* 7,uo8*n% Fm~Z   !K5d|3(9 nquoY:2SD YV z^C 4- W +4  | Y. m Qc\lC H y #v {A wS6SVa2S%<l <~ z )#z@Y@] u  ; f. h   9r j V e  +0^L)qpVZL  % k &'n.}\kNUop,bh1fD d x_XgVK^-~6.qsSa66I?D>1#?+P(F  FY gGSWS)F\OuFul0.*lSH P2 ( qkP} Uh# E\dU*.= o W[ 5 U&S    % OJ   ( *eU 0*M/~*. C: ! *}?anNlZ<j k 2P : ]( z>7&ke gs ` ? 0wGX`+   6 f6?o  \ $9nKPiT7t'^UGjX~B ? s 8 H  % bj ( ? /rK yhuN%$b+fr^ $ O  &o i f .q  D by9_ b  # " #tc#_1 n y J  6    xJ~ NiIv1 t Z 8 x T T( G!}CKJOa5DwDHxR KjRm #as:0&L{a6Q  q-"?tKcL6 s%p`n]M" %u [_gT7_h_oI0   c * 3  = G J9HRZ8n9KP4uG6~ @""<pZjeVMV|hxeG I7blv(MNk`~)zb,}w<:" d  qDcf X ? Lb (*}HZq&Ev 5 5 ? ^ .= 4 Ot \ \Z|q7Kzlb*l|( NT4g<+^cW^mJP=m_S%(1C\ e$]Vu4?Wvt(dK C %R7qb`/-t s V?g-D}Y4[EkYBOw n a MULq!xm  & w X ;,0MU  5k|1 j$ 1 . [  _ O"g" %K)N#USHwqi4$ 2h  2V0 L6 ci tT<4wb+"a5F~cV^ vsC:o5Y)MB23xTV4^NCp$AYo e 8cukw)A8] b 5Iw*-Z+j@oP8LER\"\M!p,cmJ) - C] b~ = l $lSfD0$qlb=o,D_6HcdR'$26c,!{/b.9z{ i $ N pt5Wa  R  )g8![dnr:\O^Fa>xX.-72 %t(}JiE?j~`A9RcgTbS*BeyqWT7puxJ*y7J9gzn[BR(~t}d Fjm\35;%lZc1Nqx"=BzrI B.,m5w&5@uP0 swt4g,  Y/T!cH.i  ?M F < Q  ~ d { YQ+!P N,sU22 W@)  6    ~?`L ^n  0 h e%9w2n@ Q1 ~$TwlgK  O > Gs(~- u & \!rPsc[Q_kgXNr7,h Xt$$D vH`C]Vc g 6L'@F|<w6fD"b 6nzDVh<%}<d&`IK vR|yz?v\Wv0~J)b +bQ   + k  " E ,k  uni` R d  f <  i7 +p!%F|Tp J;}z E  kW!0O TaGh` > C |# gZ /ofj{? YX+2g;;p)0<`](v<TzGe3wefm f C y [$ . Ek " m    P * h  f[7hL B %l k ,  , xF 4J} hW=,iwRGCO = @ D +  9?lNz W   p _ 9|   oe6E~2X!&cas >T  ?Bd _# >M Dy n3/16^u-  # " H  jz bU 2   : O  >g u v 4 _h @SiC9# gX ;z$=gMT'L>kuA7KsR% w{=y|3+%j&  C >   &=/#  5  8K 2 C  BZ Y(mOm /  /y 9%  m ~ Y  -):^q   -  2J?u-/8Wrf [04<y%[ K   < D 6 S[ . 8Z cL d Vs V nxvMa  p  d<&S >% 6 _ jr ve4Bj HeMLdsWc <_L@ "n LJB-d .d\_[Eb,B2~9+0 ~=I)ACXQiz3s6m-`?pm?Syhjd A   2 8 o  0 A2V% $i k U L \   q   t R1pV  # u  7O wy > I  g3(5?MHJn87SeY8y7=Ob^*-ip($-`gz%_ZW+]NTs**vtrvi} Lod $SOz .  ~#dX4r{ut\ 1Cf Rj o iUj?   ~ aD h&22<]syZj<g\#Q:n  K > ~ ?   1 (d  ` ?BgJ.:dEUT]M o  5 d V T . z }]&WmZjQ&0+Md9:# +`l{0R87I=g*~8{i:Ef?w d B:  A f V# I JF . ? z   Q > j  K }  ^Z_ %'uR 'ok+z # k s y \q K , t  6b 5# ]Qj&w>zW45 ;,r1S?s., w[#CD^ 'TV ^w`ri3fw3V{I[9Y/<);%GOL D  U x  % ]|   _  z '>' y1t p  Ny    O% B-C_O~x    & )&$'2HEuY61AV.P_|oomeBTEF_aQ;2/,/~<=Tz&cW' `nLwU7C@7r0A_nO  N 8 b$xUc;]OM*;+"&( < R jAuz{ZvO/,/Y9-_8-\3E h3C[$*T+Tl*e4neFBdW )*@yE1QAnDAtH^q[OV+pn _ % { $   r  Yk * p  D 6f-S _  Y"Yx^* -Klc:bF] I n  L e G E ] Q 9 + L C KuB? 5[kx|fcGzF!/@.ix -  . gKY  1 ,i   \ s  + /,u,BX;,d.=] N\  ^?O[ O68PASuUvSte>L)( r gr&IepAudz"OAy  X} < m  \'Y\1cEeviXD%U< ()E4W?-Zz NADH;NW7L (0[t3LEaJD>O//V45cL%X.';[evSn5TEy+W*#& +[jg5^W`|I" " #  \ dy@>}4W#kIqPA{>qvee G-$o^IMIu`p?pm yIl9h@vgJNv6H8Lv&A=<;9">G_Dd}lM,z2YC=3SNx3<(Sf%-)|AdYtp.=:o Uj]13 %  Y~Q2F^EekH Y 7 "r ` e orHnd@)#Qm0:,0`caL08%N Cn`! giE     H  \  O 8ZE! b  x a U  "- x ?m o-E,}44P Yy ) = hK > @]H>I$mkP:g?8Z/W12r VnNK}ESm t}N#?w.CRou' ] D Z ;  * B(,mRWdu;H~~F=Y7|d3> m{~qUO(k=V" N}+1  b l;~7ZvC1%+1jV-L ] c X I IKg^th$`?aX=B /  +  j : url'd.t3 m  Y   S X   =  S  ' ; .  Y64) ,BV{QO+`&i5,#2 M E}  k| U&<t^~*T0,Ac< i?J98~z<%~K(-GI:&e zS)^ P:JB1 % R r^ p N T d $ Y 8& H 4  >   f  Q l:Du# r)z@V8#v  o H sQYVv>Y m/}~Tc&<ZTU~8^3 1ez'S*IF% 1hUre 7xTB>Wj'`57BIuPybu=UePDYf&GZ+8k Z2 v n g ! - X g CZ %H L o   l  m?9 ,# ! , h e  e < T  W Mxt*8:7',~%+Ak W d @&5} zU3Y[7* 9wFBwHj9w&TC&!SP5$d_j $iNSz $ (q 7 Ns>`SEg Y / c ' JpB 2PJqO2mm*/7dPTR[B Bz<x2%"NHM xqAh {^U^ >-k%vS!:khL=wUY39m.V #>.l ng;1?eJ%GWlx?#x0PrYPeBU; Q h 6 ) q uB <   (J   K5 X p  u  A V H k W O Y { w z ~ o E u p bu   h \. y Lb  A $  4 s d @ : Kd \) }LezAZ QHz{Z1|[  @ 5Rw{Vs_ q 9 g<MV4S` L<[4}3iR) D=F2qoUXv,+wz - :C;2kPChGLs\&@| B \ 3 fY QeU'e;4Ft"T`AP @+K19"gvWe53#wHOEg /w;(lOKvN5F<bJtMcO~pE;p7z<XMnE#f*^P {g=kPV!uTEs][F =y7CPB}G` *#Un7D#4n2<)2mq!e#su'nW_*9_l| @G6_DD~7 .@ch?]`R<4K*klY{:f,<%8gcz ,b 6t ;m ?` Z] u  v p 1c  ** V  $V~ }>nJ.a^MwT'76VU9$ 7No ac S|A ;_z086 }   w V ~ u0  /1'uRF~ UOh1V)L -W}pT  P m OS O Q&K1 ::+?=sS/bK5rYQRK3b [w*$ v & f v $Y  P Dx u WqO + Ir g |  @ V Js E `o_2z#*V[cIORvd_Y|w!@OoEHiUk&Y+ 20z6B=j; H*R{c~q?" $zoN$4o g    ;`  _Fq!%]p"+&;L'D#I.mbTI   D a Wc =mE1;e)g u # ltB\_y.E6o9mE! m`t[> Z.lt$"p &r` - #   c  74!=P .H | 9  >L  0;  ,^u3x"njn@t%qT zO 0hWtn}1 t/PY- m6h +;+^44+3sM H V* e o fS ; l 9F   @ X g Qj f[3['Bv#)+%* +5md' $8e;nAc.:dd[%#WJd&"4 f+w@w O   N'  U(  X/SCyp P^ L  V= O kBa7-{a^UZ}ydlM=qfg\2%W@/,z r4  y[AoD!X4=D' "b2%bt 'mZP),=b{pbvR\zLI)(Hm-0`NY W q+fl$?LCa- DC82 x  5  IYl:&q$/=34 GG$poiOL@HJEAZfm.6~<f$ Z D \     r 4 f7'md/ 'W_E L  'R)/u>)I}!oy39  y ' uf   H T   0  !  ?@D#$4QqsbHf8 $utkN^Ptyxl'8 )ELx\JjkSx %&`q NVvY$FNk, = 2 R(   3G !K )  3 (/ S  YW; Q M P S) T7 V. n  _f  @[fJLSxyd!yPz0/"*XUuqxw^hVFY@A68p"(I.2@xv/F_Ob c 2 .  %; u G # { : + | h j d # o g 2 em -hZ0+w X1p`&)]1g!BmueWK'Su;fEHHYMF~ Aphh@BX6:NyqL<+ K` FLt!VcbqGv"XmgnG4u,9a/ IO@Z' [a7uYf+ mRb[T\cM!&p: V+   #xCdLbfz%#9akxn `FlSg1zm.11^d74Hpz R , o I  8 R I K 2$J1K?-EAI HOG u   - &c(ehlZV9w z_&  1{ L`~v'&m-z^T+[3"ARr%&L2 S7E"4c+Dh(hI ( r  {< b z m Q M XV    Y o=  b U>DA\.G pVj ; a $i $b P 'H;:y^wo([SF/dcD1vAxi-p.wl$XN ` R @ _ rv p 2Yk\?"( | O  x kUX>&s1,ex {-=]W|y81!j"r c  8-6nLA(jceS  @ !s e XWZ<4E6D,fvSbr<zsj v 1 x L m L   P Y     5; 5e2E>0RyA's: #<-m;\iJ Q9!p*\nb=_ $ u@QN+mhFa 0-:BPb~x)+z Hut}~+NHxr2$^ Z tV { 4|)IP `Xh2}m !T)lO   a^ $:Pe:{u d1kaHx_3t,+ ?uWu8DA/&YW K [ T8 = ] SU .pG].{{!T?ec y6   h =/  wy*LTH1  =, 2 R _ U 8  D{J!ZF4#Yz0~!Nz u(vXo1#0rS qvwT@  J ` W ]O g{ m b =r  t  C tm>t&O!Gkq? s  <}[4a ? %m4fZilRWgpb<dukswsh`S+hU1x[G(# C<~JRncRpyJEy`V%x ;N"z tw5  n J fMvoaJ%145 = l | kwq>jLW&3[pnB+-Fu5 %\0GDxy>C pUv=TG4zUK eWx3*u@a\Ey#CFlOM{tBh! y ) d M  ,\ t / 0elD6Se|1mIe4w"d4k_ze-)Z$K S?X| e<NWouwd=am E[GfiiwjKs;Hb-w{,t_NA ]t+kMuw " c* <  [  # kb    #> 6U <R C- P U VL W e % - w 8L  xam6V6ef qn"8n/z|McU@ raW~\q%_r^ i ^ '  S    ? n  q  { BM K  i  7 T N h m "kxc?L;iB*malP <  gb 2b_XqwXA-EXA^XT9fU.:&xRe^eq?xwrx.(?t 'mHM-  gb {em+<;8u# * }  z>:W(.mUK eJs[OQf_72yV*dzmq{&0w\ 0 ( (  0  `rSU1jV=* (/LLumNy<Gu&h8E9rirQ)LXmsyi  3  v #  : 8^ GtcqD6g(n`?/r|" qC9<9 .\TT;7"::y/V 8  n 7 6U^(NVM'ZS] Ntq (TYUn@EP T    G 6DoKUr-3D +\lj J7t ?!ui9 zNdH(7) ?c;,6;m5fA@tLW6o) 1K d eq q b9OKUQ]#|R*+J-  u   G " w ]  iY # E  a      T   z r 2 *IHakb ?D]& Fv]9yY6D2>Q$p>< ;vsFSLqK*L'/ .mznjx)Q%&!0v-e9d; cv1qk@@n]~eB 3]2x{SmMU>{V5?S{f ]t7gns'Pp4&:.ZlYI> D!J=SU]('d-Af~x7pM^/; ' e d';dl/:O zr mKoW9q.E]_xu  K 3 Ww MJDBUgw[op.GcKZy6['C 3"e5A5Eo]G)CG L 2, G z3;4f:l^a<Dq  D k a #  A  J $/2!d\#K&ZUF =sIv%&! V3psfx |u F M 3 }a L ^ ng F Tw=r|q ;- yX(sfO6OtN\7 -`oJ>xg/.P  x  "5 U C U - / ls  pPhbIp:g 0dY^R's~h@hchzjAV0. S5tx.6I_-W|;  ] qL^T6Q>yi9e#tLky~SX[  :D J & : t}R ^e&OK7|>US@?9V0TkfMj}  pDZ\ p ' X! v |    (    K h q  v|NJeTFhOb\>127]9V4}#Qyy/ qxT`p"PJj D G  Ts%_ K*? 9Oj  8! V y     h = ea y . v  \ a     1TtwtY k8+2I90GA[4gv.&\pboi<vL$B|R%?*hguK'Fdng~YI W |7 x, k! I % V\c1.` u [ PL [ t2 0E%7''r` 8  wTyX&'g a ;  # - \+%kB z<DN)[fBvZ p15;I0&PXJ'rf' # >2 ljd))q1FPYth|C1*"+&:Ue|. ; m v!b  K  R , , ] 7 <  i #    ~ >6 ' Jg ; M#gVJ]33MQ):5;Ilj1S=%v56~y*Wf1*7=e4J+geqqO9; 13V=ee- yU4:xakS qvH|&a<I.&_{^99fi x\,9~%o1~'+:Pit22BRJldb|7 W Q  .    d! ! 9i>?'$@Q\i'jkb< i  w T   7  5 i $  Z @ s e  Gk {Rx9m1e1_-`-o6~CPitkd)ak>]2'qD EY g3/P(a^B$'P+!6iS/  l 4 R> $aSRihKOoU,r0R 1  b * x 6HhtY%On  - jTlvCQXIJW!iBqCpPer~0ab{C;Y 3} B s@   SzU I$     *wJ;*c se/3}`7 PB/a *wT\16s9]q1Z}xXB2^ja1Os@9/ : B N f6l?S:c6j)Fs@`6 ? [ h 7 B#JQ.2hoDwP0":3K>6 [/&T3(dbL`,$3fH L3gP~rJ >5eUmhPpo@4FYe^wcq#r} N:0E#sJ0~H]c=6R{49P +{IMh,  d  s q     "I   T t  H& /~[  *   j !S l:1| e1 [F0|:]<d2H{s]vgFEh?Y@ " 5 I 3\ kdH G(4DNo_{*:   U 4&#3 i=Sov2zw%O gDvVR"\g,}IFJ2P|yNN8Jt,p:0a4 l  | |]U u(6a p#j?[s Q a wu eP /  Q  * `;Ef Cv~3bf&rR!=jgR[f|}lf}C1"-]C~glqgQ v  z !h Y  pQ&z`1M%nwDj}+7lqY^ .  8;dG<~eCS'H_ K pu x KjB"tuJ%'k@OT(IS  b l  ^p $  ll  t 4 3 KN#:H{C@. 5hH":&JXOcn".-!niUw{ )_DpQz_!mH&<&q;XqnEVL!#\5\d ^LY +!Z8FA -0 ( /' v r? / 8Ar6ohN   + 2N / Dpv R   S   D $ 3 { 9 IV_^?lv[{=ah5$ F b $y T y 'h ? ua|n}7Hg(tgeF ^  } a  & n ;      w?hk U,Ec+WzMY@@7= icb@MpJ4 aV.6#I>D6GOh8,-u~\# b&Wxs 4]! I  6 O  [ = > rgry v t sG T P z  J i>qs/X*\iwM )zE~Atߝ$$ޭUu9ei)SB2_Xg{ S$_q;/iJGWPC;Z8kK5ol$vSd 3z mRVG0?V%( 4  f V 35_5Ko-jYCD6 7 2 t_ [q u` *  sI ET}eV@  | V fH U T  + Q jN/7 rk&.|qg@L]dyK1r?L@Wxi m^ F (U <tIX87J   O  *_mp i2 tj]IMs.oq[26 yD2v\'lWyQum}n]>7'=A6!F I:sX )  A  zUPX^ Ac_YX g  <)J:  `< 1P/E7R5jQ9k IyQCZ;YdmV+he wwTEF$j]* &`AF0 >%Pp-B_{N   K  tb9P t  a :  w 57  ? )  Kvh < n 8| Lorf"<> W$e'oz \YU>:qhWBst1>O(zkksh 'jm6kIfVEB/NIUHNTn(u/bA K ?] t8 ;_ z   c HyY^r`%K"HV+dR{ ޷=nYzr@"Ji!gf 0y'Nl.2l#D0Z @V N^bj1(R`  wk  O  n [R,&:) > C  ;q p\MJGfy Gxo^ MT u$vK%=aV\]vHU+X   ${} H? yn!bg7*V"f9!x_k&[P   `zdglM /ob %+C)v Q1!ߕާ$)߯N 4 [nHKK5A&V  `Yo@b0 "    Z K 1  , x lc b  X i Dw-sNV +J,A { U/yKvA.}K@ -\#oL9 a a d b } rz @|p(;+ 3    IHw W     r 9]s , d'  ql G cb I g &w0C0 d ^ uwDE4p_}! p3 E > C R f:+['p[} z  xls&k ?WDM?zhk*4J Ӹ+oӒ Eq:,*%G;DOVR   b  ep  D  & X  a E  2ml1Jr5`Pnqv  t   ~ ! #; 5& . h  C   ( \  A*}%t CMiFakD@iqTuQYc.0Q/Ga}[4vt4P  5 dZue(jd4OZ'2.o(jL f s  e Y!; ?"""B"o\!\6 cvw^+D ' H-_E&K}W|rK REB1I$P^.bEf*`25&V58cb%N iK~A8O_QnTOh(K dj/ J#NOm ynN- (u_IU>}hkQ~XW@ `:!cQ7V: 7*O j,CAD0RzH`| ?$Z 0 6 9[ . oT $ 1v c &7u;L,+Ky{].U[|+n l Ld-yE G u? k$  c  8v ^HLGcJFFG5P=/  T < ;  + 7a  o?G2s ']rLi K ] ; T@:KQSoؕ]jU'+Qd e @18 xF5KP\,0snv p f K 4  t [  ; o H  / HZq SBv|S8#Nv@V[g   9%g[ !BqW9gn>:<i< u ;Os o{)LB D0S6!Z a" q# V$%c%U%=&%xU%$~#25" oVn[1jF*71 n .de Q: * 8'&BY9~^^t*0>ڝ&hٽbdݭߩB3 LXiduI )-(}8ha2xST#Gv2]l-niާ!zo9EausuK\ . G ]<i7<"(_l=| M    cd<  . Z Zm 8  -   k g  ! _s g : [% + SR5@f2~Ym}P+,_7B'T,Z)(57b~+Y\XG1v"h=dg<:lm[z}V%e2& F 1 l4k0D 3iIfM t StUx-# vw3JO R1t^:y\c~MOw Z >Y A  Uf   X   U }l O z-Ul^"\j.8" 7fQO@3,1r}[ a@TY z< aK'GI j R   5z xK p2u#Dx&7 A} ]C G 0  e X4 v I :  0C=z4 5Hx4K{&&Uy5e E j'"_e\ao/bzW4IX"Y6o~LIuS;BGpCR7-ywPk"g?lUY }/ I >V O < ^% zl4  j % C ) Z vo ,P  |D Q )  U /  # g %  \ 9' {   5 J_    % l * / x <]]|-s?% k1VMC3m x %= ) 0+ [ 0 |l@_l\ |H u"jcT}m-Bdf` '` T/OnifrPnc M 3  ZYFHQmIPRH?'=$|wCV>#4Xm\bE3$" 1 "&q_ n .o& yn:QX6]/#N%) B z0>7Pט{I&YWݣTjDq~A2-B/0xSiXht-xb`%AmB~.rz)P*_@Zt*) F   v #  n=E K# f E@/KfAߴ3qW?2[it ` 'BN: OAi [    G[  F %  iN  wQN%, ckfQe m /u^6\SW zFU?tt(^Fb jvFTu7'J O < lhB/ b [ K Y a : + 4  o qQ  ;eq (g H  aP% J Y7 \'?oO*C&^~x LRpbU$k8{kB.+?M^Dg R6 ! r   iD *b   u ( BL H0/ܼGV>3Z zTu~  hFm  nG `%_ h ; 2 b` p!$V%f%\%w#+"u  HV wFJOBT? = Vx:7s M~ $  @@%PbL ~ RjT(6%_m F vpۆڻ &x2e,xr$/[} J,{L_.YCkK*A.wtQ0 E W 2CSQGIeoO4# :=""@N:wZzh Vp9G[z2<5/0B j  35 Q  +enMufIJ 48 uJ (ωNLFssѽsђAdqoؾ-(o8 `t2 eo o!V"#Q $ % & &'p'''R'}'{'po'7'i&/$"br&\ : x$  D = %z ' Bzr1 a {  -ܮC<$ Kڇۜ0.8y gZNr W `DahY/!!pB"|"^!_ Gap>36xR2+d E[#ht$f >EFniOH=8XC+w'ހ>{?/܌۵` akhJCEpIV5I" z #^G-p#5J/)1.Fs/ niYd4F `= f1 G  j  LX[< ~tdl+ e ކ ܜH7Hլ[E+28ߐ%H_L\ioJPJ>u zpB?f_rqj  1(!D[I !$!"J""["!! 9 A ~{ w1RBHp\"HWd%, $^38F܏hgגOf dySP<$80A {  2 !/YBTx,zv42 E^ 8Q ;mg1  R l hpRF 2 g L[vldGO$agy` 1CG4tq&AM-Kv))M ? 5 i:p5 t9vs \!!7"M"i"dE"a! R! h k4U/"4/%(b*\-/1 31 4P5;5f4210l.`Q,)[&=#\&u ݈ߛkDDOyB   \ J 2S= cG ;N% 3L* 8  :#  ^ -)qe)25v24o>F L ULԿ PE4!W`ݚf1YV~ Ag~xKh7$("Mj S :m ?)-J?y MdLBVP/Z$HD" M 27s 7 Q R ` 6p8 ][n(2t'%W@BG~W/=#s':jLP} D 5  ST {I9w/If> 8    uG F > I dM"](>N~F 7 17 ڮ ZWk<DNtٲܔF%6b})LeFeEM$z  u@'m@SG!!cR"y"R"! eA4RX  d   T5 o z  M) (:#EY'" I ߮vJBhڲj@fZ?2Fo@JWQ j  t $  u"^[Cg'v<:6&^` ,he]>Tr(Qie~! M%\ &BX\"0/KNBod7/1U0jr7^ Z ?`&^ !"#$:$N$Z5%m%b%Uh%x%%C%$$c#~'"R X  E Y A :MKck0+ +baؓpk(emO?ր*ס&>l?d8{^#Ljq}}C$&v@xV  3 k  wa g B    V ! >  C7y)7dhl9 - 7R ܥ2ث,ו֓G׿ ټڎU(q<k $]0 M Bj|FX kN&p=)[u*93Y1@y0Qv{si};?S 0tp2># &[jSY& D9tXE,7 6&dI@`vbv e@o"W\Yg޶} U Jۇ _gy@ޣ#S>p G E S e r 3 ]^ 1 E  G{\roby " U%(X*+,\- -@,+b)(t'6&3%B$"! U 5$ [  /) y a@ V B R'R "r ,A . ]<f X':/Xxrp]@=[; T +txo% xaYg\Y qm:V2#0_g)mj _ a Q1 Y= >ofXH b = +,;ZߑD)a-r<p%foWP/O3Nd?h9J[4$ sp = t1Z0}6{yA  UT ]Lgs,a )!|n`&iT 2 <I\ luwd J# 0fCh?rJu6dt%Qz _$;9Fm4 h 6=G$xTs1+}4n .LY tEW$wi@O$zaSbBP   ~ o | A ^^4(. )|]i'zӫ2ͩZ$ I'̋`ݲdb ;{(s#\ 76O"(,"A/VN2\45A5C54.p<'%".٣.t. ̑҂[ٶ[nO{VTS'VZʿ Aaѐk^ TI]ntJ g8 b${h((,)sh(' ,(m(W'0%#a#K$#SX _w  os_5h 24YGy7ߤc ``NZ|<  ;U#S5!&V)+9"--,>(d# O9ߏ-t67~ 8 E:DZ(ԨД]!uS72 Ώh=*$p+$+f&o!1KNRC  le]"a(+,+%)$ څ X = 8[b/3˼`3C@֜5oQ6Lˋ!G:!Mф[ϖ mTԞ!$&E$s"!96! i hx {h n- Mx "%; (M (&s#x!= aq45  v$M)lW 2 a(-8* ; W`}fE7HXg ( 3  ud 2 m#cE8gm'!"&s"G6  7 _{: v;]G ;ގ&,./m0080W1/*#,h !1!n2p >"2% 'ۗ&i%۽${%B֣'**˔)c'˰$,"bHB 1r#O׈{[ Zvh- %) } I5h` %)& # j" &*- 0I>344h4g 4{4p441-D' H l Y m09$ٌzԯknЦ S ͱbbBi(0>u4 wf"C% &%%Y&&%4!3JH rYU  E :5;r"v)j..*9ه$5VK!1&ro% R(-H0 _34J4\44444444"߮4np3V.RS(J!.r)JJ k+I<I_ӠBgfZ<`x8^l{mk6!''%+,] d'/n qHl !V!#%' =)[ +,a,*)%k #}=l  u09Y 2܋G\$[Wڴ P tzݑ{5g~K K<~ 'ODI:!V^#d$%'^) *(%!)aAEe0 fv0T9މ?B1PZ`ѱZ֣&tf߁MQx{ ^e  T6!$3( -f//,k*(^'$!<\`i1hwxXj'UzD Z c˻ $5˻A; fG Ό'"u(!|)/   HC%+ 2754 4P4 4444444648593-&68F> zLotfaANʬj 0݋AKoӅ.R%:HC;+`:P!%),/n24a442rH.x*p'9$' "0M Sф̈ʰU2* D#6e&8F'E?&˩# <~KRB*Z 7VjS! )#T((.f]3v4߿4444 (3F%0|,h(wٸ#խq/ܵ 74ZvWޤ.ј6[VE*8]>s;n<ˁ>w+U^AvҴov R  8%Q),pX/1 L3U47]4= ~3f2T1v\0#.*&"$Y2$?+ m ͥCTz/9ujy8^hye3NH= Ldf /#I%%1%$$@" &+?-A Y|aG- F_1`i$M_ B| Bu6˦M-O '[ڱX <#B'8&!#P'/W*$+W0+9+*8)'Fh%"wsv^Z[[wt1ITo^/pGj< CA?B ?˂Gb̙D j.3*$]U%7  l j  !# $m&,(6 E+5,##+(%.9" J^  X g ug M  #!X:R@ UW׺/ըִ׮lKګ16$*^$ ^ yX]/ }{ $ ')*5*'K'$ UKB<!Ngz}ԧBˆL8O˯;˖GE1?pIZ]uLlb?J* F^6#l'h+q/6d2<4k44I444#4Z3k0,D(#l ]X> 6/)gI&!/ApRϋԻۈ\ߌ#F A  2 I 3 a   + " $H%Nk& C' &c# ;J[  5^L,I ~ # I"~uK QL D فfsJر.gMD+LE <*O [^_' 9%T),8-c,)`&EK"k@ gB, - 8y6@wP1fOoάrQN/:5 _˹<sM . #91L߆ 7Z .p s !a(D0+^5Kq4&44444(4*44444}Z40*;$B C (aVXY֕B̮XB˳O09}7рgmvY dg4 + >j!B#vG&#(+. 12s2!0ZU/}~- *\&  i7:c`X 4GUo+  ݗeߖ% B_J"# b!&sC*X5,-2s/M1"3Cw3?25{22 F1g/k-*m%Uhc  a1#hDLҢQ 0̗G˺F]H"+g#"_D 'Rzd# '[*f-XX/z00060/2. +(%!Pc8 -H0r׽42(FGˡB˳K1' ) 1C v E `3i} < >K5~A 8"$#$,% %! %%8%]#W -[ 7 5 B {FCK?܎٦'زؙؐؾؠ`ٽT;ݬR?J4S Q f.i_2!h#$&hu';)-+, ,.* E(<$& iVy G w?:H{ P +km{2 Rա1} l -"II >c0~ z!8#$%E&&, 'ݏ&nڕ$ ۝ިn (l2ox{E'ٚc ?lCн6?Z |ݰGyK < ]HNX E d4_' }%Y3(kZ!"! Yvh4 0W PyJv 5#8YWz2:xVa*&v ~' &p 3}x7H V+ g q L!"^#'#"mS!]q*G Zr Q y!;LN99U_}գь ?n ?9RwG 5Z 3 {~=_"'O,60#3e444X3211.%+O)=&"Nnw' &Ogfaf](W$%קTX:s ۇ\} < =HG^ n f Q -DE-"$%4'())'> $L !   \ LO3,hx'e2%<WSUB}Es^: a f@.YXTkC x7jT>&w ~(Yd { *PNq ϋ `!m/ ^_ Y {V h  ~:  "!w #%3c'M( )~)G**S*I)d)' # hu@k WN?Sh0ݰ?2@3Ϊ˨E˂ i})$  L a!f n 8RZ$/< B  N  ^</k m*dݝ܇3$" YRxI7q @ ޶bG'1GX -_Y#CޠA2ЌFLL =V0,ٌ=4\GT& "6 zff!l$&D'Q'"0'G&%cx#D!8 v 3i/< F^0޹>aڮ!bݨ ek(p o4?qG7P  a l; tz*t  ]4 w( v kq ]BEgޙHܞ'OTF4YJw1><7uI? qh+p&B #y  n c l zo #X nl,I ׎ٓl T Sv JS8HH \ >nA)}J"e%'Ls)Z*_s*q)(GH&#/ "91h"< i _ *׮G)m :PV<*  \g < m| W!$E&c'E'?&$O!?fQ#]G Tq KRq UU)j %sf00۶UEBk{2_{*_2 1SE#''+"/1\.2S2y1:/-+)"& f" Qt fHO cC|+ y1- ?ة*]ܪ hAh(O' b d  !J%( +,+*('[%R#S" $S8K &4 ~@!usߢڊקQ֊֨3\ ; ߆ z + N L _ % `FU. oWm Nms3_Nr ! d8 s' l- T V m ./y&o3n|Fc<  um \  t  ]0zJi\2W Uh f t% 0@M`* *5 Hj ) FcV   7  MK ru7#1&O):Z*?*W**)('Z&$!6{f.vU 6h`&M"RQwZޠJcQfY$BXssWFlLJWd ixhoB s ~ 1 S;@MF I tO q AFL {G^0mXX,*&Z#~adAqi# y GH$D G _ )z 4!P/X$ / ` G z c MX5]RM&!eHy 3i  I.? GGD)TQ47 \ a NnQoK'K?lr5 Vއj5L߈ms tqBy   T<7 U(5zh ^! ! E D   XQQ& _ {  vc20E\7<CFcy  0/v9Z`wD@K (N]X r"m$ah&u'X(`)))L'%# 8   u % <  ?x  6 a  YN}K|b< 77Ig7q A!XV"r" #]"!XOpskT:P_mBf^t1D&)'kZ u_{&y wv }h f3H\ci  y NmfN +x  i6 I~ _Q}|jpUC mzEYB+k f2 ("TQ* RPqAA9SzC)93+?cR z_/9W n*x /l/HZMVޙ C p P e%E# L { /]{j-H+a%Y ?x qX/X [0rWl}r(ރhڊڸ۽.ޞ_4S2JM_ b1L]N I E<ZIMZHrR %9jV!LB`/A}:GZ7 qt@Ux@)~ni|_<_U < ?O Nlw_U4V ]  I5}d G F c BwB$Ej5rg.2 / ~E+   b "#t$s$#" !l$ %2 UEll8V$=N8 XԝYՌ.:/>h:indB 9tR :4+m@!;Db$+ofP6Zx  N2a{S.V{B$g>\fcy}pl o CS5;,v\>$rH! 8 " [&NU[4 ' w`  uBB<pb1:kPOQU / #"'\K'=y ( 4 )'OGH3z EyTa g1pS&ey y 9! |)K;<m  M|-B^nF_&!6 #H$$f $$ #!?  yF 8{jeT_<ew"I {bEp#E {)`-P'5@@nYk.G` = 8 R ".sM Tv6/Q 3 G;F[ y |Z%Q n$Lj\{  Oe&J,m{!yh/`k%PUnTw m W  ~ I??ARN2 jK  v;<-W  - 3  ts a !/Y!Wh CP:a{7  C  u "   b  q#xG< } 9 "Cg$ )4 fI<)&aJJqh+^D " m?&dm 04ۿ{)m\ffڙܽQ*'@Y8?8US:6 T ?R6k mcj)S !*63< i#zn^2sGvmU'_e-?n dT<Bd> BsKj G H '$R?To*B r {D 5uUxe0a x J Quz,  l 32ht^d:DDU?J& 9)*R]UL`>߷ߍ2 _NHS =c %[ Hp d )8 J P  V >!  } n# 4 { | Mb5Yh:]K``w6= L 7M8z3,NM9 *s5xIEL; $ ;  NG+ /  w-2BHJ9RyRr"f(G/n A, \O H8=Q}l Zqx'A t k f Z.hu%XMyoj1K7" MD  G KX ^^ 7V2u))ZQ ?P'S1hCB4AY><3&0~xGz @ U`\VLm_S   @ D  -kgMv)߷CRI-Z g{i]+ T^fNr-++* + Xc|WsRABN-4 %mq lUe@=Sy T s &.2M?^+r\^' . 'He #mJh_-@9xY4R /i!HH, V> 7_q;no(:Q|G-zn~r * vq_E 7 6 n=4H{Y0xZ  0_ovB~: <X? @qxu/?(1 h&zRV='7_ڣR{ ـ^ZPdqpYi}3  bU~Pf  w ^ j P d Cd K)_JZ*/^y>_, ) =^q4%@2'7PX~ c\ a\/n  ("z0}+ KG (Bwz+?a5 N Cck+T{byD5AvVSHT/xA# >5H@PQP#87}dg-qC@&WpKUB={(4 tr Kjl +me8wR  ;r  u)1) I * wb LM)&h -3)3Xc@nKg8 D  >&F8o}Z? h   + & 2 Q |^ r6 4[S:Ed@, <E bbY2G2 Ew$4_qSprz) j " E] '^W vA ! =  U a| z sL r|}a30V     /AG7@ | )ZT</@ E#C(BY)2 9Tj_ g)R:BYkY܄:w3` AJj\'`S?YI.xzr:}`_ ||$)JW& ]  8 & 2 ^ =ZCS'U K P T %5^^VEnSg(4/ g @\ n w_ wDaXt)E(xO  Q > G%Q@ PCGF$wn1$[ < E ]< x B ( A1 R\ B A $#b;>Is^k_4h>553?UR{zF &zUF_73_;G]x8/$ B .\ =  G  >T&'U(  S |= l5m!C=iADk Zso_r'=[~=e5aX.}!AQC\  OUH|,Cp~(/C 8[ ue( iM ; j{` 1 0 m_bkUJv* k~u;[aU(Lj߈a'eaMJIj}f9 CGw KXB J { \ ven hS#'V[yk?y ~ 1j + * |   #_9 Vu Ll y A Zz Jj{ZMf^jJEtL 9G7%eN&c">"0N` =    |y_5 H + n gK ?+9+ oD &AuanwJ` * hI VN.IM^/,1tWxCR)U 6 7^due`w&*lkOepr,4}x" H FH B  Ma  kY.4\?|~ S  uZXXsH? 0&KH}b3 @=zRgi!Mwz A] I9Y~=(Ii)ma p XPes6er/ D"R,#]##K"z!z  mOeFh I  KDn5 q %v ! s Y;aMMYh Z 12",F/\~ b}:(6 ]9qZ9S{.sH b& J H r  '   B  d  {& [1  ` N D  G x % ' H= ,]-m_:0El}m9<NS= | c  HqJVG6pGG 7ߩ U I PI  JDNgn_2W-m.CFg| NEE+x|{1T 5y^xE'\ Bx(On_.au_JVVRn3R7,['a o?mSpkE & FK m,X b = E<FNfrN27*tW` 3n9?uqk K @  w >/hRS\t lU    dZyk YOLz > B8>"WHC%xb^ f+`ZY_Cel t   h iyiFP `Z(d u  { W^I|q C p > .~ bN9VLd<&5r7)vC(,b -V %{ap*& b p >zD)I[H^)kq=gy+ g Do={K 0)dGmr\nFOVu1R}y@13h  B>i@^R\)Jw^}XZ6R <aL,6Iwb&X cRr{l6b>o@Qkk1  %mPOJ)~y Yiy#D> d U  8ZC uR $L VBXWGxi%1GCc(gqEbnx0&/*4  1 :Tk$KiiI%O P  x _  H x   m t \ '>M zY.Gc +o67[/WNCf.KGA~nN5' dWt`{D&Nl/9= Agt(7^11i{Tr]  =5b8d  `> b ]w~1T  \ ncoz|| kAg2/+Z9:]pV^4pN7R_, ~ V7 .Ko$u5dxr   /orH.'B%Xi`[/e; x9%,IrY V5l=;Yg M & uftVU    5<sA[!R>2q:Wc A/aDGY btY5#20@^Sh&_   G /2$/ SA E $ U  0Nh N: TX     5 g W  t 0Yeli5 ? _     [  {p=/K$y x'Y b gJ 8)toZg!  i 'N  4m  Iw  [a M!["!h V J $ UN \ 1i 9 G # 1A A G_y*1'D$[fV r0ls4t.\p B J 5zz+#K.b!`>=^ S 3 A & dK=tF\)/ K o j 8Woi_p?DV;_t}MtQ4k l , EEe~ A : q"a{o.zmG! v 8oq P^ &xIw5%._tF E^vFx!]Q1I0Oq O6y/%q?by8!Zrqn p\Gc@VHT o x s ]:e wH = R{wO T ; y {imWZe3 )q@f-+3,o0}L%v@}<cav ^I<b i 4L  | 7B oL, g B}u j BreXBq8]iYPyn%> NqXl B< ={ * T9*U 7:oSrK:h2;"s0"0  6   QO{C:B(:bzpkp?zk D n3RZZG2N E y H 3 B"Kn8n/E/eJH@xil\^~L m( y Uv s ^ m" 1    z !T N0 M7\9  * % ~G}gNAs&32-$AE&}= KCWd I@<mz 3H&RHX, nWn\wZ  ix9[z7^`_K!Pv  9 $ b9c Bufsf`[>^2Yqz?`Ly-$4Fph\W a  0 b_F1:?En.Z  P \d^4ZC_!R d up "pFv,- oo~i;$d LTGb7kP(14 iuo$a Nk  # !# /,ESO"npBaM.:"an)C ! 7 v p g Q    .l#Pik "c   J AIv/{^f4 b };B^94aM}hX^;Go9Dn$+f&15 * u ] S  N@ 0d  ?!b5'+ "T$H%%7 3%] $"5\'!;t  D.+JL(od G XW CeF%  3  ropHfV7sA8 'K6RUMLCW;xH& #"7g %  h V   } n l w'm7=zB3~sD]  M " q k  `\D1]=2)@ \R?`o  N= `wv^ !q"#B$#"AE"!V0~{kMT / 7eEreW l qxszL4D^ V!p8vdE 5>``OMd  *:b $ O  p %(;zhRv a+h  J !s +s H +9,\ llaYw<0:J|  S 1| Iz9#._M  QU R  m x  1 ; F F ^  >| +<f 8  U _?'}aD6S[6Utb$  2X +   @ r:fvs?Ov6h*& z w Mm>m(Z$[#? 2<%a ) % qhX?AgLU{=P2~Z<~Vj J, 'xLw|'Q%*x'+DN e" \4 8 C M X }  $ l } 3 [  H _` /:  !%&@7m_b$kn!N27n%e9QEd  6 /7V$qblz l Pdvd M2e a!rFs4&XRH6l^Y{CU! gOd C2A W O" x#-$X$Kq$0v$ip$ g$Q$ $#P#FB#"7 i" !G  G  R cK># yS*v4 H M*td J: u J ~ S% , <! Jl  ] % _ u ] ] 8  q ]M E X{ @ a A ` M%   O@-^X1r$62;ffJgmf{N F K ZWi D  | )c (z62~mU<+8t gehgc*g-g _ Q \ ht7T&B.W{uQ:UUA]H%TPI&$AߢT6IWSkL8ޕ=ް}޳_m&rofkSKl-j@Ou{zW=-0q X U^ DZ 7ugj7S>drY,j?C=0H71*Ox`t; d ( a RY u  # !   `  EJ ' 4Ti^y' n[})`CE,  wcD Y\h="W*5V9,uރ^E58E*A!+dpeo6O}se ; s : ;T^ _  6TlOx)9h2c6{e+^ y -4C ,d".pa: y|-4)F) ^@^`d3*}ImW@W>84CaiSSx,De?HTnwt>``W2 ` _B ^ zX:[   d^>_wHJtG~P %9$ O  "1I~^mpEa  @^7V VS Eg^*yYZ G` T<n F2D|3\&RS0DK,<]vqvcvK&Ev (!pZG\`\=:yfYCac!"jt*Uz:lsM{><@(0 U4s60u|pwV+ 7Ic<,`+$|T 4s <<u ^ vSh|qx Qf l7 c ee\\SS-6KQ? ` #W^)c_*Fpf.HD !|G=L<   k` r 4 5 f y j  f l i 9 [ 7.A^vEfg  E? i??swy i  WiS`dzr"RgoZL P r Nc3Ez8*lL@1LH^;,|D*ZlqZt1=p$")ߪY4ehgw+b}i - O 8t53m^&\; O c pP'hKO_;yBJ/O6!h  <ascP?yw~eGp67B.@$O|% 3 8v >  YI ^ B P?!xb$r&&*'& g% # !  9  [  < l   N  qE  &e \ 5A x z h E T]T`^} #`D8\_S- _   n S(b?G] "( s Zm'DU( = T sh YHCEI1cpM~Y* X  U8 9g$ h  s   "~|Ybgi  njs{9rFT +XXq !`"}!GF [;kU`C#L/u   . v  Mn& s 6tewK_O>^-K('=q%E_J)  N4 Erm v  @z Fo  u W vq"gi   Diu & Q2_("w% KG L ,"uVm*KF/?f`!g8e@^"=5v} %55_Pj! Ci tP+2##=m|iܣOۻڱ#%ږdڕ9܆ݚ"@C]|f.\NUbrpYW,=GJ.pPEx\E2Nm6GF`Yv(2n#77 uNY=?V n  E 4 V0 >)*r /s?K> w 6` + m=7]d6w6UO Z l `/Oz#|m[bO?Q+k.rNTzF1)' IGuO6 _* u /IJo b  RlG  T y!!.!!! 64B2r* t* #dZb5!7^; Mp{1YGic Ph a V  b  u=>x/> Y?[c-=$yh/t]K(T$81;e  o ^ \l='m"u^j3\=/00LYYUI%M5Gw7zmi{#= #xM%<48 tZZWua?^0av FC dUzx@KLvK:]N\D<f* h Z 2 U l  2   -W } 5R # [  v Bg9F 2 c 'rZ N   = EMhS]K  3 |$ek+  +  A l D    ! S  -  X)MU{ cTc5G'avr" L *X  <)(zCPD u / c1 q .5  r  V p _   >  y ~ uV N ?^ +  V g.tS](Z# g  #2s6Vi+3yMB 2 3   a t + ~1 y!4#d.a *zA.vd>Wcl: p f | d-  WU  "KE  h    0n $  @^ cado/Nm0^l+Xe'CO 4 t}zmI-  \@lq $T  1&'Mr$\DyeCphWzIZUAټ=w8ձG'`כ,z}U49ZoLRޗ)SeZބKV :R0+m`}>N*wO{C #^  7 | Auvq~  $:'()'q$!wG*6\;Xj c L f v}`xB0eU>9bZY$ 8 9f&^r:8!Xlk_6cvKjfA E 3}KgA._D$[>ru jNXZb h M`bJl7p]:Q 8 @ Lpa<fF{>Z%B(.`V&բx| / jM _ j K8Qf+t;/=f1OjKSH- "]V2  }! [ i0IV9]5l F b - B32nQ*a=lo R 5FL]["xw#__oT_mYg:MoP | `  q3B!%y Y  (g"$XR%<$6",3    `8 f 7 # N c7kq'Wz(~]Es nٔ }}ՙ+lФ" 7TO kԯתݺ8bul Y3<]8 7,ޛ> )] o{  z  8rdZ@ I 3x < P 0H % ixB0mra#m`H{Gk%Jnb]ߍܯQ QӅ,1"ͬ˥ ˍz=ϲ+0u|(D+nAG p!/9W h '  * r `! |% ( * + + * L) (v :' 'V'a''6`'R&t$A! =2At W+! n}w.9KOtن} rU%қ7R )(IFny7 M6c 7jmE !="Y! i|Dfb}@ J. )2  z? P"#dd#e#H#I##A$5$s9%U%x$3 R#K v!N[C9 ?U W ^-DsۊھIG9ֈ-=XjS2a5{vn 8b'E|n)BM/k{"%*( * N,B ,,=,,,C-{)/012720(.~*K&>Q!\- `]8Gvh_ `h{X M ϕzͽW#X\22!D4< Dx0%Ob#%[$'/'Ub''A&&w& ^& n& &j &] 'o ['''k'v&tY%(4# 3Si y!T#ky$%n&&:&%^$#"Q z! T 1<g N -oW9Ҝ}ӾZظ:lxVn|]VQ?,'j; _hO #_% ]' (g )>+,Q.0>24,55T5~3,0q j-[!)!%b"""B"."2### ;$j$ $s"$!}"F" =Gͤ̆̂Z+Ґ;,6>e #E bzlu !jhoCa,n Pi"X#5^$ $ $@$I#>" @! < q T A4n< ZF / I(hd % X v ,: x 6h $mbkE̳ ?_v]8ݼjbb"sd\+BP] Z\-Oo  V@9nY6XSk]4+  , %   {p " U  YL }R RUS2g[QQ ZP {ԴP2χ}u *B.:Wa8TD١d֧ .k wHۿݔ!Ui$M&m''h&$" z,'+?( }FPc ' ZrR#l!-m#`%g&''+3'%# tGK~G/ #J }$ܑۉܳVߺuNr Rj-]]BEhf}?Bc8pL %  ^ fH M  5  K r e V @1u  ' 8|   * Zmi(l0% " 3 6 SεGF] ,)e ymZI7p,7*ygvߚJwpF X   < P A 5 R _B m:&ZT'9w vyBXm2x/"}L%z~h$6  @.  ' NG*F8  H1 4}R&Lz|@Jg{P! T!Od"/"*"i\"&!  ?p Zy*Os #&(<*+A k,,e,e+ w*(<&# @ҝЎJЩs 7jJ rl!#fCuhU5  Ra*n;JQST{2>!zv(  Lc y?{@dl  ?. r0{\q8Y ^|*C'8 E:tLX?ZX14.o<!  i @\mCOKX_f  bSt!#M&"()g+X, , .- ?-d"-,,>,w+^"*%))(+6'=.%A0"12s3f32! <1.@,8(%"%2s٭?)q~uI؎ : +f4 n 6N>Zbho0^ = ek TU3)c0$!K#|%'68(v (t )L((]8('&%$s#"D! :RNiT_ 5Q  ?W8 g3C6}b\oiiܩ^1ׄ؂8C)ێj%ٕٓaܡ3;ݿ)߂nTkzS-sbR '7[CVdS ;6P9SEjiKu  @ 1  K 3  X l &h!sԤЉ xR,~Pp͇EόVԺJ5-Zqb'8&\En /R|!F eyzaA "$&({)) ) ('&}s%n$#)"]!?@%`_ FT ;~ . e aB` >y;%f~W f2[~ *iEi9@{ >6cD- v S(:lpJ\Ew*h^apsvK 2 BumP)  U.|4P"ڝQվӼ oY VzA /2׮aٰڌ܇ް UvhC_ު{@ڬ1׉,cט?QE F Sk Lv Et 6   P- v v IT,,?*Nxq/a!~N? F7w~ `  x Tc    J p Q l! r Lh V f t !w E$ l !  I9n6 >J;d qz WW$5 @ 5 g k0:PKA7_Hgޚݵ qt)4Aj:<WC(mZ(|U`]"OۨNv P  H aIHf3j7#0>jGF* rp &Tw) a\`<TXYT  }+ jS 4 {ߞߘR#eOY{+$sg`=EIdNz[m_PNX S \UbMP`E@WZ F2rL_A!N#h&)+-Ur/ 0+/, (~ $c38 wQ?2,r )h4  ސ50yx]'eV45 <@p 2 s+Bq:w B!""."xh! O   fpvTuY(g147 = d X]mܗ(אa]օ,׊twۢ߃ %p? wL[.4fI'MM T{ q A x hU^* V *=` Zgd  0 X ) ; C ) IF|!""=ˊ$hf.є O"6VITr%Jey E'S G<Pu8f)<v U [*@qb- !,!##%$&Z%'k%9($'f#&!:%8#g KL  Z }^}=@R%-ikJ3ZB  EZn5eA#v  ) =aa P= *  . * >wQlo& 7# Zt;fu    A<4njx9 AG2[q*S 876sݵBݾxݕ |f ] y;GO/ 9r[U2NI&,}]#  L alw!= B]m" F "!#"""" RD# r o #  q RwK._t#rz 5X  Yp  Y 4 W n = Q y  D+YgP psb c k nc~8_GDL^;.= 3#? & 1)*+,kV+)A'j$`![!$?&/(3)3* ++ +tq+**)f'g&b%#m+"H CSYr.Y<  @C-Od%:iPۨٴCب.0 w t(?Nԛx׶ޟVcz3fh3x~C/YۍoذNճ҇`*ΏͶ== ҟԓ wCbL6 4bJ48_ bPWCYC7ސ1F"9ۛUsߋ> ! em\ : nJ ]Yd( TF U lq%Q;R]J4?*8r g; yxqvqS %  e(M[cYni  AAk.i ibNs'W%' m]p! Z8(EY#'p0opV`He(toEsJS`n.%.DHnK E*,$ Q -tG\Yl,83AZ KqhRJkhML޾ AG:% xt:ڠK+*"B'E%j'Dl߄O!(GeqV\ K g'#G#sp1 u _!"H$U%i '7( * ~+",;#A-#h-5$,$+#)#'3"$:! % p/VU /A@ h #gZ vMw`$ VMnw66D9{;2Ro  q S 1   :O w r 4  Ry  X CUL^U2 _, s $]nN1e!d>R;QVګ֔ӢίQͪlμϔP ղw}Fךy hkl3,klMEa=7vO? j4n\>Q # x3 T 2  <  ZP   3  X  R 3 7 wDN+W Q! iF{,S`N)Y@cX=J1F\.3 n &=}+Bt)F p Z P6V< , sid-& ED w/ N9 FCn&c !"#a"$q$#ey" !dNNz0 S <' us4V~6 P 5 K 9t]1ufD O2Z<"*k & WC|  Vg0       E 2u-nH  4 lg(r;X&HF-!wh?V~AsLTS#}U eeyU ]]MG*MM`%8ߍߟ.Y X 211sr$c iT6  ? ^="=#1#r$$k%H%{%$$" 15 +{ A f H1?GM|  EZfQ EZ7o:)rU}{WSo>c Mx !9b!B" #"&." FJ_9CI? ;4|J4w=IKH`4 _)@u/6(hJ<5{$&B=R9T'V   i FqS{)E y!"##\s# x"  G"Z(ac^ >hxM rKw%AWv `  ~ -E3<Pn{g]a@B z tiUdFX7-M*9:QXd{  q#r%j'([()!(#'% &'1$h()")? *jY+x+"+?*i)X*'Z E$ HN+pM .# Zg7[)|cXf5   U ~1Ei^nq_'^ DE ! # "%I K' [) &+{ ,' ---1,+*h(&x$*"!z <GKT#I?O,Sޓ݂Vܪux[f&խLӑfGx:kRCݩjߺQ&b(482*fE8ogt=5Mb";fk\Er>  X  a q  v$ 0=,j#omg~<+Tl[? P{p2;~W#yby&wyfPy. 5 r Y ^ cIXd(*lWO K]"7#!g$$@$#)#d##i#"^!)qD) %#*\ S? 3 2v=\!v" u {A  YcszG6&f ]:A+3 QOT6jIb@YQ!N&|aJ @D w8Dk  nVZY<3B3L/p&<^~+C  <$ &%Ku!-9MqAzNr+61;'JK>FAEG0zxe-Nzwu:@]bK-()zL^  Xk b !6 k`IN ,5 !N"_h#2G$$$x$&$#i!#O)Z-d$ 2 9   wRG aK`*cnNh9N>yhI 6  n f 4 F'p 7 ; JxZ).  ;H AI`DBswM ~ _JlYf\eG(e^7OmW 99^ ykX|Wn^Y`Y_oqLs$/?( } 1 E X-nU9st _zN " pH03rߘ9k tTD{w P ]mV2PoBAT!7 "4#r # D#] 5"q 48Q0^ 8l H g1   S =<\\WHd{s"*$h`MB[[vFBbPgS2^f i ~x 9 ' l   _.RV[v3 i2#:&A(*++*)R'=$` c h6V?x'B^3wsݷPհ{7:)vSJe֛.FdZ`#)!=n R: Tl A T  XY5`y)= R Qp aY3_ Z t ~$~\=Q|dZu>h>5`|:2߬\ޭ-)'8ߧ4LaC*)Jtx o H   O  W B   {BQn w & w  R#   !x$^j&o'''g%"Dmd1A e$    V CV8SeE+*N!M*QzB=l: E  #I ` 9 b7 BDhde'J)y77i2l   8 p u. S  U w  I n X!H"sY"m! R`|D0kj{N L\ 8K lALeitM.cjm@ |4sF) PP;E  K[1;Fp +   hM   o Sw vaiQ [ d 7  W{N$#)?Q1V .;bkp{m_ * fmbv 5 ; gB V@#~ } 95+ Yav >k"#$"c%%%Q(%*;%c-}$/#1e"3 4\P5@5(43625W0-%*'#Q vK:M m 4 f7  e  9 d=F+i*Y-&+= 5UokVh7+/$irs+ c? y D W{hcEF)cvDNߙtukՈ)  7Co̽~c,ׄ5٫cہ s|&}B}U=ߵ-\ݹܬj[ =۶k܅RW( ,  .H,C!@T[ka%  @ ?'3eafK vt C!g@\ABRS-dR|7c&c4]% fxI Y1, > |e ]2\!ngVc*\ (c/G< 9hz>`; y t 8 I k , ` &\xWp2Mp2idw})C " X t * .  ' .b  h  > $`fSb d#&%()*e*V*)Fm([&u$;"s[`GHj3w ! ` l5  :@(esF0cXRi1  E  | Q  8 Z  N 3ZpCR[ iYN 9GSOUg7: = 4  _  3x?UWe3A 4BkX'=:h  -~]x%?3 D " U|n[xkJ}_3 bV 4I O   k<5eLX9 o;$SgrBa """Y"E,!Mq}I )   P >wGe Qq08LJS} 4} Irx-w;r2.$ D .Y c~=4  hU S(^ f+ ]XQ; = ^n]EaHEe&cs(hZ*rTF)kH1GyICsEfH -L#9nq %o 6 Up   ,p e  ! 0! h??nD;Q>M  O&5G&- U?nr40wXqT+> 7lcsVk `"m ' "41rYk<g]c5(N 7 ~,* fii$7^W؝_!;ha$h!9  [  ^ W ^= Ur#GsHt*we qF^,Z"$; ' ( X*k&+:+j*~L)jj'7%h"7%:-QF  , uDHs " _* O='l&( "zgP=M 89|m5 }l6`{6093 p  p xu[~[br\,bUL9J$ 9 ~}_h t   V M'a6," HC9/^U  nru ) %lov & < c~=!s_irC0*!j"y$%E&'fg'&j%v#*!L~4e>  _ i  0 } z b6"jY][,Vz ))&78_:A(M -fd,< 3۰Pkt2ݍ&b&"G$(Z{v3Q$.A  ms  2l  R <6  j '   = * q  %Vx$P7 % qi~jE#j&x4]=5h0zJM o  oQJ><f eqrO@ @ A  `_  N U V " o  u 3 B |( * 2NcO^3lvC{^,nS C qZR*]RX:pEvdc5R RrYAN0 O  7@? f9L P@b     # T Fdau@)Aw tA1>DojB5tOk -uH2_ڵ`:N- Զ%oRշU۪3cArrQd f oY++7c)eg9DxcTq! o D0RJp:]fA)!1$7YNU( $ u | R`gT0fN? } i) >}^2J" ]BhxqXjKt*`Td9Kex6Z  L U4rzab g! E  d`$i>#"9,KAXz#'^j7el;{D`=Z3l ='9# h>MaI>NNGHV. 2E 9y & a_3|a N 9] , (/rObh4g 9  {K X+ m )   :T z>}|7\#c]n-'4m { g d%  HIdy*hmjp?Ioޚ$%yJq߃0&c~x^O~t*+L   8'[<<(O)n$!n"<"[!8?!;[ 4WXx[7    N 0  6  0> L ) 4~S(("9%CAMg[Y&G*_U /p ( P "  D  ~ N 91?o zKjuߠuw_Z[3N pdz5:~Es;VuGE<yT P2n$; <+6.uwTI|RZt/^&B'B"G`o>T Cz *9T F| /4 4zYn{ H=o5 g } kVg%/_',E>q55> {oF9iu]Z(O(WeV&;LQLesUif*~L,u   ULeu " <{5thCU s*!SK! OQbYOP /swy }o.bz!Vd  &YZG?CdC4j>EL Qk [ EWg( B7 8!};#d$<% &F%TO%!9$"R   '\  FZZ/,#2 K {erT z#5qEoZ00-?r ^ ,'G    !X-% 9r!"t#%$q$sI%z%ra&f&T)'*~''z=(}(Eq(''U%#@!MH.\D R"&\ ean\^v -l7`>!f'c722d7 Dl k p ~ F "D  5i@Yx&On߭ܜւԆϵeRI^+ўjoFcsb+2ZJWok9<|C HIBFWaH & " {  `k " D H 6\{G>iyL-|MmWk4\ dY }r?V6n9 =j2Va:*5Jo ;s z / O  ` ;wWP:dD$ i 176_@.!aOI C" 3  @kq&0 ZxwS)e~*M7NF&j< y E$JlyZ \-dKgWySX[uTߧa6$MA8M*Q)Z%fWR7Mt0   Z a { N= & $GTajU%%ns|Y> &S]S + 6F[;H^ u%# ]u"#$% %%$ #2!)qe   Y 2IdcBbwU?H L+l3N@ljmP )%I|d\ Az*AewdQUz-1mqHP[P  _ j ;lB3gSvE/߷@h,"ߙ: 9wQxQULD R} ?[A9S-@2v qi >  uI y` !w Q"# %!% %$ # 1 @Q u 8 _kCAR#X>xrIIru) yRJ"w V3_/@  knfL0^*\MN.^i-ROtNL0< U 37r  G v0kX( %s[~ *  oC,{%,f  f  n ^: r e K ?  c g5D3nI~ i"#s=$L$#K#`"%X"!!# ! ! J"v "wa##^# "f!0 % uEs\w 0 L{qKFG_!92"Fm2R<7_2ީ]Q5ahڊڨt/Tcigyٔ;ڸig6ݱߩ(|f4v64+~Q#"7WI3 U o   A bE >  )e.m a * a ` = cXZQ"2.?5e-rr>8s3}311I6wgI|@O]XnR&Eg{@~0D9 }  D I. Hn_\4 +vqxa_)#h5LdNwQX[{,\a{O_vjguo) U  F < l y   mjfI l  |@H. 'D"Hc*F\N3EVN`kY#20 wc>17w2njTDU) K8q+-mAD5 Cn #G86:j,JH>w`fe  v  + U T $    X M~ o`  Fcq7h^)Eu }L8^u6-< V4D<pQw|/hW ? .  <n}-Zzz^y_ s qp;H b0HA~|\P $t[F_I\i2mCc}i)C&'EM{]X }G  S]S9JQzIJ:P@l`D^` >y H fji=  9M ] v q N @ T v U GE R0;E1GtiC 1 Oi)Vx  !  . t v )D &   t1:9?>E)h(JR?{BAatc[be@\XgccRZdp+ M T)T#Dq&.+:A]O5G    ="s p V  f +y _ WS ] 4 e /@^G9Yk]<>U?}5[UT\=0+ bJ >* n \ %^ uD 3B  z  3 # 0c v3NLUh:5]Z=74bKs".hH[[ u#   U EqP  j `#zHwA { "%! R =  OE @|- < =WqL^=kS Yu8?NUuNSUXk | ' X X <2@t2v=6vV@jY{ t7) 4  MtWGm ` Mz4w9F'D # < _ yP Y  I ` ! g3 /|P  X  CB V$ q 4m   y iAf@UR P  i C<     ,   \ 2 u^x & SJ7Oo[dM*"F ~J#8mF)H + f_  &   E [   Te '  g C z  >dg#GA p D l w+ 5 O l C L_~hPw #yz} B"$&dF(Y)M*8+,-[-o-R"-, +*@)w'n%Z$32"F <01 BEON [   My =1b?0Rz"%6NPc pU]1x5OU=,>5O="QFz<2Q{;V9EUChD - Id } [% 0Az>JzGrfN W lZJQb ihf:fT5B t|@4p;ڕ;"~0.4e i 'S  >*4keN.@  M A82w@DO#0ug9JG;d 1j}"].JU n17/}SQs8LQkT3 c   Pe3.  f3xpv A N n 0c k ! kw_`&'rCt2,M1dM>#j'C& eYSp?i4iVI?<fJo ^M^?/rNg3Y`uo 9a[ G ->rEXDpYL|g YR V- |hLlF&k Q6OE$kVJf  " $%S'u4(t(t('&S%*# Il;[g ~onzeByY%WX&@+2T|l  7\ Bk j^ $kr 3M  i` (hTg7Z^;gYnDuo&2;'Xe-sz bP-G@!qJBKB\M^v*~gM8nPVg<Q6v b U , E ] B  JK _ 2  }W y, \ + T&u{ G jd~:RO[37vK1@C x3 HyJ7va!~Rj)4V[e7*R*| 6x'eb[1 L gksCE*!Vo>#    /> Zx ==   a q  BpcZT \ o K  e Y 'k+HJ,B\>buAA!R_q8L1. lo3drM1j;yKdQ  gc c Ife a' 2 A g&!Qj_7p.o aXaQoJlqPvwT5iUh9,>6]Y&XtUwI=!}(H Pdg\t{`Ol &;Y& T > o&Y]rO i9 z@ !6 s@ m~ ! "#O $ }%m % %3 %C %0 $ Y"V L p K{q#{AI 83P^J5l-'#c@/2aw1 C4^ Ix,i!r72W0J8 h l}]]R G{C~VPVP*c-a~[]{gIc~yEA , $     k  .Rv;?O3pn,yT-, ; l1-BE<1aE<#@    M   7k   vH/ ;JY< Uqu {@  2i t  Ypk9`vIFxZoG-$4] D I$d|nIdZ M  +p*/% uWp  ) , J e ) ; *J s W %i 2L    _" $t 'J (*+,,-..-V-l,A+|++D*)'U%#`V!JdCV\W~7 E fg[^OnQk; 81$8eVczO EH1 90>~09J$(l5c'v;ZBX4 @<L;atTpYpibYFJz~YQP7J?$ZR!>sHQYe1f6yow-0}.T 8q]Z%HnaDQzqin/MpA5!k0ovHf"2 m!To2)5`3:7^ b^ K fz J :uD/Hw+|Z.R-c rxa,c{G'5q6pefpH#q0*G2LS`@lvY]F& 5w @uJb ^*5$  0a K K 4 {T dG   V V 2#<rZ$sU !.bMsY5ZD`1^<08X{%{e[T q - =`{jbIP%{Ax{Q9&/{h 0 G Vm  :1 zd;i 9  2 q  6 r  Cu   l  \ F9  v ) n h nd iY _V aj h x 3 H{$"w=JpIv e ; ]>xF@k.z  D ,ru?7T|x )eVJUlwf$wߦ \ޒ W(~rߒߊAt~uP&$.>81ޙxߝiH.O3L;-&5/K<p  }T Eoq  #  _l  5 w ]Y ?$I%J=` (y1!K 3  _ >]/Y^ Z *  iK ? 4 W    Gb{#$y^5J:%  K  P 'bDaK&)i*aDCJ 7&s>_ 0 @ |Er!r31az2  x  [*&IYzw & }  Q B{,&w7NJ  ]5 ^ l  Ld"EQZ@K 4diVm"*l2v$ZgLo HH2CI?]d5><\YUl2oYor95jf?:"a'IzS*fGV3VH(Dp"p   rX 'E{A[J"B X=h +qoP%: r  D @ 2 [ M o| u F8HH"cR<@{r4QK"m L h##|`rTa~pkkga@.!C^'"UJM/%^DnfDht82Dpy?x wjPxbzFPHNH3.X2Q*D'o J]{7 fw$B/FV  . E 8 P*r1P 'b #"rT QtPe<r*  1 | s"piZ|/  [ BjE$x  u 0} : A_9Y+E"5Lxd+n I a s C i ot`WtDb=)wmvxiTyQ,@8i BM  & TA  .  Cc4:;H x>! """t!k"""#!$!I%!&!&!&F"&"&"K&"%"%"Z$x"N#!!  ,+,msw:e  <a+$C VA/ $A i.5kQhULr1af߶ Xft_;2gq$b8{[ZbudoEyEh2Y@#v:\$dA?xc5l98e:RJrSlh;F[#hX`t k ( K |b[lvo r BN3Q)u >Tha+ = I&e{h | \D^U;?XQ~-%# @<QA#oaQV 8 x0  f\kW b7v\97jHU{|c>.| YXTons+w4L@pu'i<7X]?!/7U('Hj&VXF@tZ?0 >ORK}5 e ܬQlC)Z^>{H-JaU'!Gi~axUU ]  ~l>p M9}K \7 hN j9xn|~N`sa9i4lq 3]zf + U HZ~!%U r'j (~)T) X) 8(1 <&#!iewO]gGi lC=izX  ]  %klZe9JE^>vN(*@n)lnU^} dW!|4_ mq)'Y[LJr+^  [Q*#okXz?x^pq :A   v K KV0y+hafpVr  WE|>nq V:wNkA'X9 gsu[@BO(Tkj63:"D|sI x:hO R7  Wsw    ^ g j)#qjnK>)^Wt(? -F[^lAAuII  w'q8FDuR .)meBDLk'kWgXڙzּ(o6ЉO023ؚ3+r H4;%3)Ld83JwRD ' )cx g#$W^$A" &"\SK!X:$ &[ (i(&3K#| %TNHEk} S  MB<5 ^ ^|[AI&cO7YWb  .< p dm0nCz`ppH:G7&81m0BM? % o%GJr <3 @0BOvߕKp ޸/݆BVJc+*?3L9@Jh I> MwK % P#u1`dR"?D 1"5$$ $"s+! !U ]^0^:=UD rY    g R# - D HGNa8J< mtE58bzyMl/do ;0 P ,u q%! F/6utTc<7 > \#.'*-J(0e12324%4431;0</?/-Ko*&#G!BTG!Eq# $~ "   L1; 5 *!`2Hy  p kzD`neQ~4R_Fb=n p  vz`Ao a ce{ @ ]]N'1 %'C]@%;X5%%y7gmk'%)].mNN(jޞنMeBM!ZT S:y< pk@u`(h ,eu9C|uYv4r O` )Q9UY ~!b!T !X~iBh,jT= i5/c [ r 3  !yF#a()ej+Jw>/|i0-G$f;iO gGw=~R.4%AECaJc UQ1b6}lqIKp"QYE 3 ;ya E :wy:~   i q^ J 9 $G iB Z7vfF-OOe?=  3J#F  O  Yh + /#r[&i: A4g1@E%  v UT ~ K RpvltOlvY{Lm:E[5X `< >"d|%& # k^Ns'd*1<ھYQOA68Bѧ*p9dd4Vk[+dGa&@i1uE-m4lq||a 1 Y 3R)0D3  J < HJ ct , & G%h [ iy?j|9(:=O`Qwm E_i| +6z QxrX`M\x}[Sx /  mTF 6  ) RO,  5  C L2Gh,( @' 9t) Z5'b|z2 $s!\=.B }c9O[ @P 1 ({ 6  #  _lSiiZ u R~R: t q #77qT#N l? . w 6% $ o- P ^ P#K?Y\r|- bxqPytZ& F e ߄qSQA-%}^7@VasUOhQA(bN < 5FyP+4 2 dS!i"A!Ut\  uun>4  5xur]/O#?lah6(+r,}]_Bi&q H8 l ' g  x y  { #"  jYX{ H# 1 < fC a ~$I<Qߑ<  J/4 m3VKMzpn`))#7Yէ"ҮQWk_*c7gn) A .dMt KbJ D b "0_>(?F' e  } b_ V >  d       ~{y  ?wO 2B  q5l#  q0    7 udssp ` d  e!i(Q 0  e o]   he  t ?  |  ka    t H}0d7g(` u -"$&n A((\( N'%$ !# &(|*+3o,+! *ya'mE$gu!|VT9A #@ [ Vh! "p$$*$p%h$"B UC 4 EYN u{!/v9 J >R m yf x= f/  ; v TJ2J#u^24`n_K`Mdr_j/:qx ||+M"7 zQl#*O/:c:bRwX޻nڮs=ۢo?-݀Y-KX 0 u<,nncJT=J4\R  Su q 2    g72 [7k I ) "8 u `   O*XY-1 -eytk:#?/CXR~iPY|ۣrD gKֱGb/܈-h"zwKqv/**gcf UKl^Ia5U,kk?_4 jy p0k]N" >v. ~$>M F<3'j h<j Oei, lVFݓ"s,2w|yl_ݮ2F @n Q u<Af  D  k &?q;2R'nW c =k~`_tn w o m _g}'$% `r Dfc9H#%&6uܾ{֬~YRAz4܎߲QO e H p % L70DIOcj!,sNbMZDM O  0 ? pp  C['cNF>r;~U7Udg^F}2? _ n er % s Va_ L(WLZSu>Oss=G+'Aodv+ohDd|i,pXzSkX Khgw?ae[+jl/?` 2 wN } 0 . "J F"n}k?3c: ,1iB[(KWWjv? Q n = j< Ig A, L R^KxZ6AkN h 0O  rzH3$@nr +   * _  v Y: 3 E!izفڒ>Jr&{_\:J|AW+/,\ _e45E<dS YChJ &Z'9s2_sK2[^"_V*/Ygx_aqZl   x(    W    @ D ~` *$5CYgi+`hc+2K  G    C p F  6   = c*~v .'Hu% I4~ N6` AVa5b7`8?kh_ dA blDH0,%V {C LL # T 1 + |A f  , (<5~{h c(Hd6).{{, ~O I"#$I% )%.B$" ?W0)  F _t '0L\ 0Uo6 j+c/79Bc0_t2< ! ^ik:ia 0 WXM;M*iuXCXbe w  1 | q  x  Nz [rFu 0  D( 7  b ; Y D = "!7|0]b)Rp0oH<&2VI'&qe4yn$ \&  ; p   ]   >J \? G F V  4  NS]3COI&;P 8 _eH'2 O"|[WCh]E7+<LhR% M `F H6Ek . [ hkb^B V: X,3AHd0 %HuO7A+* . 3q OYkjv=we,4 f!!"##8%(%&&*&}(~% *)$+e"V+E *F)+'%I$@$##L#}#8R#"!G    umD(-~] i@   }= u  J e   .   U^34QXH4y0KK E<*6Jc!+fCvCg)3("`*U}@TT^eELQT^~lz;i' )r + v4Uz6TW5}(6dh_}*D{ w:  7  ? 7 [r%ofG2  P  o ^J mg4 Z-Q?Em0N(FVު=ly:; w9g_Mwbq8jMl<A:L A; jDY f{'^W[  fD b M  P[+,I =  Y  ;;  z [ 7 N1 kz < q8];WO$IxN*  7 k5Q`*\ D_& ?llU;BSk M N ! {3UVqa.RH6 0NMkU| L -WGEk_*yE-;(O\ٌق{\ݾ3;8[#  l^m(Cj2o1g Nf ^ c ZsK  D+^/,}r@ycJ!:T> 3 @ C EuSYORF fM#v,kt~ߚe!f0xj'v@y+H Hx`jvB+;-@0dNi|vh5<,^~$`"r l >ZXFZ_o7Tz59CD<h2 ugSPTffi I28$fKw.W 26wKSla  ~ Y(VUt\/: Wu8ng+8U,V]?NxF\A6UgKIqF;TcGV #i ryo83 ^bvc=Ow{~z+$MtLOd?|Ta^|30a.^,t5"piEp ! 4 6 ; 2*  w  N+{>aM/Mg$c%cX5aD~aUoZ|k`nD  C 6  z   @ : , j Y /"PV*YkkF`>IB uF6 # B  (SO?k)GoL#r hJI98L,VHO2 X - isbgmY߸ F6״`fOՂZ (Ԧԋ'iS< Т̑Mˏ~CW1~I_Ґ^I׼~/tޮd}CH?Hp.# g,:bA7@R a / O"r-VKoBXMClz  x  g?.pXgp3 c w  i g \ wi0~>8*7O,7]>n) Uܚ$ܕD<vQL18o-.%\@ nYmDIhwjMJ%ZD 5 W C   AlS _ \ x : @0 p{T}1U285q{^+AJ>M ;o!zs Ro0xLx4RkoKW4=$c#) uO;t1)W\R>,p  I/ZPncWd|~XCQOTL_X R CQMJKCk;  P  K     L \ ~ >  C'z( C Im  !m"M#L$ [% o& p'=(p(]2)TC)Z(h (&Eh%U#!]  4! SZ0Yei gK|_~nV<&*&r:NnS23D^y2f"^=iz@&|!h/Snf -=7O%H;r!Ql#(Y=q5+i'0S-O2.R'JS;hnY]17s3!u|dnG' Q C d*j*|GA fD `Ppj" ; IqODi^r<4sU *W3I+[O~f)N#ݴ!ܠdRq"2ps2w>jeHR WFDp "$ % &e]''%_(<(.(('B[&$"b !.$&'d(!))`)('S&i$x#!  -|nWs ql6fiWKh<#8H )LKC~9UV#] u^2y@ _Tfw |dS|8.{ { VO  _k; @ nby\FBU@2#A>UG4a4s1/ 9!"(#r $%7 % .&v 7& %/ %%$p S$ $W !%p%&|`'c'9p((W\)[)h**+Lm,-,-,r+)Y'$! @"A G m0*,-q  x o  i6.iN(V1}w7%`Enr3.nA7^ C_ V%kZ ;x?d 2& l@%&X3u03 Q/ A8@nTY nXr~,H`iv$GDM;#4hyE6#D[ "dqm!    Lk=_ <[1)* 5  6 {O ]  ?x |9NGMv ^(K F ] :V\ u0C6*41 y   I  ]3!h!!!Q! ] = &^wZ">I'\q0  qO J #!>"i |G[~;BD:l,0`|ԂҲ'F>͟ "λbd\}wԯ]֘.qxdZA ?C ߯.Q34 !X-!Vp;E>)s\ 2 1\lXH )  l~7 X^;Lc ."B$bj% O&p & ' %' '' &. &x%W $!B i95VRQi ny,7&>j g" *XcQ cPD XV,-M{bv~,7WA-!pab 2  /Z?q7NI;)  B!  s xz $  N  9 +Mx(rDE,>9lyS'iJ +h/?SSUkqbl(K;mDlh"l)b "` M1$ > WzTRZ,:_&\KdUJ5+k@Zxm1Y\v vXgh\ "}WD\EeCfao<qSU5QJzYnm3ou D:A4)n ,= <D91M6gZ[Tio  J :c!Uj$_b = E   Q `S5W I)H;o/"9iiYf_i)eWp|v@Lrt6 b6F , qa;RO"G&t)n ,-L:.9.- *, >*')%5"% 8, "$& (q 6)Q )v * ?* H*7 *G ) (\ 3';K%|#& ?n# }n~x( 7h=ySaOA]v7>~|DrCgOP I ma f 3 V`TMFRh m  z S s $ |LBHQEu "s%6(*IR-3/i0= 141j10W0r0>/Jc/ /.-K,+j*:*))])+(t('"'c&'% %[$>#"!4< 4 ^X ht "U1_IY\$; c] E  by P E- XX $ !u,  % ' _F   "E;Wc>ts$Y?!6"J,s( ^|e5}A}CFZTnC"E"2 :!l.t"Bd3e? ((CP>C = K. ~~1 *_ ryR:25~]8kLbJF.h׾w;{׾*يݓB3prITI#~*O)30z}.O  p 2 h s b& +   I5o~b  +  P  va b>Z/7$X->ofasMb3TJx5 rNK E#  x6FBF/m   N L t{V2efS_| . #O   \g    j<    2yGc  VNHv5U0%b|'[op7X?Զ{iCL РokDEϯϪIО.oѫs-Ja#Ծ=[״ g۲g\ܗܓAܡܳo&#&~)FZ~ FJrHe }b `Jl(< x F T\ -' Y4 k 7P9V #s&(**w)(p &I $1y"E#8'DWnm 6f4=KS9pQ(?"3gfNc;-h 4 W  B(1 yeN"g=]= 0x2e[!BN'+q~j AJT}+5S\Ce}k(J$,Jz lp cjO:u:|`t-8O  +   xev4qQ\(V  Z m0 1a\kZr\g e&hbL* i Q j h / /8[ 7A7UU+r4>CMwKX`Oڲ!QٲFB1ۤ}ܙ6܋wJ ڜbك{t׽U0֕Y*D֘B^pܵڒנ'ٗg0NW}q{WiRoX; aV Qs 1 (!%-)J,/1O22<2z0v. * #'#/"m w=AE0!&Ybj@M!QygH:Pe)Daz i 9>3 s  ( &  = ) e l  N)w&'  7 $ n  W S  < Qv )  v?< sptg /83>Biu>?5!wwFFP!JUh,:r+M=slA>n}l.wp;NK.B&PqgCSW!T{bTTL)IKLP,^=jQ qV~Za / @GRf  d ?Iu*\  d   e  E1 v   y  !0 h    & 9 ch#.@] "Cu$h&\'b((()( & I% 3#3 po'hc*  [ T %)-&54GcYA2(ffd]C)Jc&thdZL}A"M-E3 f o D n T  }] _ !l6<  $ {. 0B.S/);-Fb0JHbjTCA["xk#cP~3n!RfbdZ)gGE ' ^ d*KeHtgn7  VvrDK "}$d%X 4&{ Q&f %Q$k")  G io RTJFgRRz{3S/hnf5Nf(F <2h 0 +?54`1}tVuY8F.p [ ? n P &M K L U /:cL?o!$+'&s'rH)z*+,^5.V/713222211/.-,,{e+*=*E*,+`+2+*>R):'o&:%P,$ ;#Z a"v!Y P.3MB Ce`m[E U 2O4<Bm]ih ! _ Kj35oMWO _n@Q"qsZU3G.&>cp   {QMTN(3}1kG.tGhqPw# b.o?hw\H@z'![4\:(p6UU x N}^] ~+z@ N+ h ! 2 x  _K;PACxi+Mdj6&-d$@'M9gH 3/ WIS$e%OMy=6T&/FS^ x;IfciO|1|.5IP&x> g O  g I  ^   * }i  x ~ N [( ' m C'~<>    T  @ n  : w 0 z GT  0.J~UD{TdgY1a 6 3  cS>>Q>B> | # D/j6vZ>]|nNu|,2n!DFغ@C"|76߮i*sb(iOݼݻ'޶ވ/&<"y?n]CxpgW^9ytWd03?z= W 4G %fcF  +IC\w Ul_!rgT 6 =|lZrsi0l?1iOo#~JD QmAJ@CHt|m&z5SE<K7h)< % v S  + 6) y v fa / m Lp  2 D& Qu<x-" " a  & <J 3!KP)B }  ~7 R Q {n v8(lA;R3 pt+ldeEd8d>Rx>a6|NA7{ 7M&݂I]jvF߿ X wEn~#`G]WG}5%UA/Aw:O9'f2.9'   }  G  t     7Ac5[Y q I  LI?}Y5G 6!#$%&'()Z))Y(y Y&o $f!oBI#m/wMrj|]e;Bc@t\Bu : p$ N $/TcV{oOR`&F:W?v Nk4 ~k 9 ,^.q9oouwTrN76f -pSTG1\@\_&+8J!{` Dh[PEs f?|  *  C} ) ! A \4!]d(Ojx)<\LY/zOoWeg`L-'q'4m*p'r77/uA%ss } }G %  ~4}.: )bP:PZE u )fM/BHyP2K!-W#$F&,'''g'#'h& x%0 $e "eBpJp X@xe,FiVk`i%cRe8~L o4(3i g V S@ qw z j 5 < ' 3  v  m8 x 50  < \/t5N= y e 0!G!e!T Z! =!" C! t!D ! ! H!W ! r   ?q2 ?!!""":""-"$"H"v!qh IIIU$GkV;]O]F C S <;   . . /(ge`;cucKm?t*{qN0H$d6}1 2u  a`=^83rN=9F8%:\)t\]+x<:~=(/IQh`/v[ ]y6~ $) ~1F@>7H}\Wm`nk9['oކtݹ4BP* 0KYt|gwcHFoHe`k+l-I eM<+Z2*2KKn}K:=_ke_8kjXXZ>gC y R  [ ' ; -6 = :~i  @ e S H ad   P 8 @ .a u SRD8  8o  l  t ;  )  9   t7 h [`0N xo  = C  rD$OKTE5!x6#zv$W2%*%%,_%4$#"$!,`'cNG iv Ct NEBib}Es@_tf4on;~uU;uUWy\\=@ CCD/t4[91d4Dnd//~Gm'|=6h6  N ( 8 k ]' ` L9O-N(* 'B M83)u"\ :c]1I > $~VcM+-/~L2m]j+ G9/  (a~S9x  [= (9!Wdu S 0Mr-dc*RW _u " :  Q z1 Z T /;2_(3N5r2tJ:N}m 4_4|M 7WW1(lQߦ:<ެ> V]݃*݄LW"<ި$sat5ߠUm"7+%QDBEy0G*4jw~S'\=b1w'"& |v~W": F E  "(k  | C {  x @ d u P 9 !u U 3  T>F\2p5jB9Obo!;#a$ZF%&r& o'b'\'t'&%i $ =#!h  vD.xCCw ])F@| Oo'sl*G6 Q?~' r  vk {?^ F$0?w^ SNh"/@>hHoFI 9 (aUvE0,y\mwF ${ ?B6|%y&#1VQ]0L(5#JM.Y|2Qf`n>b r  V,&# P"r#p=$$$m$B$'#t u# "?!9 PRKQIw$ Bx +j|M~6#;'6Nsߟީg97@6ߎw AWBj E ^"N& 9  kN), oQB< *a1 j ^ ) u *.LF'*V w!Cr";#N# $ $$ $y##" 0Jw+V+Cb >lt|p _p w _$,dK , _ ^(0PoUNvxwBf9 @9U|  v 3 * K e V8  |/ H9  Adns[pK1K~xt = Y.*qc5vJs]r>S#jiQjRT#~>$j k"V$*;O@Ne(zhQe9k@Gk #XHJn35#t S} 27j %fg@$LKKG3HrwqF Tpf V>q^DTs_:OJO_#b7]l#F|g d@mp)Pz= O ! 0"] !c0 uv+o!#z$$I$4$%'%/&'( )z *i m) y'j @$* >5 S /! u  +D mbDGi]W;3p~"FI\)݂f/fܸ9X5wpm{ܤ`t*q* `޽-ܻ^ ؾu/ ҕ}λ̀8{]ΟBU 3 [UWwg3 mUh6߆?؍}Nz1$&LM |2|l`ڥG4v-t h9ytp MX ^ 8 |H0c+\rA^i8:"B$%&i&%j$ E#6 !z  Qi  uF"  c 7 y  Q L = ] g{ d s 6 ,8bw\JێhnWSרG_Sߦi2`SUA)`4UsU\>EB?ChiH(2):@`j0)nt7'fCFۇoֹ(o6З vq`` ٜQn<.64f nh Her;?)-}ix.< Dw:H p,=ZX ) 4 !!\""#$7% %'2&('>*(*+)J+*c**](*;%);!'%{$uP"  D) m tIX - 5:wY45ANz!-" 5w`[Yn !2"! B=#fU0PrI <g|N}j?k  e < m >&./m ۜ g*(S͛Nʂ6ʍʎ̸89_S W3%|z^$_G ?khp%s'^nf f`f   D 1 ~   \ l * w~ 9" : a  ^ e<"bVVnH# \ D6O,C,uhCK 3nltGq3IW 9 dB&:\JCs 19jU87X;_MX!9Q""u"$"! !W Z"x ##$#]"g!z  xg"<#### $;.$N&$B${#_#*D#q"J! 6SwHqߟ~+J'݄S q aF e jYm~4u z*c2X&Z h" :###_#7c" +vk$QF sbnpzRmo8 St9CIC$Z/L535x\V-=J/ڔ}nD7(!_9Ϛ/>԰B 2=G x u? 2S_mPAEg6; U{"$&5w(?*p+V,.i/0]1:N1'0Op/E. Z-g , , - ,b$,&Y*^'#aKl\6Z0 %%` + -$^u|۵0ށ?v6q<=Em Gee}< P  N= `  {9-ple!92#$&uo&a&&YZ%2a$#E#{"y+"a!OZ DiOpTY  0O]S"M]g l LZ^Nq]%aS6S\*H+:Emkl-.*S7A V7 #D(-?,8U"P" Z2wvCu6Ki kR 8[Qa% Q- k2UӔ}OːʳXWӦ؊ފo@Yb!ܑ5lI03 %< K X! 8K?pd  C PnUM9z B! "Z "/!F4lqZ{e L MK]P Jv ~ H v% TW o | 2?> t mf_TN !" L#""""# #f#"}!y fRdN  Q03M2 YBC rd3+Q+Y+ʌʒʲȲ" 4ʀn:#ʈʴ.FN5Q A SM%UMVP`)S_%Vy mi,`~Ja@OR D     QFu,0" 5sa" R7 ~KXF+S`ۀWO9l~ lX @OR5JP-h K\ 1ed* #R%SA݈ݯ8߳BT9+)T.8 _ O e,t+yH[  K _A q Q c4݈/~o&Tl)?a> 2Cxd<@M\VPjQzGhg9B s w_{ !"+#M##c"1x!N &u:   Or X" 1   ~  L s  % 8p1SuPA!H^ q8oY*7b9$Qe8aIh23P ~-8en7 K#% ' )r + ,-;...Hg..-g, +(P&# `?BE  n{V1 }}tuV:?cѴhZino?|*תhݜۗc-P6vJi:^ W"DL.K B6LU&  h;N -!W!V6"!!!HxV!|D 6cH@y Lk "F 0)$'?9VPM:eH4}%6 W-FAJ7e)n5XdS`xGUQm=-RKq 7 !XZ82 3`!4" $%%%X%^%>%\ %$ f$##| " ;T>#s$75 .[ ]y 06'_M@Eg^HQWKt~_  Tc h B v)c10wj K m)Z4=5a]X2C#x1aQ0*^ߝ0%WߢOJbmAM4:X@uLZ [d8 i?{A%,!4owѽQϗ](~ŷ! TЫm050,14u G&" !? Ld.i)og<O*nV>Gg:;S̓e~؄T) v_lC'Gh#e;u - I ^` ' fSa2G1&%e$ Vh?&qR[H  s2 2 ?~XKgYcw{} E M MQro8gH>hOlmBf$jU7   w)/   n w= Ct@/;?AG c" A$%&)&X%#=!ei4 {XK$ d b 7XYّؽ(; z;bXj-ER٥%٨U8C/ۓK6eg[_~d8E34>>q%=HB c|-qG0j z {7j k n L w"h[mYX"~^$޸Ea6 BDl~-2 S?j~>%*{j!  /g 4 '# x% 'B*R-0.w4B5~4Z#5;!4 $5&5(5*5K, 5%- 5c-5-5,3+/***%( '%$!< 'IBNgBc m# f"{vH! =<]1 'o - VFO 8EhwG#{ ] q~ -  _ NT fX  [ ?HHl \h;'T&1%/# ^Zv7  iZS%|R 4W<*6Zu2P_8>QA`][<G e % l  ^" tz  v  j 6 .V  Q "g^$^*  d4F.Q'LM=U k, .N Vb ou] J?'{Q 1 [G1;dܻڋr"8uu2{oZBԇSWW׷0d`9x# 8Y]H L!  u  7 ~ njqAb l OD F  a^  { ^ ) E G 2  x d J "  z  'M !^  c  8 '  L,gkMM4gzݤܵޮ\ݾܾM;B"߅ߐU-In5W&L3m. z}9Qt )mQYr5`7es>`Fn G _m!z&{   Qpcrtl'j!Iu8zz*]'@2\U}%/(L Yu "  3mnwEq  wzk%X= CFfE lO )Kd C #y.GB Vjgx gs@?%>B%KE7 u kb 5Y N GKLv9xyL;V]m87@uXTY> :.}:i$H9 NwF*- fJ  UF,J)ݭ#_y7R^F  0ʙ:Gмt5A٨l/Qcx1N:Yj=QyOkHwr"BU7t%|Q<  }u""&;WE K  80f7&w3-I}g u#2  UA3Q{"c-SF O!"n""F"?# # 1$$p%%7&[&k&xq&Yg&a0&%#%]%%%n&'( Z) ) B**|)x( 'X6%u"") ofZjz$ zTu D Q $ !0D@"l>-VDgx,4,`Z6B%S{Il D\;-*jSw;A_[~q0?U=|IDD#s6<5k#bW ^;lF V}q  K J%b:[{%]  D " 0q-}pW5!#l&4(S*FP,>o-i.@.- - +T ) ' $ !/ 9 -B dqv<UQ\#PHZC0TULX w qz=R[e K X ]  e+n,"*ky Q  ! +!A sA, 6* +q  G m C 67|VLks;Cy >s d| <7n5k=!4ޘ<[qmaUm->y}F+*F-Wm:D MJ|,zhnvb?7W w    [oV$*'L" ;mdJ.} 0Ti  . -sJy? 1f_f YQtzjc |  }(9xzGf ?v6IY  # K i   9}xBdQ  CnS)m[3fb{ K n?z^ " R0y#ZC5' w)2Zg c-1-z@~D$pZ;dZ6E)>~.7 ]~1~ =Bl O c p  1% { (N):<7^b^DgGj=-|NVumc@J D< &rmT^z K   b  i b e ( KD bi fy!{Bn'Q|jpDp ^8  _ {q +&  L~ K ; J s z : V  4py6iS)49Q9T[!"Q$%'s3)*a+w,i,%<,&+ J) & #  nl- BZm(_) 8&d\ /xk*2B~@0Z7't)sGV"Fpj-Nk`baPߢ0 [-ZM_Y_/&H%_GKOޠ:۪ڸ&5;BbO$|,ibW>K>Yݕ8)t02eaT3eCgr; > y X1 o 49e4  = ZDTU:S"90 +  D ^H.:933 */q {L6/Vl ZKGSNT4=y~t y    ;.  J ah <CQ*  |>"]otb f&@(RX<4(; <1AM*p&GMns]9lEPugHR]' 7 `ZqLVkd_<?TE>A\'nj|Op tuTxSA %$  F &vp\UV*ff[A&tNS`_X`9([d _wTZ\ N# k7u   _ B' 8"c? c   dM!8 %s(0,-/13L4b\5532/9{- +('"%=#"6!) /-~EBKllI2    8  Q Ci^bqE2F:2( (pmUW,7th _Cpv&*q3 y8Z7@xh5ߴ$eZ;z?ts2l\j NGpjM( ~ &xp4D6!aNsTm  ,1 W Cp 9   _ c 8ZDL^.|+!W~l_]R>zo g 8 > O4Kd1 X .n UJ  !b!g<=*S 0"T^oN6Td9QB  n_wQ@3 /n  j j~?Z0 Bm"l]kw< w  c %ZY}O"&Q3PQ9ovmkiUWt;7y;2gX\m~/~Va.0.$f8 : aW5TY&5+(VsE0M6xI/2Au(wV._[  E{#xru_(J\L_;1x "Z "$&($*&+;+,,;+*;)8 Y'? $ ! Q/\sV1|f R i .F?5PrE3t|r'T!0%@ ? v d Z S F    v@9U@9"BA'ovI>j]E;| S0EO Y= b0x {&ܦD-9َؖ~Z$YUu؇مnHb݌c~L4b-s]ChJ)M4iT2:WKgwd|dU{ I+sqQ10 wh"2-v[`BIdU]YCS.A# G !   s O  `F <  _ M  v  j5a6kzD"Q9/msRI z 6\ \ Z x P k>9(F3)9G)U)B Jp8Aq{I'S o **DE%a p   E f vY i / d p 0 6^f   0>Y mDyX %s)Be'Ok2x, mncx.Wk^Zl&ot }=+HTE(L:I ' w~ F (Z/Nh p (C ' . *h 6q +   ]  *:Pj ) W2Q D@r@es7S]T7dd!j" RbP`Z(\ |`D@G#6 U^?u9 53Wo8 -    uMq L -:w4CI[YnH]%&s>wXZ["?b COC:Y]:iJ*D w +  # !G    y rCxge]oӕ&a0!%C*QvS ${,m]b:8%M}\J? o. vb/p7q*>aZJI fv |0f J uN  |F( >7c -xxga\ _< f7 qAbL)K0{U%j i $i71 W]g r% "mh$%&Q'&0&%W#"_  E s  P 1 b   { ] Gq I1L@c j|ZizNa-1X ?'m<*8(x~qZB]W~aVXI"mN-esbO)P#i+{?j$\7$]=Q:fdT.Xb <hr i4; `t3t !"F"V"%["EY"x"".#m#"#v##l " Dkz0jt0=j( ~"_Ms0%WP] V J ? @ ]Pe^H)D6D1ol . g j )r  Cxm;I;+S e\ " :(Z;1co Y[2  I  k (  2 k g%}Mr=%۳ۈq5MݚJޟ\9avFp> e* >e 1D a , >}6(^N U{ C Q |  R    Y? `g     8G Mt  z V ) ! b Z  ] mt8eb#h7 E. I \j u !Cct  y q  e ( w _  IY o l  78;*qN5 o *@  %fwPVINuIFKj@CRQA~O4+  L4  z+>H/}D|wIdkL#d}%lK^DRy>bt6/sUZ 2U lvM F xe Sn!t8+^sH|9a/aRP8i[07|BuA_ {e*fr,r- _P#44Co_/=q OaZ < e '> C/g  SDn> E N&wQHPIS 6 ; Q 9/hlc y m / E L O  A h : Pti%'@0CHp7=;| 6_rgQ2\   $ w )L  x Ou"I_IoUJHi3r 9;u"m _4`cGb~2+Tmt4pu=PvJRl.2 k  ` H6 4[dC7c3rv & m ST { P\  ܨ2ڻ)؍t,gۡ4oXbPNJKa^^qNc"/svKHq{gx<N 8 E {q } kuafdXz 6 ! (  a:lP$  M $Q'~_sR@dJB@7 i;e1eޣ)<PWdF-;N6M*ma @ڨڛ_9cM;3);(VkYsI #   e m  v ^K > 3 - p -   'gH.p'%K=rwla,-XHe6+ G%{H [ D (: q(MNr{ on V:WS:< L#W%[(> ) *) +k , /, D,U P, G, %,(+0W+**ap)(+(KV'`&Rj$>e" | M p 4 C + ! _ |g6.R_/ GhSt[X-Jn` c`%<%AO^@#Y5Q _: (    y F q Y l  6  W  I lv VStDG<I*F$/lS59Gm2cT^fs BPSmH7twAhEFK2%U$6yfVc+Qda4 5 g   n ?  A  W q 8^   0    9 :  & ~ D^Ljs s  I y  < (  G 5 $^ P T s NF  m/zWe>Dt0 vf|WBP+   e h $  ^4ACq(q  G D  inycYxtY PU:Zp7QY`xi T 1 I f   LfegJG0Q+|@se=VEz^U6 8  0."8 7 8M  <_ % v 9 N i J |  } C  Hc * g )! |& k _ q o:PiUZe`rU-m`'cc;tץD֯rv W"Yډ7޼ߪZ[?=&[S5O;tl,|._F('?){-o l*wQCUE  yE* 9i_W/=$ ]bnx 5  S  w q J    G  $  &iQ^<NDI?nlO7  a(  Mk z @ N  [   v {.LEGUJ!8j~Z8U^rOwh]\3DQ!Xj,.~.51%)79{< 2  ) B 6   .$5ShjlK}CSn$FS(6ubSO__%:%,{,BxC  6 f 6 N 4 F@ m0 4 d y y xr D%B1SCzj[3N s % e +i 6;*$)xN>0;f_ qD  T#|o26 9ty2sW!&k8HjA^KV^  H O K!K m t b |X &    A 2&;Zkw:VmEL$W/e~J  & v  B  + k B U  -s ] <s@&u<4\(]8.@r.dn lm  w<nK P6   3 I  V L: T _@vr<>6JR[jnsOu_b < 6) .# ix I 5-=fE7LEEX3~O 2B`AP!]LAVMj$,Wm\UDFW?dyEu1?OZvd;zvpP,g}ue1]d{:,sg O$86YI>*&/T-~_UQf#5A  x f 2| /m MO_#Y_+by Zw" > !$Ei`AQr#qP%,f# \  CT0  5   h m  , L! N1 43 OgPAv35 5v (j X( zGUIBV{2}PIc!`Oq/(lk!H)!*# jc;Bz`JDad-H,b<> f\u>U3cSt? f~D;8.MI-h/^Cw53aK`T wB+)l<^X]A{'b?p(!!! 2 er k 6j W?-3 + ] QXO^L[m{9_r`IX!2R;v-<  4~pm!lwQ j KU g]B \A_v3sk9` CD&Wj a_ |Bt?;+/CWsU,r  5qL %)6FAۨiHEݍ~}ܻ"uۃPA;? } &{ b `  oLz-65&KJLg Y'O-   E |a 0 @ x ] C   f|wIHk  _& n'46m ~ Ru p~X[,]5IDnta 8 +?m/)st9]ij!~#O%a&m H( ^) * d*x K* )@) f( P'P & $ # !q  " 'C 4rg+ Y |!_jg7.'Y=Vl#U4s@5,1pu1USY "o # * ' = b ILJ,j5&bU_EO sZH2e$u>e*o$Z+Z R Nb l*4 4?)F cvd(P91 f R N l   @@ c J * 5 *  J-{[SV2. to  >  "F t  s6F[x ) FK g n q / 3n  ~iKHD  :oE=olIG$Du  cDIt11L(^2s5`<&/24 Q\cN!cyVB7/^PyVvmWl[Y BS  Z2U ys),~S?,Xi6^d/o{' ,H z  XcirVzI  8 Y  V j] <$ $ @  R1m OoD;Q}/D Cj  GD }8  ]slbv_ !"RA")"!w!! X = /_\ G)oqi9S5{ E UUx:%#XU<u# 6 s]w-"hp J?GrjY@QS[#HQ 7^P%'TLXܪ(0ݝT3*IvwBzk}/x4ytS d*%G]$Z;;dM}*=N=7b+ okDBj0X)@\AmytNX > pA ^\Kogy'Q&g'J#_QOH E (  # >/ | f N ", / ,G2^m|:b[2RHL!<" $ $ $A $cp#n!G_>Eq@ x2LWe:vRwUhMLT/8o,{w=me, sOWY@ao(R P? f Gq+\hX2   cb!x"[e4R\@a! i u ^ ,  9cfQ ) c# w    D  4~U:&VlITJ{s?&+D:oj BJg#u)gA$ I^[fSZ>*`dBWu=Q&5j :gGs2E)EB~1nA 20 X iPXL&?72dzexPJ8Qo5Py9; ߋd8#޾seީ5ߴ^FV#eejc<JpDoxn(Yv%tO1R@>^V~ `#nk   M.n4)  g' ^ | 6"  jIw<9 ;=7 F c %  K   2 k 2 Y   @F9  7 P,&Il]u"{ppB~J1 ; C;RPH/A7 . )P,  R p # t E t yt]c8 / '( *u J ]R.i m6 yc C (] 82EjV)A #:mTZ=#*4K 8 % srj&&xM`zG[H:[8,|m~8w7HBIC@"WFv^GobGx*&jOTQ-`!lZyRQ:k,* zޕݾF٭v^RWjkӤeԼAMQf8/ Jڕm&޿{| WPc 4 /   "W %!/#K$d %%% &%x%S$#"\!h% =Bhr5  4N ;6 o .Hq1~n# 3 N~t X[ b >Cs2e?(Pip LzD D%P]RqD,\c * *9QE#=(A H)")V%)k'(&)a&*!+*m('at(A)(:''h$C hr7}` < tb _Ue?x % /~q((] ? j y P  t j K p    VT}G$I v d ? " ? " B<z UHHu0B) A |. c1 l"O$ft&>r),^// 4.+[D)'4%?#u } ܱPZ͏-n W6, wA ٢"["W!Fkm`D>o_ ofWDg ڥ x PhklӳMԩzԌ;ӻflD؁چzf%2jX"[ naau1U7Z{!%()))-`'*$S*tX& lVt =  X_ix[ v %j'(2+<.d/pd.+/){%!tesx+4%}DGNv@Cdnۈ.JL44F;kI-c#A9^`<.d(T Axujj!s B} q.@S\ 6{"9Yin~ P\V)Xt |*B lE|  eY` T ba=2 G V h,y0brWc"Q zQwܣ5 ]ڴIZ=]W{(nI <=BXW8- B a ^VRS\V }  *weCe/U YjJ J|m&]0  k-dz e rڊz9yբ jӾ֑څܽlڪc1zؼ֦JKe ټߑGߕ-^0M*,~Zr; @<T?!W"#0#a$u_2Z~^}rK^ vn#  ~ a  ?9Kw#( r7J?k~ 1 E * =  5G?40AM"J  C   eR91|RExr7O MK" (OLcS̴0qʻ6>/<c"tySo A Hd{W$ (**@*w+!<,,d#-&-},L+($( m;; B_R{^hK'kpWg8yz%s |  gUoG C!"!(>& A "h lS `+hy6Ֆe{{Y2J+EY%SA .IL "&Q%H=(*U,1,g^+)l(VZ'ob&%L >%"$!hHT]  k#%@')*Gs* )) )}(i&#i .{!^~ym ^"T 9 Z  ~=2v+Ls%6+i2ދޚ~:@`gJlZxUmS\bxJ, u BtM*CH~# d?  KjBuM'A|Y3xۂ~ۑRdG q`KD^$F M\iJ ]b  >AlY"&(S)t*y**>++,c---X-m,$ * 6( $M!"= U FX "##V"zY}$am), .? -K * %  = 1= D: 457  />=,jP.-+0Y a4d3gm^'> -~0e%o:=qG b i B-  y4FY2$`|D1]>gO lO  {bh a^/l *yM4E߈ C|{ 3$:8$ d|; .sYr~F/ "gh9W>SK.ues 09رקg+Lc]Iy&@y4'LV M`N[,V[YgQ&+K=nP f?"9*RW }:Lb\SnlLTQ^.f* ) 0&o D&pafY1m q uy + wrvrw- N& }9-X9  d`CE#fa9 + [ <vc? ; U /4kvXz9|ًa \˗dO*̌Т(ڕQXxI[F[X  NNhKwBW>g}5 QQJoz}r 0$} A&kih  re 7;s?  g64r q b 0 46 M) y  r Pe  PyU^"ؓբ8g( L C"&# .L :wex55@cl>c(asj YG$ Cx@;@MY,:Q ]f ;S( t b+Mn`rKhJ'- ${ pGP{:T=r h  Yj]|EGLZ Yf?1 #TNOw4 3Da7F2" N % j |Y?  y>wBp%GJNnraRe]"$%e%%d&'&$ $X # S! ( -s>" /  7 _  c Tm9 xwcG%x,JAI(ދܸۤh۝ܤby'6f-BVU   $lP 3'FH  GpswojSSU/-`$)?_uI/Z&1A-k(1 x< 1CkF*8>&`p{K u O l  g   :  "n k Ef  z   _ UM H"# $$8$" ?Py w   ~ Y_     j +{P}SDףW6}B( * 2 Y  6p + E Q  [}l.Wdo"`h =3 . 8 Sb8JM$P=7TY6H$ lh0 & kLKYw  H R  6J kuCzH  /OP@GHx& I׫K`uwf"p4l=HL:@3< A UG\>uM*QX3]}u['%C 1=*o -= -|& 8V"l _ 1 =n>@"{ |$`2 G22( ~ @5 7n E f= W?11 < $M)v@\DgrCp M6 zO6'  ,E7G)vl^]di K { ;zv - G / `B)>OX 2 N\ |&$h hf?&N%ccD-ۭA[M#, ^ ;VsJ hO5{$I ެ   Te l {  p< 7sn#>* Ofwm_sDYa."9VW- \rTs&fu<P6D *7 bK=Ut    9 Z 7 R U ; |"VIgdEaT['0q[eOw E 5 U 1 7#    @Y@XI-7OS.t^xvi )r#;M[-c biEuޖ{On&$# W D  _ 8Ej6RG4U$n?pDY0'1i7rV?r4]߅k Gָ#ןQ٣^ܮ#BhoHM | S v0N_P}jZ p MB V8P%9#~9'  : .F0I/:\ag{A݂S{yWYA;=6_VYo#_W)H @\ - 6eK>ITF|jcmhB2 ?L bLuLI dqESH,uv* J WF"6j uA  c b Uw p 3 h 'o=KVJNbB7LrPVN }#Dy_=eO 2 .O:7  HsDNUNf.e1 $3\ k. 6bUai,Hqi-#288SKy 6W  !u?rw 4y/ d $ V(ui9TeKl<6 QV ^ @ Y ;PT !m"+""9|"!D!Qi!!_ QI{tsO `8s*% ,&nCs} bu e4HgeL :#.@I#y&+D*VuIq p8Ra2 ]e ;l4/H  ^g>  S# {Kf5aw(34^/[+CO 'wC %  'nfHގTT :wp3ZLt+ 03q :xl 1!JP`  EK9%tN  IgoW?1d Nc {a s RS t K|4.X*VW/ f OC FD"/wW 3s y=-]$:o{.}-s; U>;^i  )$A"K#e!"[$"&v'tn(*)?)5g*\*;Z+Nc+q*(W&7"t6, ?, p-k<b2 / y e`[6Mp{hfP 2 c?m7l]/)=   p|$c2pRM% ]0n ^tSR }2,/^;  GSy,x  g B xi *v d N#&kTyJT1K +ARm1[uf"x(ۂ)NesuHz68.c_Y^ %GWEV!cK =jI?l O -MC|z}a 3;VKS  / .+EC  z% x` k & &E_p,;cRq9* O=hi\zx xiAsr6T   D,<KFraW< 4!( [3S?r| r C  KI};mgwy :{qU: .|y! R` ^o\"+4ry6 5 Q K @"`UF]*aLS=a34sSl5QkH:c_ ,9<e2j|z vF  N  u - c < < \gN>s3 fmDR$P :'qN\\1 =N6<!Rn 8u V% n 1S Hb#-o{\:XjlwT dota .= V|0k5W =  &0u@7[w"K;Czm K!l"inAczEY (- g,'!\et\D\,eS_4 t  _$;`Do2[(R  $ Lx  _ r g | J[ wy)Y4#xq.@) P L u 1  T T <rwwnCzS{Zi P@,' E d v~=FP0J<Eoxk l7 ? bzYXG M6}[`{l>LE%m:0MT9ek ,  i 2Y\}9 N"g{#=#V#"z"`""f!F rK`!l e >Ez]j2 7d =06^ R\@  U C b iry7 :  R 8 p My n. 2i*rGc1RAo9"s@ H .5NTtt,d2xl 9'[ci{UTk_R%;ZBnbm" h P V\  Ys5q|*Vt -uG1}z/w? +L^!9pM' ArQ+1 `6*f.\Js   1JW-?|4uU[ z#!{}_%-D F   I  n ,4 :R\j<IjMrfa'&q5Nq $ dbnzu>(hR Mjr&'! +".^$[%;&&MD')'<Q(()-)('6%x"E  G - * 9 +m y`Hv{$wXk* u q}YM~) U Q ib  m 1 .~  2  ' >v}&yue83%|CmD9mX'#WBksTrY EX qLA"e+T   O4?nN)Cz  v | D +e(YB@,F|;Wqfm@zs]O~c)w6R?J:U    ]   S f C V (Nd s *eq".=Q] j}t  54Q-  ## J^ { 'CP d K H J e 'lO Q!! qR~ cf I];" $ 0LHg #+ `};s1J P@ d^V #^nn01LebG6_nhr#08W" d&%wކݴ7zR`۝rs.ߧGY+#! !EhwaE5l]  zrikcLvE8IK :  se D)l+8Ob`WS4n@g4.%qV =n ca W  @  ?<bV\zb e 7 FxL_| Gi v \<] 2NPJ-  W  % 7 He V  K  t  4 " 6 %rK]%!9hxV)kB2@gݨ%zݫ\]`<=L5!-}"MC i I/m9 f] r ( 9K 57   #K\6`8J~25JEK~'4ETBQ'^&W\#Q0Iݚ2LtdwE&e4g2ry18cZP k44 pF:fvr   3 ^5 3 B/ u    KpS&9B/ A  +G0{w`*i@>(K7<, or.ye  t g 0 xKP S " E R  e4:  w q  [ 7 ^ o X-}I[ K r^7^e}e?-hfaI99mznQ/2*yzSgm?M'N~}3@n$jS_>xB6g&c1NT p53v\ Znn*V?:qej@D&L ,b ) " w- 82 : t X  l=   )Oj%t (q 1  T-  =&m#%lUHK57qqU z;@f %E*I)(| aI |Y<Ji =| CZ5 ( s  +8 ^< X .:sk!pF ^ [   Z e  *, 8 zl^8Js"0L/ K &,_!3ThV>&&$yv7w  M b C x G zX?YnI>7FCB%hcDzVx%A}t)jX s  R Fo4RzOG}dMy `8|N03x  B P  IU4Jt2   h Q 4 < V n 8y p(   s g (k  HM   / @   T ~c > 1mp!$e f#8%p % )%j #H "~0 #Ai6  vL K X q _7k-if c #~ B:#2/q-J#w"7Bm~\5m!7I N[dSC:6^ < PU@$uz|[|d^`IX- @ [ <  N>l/#0e5 Tqh%s';y fFhL\|#y BL"VyW$Lz-Fye:z-]1ms3.c S: 0 B^s0L`K | Y y    v# 3 t@#| 3y*lv6nl>{\*Tk jf O o tP7A5+?M\8; q 8lw 3b k P @   H  h^(t2Zo k L>i27Q& %qE~mE,QL #A Zj 1I 8#fd=u3!YGveX#T Hݺd.ZM*s h}tbh4{i(*b[5r% Wj|(v+eon ,0?RQs L ghbq&+n@x5% { vf>B,f-~K X 8 r6fz7Q [  56 d  / $?4uI=EPJ@NF C #jh x Jo  F u d  Z i=  l 7bLRt95QCeXhtN;@mM$ '8;hy _/-^zHmbNaYTPo^ $589|yc0Y(`~%.<.&6]1\";xb~1@?5uS@g$},z#[1\ YmGJ:k[Gf ~:SF{cNqb k7r t 6`\b Xh8?X$ ! P ,Wb8*" cH2w89Z( !x!W! 9 = .;XvA'A(h$+#(Ml o]W ! 'P qw715/? > ! i ly 6 - B3 m>#I+r Huf7'A  2(Rdjr@ p? &bu-*oNC E D`3t-qhk$IYS.~q[n_|k @ sx } T m K / Z[J0 1`CY@  w H   ]  P P G1SunM Aw"pf #4A" E/ 1 F 5A gq7SqZO}w$5q  Cg b  , H  |Bs G "t/v]g;H6F-T=/<:R?p ~ 0|OuN)~u%>=0 ^q3OP Oh b Y{6] h= wDgy`_E1[M@i \ A l 8=fO c d E +  y d Jp+,K]#6|<-"n ni \l$fuXwZo2,  eZ k 9 m  gj   ' Y >m/P s A ` = B _ G-   V   "z !!"n!5 %X(c\{E[t&#P T>"9N Ehp  D.   >78gwI>=-G R6"`sjv~sK& Fs/3.Nq# ouug@s .B6PpBjk]sm# &x/+r  XW Jb 3 te~a qy!-o2PcB3(K7gygXho ^H(:@qRb: D | &Q^'n_Z1=`E`o9.$ Anwh:YPhB" U  L o &'  ~ 4oL M 3R6bM 3 kZ YT*^L  2 "    j > (>kq}JX1 < u { ~Wk h  z4<cX@M1 06>b;t61.D XtwrVjcJga1vV>X:^ߓH7fm~RtF%LtYTVS j {un&jlP, # or K n[6g2%4%fc(qkXjL=2wMW9]c `?<5 j* DH{{T#'FV&?* / lH4ms+C/  `>1,NGoK($ep C{!4 ",b#H#""t56X 1U3& %   ) -s 4M qEs Q b\r}PVH"3 vX$5R 5xLbq/mgn &}fLw! ( |@+3| +N eaO|J: uI 'Mbu\K`#l5b 9X=6inN!P9YY/,leV3\Lu`r<^[a@e$ZL4.* `m90 MtEe+KJ  L m ) O &"X7{ =J 1! " = %s  M l J? = -P M R.:99Sfac]6*rdf/$%#C{2 < v5  ] #  Q A 7 . y   +  d Y I8 C s'_ : G Y J   t] 0$ z< W~ O , thUK8xni]O }-.F\;XvIel,XI4EO., >%U7dG )x 'K2 Y ' W n l 4~k JM 8n1g 4Qgz]mW?K#] 4 A :   l 7 ' F! slPM]1  < v7 u V , 1: Rn!F R _ a :Q,kC-iq t nm"%Y'A2)*X^++a+*s*w)9)0'&$"l VX +O | 9|n ,- nk-aHy A ]'gf rBFu ,iOo}=*eP]{P TZRZ=Q\c 9TEU,P=U\; N i D^"  U   gY `J  A8 IP E  z"y[ADQg~HK/M4V5^7:0xZJ T g tlXw{%[u,3%:Zo( \ . ]+N^ 1F o'02,J+VIsv0S. = 2 Y Q `  Y  ;&  [7+K &o ;~ Z ^.tg/_zyo] E G 1F . E  Cd _9    ?  [D z  FG ^  [ 'EreWVI|?p{$c ,~!M"$  ! h;iEp ,   2- .v   d ?ad |!  AwI^ (Q"w>+r C 9`=Nsm E {F<H{N)S @ L!} / =\  0 , f E [ HK -1v &"Ob& #qpC4OzKkjY=L1 gc*wbON\%d.'h.FVNo|\K8YM. 0: 7ny u(YZ!zJ( 3 {9IS* E?h?epVT4/_G'#;gSO|  I"IrD`Z o I }%x'&tUzGa6U: Sv%v k9Telrj ) Mk>K wq*B8sdQy`z,h/L~X3 7 ncF9%ct?k'0)XpUfE37P R -u^MR!hTmlds], ek7!H2wK3 I,~SUBdwHC@U u-Kk 5aot\`3-o fK4o 9.;X@dK ]t[Y5~9 &) p C 2\#3%f'm)*]j++ +s /+ F* !) ' & $c!WF+l) qJP}Ka:g  Nx -mN?k<.  k ?= n l > F 6 je~f)B g H> !^F*?DSP q  Uv A : P ht Q]    _ 4nkz+VhjZ%j6~4NZ}:( q"`m8]-r%fFH)hc1 y I J h[,avYtqI!8! .  z* {Sawo>RGy g4Mp*Y @  # 9 t  !  H h6\~ | Y:  4g25Z rq g9 ; m}!qFML>>^K` uqN* /GQX %Q &" %'(*j,_-1v.._.ZM-y+U(%"  2p 0.S i!}^y's ?'  PCm]pi2E#aGgWbڬytbہFX߻ bG{Ap".(}] z;sP'qpq/||jToT njX<Kh*y2"DJ8&(po%CdkY ,vLT\=7~  x    i p -Z"w=Y}4 J ^1 r&M~{3A!Ku?( Q5\u*9=J)R>y e o  z  h 5 ,L % :/'L Z =N'& MdP9DQ S A yp~B~fa'&/Hc]0 { H  >D:?sw/ } W = oaL% &~*E.J07<"Zt+ji>TN[nEl\loTObdfLx<}ݽ; AeDO ژ8kد4[`]9vF6WKp Dj b <S v"%C% w'[4)!v*k?+' {+ + *D`(s.&{#g *1~+ GaF4`nx Y ofaO3G`r=|=] I6XjaP &r b 6 4 9>:gqB  O@e\RU.9^%FqA  qa HZ BVx Q\NCGV1T]Na hXz_no,%?6HIom(yD= !o[p{d Ob ={ -~1vKoQ$psW  .v bwci1{3 qt@ycwC1gN' Z X ve 1 % 9S f.ux]AP+j rT3 >o; . H  " |D n\   r| +  `G = CrQ   *7,dE_#$;w;< X Wgb](">]?tNddr&UC/.Dt.3  9H]L=HS*XNnoe}i Bw0J`^] x3Y k l t  s ;  1 &   V ! G   9 } I .DM7$8HG *th@M>-`G\rK(g$|fl$%/]`NLbV # AT!XT!$#$1&z&7'1 ' &Q %($#]"b o 5[^Ny>  ?vv'?lD+;c {i F?2$ E] N  O O:HQ}Yh *5x+e"l@ e"u{wi k ^  OZ,F[GX$ 6)M!ba K BIX`GR pDV{}kmt.\2>1ZF& ZnAoo.9L(g  } h9L qqi +A K ~(<MW  1>&YiPCdn*\CQvWj72 px-pI3i`^ g z O_PfQ Kg  0 M   '^ +{s_)O7{     L j  &H  5 LR8rt=  K M_S- B n K b!Q"##}#3#s" D!i!!k =VTP3| % "" fahoPf# `R #u [ atssf=A,9>$gCWw\Ii-!~l!U߮%E"JPKmA=#k[8q JCheV MaT>Wx\ Yd?u`}_op.s]a2(%At!hKTg4:P"Zr#.mb_;,46,  :XU4Bq7zc i  L  | 8 < NS*,tcKXFySkGtWuK H i   oS{AE&<VD N a1Xyf-I^uP h  u6El; E lp!z=dnA=_Jk'a+R6>S*@?OF.zGbd\bwdO_'gNt=U%LI7b,.=*s1|dO"Pf?V K2?M-ZgRc/I ) BbdP'<!~-!]#$g `%P o%"$#/0" i 9Ff V P " 5( N5.:G]p] C-]( !}JW$7 % @  . FTl;Z> |-b1?X6 z  M|+wg!k#$&%E&F&C&l''+'&|& % j$ " ! zg+p7 ww;@,9(]J F!M-JA0 dGڮir؀ٹ0kۊ1>n6v3Fv1/:\ r gEzJG  JlS/mN E^4['W&+I~e-eA[TZދSV,z)W7dhGQ3Q}: 7a4:R*~] a(g  ^  [ P155x  +  D q$[$2FY HiH^z8M0A( 6|O o7L0O(V  %  o  FkKB 6 z1 @QQ 0Rq;&y! 4# Hy 7?"RO[ApTf-\pP(9?_ , iIG{ y  ^) ~L  \U``^]W : qvZqO$tߞ߻޳ ߱ۡڵ ۶:_3!Mj2idwl=[ X > n3!9   R c / k Qh*.!<BGHR+TO^KRj :  eu4L  X b !` 3 a k { f  2J^    x  S Z[ $ >R X v< Y d :Be+wnc' {}\@&oWI|%*> sݱA[ 2PU gd,ޯ5itW. NDxeoP9A P .* !1 yX.sS}weVQ+4K0nPZaLLs~uO>cnoT m x[LHIGKdWM*    OG T%_ (!% R>$"O7aݥ6d.]0 =834 |4g( mvf jgbC 4& f  q  :x `g 9&   Y . *j"Z$&c((N )m0)(')$|!j!  YoktlY:EXI{c2{TW=*!7>\_h(   1 ~`{voj*  (Y3>=RiyqQmVr)V]wh܌ DT?C-AjY " {?7NX55af8BF\  P  B:8 { @eN=}-dA 0wp  f s ( O  'C ; G kP(jEyF]ki"g a an r    Vz  F A GCx~!Wm  O j * s  ee\0[$lOET3a?#mG[g ߸[XXTbWl?C #D"GUFoAnCxvoA n  R 8ww( @y]pc> "5/p&yGTbSC= P A nF"  ! "H#1$1$+ # " !h g5Mg#i"0N yjn6IHL["* j N L wCC sR;ct Q ! ' H` e G g ]  : =  ^ D &  9  {  xOBT[m*PF95w ! ! !C!Di! 0= *Q^KAcJ  x[4  DBUZgzzR%C'F .7@ABQ\)eV3Qa=%kzoR 3 D } V c ] . os6 -i>b w.ڋYaJ) nܠ޶wiD6>3JUoi6&heN z*#^ !th4K Gcl 2\ zO  d )  :  aV x +FFT.K~I> # & A l ,qJI`-1SZ9 0B )5{\*FA c1!!!!w!b  [ml~:U 8 +s m1C4 n /+[S?(-X^l_g hfmD:5f1ߺ#7v4ުd>ut>. < aRse)O } H j B Deu<uJ"p mkS:cfaKkV}c^CuMI& &8Tit[J? ` \ IQ(u5E [ 6Q  t " P /  rZ "$2 nPqg0E: St 69a o q q~  tr] G W  .y11  i  x ?wN")M c   `  t3 2 $ J I  `* [ ? v  > ~  vi1;ed Y$^^KE:\.C9*'ޕG)pي?Y=K]nec3A7p<yTVB"Q*FUH g r @ .2 x %- J  z 1&D" KNGveGW@t=?;U3-N ? |jDXP_}'+jTk=O)#Qz,=.   >YM^#  gI NU 3.0](bx/zv, T[YMq!k~,E %Wl@Ag  wC  B;2X !#B%&'R f( ( '{ %e #B ! 8x -|   a 4  ' !M 882`LxM$~$unBtv%u=~ff7qH!.Ben>cM@5f0BT!83rr@yT8:$*R/S )[Ml8E-A4xonhv nVv^a[-i g jp  UB v! s VJ } X ~A (h)i1C[&ZG9!v B6J | 4 W I r   ~   $:  c3g/s)CZytH3<m9,lO6a*7a T c &" }   ; e (&4[BbH[Kal+ g7bA!sWi7PFSCz*%NrhlߎVޥ=ޟAKwTU1}@DY    PW+ I ^N x, d 5h1MF=eC RKj3R $@D7ښn'K{xyeT5=. N !v).h!<#y$=k&0 A') l'& &"}% d#  U,rw7_$ [E >xRh1 # #Z i\)(qOe8 h  wZA tG -E gfRznU5 5  n NEme   a D  I\/e|f .Rv W \- 'I v UAvVnt4>V5hxyhh(%8?FXzk&l!~UNn!!BG/MYC<' R]ZW{zybALL =w[J'-۵I<٨بaWKkߢj,,/ A&" S+w &*h"6\HKmk u naSeip~'gy}VBLl  }K 8F  Hb |. p!wWX   1uqd1DSa  vg{D 1rP4j!OW}^'O   6D< N K 3l(UQ DcYW6V'AWn O%)A`)H$?9!l#'A|= [ ` pTfjtHD'E!fc* u 5h$ )e<[[gcP|R7!CMyQ6;*7!KJz2<^r\v:O  +_Ev  f ` u wp [ L % GLCQpI 1> 'V  *  | * !  %f  e q l . >  " #  5%!&%'*Z+++*)Jm("&$" Q !  v^   ' 5} ^  ` X % @Y~u!F/_IoH,|\9Zz>i?X8n8_{^PJk] Gn.~>'rU42-+\68BU(K[ndV+[[55Y Z8\gv&M1KX8jX B [k&v;|} b !@ !# !q[!{WM! E W i u3+e T PS_vF~EyZrFM. zL5dMpi{@R GBt0!{ K  |  V6 A ! ! m"4 " " "U *! ,  DouNp0<u z dewXkf(l~ ZYV`5o~YWV\2DeGLysAWAX4 OK)aH_B z9NTi3 *}nw:O*ITAw?s8`fEGM%6F.[،OVڜۃ_ݞS '6^ 5.{3C 46(5".1UU_l5:x7 X04k88:f/>``M, wR70:L|Pz xA+8S{7\[h߄߾ %9zF*`k%J    # K%0= cj K Y b LL  xY        - R :  UZ W* u V  8 s l %SC(]B;l ]!#$ ~$$`E$#Q#" " !" ! ! >{ZsI )"{by  *o :mERXj'# !hG~cGXyk~e9ML1=F'J3v4]Bs_,z2Ec1jD%.v!bp-w) c7bOCJn:`yal'=^0&C@I s A  7 X x> ( u )z g D Q  3 :gz~o }   J  ,   }e.t|  9R2 pIK',%X@)$S9y":jZZZ  y % M2vi1dt - =  w; }#\U3# B   >Y  % S"#7`DcK(_woXLt'=#SDEI3< g   x  I   ] +R>1ZQMS1sq#2*r!kF1;Jg|L0-Gzu ])u.jg]B9 eqOM00pf('xCXNl)5 HRXf,0L8"P I< T _Y3@@,XHDQ& " JVZg;Y&8 G 5  / ErZ ]   e E=~ 3c`4Kd! X fg[pQi5 qm g l\. [ez%V= P 9*}rR HPzhx7zlNj HrI( -5C.pZwX\=x7Fn0SOv QX@iHC90SC~TQW VS;J Hl-8a}!g#'5~S" + V 2 m a C ]lN  @!b!YJ! $ i}O%Mnp   8 6  v9o9 ce$ K >B _}DZ wxG|]1FQg.   cCv~ ZxW    0 >  8   0 ^?\c`(ro"v[Y-sYiJ - fz 5n4V, @ SN*Y0}w^C.h(=~g0Vex#G.KO.#I%`33[4n}BH. "{(3_w6hND  Y $ P R L t | B i V wEG>cz \l K  o  $[>&0K'B3b;G 6qq>  [ B  .  # ~I^=] I/"#$%%$#E" ^o  | ?& +,pf}tvawnd oO{[=tN<!bNBLX$)     V4^MxP[m|F_z{vr*}=1+=P, y 0J : U M \T K3$oR@N0%_mO,O n rV#k2 .U T^  B~ hP q   b   r D R(c@Gy f Kv ! Z'LVEKItl%+HW " nE lV!"?""i") " I" !} G! f o 2  7 ,   Vj  7 P J(-VjZ2c_\i%.^E~}R.s9aq[= k )o  M C b  y6Bb][%A wN\`>?(4 _>$K5Wy1Pp:iT&"Ing?Aw'pdv)[}t ^w#X,`&5GfO >    K5B  U W &X8#& h= ?H K/9G u -pU$:]oZ 1: z3OWqv;KYn =l 6  9s v]} X . 2ib*/ S  ,z   q(3 Q%  ( h ]k   X>Gkpt?~UotP# p9 ! \ r[  ] ](}WwiOy-CL6tFmA j/D{{tB4ha 2v p Y c/\ C eP*MIR}R (Ax(LgqijE+(!F1?b [1hbCCD55<U~}  q U; | |$b9 v X  {P.Yr4Y6y  do B0\ 0  b eg f2 !V*A4ymkjV22_VT3e0Fx9N*% U7,KL"We;"$eNW**[WA1O^Og wo#352v03mz dLhd/ 1\#=0FSo0QQQjI]E5-|6  X $ .  o&2%kQ` S7Lp:5vrQ ,[ v _ :F]E + a -j m a ^ ] 0 U .#Nno  h ) y'x \VE  *c$ r G C hf]17="|EY` ^ E> X~hTE$=+!CZkm>`# `EX7| >$p :{t^I ~ &5imA{Al^+)+0+@_[EG[p48_TM~^[}s}oBGS8i qJ X=@32{1:  @/5lx J;4XYD} 4 ~ ~ s *c k bK &  . } p'v0:Q{Ip. 6[B K (  _  b  X bT  x  g Gmz z!#M$\%e%b%s%H<%$%$J N# *"[  u  o9 [g oM @ O"D2kc=,ovf:| y7%U_puPm7 )\sbjVy8d _wl%{-Tcv><.,J#M1(f\6Z4P6Gb#%hr!EY9``>IRfOC}e+[ (  & I ^ : '  2 M  s4,\Fo }4'W&H2&T>w B  97   - j@ I M E F \X!Ie!rck[PO U  UR&Tf" E@ ~ Ih`a >  f, 3 i\ e  Yg/<pZ\vcanlf (8M+=:vU!+d:`K*]\k g KF[)A~|sMOc-HD! ReVp7s0`f!eA|y'[3r/NkoVJ_^0D2g42H$l g h z5p_  U^ _K3=RSA9  B 8b  k {B<IWx=7 y/5k V R  X;q(a8:c:bc+ v 2:?h~m`6MqrCLe 'g  ./ + rt   f %= ,  % R s   `  U Hm   h  R  :(hnBm4Ug\R\ND{1aXd8 U ? q 0# o w Z(;NV+&Nf u Uq `1u;[@MJJ/ gqp/ MK2ah! 18i@ W^o yeW9P5RB K1.Lgc@|w/k2\ u!}HC~U" ' F~h xA=\B|SW0%Ehr E sN   QH   r` G m /    _,UJHNC+< +_J;    + w { B Y t $ + CR 5 !  'g! vEbP ;G :d}A WMkCV>D m68yOUy66|o]7!(4f|?[zB0}!:PG N!hx+1#LTeyPh"v8lLTuA+S(k ?M[%EWk/4=ns["u|@M y U 1 R ( e fT 0j m ) t Z = "  E|m!Oa;G.N"w5qI  j k' Cqh[q>R EQ~dXY #N Ru(W%[7bV fMrE2P^t|f3}ro9!#3 6;S4V3>()hCz4"T`<YYMg[;8@h:, & {5N9&7BXre;TGfP[ N Ac!NrBxQz63C+M|+_`t A ! {W&V~0Ja" ?q  Au24l}84&:x*z}h4xpE'O[0pfV. S # B 70  . r  gk {o <Nl|7H1h38GC+ Z$ BNq>Ly% b  y=/ng.AX_J mI d ){[ ! NA _\Gs|56ee0r & (\qMQZV+eB+&CM(Q`S&P\R1E83mZ9%v~d#2&{JS?s6%p,Kf(4`"n$Ss~F8;B9]=?dJ   7 mj:;?((#=2 L 3  f0 X -   W   zV  j} bfti]cd<4.?} 4k{ t*1FuUeD"/$}c# a<],'7}eDbf)S7fY(YXtR@Sb8nu1I   aZ - ^-z**D / ]  Fq%C@XS M  y3ljR4`_z k 2 LYNefAV/}u F   W `-^*FH]5 Y  r* @u@`~Lb x a J  H a  XQz="fWrnmd k g 8     mA   7  G@ / z.7tC$$Kc/_#PI [P:[c{F! '  x 7 [f ? h >sd A=O]! ~ R c FY2KUN#* D" X Q 'A'!>!,q|I1:'i"_C6m`]e!D|rfLdL%%,U,+X,GrVa>"x 2 p>Ej~  I% R&~Adj!RA4AsI E 8 ^F p {X\K< u 8M\Z4M%0CnI<*T)I $ V y ?  "i u G c[/ge7 4 i J  f  ~m   2V T$ : & /;   ` tZ{5=RZf:QtJ_$k?[Dk0m ;446J9YM;i$7._zE@w, 3nR<mn214Z;w-8x9\X"$H_nP NC0iU8mryK9c8W&&wC@,$ YN4#sFtBY`u|ytFH]!fiU~(fzjLrc ,aom/d(Fzdh>e{ )VBJ4i/c~liFQ>${ - \u3\NK)5e" T   ]  H 1&B{ qb q{    C  " 6 {  "urPf 4 [ )  e#!G1[m9VP s4v&/t~0gg[ +4 2 q 4j8pC0{ Y : H8-TrCC!!+g!wR  r u `  <qC*D7 ~OD|e7*E # ?~L N4.KEpl7b y1@ZDN]e@vze)O}&1jm ' @i;C5v8=`W@I>x`jl< K  $   A 5  U VWs@sJ5QYQC )O2|+oE{wYA3I7l B - ] & =~z!U  @ ecy<ifV E 4v "m  7 d 4J @ >  G _ {  ` * ] .%]H!yYn 1d;M;tU!C)2:8&|[Qv, Wz)uP]ED4"@&pP5DG5tOruBhPG_t9 ?d`W&lkr9$  _  @ : o ] 7pE{?|C+y  z MjM: S V ]@a&w  _ " D {X"xj k @> K p:2 l N    + 4>)sy.w<#: @  0E DzAK" _ 9JP`7k0|+?k:5|Q )e?cEr3FFsb=y[\j   MK ]  ` i p  N CF(6i f c B;"/:.~:0  ^f*x-BxR1 aLc`qjڥ߶g/^/۱٫ڻۢ`PV,Zp""h_$E4,U8Ey0(g` > $ w \e .4 { ty 7' v g  ZsT JjEou s # m 4  I R 7`AchB 3 fk~4Q"0AH GGIo{|i<I{ X0w51  N \ ! 4!""#Z$.$VP%% %%V%$j$#""n!H  /xeSZ h  Y0D"\\4uvdJ<Ya1J+8Z MH=q9vޠ^vmq{>#AJ~p!Z< ek}]u^PuRI|>m4L>,79Fnk|{r WUr H r <  W : T 9l82i]b&ugz"cNe'1U vF%IB;$cW`s%/;(;WT|pecj4Z0eYqN  Bf  i%v /# W%8&Nu'}'&% ""%&w'w('l'H &b %| $W B#"\""1"T!A2\6 g$ S^M8%P>I La9"P-oK3%UطLq:j J>C\\YPXPJA 5' n W  QP;H z E qB  n f{]B d  ^na 3 ; f7]eTI-J 9T/k1uEo/F%* \w4SrK2c7bf 5 n Yi"    IU  2     t q r Oq^ d ^9 b  az3v0IJxRD EQ . % { l; )O SC  wO`Rm;@}U:pz]KO+g+tnJ > `{d3-p ? []5}ndW8!Mb"k 1# ####x#IC#m"nq"B! B //7 _ *%]/*A\oCHbM_g6՚Tfb4ӭ b"[xFԻ^)֫ &}ۧb^$rY-  ep3  nH=S4{chD2Y :b '#[8T j U RE9ߓ"sK_9QLst7N3:8Qc]P~G9`lZ& 6v~paL@Eckt&l 4I T03GK@EM&&_EK#DRxE sVH9; : W%L[g, ria;} F bn\VzYu{  yc?=H1FRLtqpHiO/Y4trA{G\Q | U  >1pG&2H| VM" ${%%&'(H)a )d ,*U w*I *P *t*M*b) (tF&C#S!Pwv.//R<b $ JIOd0aga@!\:GWCr^'9BuF 4 7  ^ XU  *x Q   _T   k }3G69 B8`Q%  a^    xe `U Tr\'}z0Z=}`JE8@p/6A(    g  ~Z 2$ h RVU / EO 9 > %  yI L n0D{c9{Rd}4:u K (3-B'6Cg1Bu9n ?h y A e [ q_m.Z q]{wkro ,=N5` .J#!(~r`d,+$!FK}%2)yPx<>Ho&&  o W  b u \ MTsK7;lX  U )  C Q3 ]i)q;'5sZZ ""1#"!)Nf ]  Mc,$`u9 % 9  w 0$ m! oh  6PUrQv|#!","T" h k =G  P 6t.pa(R .EFrt;ۮvtXUoֲ\Y֫Fح<ݷ[=Qqz`|Q|'bMX:S~^d#IF&-c >R?u"l:^YzV VCh 5=?rRSO*-|gv`XH*f#f%1=BO{J { U Ib^n G' ?  ! z ` "^[ /[! !""QL##a$$$'$S#R!!" F>4?6zU   Xa x8g9o  c kaF4K9EMKZXrM#S\NCU bge:gb&   9 G CH Y e q6F8fvsD*  \   :jk  5% a n 6 fAIIyk1epfv&I  {  <0Kw WoD2t]yip1߆[.2TކݴMdP׳!מ(!1DzAؤءcclڑ6]'k 4!HD/x'Q  !!x$"(g"|"i"!!JI,HRS+_! 8 < \ 'BLj ^qWK-c7eQd2_7.+՜pۙݰI,N~+ O T Fa'%kJ  G ZAY0/=hSb? # +)QWCF 3 :1lo T {9b;> C B 'F F >H /4RGv_b>AxQV]9,ZjpbuקAL?\@ڨ,U܃ &tݺIz`^>g)N8I}H,  )MB [ V^U  X\ Ek2 /(spw{] Noj@p|UZ!#H&!( G) ) 4)Z 5(" & %#` 6@O7/tDC(zO } [|mJSz4k/boeuM`8!M0v b 2#Z2y7\49 U XN "}$%) %\#%*&%z($3*#\+",A 1,;+8F+F *y(`'o7&K%$[$h$@$ R% %%%Q#%"(.-j d 5uUU8abv%[c4ߑ"r(4@ܲ܊6ݻ 9ge%DV55l EhJny1+6*L< $c nJ>]I}"`4 x>&as&z ?G 652bk=Ϸ:З"{s2ԗ"fاb%BRUak8E"Q7U2 ?>}$](u1SRxz?p5#fF~^v9-G^Ic#eVDp-A~bN8  J  R8   _ h F/^v)F&x`Yz\ ) >s #xrXxuP):XY5cM#H l"Hn<t.~OB "l $0 & n(u%))C('p%U$"BD!l(^/  ~W+(>  5 aHya|p!M  8 R"4sS)I<`} ,+T|5-T;ZVGr=ZpTrc([^ d2 K=R-D:@;p3 Kv#~ d}"}&^1*,L , +*w)j(C('/u%J# FjJjV,+0'J nP*yaXTY 81wl5iI.Mc0BtCM3U67  C  ~'g-rOT!:""z"Ba"~KtjndTOj fRoB/T& R+KrS 8 fS{ kL8=4cy\Rr p߱a'lg.:ݙFFދޮߘ|IA+#m f ?B\ <m7o,zS%,ZIN+ Y]"& # & %   H:cUfGZ8F,{`&e+NHXe0]&1z. D֜  |l)$vgyzk^ߖzA&^%Y,(p z]WO"[ at;0bs}DGkaxy(kq$*;  @  qW * \ s &  5\cx 8|kS;':t3>r//$S 4   d ?   - Y | NWWHF!1U#B7R@"55m܃2ݵ?ۓݸiޝ}>3^(kgg Gu1k<߇Dߠm\O {*EB*@$T0)~kPYCk w v + P Bq >3 J!6" #3 #q$Z$ $#"6!!@!G !9 X10x  \ _V?t=|wGw/w-^k_%#0|5"Xx[[!`iV|C 1 6/ |$ IE "/{$&}')/*u,,,l+4(n,%9 tn AagMXiy)v;e- I  ٬ w֮ ?\ Hˤo !ml"2DXٓ5STH%np.1~G3@v !*|(L ?v/? ڪ)b35?l~j8L8k0bEH%Oh _ ze W ?%w@%#La$f5CJ/7MjV iE5nX j9F:x ) ބ L & T  w 2  A <'T;N\h!] 0_ %ioe/! e  gT"`#$t$j$R$a#eM##"""Lb"Q!+SyqgXx[8nv  }/@ w]S8pٿִ;kaicd: X7ܶh@7pOM]^%v~@aW: c 9kgW2O$j{0 bV15Fd%  }{'A%*84a's,ZM PUj'<η{ӈKW\a%$Uwgk C[f)!PO J4 T   -  _ b   v&YtHl   _a ! X  r G  M   o p \  m84? FvIMY_puO; $D oGWT65W%a}8)T\VB'M+% s ,1tE6 R "c%f -SE .6?w8&MeRHJWfJ]U"Xm+  )" = ` E 9^^TfC/pSWY . g g ;   y? ) } "C )%h r' a) *,',, ,3+ ) G( <&j#]!xKC{}:ENB  c~> ;0`X}  !M A8kD o F , M k H5^0;  j1'4%\h85 aS r`JBG9, | g; Vq : #Fk{>dr I d 6LJ{>-~Hu"u.'FxnoS@Ft$  # n E .~ ZSY :&2k*E83z}CEwV-n ޲ D,>3&T^ݺߘ(k<PouFOez".-W+f}\6e8^ n ` /SA)Q a!b!e8!k :e/$ 0  jh=sh& 11+{? i7  nnM ֌x Ԧdo{Ԓ.IKٿۙ?S߈,QN89CchDDcF * <5#+VY$(\+M~?` $ 0; _ //H`i" y -umwޮ#*ߞl]U  AcjZm' $Hw^wWaw[(borbo U =  >q [eW 4 n> 9 p >& ? ] ~LLdM><7 i([N ,g YwL1L(}Op | %G Z h$4$f;ehG cnQ+B{_ .,T HF9[N : vaPzCQ04,>e C jg~N|N`K6Apr :!\!2] X f&H}).GJ s 8I*{}T8hE)N+_[mxV!ESZ+ ,5~ ~ q fhLU'#9WQ]c J_   mo}pjOV *BVP( wX`1|>|Waz&G ( #wv_M!*'MGb?b?9b0g19Vs-_?Ad:]feHfad N* y7 _   t  #   Ko m >cqY_ [rj~ u7!3l3;g(iX$R^n_ܘ(5r߹fnj_&3yi 96+ K  .b 0 M '  &   `rU<ia  &bd$/'K!(3BIh B> =HuTouy|qa3Z_t.sLW% W . i g *\ ~ߎ T Oz6xh  &  PT@SP%Q Cڳ ~ٖ h >ݰIl2A\E=\v;a0 !w w > 0/k#/!x$&'') U* U+p , @,+ +)[L(i&$4"{ Gt"3^<lu (  u L! W n!"E T ( eB 8/pF;+x D ` S' Pp ,    {\  y Hz  / _roC@LH# ,a U_ B & z 3 M 5 V t mr ( !yUW ~= hq`|9 }o /+aۋٛ؍׎֝Eܧftw$_:?v*jrk"v4+@  ^!qzY?=RYxGEk4Fi?L dW{9:'cf;MM]-uEH\tm~ tZoQ[[CuzR  'M;$ N +0 ]  4 -Wn S:r(H\6d*|/PT`{ܦ܈یA*O~Bu=4r,~ar7PsJ("ABUppf L   0 )   ;  N[  b xo[v }R-O`ih0uuqUg=i~Hb]2\iU`;W|q/(7P&}K _y|?9Uio"  mNZw)N , E}  yTyjIZvq$aWN,E\ouL   yw \ BVAZ~DW;t ll'f'N]#g/o j] }uRU"&%p'x(f'+&|#h )i M U?Y6j* 6`fdPM|wC3iۥ6bmW9+s9plq[c{2_? 3 A Q D=6aZTCq'v sUNO3 S4 )PB8 ( alsVspH}eUNYcҭrтeѦ c[&"ڝ  cZlUa _*XJ f @ 5 ."0$l')U*+X- 03-3޴ߔE5]}m)a| ~ }D^A= |VfhYXLvS* e/ H2#BS: mBdo?L#(3,0U1=2a2}0Tz.8;+'{#\L 4 * `~\% V=)ifAx ) ; % b PރFߍ:vD`k]C^zMd:N R A, s " P ] F bJwW3Qv "#C#t"s p*1U < C}JZ6yEBoE2g u ?):X!b":##p"\!|~O   n 5vh J !E_V֌Ӛ!M")ѩ! .l7$VHӜeIs/ 41#G 6g$I V4Ta8$.ҫ)]҆-c0c2Nѳ4[/55"+551na.*%s WY th{ 4(Z $.u# 'G*<+*)W'i%P$G"iTi(S ~vm]r8O ue=q3=fD#Z(?-x133Z3:31JH/+}&i!&P>`zBXTxd p_3 .P;ۥ8EމL<;PfsN % !PS^kDvj hLXwd! !T a # T~}J:  H{"(%-Q%1J-343%1u/-K+>)&G&~"M+?`h-0R)[#MEIh]n8ܠ ٣ ׹،{!XZJ1vTn 1+vO  @{f ##F'&+0p.01ֶ23נ4z4K44?431-8'!L C  [(_ 00!Wt#$i%\&&/%ؑ#4u$/>6-ݗ p[Q GW:pG,04 @""ˮ"Oˆ"L!"<`۰NJ vHw"p5$e>7آՐ$Zs)J-Qҗ2>5ԭ4C4k4414^4 41+&O!~NCR P F7}@]"?T&*r)+c- .Q .>k-/,ݯ)v&;߬"^b /bZo  sa}+H6 GX]2B $C(K*+zQ+g)&B#8;75aI S@i{~~4* % @0 ! qN#x _Wntk]%G; Ym^WZ V#%&o(('%!e/G %p RY# 7w`aްYܻ!\#W$Jٗ$-#!Zە:%hT ^ OGX*[ w7 {Σ̗k< a׾#D&p'n'@&c%#"G,{%1}N5  8R]E$T`)/73| 55, 5c5[ 55545429.c*&9M#CGf II F_  z o )!>e"#7" |S c 3ٙ' ܶv&2D90z܎l٢z; KU%H; %&l  Q2{[a I2Mh!=%T)+#-Q-/-?,,,+*M)&;#>R %* '>a o*&>{#%9݆ ) [/ pi n ߒ߽Ug[Y>]m:` fRd[^vR ~'z bt  %BY*5.`1{343C5K|42z0U/U-X+)[(R&ij$C!Pf2ErLE_qRV $0Ku{:PjT#`aY wQN+s/  `rѦ=ьѳBԋ@ LJe yt+~= C NN!/X& ) `, f-\-+* (%#Kݠ Eܛ!8t]4 $YNL`L ݐ +۷6ڍڠNڊDoW0) v9>;-VsQbr8#&)?%,e-.r..Z.2.-+<)&t9#$ T >  }E]SJ>6,j;Lj%eq |I !X_yjq `@jpqDX+8 IsRT! r  B3#&)*+Q+8*g'W${!" Vu/ )p= iO uT- `<CڶRڭF"$?_ڊmrHLra'}N2X N4>?X z3G] {;%*)gB,م./$1?1s3_4255+5.5b$5)4Wd0b+d&gJ zW; XAna ~ߙ]rՙ? Ք 5 , f 0 `ҭ1= քFP ~P.- T ?(<6" U#.% &X&&I%}\#L 6@mV ] 2 ?U3  7 < ac G@  _ T"$'z*L,K-.}.-#, *'$ o?smN s87' O `p]oE88 6.9_+- dZI$GhU<82 > [z v ?KRw2i7z9 P P=C m4 z .- q|RRiEm  *)(%qgH{Qk I ;$Keo=;?5MB   K; [|"CN&03)2+-/6111ua0.?,@*m'$C .URN' {qn 6 |/qP8fL 9[>Mj' ZPUUW`Q=)< ;A4א\Րz< #V!!!o#!׋7[f#Hv% o :EJ ^ A" &(* ,--.-,v*((k$ =RD &S $Ow? -c_ }QU(!+!\)&Z c9 wE8 * =U5X ݳ|ފv_=w?;9)#o  j c*!EO!%PG)+,M-(,B*'$(+!?(ha& SLw2gJ%n E@ea%xWpO uU  ٢ ^h~arGbU$?^@H= U!C@vDߪSz umu'\>E N 2ut [J|&NI z 5 * W ?b'j g-VF\ H_TU]s[ kK F_I-(f^BX^ :" >RW<?\0T3ZnZ H bt_1Nih>z$ f46/r yG!>" v#\#r"[! &(M  3v| 5 #2VQq"I&),-.....6-V+{\)"&4# 1B>e _$EKX| AbFm/!!!; ށݺݢ%@  }Fq% < n$"I#TEfE a 1dq-?9 w/,)ub7 SfqE+TBMGS\lfaX)}UI} e ] BH 3 7 \"pT +2&$p re\]v P`1U@49m4P;qX Tk ^ "I'>,v0 4 G5 35B5?5f55zM55p31[/^-e*'o#4hq|z M!~NuT(K267~ p Q | ޅ }ݾ ܰ Uj goۼY?PcVf(r 1::i~$m,d]"bb ݦ qD# de L %$ XH2e#d#f 3_& / *@pm'H4Jd$=oJ+'vr(!AJR!f-!]Y-jr v<i/ 0c|!U!^""4"|"04" !\ LhD3 ,  ! V}qU1MgOKuj`u482M j 0 >CV F>_V4~Q[?A , aA!k  N'\c9YVPk}` /h!4BNg#.G - RCfZ=v7'Ru  wuHw@?H Cdv }h ߶ ap 9N߾UB/f߱2K-4C )gK$d/ K]u0) Ԯ ӑ dӐq֗r2*5PGG \G [po^n9HO]l>~Tg3]  bf O NZrIj g $Mu`oj)    z =R e  ; 8-MG-6( tIox3b  o` C C  d1  ] V *  # j#  g QM ?k 1"$%QE&m6&FO%#1!i|Ygo#n#A<7 ,|f=z)83'Z9/YF! C A}ܵڧ؝XvoXp֚Kة3M[p:f%Bڡ٪ 4"vS؜U,6j!ղo^lkW#Ij?fNB   t P$Wn+3v!"H##!$$$$$,{#N"B!_J aG{ooB hYV-  3 } l F  u VD x% vyd1d!}Y, 3inC P[+ydn@$MyK'DP Dy(27  "  /_ E0Tginr;t=vq6*( ' ?+6q O D$Y\ i  z z4Uu?poO, q] W[bA7q|I 4rEmBjRM.  2#?UJRoUdx %t 78\pxr 6w!!z!-!b+){) ` :7 N ( s} 5=P[t {| L t o~>)MxeUtOMR6R r> _{ j.()h / % 8a LG,&  c1yO=]81  /DY r u/V ?1N;A^7RM>WGB7 wS9i(F <   1kX "V'qOv\-0k8 E)"B&)k,/(1' H3 4 ^4t '43*2q1:0vc. ",fW)%*![t1 _8R NttuP]/MG.ՄtoԴb4Kj&e$D ?fnE z$I ~~ߞsi5}=I`JI 8 k /7x5|Q!"&$$E%$#!0 Uyd& Kf*NILKaZ +|yC-HhVtrMڠm٣tVڐۂ"ވ[M$\>b"10b ^I m lO D" cj~Fz 2j b!}!!Z!` fZ gXiyukt'8B8gX 6< ;4u> ?  >  c D @ _ #myeh l/ Z*]L '!mf&UZ  {Yn0MSr  s j M )=eo (XmF)a[p;'Cb%  h\ P D Q36XSqJ *)qKSٱj#zj  642 8  8Zu11 l TZ :yKLOt;  S9T}, *%/+. QS V J3 X<(U \  }[ }pr!Sim*o  A r \ ,5) 4 O N B - G Ik"u73L._GK@K /uu4u> l  G `1Y!ZsX?(+v * p Fu j:9!"$-&&v&%$7#9!897sPTXCT1 \h:Q_Bk !,m:_lWk!y%R6Xfhu;1lQf:  G G 0 epH M _ & Z. Z t nJ  ^ =swt 7 d$6>=d{ [ +/ (\*aF@ $XݐqH 8 C s ژ }Hgqy^  McIzo=tC0>] !^ h R ;+h6(me  *r xl'w,d0Rs n TN+^>w$OF_x ` - !)<c +rV3=p~)}`JfS  ; % p hm}7 5.';BZ7 O !B+I|oV)e-p  =4]/8_c T cr <zi(yMSjy27:4w9x < o% Hhwu"8IY-: 5 u v g%9QFmjS R d X>2nna~],9m)}r[n  lTFJq\l&0H_Hd  dJGc "a$P&(Fa) m*1 + +E*(&=$ !3AU^O  _;^{; PX ; ߭ NٕW44<G_oM){<~rS(k 7p'Fx{Smڽ&ݦc{GITn4  M dU Lb?vLv =HSm N *kOB  VVFs _tn*h+^,'4}Zbqo`U4[U1o?~JL ^ H :yY kB* >",$h% &&}&%$1#N! l    !?!;! 0 n9OA0'o("l6  Il7B =v m p J\ [. r h *W>~|n4WX(OyW{ C Bt~I Wd(3TRu}8\   6@I%'gX) 5 S!Qk`]Z'4X13]aW=1O7'Y/U0 i  p(7icP ` U NF  r fq7v ej=G>TS>wf) N> y   gs')q '   RI v Mt i SB  9 }`j  g t| 2B! OqNFpz>sL7 c  7 S uaPis>Vpweh(U$2{Tqmm,5 9$ 7 < % 4 %q 3 z Je s$ \  $ sf i . 4l`O"-c!YR%R /h y }OSW Wv #S{/Zx8X)f[٧|'ڏ4oE+ Q /jXYjQ'$%!ލ] Q [" ڢ ڽڗx|k`iXuy8e4%g     3j*`y-6:D"%.*&h]p  ]@>V jr\y {UPHPqdgOEտBj0]uiNZ`{L J yD)1rG?q`  QB3nl ,p/p"'  VE 33F+h'f &@towfy/oqaHH<ԯ84؊@>ml-_ /g Z>Gh0!G n8vq r< lwfA7eCCecB`JzYl 8 1 f.H W $7!+$iG޿n} WP 8g 9 > j^ q P . ( 'r|=spM{eyJ SO > > u # R ,7<'9C# JT H "  ] S o ]zK_ZZuQh(! ys $ Ln&,^pwJ-F"Cu-TZu!+COZk?u~cCA1L8\! (    i "Z *  &x  u + I * G YzX$gVxU+c T++ L 'R}PO(;z"$& ( %) )))E)&)E( '4%Z#!5!'|#$H 5aN/} 7;2l d% V0% VUzg Tg&j'u3)#j @ f%>~?DV$-X}p  }a  Vy 1 K &l181Bj/>X^H 0 . L=d 4(O> e5pb+!:+YHF> Gv |QgkLGnq\L*xo#N p!##J $ #f"i !9{A;}!3j/Z `:B:W.>F ) Mm id ~R66,Wo#i1O69oT Om`Nwx m i:]ObLes u Em+h~YExb !Gm An -C V H(  *K K; ^ x- c a a4 7 *t#.+<\Al!hTzbi8  6   G ) r  X  K\cp1d_KL/<:rB-n J Q 4 59L9s^ GF *C Yt -QRt 'i1 "e^ߝJcn.[D1]B j Cji3$4MYbQ@ I j|1}~" ucaXTTD|%=+LXjclW&9 $|-cm9OFA?fN~O00 z6 O  Yt     z_   A (PEl[` R 5   Pk - * NuFj[# {8[5Aq~%< r-YB E c  L  W 7U9'a%R?r]UOsRzh[o g :E[Lj% .w *Vk %x zE2  Od6nX [HL H`VZw+kUnb]QqLS+*i@+{2@MuB [ yh  5"  }  C# 8 92 . ' . 9IHc X) =Y ~f Fl tC|aV t=1-.H<!yaG" \!C"""!! 0B A"{_  Z4sQ[?a.ݻܤqlݴ( + ^ * rZEqEq?(' . M(EY(Ex }< b T U o)u[xg B -gJ.yc *> <kh2#nNdy gk,~3&F DqarEP7\Z n<\{Hs) Mx!Y4;MO*@ G 9   (<ceG(-[n!9CF ~@K ~/  &GZ)2I?;a $:&hD  O /Z41Ar K31qY"$;[R~XK3\OxC $vWbk3k \~<# K g 2 q[CHA1  t Od /A \aya g 6h ( g \ I z ' Mf   $1E$DG&kJ6D}$ 'f p s k tZ>iCcA )h`L K c 6~]j/KSLikS,S(-9 lo S jt  .k} j ,@- [a%/He+)[w1k $ jH(L",>#8FC;&4pP @:\{0 tUhU 6O]+;T  U A9u  { Lc@]aE^Tx8&$r\ob(* K=6$l!WWfݯ ۠ 8z ]` %S JU(۸A7P0 L# {BN!<kNZ p  RK= T OZ7LZ F +i4)p6bcROE2('  ~t roWw`Lcd1cܘZޡL=DFaLdm)m3dp((Tk { }  " d % 3 #Hc!fb Q&H8O&*`~P6h3H iO )  =QZq sJ KB   i } 9\E{Im%H-Q5$_HR6[ 0 S &~L6w|b f ~  %  fx R)0xXTR\ ~n+]mBA eE  :g8&fW.%b4ta(+I]kv0_p*=?)D:oIjlu k%sr{$1xGt\4`DqOTG\ES_{yC  *% ==  A Q {  | m =  N ( 11 J%^.QkP 6p&H/D8jWݢܥz:٬2یP݁ߐ <#M2?Ws w I GH t(uUK37 ~ ;3 : 7  [   ??o0a\1 / n i z RW2o y2[=)*q1 E?By3܇.ޡKu"z}Sy)%aNl8;lp xy ?m F 1 r RS- z3 < 4t Z ( M%  - Rn @.r L3fE dh @6 y a^N*][Flk%&0=܊%ߨ~q"/je } Z   m$  @ $AgK;hbg  Z| '  D   F   Dz#o ?+${6J_Ik"w+pEo 2 !   >V  8 . S U _4v]%ARhX   Zjb./%#4,NBV<p>X2>'>sA5pA6|+W = z "%:(_C~N; C -  -y*|,. .rB$J* z wwCLv_s,iSG0 u I 8 yZ4Kz=Xy n N D    A]  x 7 j ! < X DL 8  $n0l)r?  % IhA' R l: t 3 S 8 % M&~Gw{K"[1BEJ-21X?fxO{)`M\gBY~  quYX! */* Xo70d &  AMwcH(^Fr^xt^>&"Q{N Y( v ?;^ 8 ~{=-hMWD,cK Ws0 'D  U E h e     = a  {  I+J "K  <Ft:&X2R5A.:   R csA? \_- a|7Lwcv<-c Z [ wMv b E = goky!{!`r Uh \  X /'  Q' Tt , X 85h[Rn0  cYK+* LW<~ilPlm$^ 7I+jKU %h,YMp(9PZ!e C C ?qOj  CC9Fq}GNT ? : ?  ~ xD^8xq}b $ 4^>J3#pwk  Ap4 "|9ceHa-'?.\ xXz.JotWKR-&NHKOl:LJO i6Sq+}BP=PS>eޖ_'>;BQdYtG*13! \ݯ'څLAٱg٣٪9چ= /x߇Q|> X %$vF#fR zU^ - u(%^~o   !cQVofWj#bSn,A} \X%7vgmQwCM5}X$NW(} :3jyOKx).#TuL#I@<?C 0  < 9 VP # !%w% =p Z y ',pF`Qm ;3eYZJl 0f2:e8tn J"]t#i(rw Dk lrEJ C8 9  S k?Rz  1!:# $ %[&[S&G%u%f$#HT#" ""$r!V t' ~E nX cR  T m )C ? $4 6ho}6hk< ;T G b+ XbC fI(L< 0 F 'V  ^B4v R  x m@&N  kb:'a;- 6 c *+a:U 4QO4408#mU tb %M7<|^U  >yXaZ[M~5FI?E`8Qxz X\ rn  % < WfR@= u&p:. 94  w  9  9 K |  0 q  ]ij@^iPM4 6 Y ?A7$P!`o1_eik 8OLTz8HV@  8 -!  G = j l jqv+#/ C6 5   z g\lvr_U < ; >: 4=":zQLtR8ym#O0!={M\PJJp3y2U~BNAxIfTO Pe l T,Xc5k^3+ : $ " > ` Z  _ q \ M 7A uOMq|+fE[kikr : Rpa=^za,{F AKL > .I$9YbksJOHt n 3 _ )n-4 S- "8 W P8j ? ;  jba>_=\SrFS"J?0:< Wl*/=m"X\`Ha~N\ .+  p  p   7  <9#i`A"|]D~Blb'|:@y6B$ LNfU#)=TI:t`j ^g;a=09esX$k/Y =|K)sDT cp*Y q3[1x 3 SQR| _G l  MA"i]0L.JQ0ViNm]i.Eqjz0  0Ai 1 Od7_@"l n^ ) XnY 8&[$&Eb|N p#kx[s2c;<e" F M w - }/ \  j2_!l#$U%&&r && m% $ # " ! bEKFY L# o'D ^ V}sl$ e!t 2  -mi~D-*`Qk    F$7^e|_z4p x  mM BeVn0 JK.3=e41zH$'mdn\%.OiWa2AMzs5R^zrYWl,gcY$}]Ge"(\P#((rZf& ;@ Zs 8 Z 7l|A/\+vxQ | qL qf    $h );  |    '   B  >TZ4> O CM 9  diJ{v)qm0I)b3 t &h 2 1 R m P [ ` Vqe|uO 5 5 <  F h Zlh_8DM|Bsd GTI1H1~O6oZ=Fi{*.#eMvY"-1f0eF?S MdX) ab et KW  N8n5tr,U  s6D,  1/ t +0 V 7] < N1 0 lGWnL &={LR4 sl y uT <  'clN:Db9$x E  { x ~  a h  j   :5 a h 6  O [  iUDN;& & :Ya7!k_?\;:,2T !b ,}B?QsdR^:T66mv3Xi~p b5'>|75 0 R01B}?n(-Y[ 39 z Wu\z":?{eFKP $c3Z>`k~qLJ~w)<"Kn0iFv q {'~&j`9S3kjpwei] $A, GS/.  ! v+.D <}e* r ;  | ! = bF # &Sb&j'Jn)=-L BeV6ghH c$q8HUR߂`:L߱s92vG?VE,' Da < j NVYd :0 Y + f %v`O])F lI`  6 1 ! = cn ] :d-BG]y-]xt(KEjq AZG]Cdn+g|}N4c`Y>%(rHST\@a_;[WrU22goUkk%J>N-Cq t]7,g H O 8  C V #"  tjM6 9  B  u $ F = oVxv+.&FNMr#x7d3e YLZkU9H uQ m  v]&<" v nL L  ,  ! 8# .$b $ v$C$]$##o#i;#E" ]H - l  T  <  , i!Wh`-Mt-|1KIv`' b`@){ Q"!cC [ V, G9:l 3 \  q{HY!~B    ; EH'F o'=3?B!E,> iG 4;  G k U @ bQKQVib&$ r<_3q^e{G9 n P ha (  )radhWoR"~}3v{]e67D/%+Jl OlkRLxkV'P^e?qAf JXq@@Af=~)$2;;kD+oiLJRX1]iLNQPg11tv*0d  :)L zWu;0~7V`=q>z O |u # n   B?&l9  M%   }\JG  8 x J D U `0  %w    5XvKT@HR[\^}+S v9W T [ R y/&.F!=*OQr*eu~(7gQ8UGwyWw8-  d"=JdE\znWt#= ) * +9 0RlP 9ZCHmzVo-.w-a{<c9ZsXU g2.~ ` Y&=)rHXEmX03YzF?jYe r, Y D i4z-xfS}VhJb:`' (    14 e l i z>F> cb.!55`$J.3mN9I7 ZpE^TRTkru*QH 3& a^e<7'X$NV  N9Z#I]AJvr$b&GkFQw_bi-n;IGw`xj;'.BMEv_'B" |3nVo2tQyRn4  4E6fgQ=0afN|)iA;[[E : &f[`z^G  PQ rb/K:8]W5!_;89y 5v; z  o w 3 + $ ' v  . ,'S|< d +"cM O@~H0 ky ](UdE  40 2 &gH[aWH1-#9!'cm=G~nce =RzTEZ z $  # R 7B0"uy!/"8#5$.V$8N$j $#U "!!l# %&1(A)0**Q*b*))(c([6'G&E%>$ (#k ! =0+|u]  ~ nk* p7 4 N @ ( X  ] L3 > ^ %mE!~d@bp;~DN&Ho2k: u h -\ BO / g 4; 8 S,V,^&,]iwBi) - TK > ,. gy m mo,Yke L( ]G W 3e d RK.`rJK%F0g3_M"5`oUBqxN [z0H|(AZ FKR]+ng 1]u |a $9 'oOj=w,! ^@U3Yz@Za Y @b1o1qw|# =kQ#-_?tnaQ?Z?IuI*>T3P   |ja0mQ  h j v mG XkeG  F C uM   t6 e {$  5  dt:a     \ V2H:7IS 9^Z:8KF*rkpg17 &@sF eW %@N1MI Al=T~=V]rsYED?n38  r {  0 zN Ao O DR  V  *L k l F B :* oR}vYf xSdqAvz eP S ? D = ? b fG ?J # % l 2 T-D}G Vs7T ^  kfT:[dwVT (KW\p]6 CS  :3x %a4%)-b_&V^,&!oR`R; X!  :P r h _8 P p h p qQA;-!{I{^69~ rv1p66^l B'HDCHGW~bx, L"*M=s (/FB5b0NJl7} ; X K @ kN Q D @ D U l V l h Y: UV}z'[ +($=Fi@7wr=poM^5*J#k$#o/rAJjc`j3K{&E~ R la \ S 1   >FFKkjEU Z*uoWZvK   \4  A  U [^`6w\Qnek&IZ'YV h5_%m`A[wz\@m)bLu}=HoO]F@g]J$lWv[%nP >4AdqRM/Q]rTk#/ |Ij2Jt[Z.i+6G#Q{K-f@s1lcD#  !+' n  K [   \% [ [P OfMYEz+tuo9_ Di~@_MLB>;0E,g^F3 llin-%uVQD&s/A 0v e 4 8p$ J  o,   , "! q  T t ,  )d F= m  x " y y ` j    af a. "yp/hs$ C  4 l  !      i z ?   K -: cKhMr L6I^EZ,? n $8tIsA|3ITj _%20{A@x6Z8JM9* / A6  c>qZ e Kc s  PWstmv[y/Kx-p62-Qm1V+ .Z  p    \  _ Ej =UL// G1kaQ$> *r2F*+T98s,i^c.{L(PRM#ZF'6keL|=5[-2Z7 WD3  ~4<).? Ch f trY;##=cRV@BF.hX/^  d7 ~  ?$ P ? a n w`ygT;  Z8 zwFPA_ ^7|; _ 9 X] >NQPe9"f z y  Z) JSjWvt s h E  88bd~q$J*  X | j+\T   E s & ES*T.dEqd!s # 4 1 -kZkCS}6s+>pv;Ln'bV_qW,i}!78 >  F$~"iUAZ?MIQ (  80 `( M0mg-Xx||/.o\46C|)&oeY;lt= /p:c*@4n+{e0MW >A* ]E  Iw.y"$3Z#[/   HXy7Ifw{ 4L p ,~ S~ 5q H  TZ m+UQ& j + /qeTWX0L$7m22q5*_:$!7I/"IU ;,!- r qw C - bE B uDd~ ,5?le"MFhޮXQݴ/eF ݰ;fB8.G [(S0xdjFN6;->1 BihEs^vMm9d(C&J2-{*fDXk6+:p=T:# \  a  VH OkzB IW%D5rA;1ttC}&#RFA2Ty3F=t .  -g M? ~:J]bd7(Xb3Njr ?" } VT( a>l<I^&U9m.|45& K [@1u&Wt~(P:LL 5  3  c   $ J bs.V]0)/ p F a M z k +' ` NA ? JOUOK}"G_yG6JcF{Q\ > a71$~%>`4)wCk'?T+\WIO7!vAu=S KC@\/6CfA*<q%/VwF %VyG``Y+)U[]($  d# 2 ildBn1J2 l  ' d F ]4z#;A- $!l9"zl"D Z" "R|!  J (.]d)Wc#  9=C /  clH$ < = F :v 5b;L;& %|9G%Fh=' +B [}  m C~SB94a~G@&pc]SWx 3k<#U.] 8X}~{S 2S9oZ81CoY4-KtRFvck/[ rf D .*(%x \  ~24 !I?UU/'\mf%AM 9e;S2 T      a ' }G@ZTRcWZWF_("EntE}A] l ^qL y  g =oI5 3  w2eu<X|,])  bS 4 + 4 EoK4=  n ?  N(%kKRTtli +  x - (] & A   =E H ^ > ;A M _y Z -(  3k+Ibl |P(f< =M8 uXaQ96S{/ J $ol"Zv~e>Ly~  { ?   X u Q  @0 iY X*[ iD*'V p&INZMJe_24Tw' #M3Q*g0wtB,B+R?+2]E t <  y#i./"'p; ]-K``b6Q^5j _VPup9Zf$u#) !ZlIsbPfG 2ZE7[Pq[Xֵ3Em҄m~ԖRWؔc ܃P7lzA?$ 2Xi`OV|XiZT.g,5$fV#(yv_>mT/@! W3  ONhT w4T}Hs- ", { BJ;m1eNXpyhT!{qiH3(=# |O|~KbNNZa_L/Dd.s   ( OB Ug}E ca4|Y6]r{ I vuR4UfJMS&3d.X o 3 n U 3 " /EH DFozwz4&\ i F  &l #  ] [ @ |, H3 ^ }  \ ; 8  2! !     A  m ," Mphv? +| 6kcnGj$/ HZ&asC&sLh@jy 9 Q   }    Y ; ie((AlG&R=jv}s)NWme U5  1 @!#OYds i 3 EQ V `] T{ M 9bI0 v% j <o^xS5d#-i5nH;,lkNPII M Vw Za Jp $ P v7_q5ia$IsEV;  d T  !  &qS'=dSj[3z?==j|Ni+':UO'^f|Z23{+/,p]v<n'R,(#IX~\J\ m-q *a$%s,;)+H]w7ge! 7/cHYI.7=>!N#+&k i \7'dhBiCvKn}.I=Re. ruqcXZw  $ Vlw;R  h uN1s/T i qS f Do1k0u  0 e ?} }v0k92 jZhY_ sw xW&q)o=lxztiTg%;> [- ]  ] kp $3 x ~'*-o 74pltUW/+' LK Mz}&q6 Xh/zMHJW w je ZRh 6$D6V >3U'upOdQ/*fhuEmw]C o ,Qoxc@-R\.\I'O T Rq:{Z+EgYpqR _,NL2 { Q T;]  _<vD4 E  mQ>G !"#AD$$$$t$J?$#"=!!" |7PG9.' % i/ T V2uPIz9_@40# b h w o6D7a9Y -VB_L"Fmn` _|ހܔ2GC\ײZ)קeۏQܞݙizVh$h`4$P5~Q`K_ jm4A/$ %j|Hx& k0P )&g W& ^ ^$@8$ 2owM@ [  Y n    =+L*g)P}p?kfF!s $ kW*A*b_5{5G`oJP5yDx^ { @ O * # .G  6 } F L5Nm KB \ y Sv4bZ?Ou:e8}[rAcMEhZy6}JR   1~  ~ }  ?  QA ax  f  g Z ; R)  M   c,+y%g4!l!;#x$A&@<'^'(w(o ()J >) ) ( (" S'2 y&$ s% C$ "\ f! x L H :~ss)nT ; w LJ6.i.K6oO! C]3K[/ E c r ! +q 7 x   $= ( h  Q b 8 c u v @ 139?M:p/wt'Sq\G tml t?W)i^$492 - zg> 1 rnSgps7oYA%JhNV=9d ~  P~d  >   ^  q eqoM8T4-}n%BZbztu N $ x=x?/Zw Z )RA_bk)jqyH?ިl9s܄qܠN"Cpr=Y=~^CnME. u U ?! ,,d>M$O7  z@ 2 fE{v ` BWw4`)/$xYNOjgrz   F} >v]A ;YLF6 Ps u7e3Mo3DC & SW.@`0 4 58a*i_}  zq L\ f Hg-RUHOjThH  9  niE7JPaW\S,o/& P,JxH@#jn~4Ad?R;O}L z 2sP% L, a,ln.K . { ]${8G h PVP^g 0DsxlZ&V v PQ/:Bv!kt-DF5 FRe5Fh-J(!g#Cv]H70$6T(de ! ,c4kb"x_ nR ^_ mgZK`$-4~*H!b 53:Gy I4_r]I   , [ P m  v  x2*?53e)A[W;gKRxnKgf;pr_^7#II}n[o;b [j   k   ' N  f " d 4 / < ' ~ G ^ 5+UKb0)%PY -E&Aky/nO0Cء,<ӻҪѺRBљ<fFֶ<)-O$x-'[eH8"HW9[O.g6,"]EO]uk*q[XB^x 1P ;gaU)-3T]Ow]"u p 9 7tGDM{dYt xywh;Nu3J$a$9.G"!:jO::PD$@]:6CSzW<~3K  p L / 5 0 G <  Y )A = /X8^"Lpfs ) #S/yK 0qfl74$CbN$]x M _# bXFm-o(Xnw!~B& "j k G   hG"*:N^mX2(!M">$*r%c& 'nu'|'u''k& %$#m"1!gXH  K  a a  0 af  X ?l = GB/z Xc9*/0Ej_h7l < l5RP #!346  r *q,I baD{-NwK b E ` ; ')y^ !nk_?\ jG L UJvj$OgOW VzYTn$y M~ J lhY=-&x.  6    \ tP5~w3i`[;G-T<i'iMO9= kE `Z  u<GIQBk:~:5b6L. ,X`5 i ( . q S^i~ 6Vgy[<DG!4+? |  'F z  0 Ylh{S8:lt;b <Y:c;<F9Ue+2F6CUn p%]w !|TdNDKzb ];l  # 2 ty 0oYgp(-IbW|5Bn FU3H/ewXi}6C  m ,*oC 9' ,8"7\#T5$$E%F%%<>%$A0$e#ht"l!H T~F]i'<f % g ) eG726?A??+UnB R"QhX]FCExn!j .c64mYPf/1(?Hcބ" ؀vOyӺaӾ2R֎ۜv z/Cm[9* MEF]Z0{mC=zdm4jQQ~{P5=U (J U! / Q=-hUh/I x  D B  U K[hc&:pvPR1j # . VX    G ]J1 F E#pF4KJ[~[01{bsh) D7{W;B595G(4 ! I~3\|OsT" *w|l/_  }  T P' Mkc3!#$k%%%2/%dn$#w"^!xF 7<h X   &  k S>f'# VN   4    wyO!Kf= hc}/6 [ _ ` ?Ne}U!.RXZ k #H c C  F    2Q   H  | _(<. ANad1M/s>܀w١؉؟$;ٮ n,1,j[|:7$_ huPP!%t  V(e^_' R" ##YO$$H$x$+$s#=#`"! )ivo_SRC_rY3:Xu ~ | |u }'   C ^.zU  H  JJ  :2 C[mDau v( K+ ;SaG{jG_uY= / : ? / , Iv q   i:LVa%d(UIjHw8!9-mk0 Zw< A,jAM  P~LbYkSz"nsdaJ^[JyLC/A t w , K y   D    * V  m>97*B{  Y I N9Qk , 03%, P`jtg$,mFajOT] > N ' h 5-)N_$I8;w  8 Mi:~Ua 5 : g` %P<%fY?kM}ntgY  W3 <;]2 V64!"ZtAE[d(T3&`[E7j l @ o r *JeVP`/ c   u iR %N1i$'7y4\|n;kBj0/D-zs K      $W 2 Wq"=8,J Lr0R?./!&Q @ 3+- e iW< v ; `  c K ] !9g"g"N"! F9~b 9 j }\i p=usxl?h^Y~4')XkzOV \O@@9P YF |\<#aogMH!7 )]> %/9Knz[W[4s J8Y#z'<I'vl,Rl)PA>yqRi0v*5k Tu)}$dS*Ph5 tZ9+tfX6Bu lz n m m.bQIJ@Yz0: I /  / r 3 & x y as_st QW&oa:!Z5(*@e+yJ4 d8gfDAj)PD(=#`s/!/~(VmoKi\O/Tp[P@Gm ]@hh1d<c3\>  ;. W nlm"S0jM5cLiK\bp?:k#O z  a  i 3K4p& 2R (&    Z/   *@!!B!!X! I"L[*l 7!L""b""B "J!)  6 MV  `% M D\n)Q;S!   {O0\5_cGH ^   \| N  146/=1E@~GlcW $q4d T /NPnZ1c-bߧ=߃_\8O&(,-;BKai;K P 7D"^!qv  *{+)Xc2![!D)rmt[(Y7"MxP-;Adz  3  | \ K ] w V  Y! | q u=N) M $  PM !"\#$+q$<$K$v&%L%7^%X%p4%$6$5#-!M s2P mID.##q.<U 3 n` F^ R>  ;  ' ] &d PB ~aB/Q,/C$';f^@n?&EQY/L2k=G>A3ENb#|d 9  m l' , F_{<   /! -    Y G S,]dU53Knst-l8MVJ-H? eK'R?^   %] u  S(C( P V g   I3RZA  [gLJUyhD  y!?4]zX  6 a6t@N.At5P=  V   H Dij1R<f )e bs{bxhKTa < ' a ] D m_ b/q!C    \ * 5  j(V+ 0 a < _ T L ` O >fWW7 &s'Oa]No+ N% L> + I ]9AK 4;;A-/2z6$.]_UA"%}zR#ErLy/Y1  hV4 / . :ZU-;7q>AM12]E tge)nz&og6btjAz9HWQMn"W=GrnwSh5xa#q6UJ5pthR|.^Vu@d/)4. ~|d?b F E k , z U//p6W&8" D%[RDM}#BT$ f . "  R % ^ b W Y Zm JUKCV2k6*v$q O OzR޾sݝ x>,~g> S'? R%]65a0;R(KC"U;1{ pQ(J&k :G8',Kew ^Zu>Jg{4{" g 7'OEg.(1oOQnI-#O^ y  [  cC+,Ll# clMm)R$(Zq 8"o#ci$d7%6%9&P&(%&%$# Q" z B L   {~ {3p45 U l e W@ B jvxk=>2HxE9*QA^-J-eL ^ M Q P G . # GV'WvePw_hIR>xC:2{e߿ZxS ep s0t.1  DgwjK#9tE@U(N` &fudkfN6E< 5  x V Pr kV C T  I   }!j # y$| %- ' C( )*+,-(---`-)6-,z+M*(w%7#ah sy'Zl e ^%E'U!_ec;_W"/8?J2 l`  MtE,Zf d j / z \ g! TMw $}Af,_ g KR(9F;,U6Dz/:e].(F|xfYN'6t `  J B E 8 3  - 9"0dCB&N7w(c-Fr2|StS50sV{~s73%TrI u `,mhbj[BB}q<RS6 w > ; 55R~)`V Z  m V ^ =2  g / Y  Zm*ok:~ {=dTjhd,x|Pi  +R s M [  \C n z +r j[ , ) 4 h x `U=fR ?ns 4Qf}N8ILx};euU3*a=dtV]5c0  o ,     3 BMW3 3 C/Lyl),%u 6a `<"a20kM1J" 2 fF L ) AZlI$ z = " R  [ v~1y,lyE4*;Jr&tl$ {%m>mn  [ yc9uS_5n:d}NX !7/T? j q gy-/pN<! &E} 89y4WV|kz  h ^ i l? Vh  # >4 wEPGT-K]!=A/ ~]+]#xD|U1zbF .L uI*"";zD !.>O)umdGfYddF$0]PNuk . F )i%D:7RzgK8I,x c :zJcI xGWf 6"Z4W//PF/@ ) V V +okFu|i *$<+:YZk; u iJ !  Z<V   jG YL F/  ` Vk?%]N.  uv w,!* YY% 7]VjmR 6^G"p3*=}d es3E:TlyB7 *  5O/R#!'M?iF '  w &"u]v9Ez%@AH?)q{.(CH   mRhS/e m$ em5!F}~A`SA;Pw$'egN}jO1>#|DFc3uC*YI5/5|pQn;B-"qf@u12lp+-b1ufcKv @)SAg-8 , !x {&*")UR" $\%A'W()L)T)p5)x((0(}'('m&$&|%$5#_" Sp QBZ    0  \     e  V %k \ -  I]   oI P ~ Y \ g  ( ZK /A A m 9  :` B $9aDHA6+=,uE d v4 L . :j [j &0 2 ^ I   OzAf /0XIRVdtq_TnVauK}_K::Rރ5jn֑\WRFl>yܳ zu1 _P{fSpbg` M G&Tfw[< d!4k"b2##$@$l$$|$L$$_$#d<#=X"3^!Vb h)h`6LN/. Z0|.RExQH+s jMW8+]!(5VlW6La^duo >) wijR*T>L -!3>a' %dwEOo<-MW6\sT@Y g+  v?(#8{@ N FmURET2:03 S8 ]kHROtsBnZnZ[rOw\nachd j 4|  i 9 >h }  d Y  ( riz7 & Y @ D d ] > Z . k bqJM,!.kQMurDG6=v%l8rIzunYXQ=W^W >"G  p3X4`ZUe0B&>B?QbKz4_HY5YEw XSQ8xp[Vw[yt~wnDku+C5M d  5 u  J  m 4 F  <o  b  < _ o ^ c  I zHw< C  4 2+x)`z[Tia   5csGlblXN{)E<"Q9fR#M = v*E#.Z:h3 \N ~  W ;qSyD4ZP.e3Ef]1!St8~e>z[jw[U m &j   S % Gd O 9P2H_9S U b %  WH 0 i  " :mlhJ.>b%qYpgsB>C_ A#^7r n8YQ' (j kfG>oC~ds/|<D3oRG)w sW 9 '~ 7M Y E U  * 98~`]e *_7Okmh 0x E "vF8~H#|FFk>w*E-/D9nrU]:%)Q^\/d*<0hLbI@C~b|[\HGfe?v2$ Tb,/޻0[!%4\ޱJ& t{BN jQp S p C LTRAI^ M[2/4DR?qx2[p@@]~}Ik6k   jU^R;+5KKbrk 7"#$%#&W'(c().))j**.++8*&* ")O'g &V$!!CwF|i  B S e * [ O 2D 0 BFX{?Y ! ,n o Y o  y v L D     # 8 W r t <  ,  Ekw>kO w $Q A m  Z >2  :lt6J g<l~LxnM_GkH wO& t"E0i,.DaۖAzzu݂U|4 Z 0c J  ;@ qNmx p^u!}f#G%g '()+ +d,,eU,+W+}*z)@U('%W$#!r l1F   V 2 e   v ( x   -4&]i\|A{SZ B AQ Cw @ < 5i.64B\G>0D(%+8H^y#N/[YvDNRcWF Z : hSVa9`{[q(!slX @ Qw8E1RvkxFL`csVN2P;aaeR1%QgfY.-U 2{ | q{ 5   o ; B  d 3 ^   e  @ o  p 7 + 1 '  rk ! ilSSVH6)(r&Iw}, .HV}GO8[&vBvlM};r587/`e'|oZ4g )  N ; y+=^8{ ~@\t %U | w kzT -a A  N ,Sn=/e 3 6P2 4y /"^K & o : v - dhe5V"wF&]g F1D=nzWZc5SmkV!&aZ"+ld4p,(d 5$=lrL-B\^{K[a>'X_U?X>2'{%r6^'s M1 8 #M`x&Yg]jZ  i =dH.V !? FW +W [ O6Rw,G*w(jiXg' m m oKQ^3wF o;'`pxS{B4W+b%X#Yz>k,e3 31{ a2Wea=N@?l 9z] sDU#m>jk/ J     7 v E l ?  @ h0 n HR w 1!o"=# $_$% &pc&&&3Q&%"%[P$ P#"3 0nz8j  Y  | i*,Q^]OORqNJ^ 2B f J   8 F 2 n b ` > { 2 ; ] EO f B K U   [ 1  1 0  m )w3}Uss9(59n[(LVH8\dN}57Ts(]1s1)` M*miN}|bFrR+2zq]+VTF2LKb0  -qH VF "Z$y&'(M)l)9)(V(5'n3& !%{ $"*! >"mp73^"[D  .HcUnl," w 3 U  E # e U W k  [  z M y1d[OCj"sv<)&\l8\r{  sZ.#ZH{G~>$m-Ik3^trexZmGt"1DSJfYyc% UJ ) \!yS|E1( #E+Z(VG "  c BK-,Bx\C 3|L r PH c " l      K   W  O N * 2 V  W  c    J P 8 Z 0# zg  U  ; -ggIBhT@PO Q^`/6qz [\YG+^*} WBQ=*D@`#cZ;qw8 5Fmj3Ks=sBqHIP(%*4S^%jN  s Le    u ? t w ldc $i jq u` J  *E 4C z*!o4p%i ! ? N[L!kdWw;    l <!5'o ,e J# V S : y >Q :.qAB. v=hhg J="7M]i3>zXJ[0O",&9\`$6}D"4aEqLK{T Odo 7g ]u,Kl O8  <a%Y8 } ,0c"   sH Td Qh _Dx%DH!6w&.1U)>NBQLpgkD8?I0nO%Vnm aa 3    A ]yzw07Z_d8D~,)lD ] Ik|1e/+V\E 3 07 0  m`)  Q   \ Q V\PR@K u*/+nR$[{ VB \5'!#o"GHw8f}$\9O}XR-XgY!GxAHpcs{o,gyCMx ]}# -$#T޿VڲE"٫M ` .P &އs%\J_A$7x5;a*=oNPi> [.-$.H]}E64PIO7id} =    14}KrZ h"3$%&'(o((*(3l(('h'1'&y&p%$-#c!%cj>|n5;%]   C .  T7c^~,zqy c  s 7 Ch u)7y3u) O u  b -o  LEt%b]}'25/ M (x ! H S>so-6 ^ON6X-`r!i/9H)pW=~RO e #R #  L= wW " > ) \J H Ni Y \Z#T ; o (CWj*0V M!Zv"g""A")Y! >}   ex-m+er&\U%xa+O *d   u `  * 0 ^ N D   @;p0d(Gf38kaekJa_W ^Il&XqubvqX#I~JTN]tP n * 3 EX \ :  ]v  x W`NQWh~f W Wh  Bt{Yw^V6n.vbq +  @ z .^T (U  ^ 04~ S xG PPqF2rzK)#w9=fcQZcNISV%FA0w~ftO.[&#$Eb)l-"?q >oraim/E>MD@x+#-> }~r78{`0U'Bn J R,,Q](w'{oTycK|~ c]>2%0K#uHf-&ߍv!wZ|9sD,$E I{I)+ P (7"M GHt 2TuPTW3pE;@dHN'B?5RfkB4Y4LrUG&=S(u + %-f  t a7O8[kQ|xh(fKe[ c $ ~xx2!g5u`<~`1;6by|i,l] < V r:8 * J] rGrzdWAAr?o54l\8N|K)wb3d^DWlAVm&Ud+2%qs.KO 'vVadW*e%/N'3vHV8O} , I n S : F R p ? nB 6   @W 5  e   > k   TQ_f3w O!"""z" !\ T scA{yA F YDs b3_b)RFS@n18@Wf@&jPLZOxS WgQW_; cV*$W!\ 0 w e [  w ' r % '{[h"syDx,2)g=hh`=2EFud$ V X 8  u  1 n  | @ G    r@(S4Y E1Mhud_      l8 @x]YQ&g,1s GeI:|rNzEd \t|&c&K{?6O"0'b3c.gh,fR. @S'{3JsY7NjIUl``osktnw#F25f`i?=-lcPyNGOT45ޞVeRߵ+s`, w{'.:33_IKu3X5Z;"MvCWmcPnAULSY8aFNSt.\x{VY aJ 0 V w M  4 V ^Et'4/9kh 2 pV  / % I N b ^A Uod G7fD]c`  / z    k C   u b0 H %! PR2*l  S & t  ` r 2u 7 ` D 0 Lk FyaVF,2o2JP  : A ZId~5K odX&Nla Pz M U& \{2}8[$EZ|!VKn$+|V'B-{    IS mdWh 5  >z  :i $@$kw0@oU 0 e @ U;`-i HP G W z+Kk?LD~@2U`:UiY^y,&\Xv(!rk3>Ma]>4FO8 W%]"ckb4v54^nlj#py</_%mvr tj"  yPZn=dVumJi`A_4 X3kR  / B \ |[ff*nG `U 3 O   +'z yAk.Q o H8 A C ib`2,a1jl!2]~ K'^DJ,L^qc4^g*[I`0 wD JK)~cC%V2Zt|Tj 'qj_}%UKP^BroWO8 /  G U ,h<|6OT{^uQ}tvM R? d < !!("""~ #.#"W"!|7!  E{  5%zN i t < `  DsnUqQ#G=L:Fo @`y`lSN}NQAqJ\E_~M$ 9/2 yC^r_)rD#Lpn5[j.`fD{CO~)Sp3cuH0@cqj#[pol _ZM 5 !- Q lt|>2&g  [ +3::|r|Wa"cr/@8UtQ=j$;%#qIrYHbEu8evmXQRo QeveI45Y'@U`hOa:vIhHRmu$iMC8E(N) a A % +  ) (- od W k !;qYAu s7t4ljW=^T/Mt4Gt$N|dI3%   V  ?1   k  5      { y O~ *  M/xsI!  H  i  f H ? `| 9_ Dj  o `Q 0  " 2E + B Lnnemok\ c(=l4>! #<$%&L''b'& &/$V#B" Q  _Nr7 F  K:>Y Pu 6 a d W  ?]  1   ~ S.  q ` T] s &97+ /j9 1  2 QV#)mtGRP[_*,LOY8ڧنٚ?A۸o)7݂ݰޝX,!T&6MI td;}X=z(Lq9ds0TStx_R[h~M3g2d i  A  | Vzo,(|g~{,y/>)_TcRGuk/5XDVhx+9  G z L u / >ZzhuUz!r[\\fkdWc63EbL!F;~6 9U$VM@:.# +2ߢ;;Cz |DS)v&gbUJBfD&40*?hzq.B#Y?xFVn\.Ko4 b   s<  2 K M  C 5 D .  R [ % fI   4j,: ,1 c  V $   ^   Z < S.  d EW9 V  ! ! ! "2 ! l!  W fnuU2NrqnICY  ? ^ @iS9j7yHUny K{-C H TAI_AB  " Z{  :   F (   -,[1  !O g  +  >  7 DC' pk+5j8Cya-<=wq0SV||F~{oU`i\U tWiSUF 'yI^5Fl/Vc+DHjWx[bxQH%?038 v "_ bv/5)N8f@%? t   t y ` 7  ,&Sny\>?H(Ai}y&-  O  *l  *v KHU<WHosdx&N>K .  , F Ft+gm-(=@8 2 %} 9S \  @/|A8rA[=d  Zj D V[  L & 2p"c }GelTyMq ݛrEm\?ښp13ܟ?:jBq#58x~6yM% |[$V:==`iyMmwAl5[<a-r/K~ Vc J ) wG#T ,J v!"#UU$%I%B&&'O|'+'(( :(  ('%'a s& %+ $ #"!O /V^d !]Tgwvtz`KJ@EP ` U! ! c" " "~ "& " " P"!w z(LY \ .  9 j 9nHionT]NNLrJf4UIۿ^P[ۼMܗ?ݍkޘߘjGzv1RPlRB h l  vH   L g k PQjhNF8OLN3'(V$Cg["be%M&k^5>0 7 1 `Y p#h `  )uP e ?!!F!N>"8"f#$$%T& &mn''"'t''b'-&<&(%#f", / %Dc)= +L3   U[S @tLIcCr^h)go I1B V;"\ ߓݮD(ۆJbٚ+'m2 6؅a/؛a? jpۀYPwT!dP,Yi .._fW-%:ok50\G ;g%CXblzp=d7## o_   6T [! ^1m    B X  %   s e S Q w N C y HD B3#-; QRfuZSP I J   S  ; O #H  "2 c  U$fC!"#%%&&X' ' 'A >'q&UJ%#N": &I76b $yc  z{SY8F>yap* ):]O _NFn ,mFzna?A5HNݘ@O6,s5ܘrܶ} Rr_(xe3a]caK)6p$:)uJ|t8K3&D. }?>uXJlft\ldtrwpnDW*)- ;gv5N>~QETiA|>K5' w9pxAK8wg _ 3 t O /  v e @  ^   /  dis+aF]eZ5u zM-a"bAIHvYa߄0S$"?\ww"~}{xKYo~G2wg?; < t "  ,$   u n GnT^3$Z# gh s b% Zs O2yzL-{De   "T!Z!t"R"##1$sn$$3$ $ $} $ W#K"!>!  %_n^j;?"Xa@+dW6rePR:( 3  tL!L!N 7 I 4R    ` 7b8J  hje? /m iM W!|3)4ks)YNx U[|3'lMKE!VDi"X;qsx`4zidZmY\WKa2QI>\N'0=HU`Z6 Z..G%!B+d% * Un  ^ 3 i| Q"q[sp= h!_#$% U&H''\((H()H)L+)(5(?o'z&FU%$"a!K *59=Z'.arBOu (` : 3^ +  t "J(,X x`,usު*ޅG;ڳ{L+׃ԋhӂS|gfLьsY6!֊J5 )_!^2qpj1uBzZh$L- I9Z     ^ A  ) T`Q&py5$}p=J$; O (2 _ @  @h  ># NXcaN w  j > h ]  - | L 09  Q{^R?H/Y#SKG>~8po=;LVip^!=""b##9###g #J" ,`hZ#+Y;ߡ{aN 1n5ݴd/DlޤF{&hM]E@#Dvw߲ު+`9' ybc^X=>T7jiQvLz]) WLF|X_rrp[]1qKw_+IjuH&f@y _  h9 Z  V X  d  wU 4 B 31J-Aw &<ESl#zn geGU8  ^  >M  + 9 A " W ( % ] V } i b i; I 4 ' d j]4$dT\$w8y[?.,KBPun 6O@lH+)+urcM:dWfQVbzG9cQ\k[L7-E!c[sPIl o vc r [z^Q2AmM`` LK  }b &   j  q   ~N${&Kc5D{J= # #~Z}Hra8O 6 /r '`kXf}< E =M L m! \ |9 , NA N CQ N U o z  Sx L <  =G { 4?]7]X2*+!d4Ink&7ބfm]y~ng2W.VrMZczB@@7P ] ` < k n .F E x /O _JIb?8Mb [ J M8/rlK?[\ +} m !""#G $$H%%%%T%%&r%<%D$$ # "S !uw h/uf@W@y%K! F  X & `MU;(i J ^    Wc<$VO , x F 2bX#MbHW 3gwID1|Hwc' P"$yk#ufF:*IR7{ nWoxy'UMsjONbB %[tKyqs WJ m ( { !  E?G/ 6Z"#~{%&+/(UN)gX*T<+ + d, , ,X ,P,#,S+~e++*U*\))l(W' !&$o#/"c ~!A k q ) 3 GsK\/R4/C%r3\l/3VQ#O xg)ݧyY&ղ(ԲZ PWѷ5D&ҼkN HrӚ@NMOZ]DQ\UBp r"*[@SWv >-u8 *  ! x - u ;T & <  ix Q @y7~qhaD  9G  kS  + (  W #  Q @ReQ0wRTBU'TbyT-4,^#8~Pc>XHRAovT&TW\oP Hv o  t  P  eaU2!k}30`f 3F2r[eq$`68G8aXt3ݎ6]-:r7f6&R eyjY8TD- &_-=SVR.j-N0a;d.]I)Vcz~*{A`u /pH LQ+AKB# n +.x}=L9lH"d~cL;'6fP33i 2MiR, MDc o y { w,  j ; t  . 7  3 C ;  A | l   E h c [z 2)   " lT2$Z>L-h|!_WDj^%-`ߴmm5[]=uPCW   2 z Ed  Mn5 b #  eu *  gy   !N) DU+U e !   .Btz jY F   Zo iYLK  _ {  3 pW z a L `  E m `  ` 8   = 'N D  d  ?( IG :L C/g[,@&$E1߃4< Wߴ !PD()+}#4_gVs[WR:OF\t7(?NH%. K V/ 5Iq7)|1N-0O0qz$6A=;g  mh=3<$:Sf#K2$$Hml` >!]"#Sj$(%q%%}%%_$;g#>H"* fv ~ " y0 / ( $ B A   b  ,(mkW[qH6:C9Zs{6 4&:Pyld!  J PB, ]YwdK^wP 5mF1o"l1IG8vYm$>?A Ay=wKw.f.f{.&["ywZ,y>7%MP'f:+%6AbH4+ j  \w\V8 k @ $ 0!E!#Y$Y&1(*_,3.V/@{0x1$F2203YN3B3%322</1a/R.,v+)c'$i"3fYMB {= /e0/ 4 l E}r!]Y B?/_XTO"vQ4&ޖs? Eܧ'tm4ل:c#[QpԚԬc7ԡM% נazم?۾GܟgKl%g8  _y s,$M'u`!:KQ|mC$6Ba]fE @ M M w2 2g4t44G*hIKk  E (eIZg t!V"5 ###Z#<#V"[?! "j&Y:6y &uT^Z+   x z u N !f Lw/ q8Jy7q6j2 h w_ ~ (af 52 =yV!-oo+ V5awz|xpk&J#B|{t,@,abQB&!?g@f^.t8rp7BQo#!GP_o6cؗ߻sל. 45eEHKe,9mb\xKA}pNK,eH %]  4*Z$uxe/yF<~P7 mC[sM4#{+3Y  ' 4 ir e f =^ IH 95 6 L k !    ) 7 7 z_HG+?\rV  *:uNw M- U7JQ~K:>NUx]a m[ e]OF=\u_e3iY \N  d0ZACLu|xB & 3{ P 3   ~M]DN|V `;}G"jX1GI1>#E1<~iz#M&i C))(ViH |3Fjn#e a ; 6B q L  > Hv@R;JCY]v'c|`H _9 KC"3 Vq Bh " aZ'WZb]= H Y  o  ? Z ) ` B 76=N`k3):OMlrGpDp T\|C+cOKY$}b J  ^<} twu?Hu#Rw52$IV{O:]oQfi^ C@u 4wea|z`: "2cٯ$}4iW֗*;bزWTa43(RXDEepC(H\ wSC(b>RiaM t = ' w" ($').=+R`XVBP_zuwjg   )G  W!!!k!#""y "#"!!ae! oSw*{/skDir & | 8 1 %%i{!P{hx-K(E pJ @> O j o| p?lE]  &4 Y6WAGV V oFw4b)O\I\{x]>15OKr'-mZOWbqWudZK, -b%߼RܔM1`k?]aר~חפ6xڑT]ޑp'- Uo(bj~]D*Y% P }h+&z95IXO_A|l40 BLQt%7. v  $  \^<EM U!q=H|  q% I,_He(k~!\MAWvOf>8w!g=*"VWysshRhx؝>L׮6(@םji[-S 4+ % Ey   3   M :l N /i  D"9wsUyp&n)mq{ } uL #s@B6n1CkfJ 8"O] I  =PN]o$XpzvC2~f . u"|PW&jd}<r66#e./!HvmlU6  R [ & wP [ ZC jz<>nJZ(bZXokD([( [ ` =  X h & u  H p T , oCQmyk50a=09wp S,Zw*6{v  (;gs^`K6yv>_vm b[<WEzv6t3gwK 7V9C+B K7ThH <hd5v   ^     S M  X gw%`.jmvhzQf-csbn.'j^ynP 1OEgnqPtU2   h 0Nu:OwN>C!ia(D<apP"vGG.yu%yhKcnj3~)4yA@'\O4*.6 0/f90jg)gFPh`iE'Ae h}    j jd+r*L~YL| !~"B+##7####h#["!+ qL9FZo"r,u5?,E Ds M  j   " Z cT>8qy.TiE" Z  . 6r+[C!WdG , o0%mj95HأFՇbӀW]Ыϱ/MV)Cb<Bս`hIHGݒ^ RQ}b ^%J O8: B %3 -BwtV)FC6t&QVCk\yzFGD9EF?g  r ) 2 c=w)Y2c\ !y">##$m$#f=# " !J vQEvVgr#Wv0cTSl  7   2( J Y  ma>SZ*C6o+  sH 6VQ@fXv *H|R*"1H:v>",Q {'h\E3sfrߎ^/ dۣjKlDAuMpעBX>ּwK$غr6 rܑ$߫D_rr3k/7|4TD9_.KKm z ) w]o+v gJ]/ J A+G>nvvKZyJTP z~N@lv?x )j8f",l;H-Q{>=(-?g2fl@(I#MCMy.߬5߬FS7j /}E n>zpC9OetE771;Y;y0  / Eb  lLhVD U  ; G   = m+ }C bO <   ?X a l X> 'btGc+BJZml\ j ?1kBNW?to' a[{j0GDSWPPpX*j= K  I > LoN/Wgc<l;AU=e-$uem N  N*tF%X]Lqai+ & Z&  y [M 4 [%  & ~ .  m2Aj"A 9V;Ja4U44h[:h7^ac_@  Q5  |  (vEYelalR <q_T 9  22 h%"3K%obqr. Gz~   g4Jn B Ke-$\"JV~1Fp6EgVHYV)%y /Q6N_@ w4h m'oFwm q_  9I 6+oZ<"@  tN hj?O k9 8g /el)wI x~/p@6?pB mOS;;. R b m- yK M 4Pc7~(o@h b ? `. a pW+-!^+E$y2r L ,<.*wNUn3^7J}FzE9&)% wI%&drz!?6hA@`x  I 9t b4q ],<F>B/B")XC6 ^avI2a Z1].CW`; W  R J bF[ i w ! ? Z vswjxLa2&9J:r݂cՐs?qϋ"η D˯.*˲#TW˘^m(X R&zX׼pm޴tKY.J-Z TG2e o wAI '![ LZc/Yh67J7-RgN yAF|e5)r+ -t qja&hw!#-j$%A&?'''<'K'N&B &" $ # " 1W1W-j&Oa (  # Z L m  d0   VA   4  |Z uS-z0-I)Q%K#D0HCaC) n 8  = i v Q[lG?^77lZrfw bBf[&T7_&VGS(j nߌkޯ4]Fڞ 1؏t [ؕJ!CاF"E؈FSk`ا+|. Yސc97: EP Fj7=}78O @ 8  . q  #5    \ B6 8yzKj_@a^Xcu<|v\%"O&t %,]v-vM>3Za7nq=A\i]A[`mT#9= 1!$Lt 4kDNM*]{p9DEt8I)%H}ph;  b   d J  mk /}*0ur?6a 3 ]8 S%Etok-"spF(Dr%+KM0CdvG1B/^9%Oj6 6 dkb 7Bsv > 07'{NhGz:b${F@P!|vbj   vC H :  9 H > ! d 6 x F X  u  !dtPI:z^$1wa= YO S> )45VE w QZ * [D1m2 pq<m C J o?O438hpXOJqK``t[Vp= ! m <DhvtyZA>B_{f2lx8S@PZ$;h^fo W ( n  ; @.& u 7  F  Hc)fuV:$11Uo +  IY p~ t  i-cw8fPmH7YKAw{5= <q:OCE>PnJi hhWD1u    j+^y+N&_ssFd>i.7[u#MA9C']gRs>;[}+Ut% ob 1l~fbbX:L? V|8nV/ctlFwQE[(iP{M;Tt_K!;v'M>  dv E7 @ Q x x#]r6|] 1b!=!C,"NC";""!_!!D!Y }  z,%g L^<<#+$l G ;8 uy } s     EDc#qb(P9e 7kX8$3'C/3A"P"g6f:κ2*~aʵlʪF)˦p+aΐϮa[j,zخ\HPSޑdBt q{ZK?WAM )e^@<= v 3  o=rv z? b1-uBEpYc~?r#1` # $ c<zZ~4{ A!"^-####f#x"!X |L  X  b D     P  n  1 O ! . Rv u)!ttp  E  U `v }  _   ~ \y  G   ) % "   ]  7  uo ?Du }l XKR@ 5"seC&:t n>Bat#^tJkp{ޏ>ݢO1&6݆pCsޝ)@ ܰG۔ڄږU0VGI.ۗAq]`BQ&TB'E~N@[l`OqusI YT2F<?G)7+L{P%BE=%ik2!b{,-~`v#m\b{ \92c 1.Rc*J4 ,Ziys\E9:;}KTB [T\M/sFIh~7ZU2ZO.q~E4es b > ~PHx j   iz   5 B , V  H o P O'    N >t.[Nm-1j#plmZ'wbC"L j V Ccwv"^]zER pCqtJ_tw#oa3]ޥza}2w 6Vqh S & 1 + 3M d v m ; R % C @  WAt+d\7:M9Lo.igs8,g,I      [  c   I   X 5   } &H+P$"L 2 ,6t ulAZq/M"Y0W2(pM%u?D 8 x ] S >( 3SYfOLm@o?h,zGgt&atNM7\|HJBF:x"!$TfIz:KP+eF p s U N  n  (Y6EHn>/qm | W?m= U|}i! Vi},>R  V a JCOG>,}&$XCITC2>6Ts~99_";?G6ElSrv1*zC4bu'^o4$G2MDat;V[Z@,ceJDMQP+e{aos'k.&T} Z >? 9 : ?)[  m ,De{EaU' ! c!Js!C! R] X %X4'ScbR6^g P " ) U'     cuQZ!r _gB`&f squ&i/'DEӪSk5)ДW }Utzl\I ʛHˏ&̩PKһԭֱihxF`%."b Bm! 49oX48i'79e. t5W F  h+h7:ayhP s 0# [(vwjf\iA& l=K[.x%S)  <; T 7    p / JZ$ L / 3{   X" ZT"9F l; Jl I *   B   r X A / I x   F   @R E  p  t Z  f | Fh{mVtsz6Pa49;#fxkLZMyV+t5"[BhiW< LOp-.xpߢc*9x~J,x}c7)3u:(2u%>Q H " # w r =Vvp2^k;Y(?l-R Cw0w>'&bg; \XrI~PVBGcD + S =|'G_~yNeX:;=<jr )hX* XJ   &X-J gA6->Bs~;/]R  s 1!t I! N! F!4 +!B !J O D )  t  |3  .  n\Vk%JEd];!IG,FYL]%8 j N !l_4X&]-z 02PN r)h^F*ޯBHܛF1zݭhNH_?y;g#q$:*T!KvvvxMN : L[y=eXM|S4G`DQjkP`?'be67 {   5 S    [   F" g  pd(Fly>.SYP?0)/kN]RhYBR,%(B}wyJlhCdl]!?i<&MAdd1(r' `  B o8.o8JFb#,b Hg1c&Y!>F'-R)??`()D\wG[ l n P    ~ c* R9B2. >kK;g+= oNbL1p5*'AnE1^J ZX X c:*JOE-lu:  m>$ <+Gd;u t)czTE]46+} [M/g/i%0'A6%7`OaUDHtjx)}cv{O^z4:4!i:H@' H  N   =L s C  ; mu C b!{)lOz mH0Ns"/r\w%BJ~R g&~ ) Dp i  =  ;% `pfh )  1ah(!Iq5HP&q%_ (ޅPvc;Ԏ#IY͖l`ʪh6M]' 7GPI8z>|([{"I-Sv>/: ` %^c [^_q6%=}b e be2c^- $ 8 f  T o 6 Tz  %$#]F[)Yu=1Yg c     } ?  , : G | | >    6 D    o  4!>aB M~  i  F U  ^ .,&M!3s ( qq   $Z [ s ' 0 \xnMXZo6]tB2RM;/u$V )N% rI*"/aSy@@"hv[/VD8Psdlm]N?{#ej<k@O;h%h l.( C  ^$|> jr,j'QDQm/Tb,Z<fa5:w\#,FM[`o)y!o :9voe'CVy>-@v]7*X)ARuzMi#eu@RM C  v< C C <Q \e gf ]R A.   *    - nC  4 y  G  .] K   c S !  J  qef_Ia!i7D8 7&*MW - DQe|6)9y5G&s-W^B1V2Fs"B=kܩ0]SC:C=J\%:/f'NPYOz4>J?v0 \dH>#/& r * 'o)p8`_Uef`dd`\@  ]  ~  l  k i  # JotFWzM5<^ )   D  ,)   (- mU`Qj'QFO1fx@|qV3~Z(_1NQY<~GcFx   =r  ?r w x G  FM } X k7'Rj|4JaC!:P\hܧy-Wt҅}[G7+>ʅJw̕Nδ; G-ڲܜ݇vreRDCJn (">LCr-" N:g9Nf LB\_LVML[H'C pI ~   - ;p , W%Z+q5Fw}Nt5D(!M  c ` I  9   0 d z N  } P * HK1 ]  R  U JR= Ws~  d>)x!$?+m O F  AEY.f# K( h~StA<d? QJHw j3hGy( Ru5s| ,On ")K8?:l)#7Gbb=K 6]Kcs)f=)jhkI}O[% c|P^$U\q#~q1U3*v}xNdx !lM{p3zXEm|i~40B0 WdO3`m79w) .ynh2o_ 2hj15}c4*s4 O< H2S xWyl[]N;Wendn;\= :u8lXgVm R  j ~ U o $  f$MZdogrC y  [  | #k )   p e o # r k ( o v ! m!Q ! N" "l J#. # # #G 0# ", !r 4(T+2Sh"aLY 0 p X<S8;%AgC)~Ck!@OUaWZMߪdkh!$ݝZ3hmV%9p\.1\ U[(;ye #LX>;nXcr&YXH{WKq<>@34;^   z  @o(&:bGz=][{YgXu$gm 17MrR .  g &58y e U   *h  . 7 \  &  : =c Ox 9e 1 i /  O   &1 LP.6GUxU=R`!k.9 >  bL(JW~q Gu9pL2'l5   O  M  1s@F @P ( L x M  5r`gW=!C)!c: C : f>1z%D?|8 LQ @G3!Vc&=LZ+: lRnm  9   !)    K % )KQ4UPo,u{'5?:9kMQnyuS=O0uFlH]>m9mm?S eU5'?^mt}tW߄Jށ]wY.p\vx$>ܪk[)ޟbTG[JPm=8 u,6J:s5tN_UJ;E,FwwEWrBaV(k 8,P:WC'}lwotd4"%`.6'&x0&xg>kG)p:tf1PW~odbp^" G$ D } .KWJ2N`[:SY ZHpMA6094JdO2rA  *!&!`! " " "# " !B y! j    * B(\1m1 % GE [ kw(a. -0-#ZwdlN.Uaf9#xY[kmHS9yh $*U z*/L1@^xD2L :\]R>?zg2|Hi]ILar2B&F`nlX4` ?b9u~ |Bh!yizpg\QE'ySStG/l0:BFdG4HF(GpV&U k 2 `+ d 5  A C } u f $| V N"  8k  k -4Zx|D"k i 9:  l,7 k)sh1@ 8lg) BqF3@+(n~&kxd9G .X x5aw M*    l (Q|@2^WV? j Gw *nH`70w//H!  l )  E _ *{Bck/C!p~4Pg+1=f#|rU46+ib-|8|G4::wCG5?`LE2+K8lUULXBF6q"qL2y+ZW:C)R:~Ey + )   (?X nt "  < !U~ i}&[WNO]+j P 3x $  2a r P  1  b  mzK&9  !!J  ke q; jt f&j} fP p 0&dWA@\p(df">Tj | O=-PےF>!ք$@>kӓA$ t1їa&ѱ@ш|ь7Ҵr\ӪscտwGl4٪!ۅ-?iݶݏOjNpG3r >t~p4?.oR=y R  ll S ; D "  q  ]Ju*!Tzo+z.  G!!!":!!$1!x (  b S i +  [; 0   0 J LSe!9?lsEv 5 .;  @ 8 1 a { d 7 % {  6 Tl l3   o&U-T=Fu:&`  k P ;  O !yY]g0O$pwf m|aB%. kx N  8 ] ofuuS.z ++q1m)`%G~c8RkD0"^}ު-Kn۰ڮ{5!؞=#ٲ~P>UCT/Jn+&'Ll0|Hy.(}a 05}AJ^b,V3v*M$ r&]#M4 IJ .qgRYuT!02 #p  3 ? r G t %qX  |Lz\6h*u7 !C*FawV @L %H-froWsM=ah uJg @ zi]=0pf:IuUY`4r6k7g3!y-H0oPitx݇ݟ!޴4_E CCo1R*twjFLf=.=/h7LhF{: '2]TC < L N T < | { f _ k j GE   Z /S %  ? ^v e9 M] a + k q/   > <   z >;  2 6 ` ! c HwS3@wOEu)-Xgo  ^ W/ # =  *a>Ta)M<"d z!&""$">9#NC#H9#>5#?4#=8#+<# 3## "@ j" !h Q * 6   @,J7<. 3e T O k$   Hu ~!G\Q/% Tn9"\8\UWoUVJ'UincG&1K^Rt={xkzW/XTr 2GlS[5BZ@F^d )e!3CLE% )^qUl> O*d ":i]-DfoS{_@?u I'Wh #uL <_ c \ Q \ =4  ! :7Zk W''mdy2M t   .S   4 > %+ ^S   n  k 2:I%R:4? !!"k"W"." # #"\o"! n+oz@ vK` ]' '$d4-o yJ/K5u! :AF.uڃK=֌ԷUwHL~ϋι"%#̓^p:c˧vˏv̧Cz΀L (Lҵ5+SVv?ۖ[81*E*ZyZ5\ M  5 7 ( ) w = y*}ETaqrZ*  X!3"" #s# " "e J" !\ W! > | Kb ` | X   V T  =zZ>~MD=ST3PV=p  0  M * b > {= FZ   l  % M : B;`;IjU  Z, 0 H no 8  w T R u z 2 n  9X"3JRpc'n; !6 ,w  { / .]!J~ 4;~u%a8bJOYafHUy+$N ui3%14I_m.{QT NB!Gs % P   . _ T8m4}cH' S|\_#`"_EmuZYxg*)oY&:J>>b8XO{>*o~EK`ipS&1Jcw`;i s> + G X 0     ]s!2E;.sA"gJey# "  9  O Kq pR 1 *  %\  "Y 9yY!H  L=*RqSD }!/"?":####$.$J$V$/N$X$#"! Cs(rQ,) d 7S(1/N0/wT R,f^\pOdfFw`;|5}_ 9xߛdݏnWۧ Bچھa4 =LC&kZ݅@+Vx" A 1G s;  5m&#T]sX,q4=mW7u-eb(!qdrr\A+Fv`aXYjk M*E,P_m^T j*= /  ! 7K K dW   rG t CD @ [ ! b r   U  Z ; !~ h * E 7Kf#)!FXfB1'7A|.a@" [X'Qk ! a K n   ) e & } &y [  F MR@E`^*hX,-S 5l!V|6:%97V [BmWXDN+A`@+?Ss<U@?  eR.JZdk-`,Mu6} nEao+T~S-b UEF4FR*a[;^ -' p[F;@H:/ V.O 17Ojm x g ( w     + k"  . z[ g c  = H    Tf 8  g  4;  d  1 ` Z7MX9A7!DkOptb :! ""#[$%%% &&&%y%$E*$>#-" s&| .kX!e! Zz ZvJ|/Qq *Vq@Vv߳ܜY?8ڶ7L\eח|־sY13Qkϔ!̊˩W'*l[TH*̈,vArl0I'Bar^i/`:Z^z-,dP } dG &  ~ K?<./, k|S"3 xx  6   g f v] %  D m K2 1  h   b ,   z i e N   e[  3   6 U bS ^ Q 3P   B = 3 v N B N  q V < )8@. s j 6  I @ iP T  o }-dg2|'=J=K /~q a . )N i% PZFq ;Un.$Zak@(A ZH;}c7PQZb,dfq p $: B l $; v 0 s { `+ 1 W ) A~<PR;4gC I}S    u S < / , \* 2 G nX 2b h v  S  s "  = ? 1 4 "    k  o  ,    uNe99v.`8"q3o' r*"#h$K&q'`()b)))pp)('7&Y%d#PU"% 7}-#'P , 5 uU27iPtQaP'f F'^"97{b# 5lD߉csd ݞu;R(܆'ۂI%cݴ݉pL ߛ W t 9 F w 5Q & + I =Rf9$]|/FokB 8PEn{C y|, 4p066KM6 C b v m C H ;  3 > T <   Jjx{+w&sSwHF3]6>vVSBbw?x_E):/w > 4 X MUilLS3@- xr .@]T7*SP)Cmj5_H j@? km V }.W.]d&= :_skV $J*`%`pl+<HU*ShfFEoYJIF/QbpdCXC|v]hw7=AQXTn @Y$Aj:?e}+v=b`kj^Zm]^X^MqEHbgk$}a 6,vYk%O$;]5]8 {K tg U + +0HRbx'\xA1T  5 n )oL_rUZE09:2w \!"i"8q##a$$$%B%wY%nd%i%m%&i%sD%$l$#" " Bvlcy61 jd i)_TP'~:/a@yN+gAbtc^ӒVoТvG@ ϵ^hut-I̍gĉͮ[+u΀JFLYwfԐ ֐5'ݹm_i%Z?  Q 8 <  S7 o ]*  '0  < 4V6\Byp.20qM:^*x  =88Wj D O  -  ` 7    9  S  t   <   , $6   5T }q7bPb A> hfD' X ;f :6 L g C } p @ M L rEosT8/DLD[[X|d5@2 n28A@> f  I f-w[5O$=S``SEaB>55O}y!b+FR)'Cb{!xN|t > ^ , p } 8  } " Pm`5h]!;Fx/7 9 z z U 8 5AeS=%>kST=l )ni~u 4 Y z: 7 s G @ bi + ^ 6 J OW$A%I Y'_@ I;Z|?"A@`'AJsdU+* .~^[hKx`Ku6 !@!?F q \ , sl 3 F +F L2 { - 3 @ N e $ ,v  Lz.c`ws7D }y>+r-fS/z@L'/BNK(/jmb9HVbVy[B6J'rL >wbA!0s{< Bt{A.G' [#]+FF"+Wd=i|"H E^{;?Ne_[q(  -7 b '~=l o1YK@Vse( # x=!s!5!"Ye""U##H`$$%B9%d%z%m%&9%3$(3$W#*"2 /X:v[ C   ' 0\j>RS,ZVQHp&}[؟;CQ׬i&ц1},3uEfD$y9U^6،ٰڿ3"h,u>* s  L S^   ` 9 }b#FVaZ^!D!;RW:yPd /RVy y O v   \x> C   iA-l6 vMN!q1L=N:IWk%G7M@9iv&\" 0  &>ZU l~_0~eCb`9-7tSqu -$NK1#!8.tZvTf) [ b @ 2 XI qg i V ! / }u  $m ` H|Jw,vZ%F a9;!6& < 3  | Z8*#a:~x,W Xu1T%yA w&-T\ I -  7 ys#UzK;O=tr&|Wf`V2C6~7@W: 72MzE!^,y8/,A-Lco~$ p4{v}@s/4HJl#.[z>TTA"u@d# r W!7zr2*p6 ? ; g( 7 +wTm p0ImcHKCjN}f s$'xd3 M !!po"G ##$W$>$D#Q#"r![ =P4'iqZ:/8E N hZv.}C%lFy 11[7NQ*J{K;V,+I[8nyZ2߲I|ݞUyIWd?0![^߲ i }E!k Rd|['0t|t{ Z 1  ; 0  m39BjTuoJ) O(g~][T$  " jh /1 [MJ4~:BEb[A.& 'xPNjyQPZ^F" hw 0 j n %  K)[v3o3ozXGfq   = ' \lz^2A\wrBl ?G!h!!!!!U ~|=g E+xrl* Ra]TU BN IJeX| < GQ S ?D )G/KhcIUU Z,  rS J ` BQXVs:/k CU*.>|`q1)d8~.{G\:di^xSu?g!HwwD(9OZT!(Z_]&m"9(AmDZO g#.*X hN^w[*u'Ju6D26mb*Q{8Y  U # Y @ c  qP \B% -c5 I!5DBI6z&G}* :^ z { +w 3 ; D T | 6 !?!c! y!\!o!8F! !| vqed@_+ cS BbjwTMPP"2gv:߶::޼:;ުG(W܄Qۯ57{iױ!f֒0"#ӚTw@JJ9Y?naҌӢb4*1w[>ڠX>݊ IF$y6 z > Q 0 NcXtc{;qsGt 4 L!u !!h!!!F! v `_/<-l+2kMz 8, 0  pd  1OPGxTH $ \ > Z@ ^ h XG/o[ ;_9GbyO-C f h zmya`_O_=V)7(I%Rj"[Bm}RE7.(6YNk}-,~+E{jA\ n J) 857'?:a;K_:{ 2Q v Rh-<"a)Qm`}s{Eu$u6IE){U7ClL_+bd7 ߈wCݰfgC]QT݁@)N݂ݯ$";[ R݋ zݷ =\ߋ<~g?8uy$`W$pkBv%"*FWbD  @ M < L -{v2)8?-9bNm ,7 4 | x M z > x6 do Y X w&P63:iYo@M 2 `   u' [_ d     +& M X G| ) e nIOC>CM7i +7 w q mx  o9 e U ,X } ; , -C$?%p yCrC!wq|P=9F> eK:;l)/Y7M oPxlvm E w   B {==$8e{xb VoS?-\ * i8 5 0 # `*>uM*߆25ݭ4oܷ17ܺ&)_~BUuߌmd\a&ZVa%|544Irs_d 0V{"r !Q6KB7I`10ge]%KQ$5L1# *@bTg mflzT@! |Kq3p5#.c 3 Z  Y M ( 7l  N Z  \  i Tgg[e7?rLpE H p m < a j?1.viT\[VK}{N>5r Vj|vu<Pf0#QZt*ylnJL~F;\ߙ1ޕ9۱[k]g֔AG գP *aKwխ*Bنhۓ+ݱjc W Mk2iE{d3:sQ \)  / ^ }@ 7jX} + d1KtSG.WqtW  ] of 9n^3>)O U0_# =)MqMqY2}+0 a L 2  ? ;9 z2B?$'C/{u5=i]IH?f\%HKnf4' - M_ jguSV=:K N E 1 9 b)v:2 ' { [-R<gjU(>TnxECK vl q f ] +/ qD{f0lY$P|c \:=UBF/H P a j D  PK { ! { W 8' t w  } A Ze *>e ?nIbRif= mI|;rn]m_F2SUe"B4WXVYxM_*ah>   ;haf .y y   rb |{#cNe ` '7 e ePHB,H Ab!!4"?u""0V" "V!!l Nma5$M@V:myKpfS|9;Up`*? ,[5QOWt   ah { (f|T+aY~Pa5 % }?38}^[_W1!K-'ݍqkbecTD:DbpE@*`֧3mS Uٹ }T Jݔ6:IpJPf4ca/b8/u w SS l!1%cZ++ /e,ZlQgQ1?5k7,IuY}h A9 o V 63[9-=SFI} r   . }  M8  i B     W  g ' n v   3 x  G  9 D ^g o M8^ : (R ~ *u @ s9>eO :Hs<P !  +_ W%exDQKU5 a_ l)yp\wSOd{T)-@H !0raWLݥiwe\MD]N3c~ܐܕ܈!q=QT.`m*zIq}ܭ |v y ZL O eX@AC  SrtoMYg  <  OpJ.]5mj^B1:VQIC X  Y  t  n:Lujj|>/lpyCQ_Ez :0wR,L #krCG1  @ [ =9~*;jg xQbu> L+/9FXDjr}o"+9jd d | s h G  PjI'% mj  I f ~ (   -lrtC.60 4MtWlH U7_  8 ^ 8? w}^2#PݕEܗksI_,1C>f%ZL]B B < t(CJ NhT|0,xDms<PK3( 5  n /i}A L )C3w^``]OE?"JY~)9A~@azb3N F !  8v mgilC79FP K "  > w Bm # E   U}f<_ z ) U!D! "9"oF"07""!!l! ; L1_1?40X1, m G.  j   r  )m ~ s Mj_u7:!/KA |WV*hJVgW:]+CSrP&ݷz܉QS2Q>םd0 w 2ן ר H؜x=`ۇ9+ݫ1!N߁z&iom_= i m h W )cB&^x8JX549AnmWD<=hL-l{]N W t k~^LgD3    [ A   m9K  'C j   \ > f 0  E  g F M  Gw>&Z3z=y >i m hi ` SGGBCH~Pexg7QUk*]*< #GG?eM]XQ=Ql ( + Y c 1  Fvd  [ U "L  v 1 KC\Cb> % )=O|nxT5r%x޾9݊"c0AA[*׀ם.װ*ת90ر?۪^s> lwKE,BE[y+HRJ>'~J5i,E~!F<'eYrnU2IGYq-x,WYkZa v2*bI}& 9} f  b Na 2    Jw, \/oy{D[|  f T* N)p3+`:4N SO\/ O7pYD26Q)} ( V |iE J*/,V(PJ0an"aA3! ]) W^eK%KmpofC27sFTfz}9'v}1 =h5] 3tC?[06.)foYܹF3 Kb ܔ ݿ  e>]x~UWamLIb  ,K e2 "8/P4|g~l5 , i/   z ) ) " # : W i }U      f R 7 o ) FoOz:#DbNZ_!pWH\*rd[  s >gs*Q9z*KBg-ߢizXWn@ަ) RGݾ7OUDߜ=l9ߏߗ'%B` s 0 $des#O!lJMfUV?2yD2p6R_` l l N ' n_y N4YR}qO7?s  !H m s s zukmx+;3A1t3޲~RO:ۗ 5ۗ;LܱTݍ_'߲MLAl'  1L ^wIz+ z#s[Q Md)RwZ e )f za O .I:1p'#uU>\ Bo|i 5mV $] RD   s YM"4LY0( ] ,j ^ A ] [8i {zGN("~M NPiK0%6QuN5߲i+ݰp<@.SQ"_NI4ߞ@7|SgOY53Y}Agn8Vp%UahC!BNYk)@yPO6h.wcH=Nz<<+=Xh7}ez rm  .hn  C  s\7B m!!A " "!n!!r!YV!I!;!(!!! ; ; V   VS rcq_hqdgbQ < d++kzLhM  IY8$U6'3l6#nb7#+fI,tq"MiKnXl/3FZAz ;fx-,$Ot0/xXr(A :$ )  B O - No zIQd uJ@7xw N&*, Go [ `z \eSA,uphdB4qE>^A ;1}R>-7;@K2x p  fl .  Z iU"9 ]-i9VmD\O7-@8 _ ?\P9D{| KNQ(M߾c) ߞ'޷Nޗ+ޱw*Eޘ ދ7g`Z{WߡL<y8 6 i F k /w L W a v& G?Rg3 + Ez e( c ~ ^z^ +/ A ;  p GC*80"J H h G G0H:I:?o+SPYYgL@DG[ ,byH)h=5'QrL I CN ]]*Er 6Kf#R2~o,7CKG"& A R  %u^XAAY9eB5(),D7~JmkfS5~ [^ { 5\%fG  ll*iL2,{}!i^&]uY5`vW}xQWP10{O [Rvg1j[<.oRl+ DuN.}i+-Rixv<mJ&:#Lgj6?7E o v :IU2(Y)c N-]L ?u'pJc+We۱|1wM=Գш ϜLCίZ<G,qU ez . I M M "V ~] L r 4|b K + H  T U 'z;|\U` xC|R"6vzt+9Y [ I (z   6A!Ay/bDH } YT`}FhA/Fxh ~ ]  yWP1Nml "Q,Y=0 TDgc@3:K-^Wd+5le&g,TeQb6t\ _h"I}D4jqZE_LM.v[whDusl Oj'9p/wRgfp|ITe8?26O>Ko&LC,QXjJCfO<+)5`kM Za xF R n (m#Ec-' ZM!Q"+##V $#&#P#V"9"!q!:!8! D  \  co8 V 3 cf bSnp| :pR  B w:j&.dc OcTo3dDK {e]gOvcc;2?Fv XNGj: &)t3FdDYGGIX6a'Y"@SS"1B@`J6& s `Y , <~/.(]wV2 mO ;  ? { D !Q>!$4! 1 Zhe<T^Lt:J1g1{ lPx$pz W  i *  N1} _M!-q&[  D w kAQ L<.ߧaCYV[ލwQtd 8 ,mj޹޲\ޣAޒ8m/*)-ް>ޅ`P/u߰W Z *l ~X 7j4!@*Z71 hg N d y C  j eVkH0HH5 TZ }XY|O`@8>DSVH ~ = |j{<+"FY)gG|  \{aM AX ; ) )JS7.W<6AW;T:( - d( 6@a( l 1{oxk@F2\8P 59`+Hp7;+IW}q3k>23" - RoiZ*>?I4X7SuhW1~r>n BxUh g%'4=jWb=qWU|NErZ)u[|679[am05[v.xns[!xxp-nLpW!p D G8glojl-+z +^wZS2[MG3HTJRMqZՉ?ѓ:[i͏X̓͝~8jR-˿,̖̄Y͍DμlАx18Փ@jۿ'~)LZ93}:V4l/x(xeuNDWg < I cOJ3_!BC^<X(x.y\L.~Z`%(n   T ^1 %*j<ycZD,TRA}2< ~:TuE@7LD9$F+ H V *,:~7YNAa8{/n4 |  \W2=.J[. vxm,~Y;LP]M2SVxwm3Bs Kl[t2p0&V>#{6EE8dnkp!znfEvT W 9_ {%7Q$q|}VKX,!o,~C]k^eA$u4 e&Kl$8Y*I|E /MvYJ'(!4Ufz(   K =`jQq  aM   !S"#2$$$$et$m$`$c$4z$_$rp$J$#J#"! , xx7(&T(H+(pw  B %]   R)YN;<O >_  nX Ha  7! N MLXo;.|;Rrߣ`,QS M:}IOS6 [{Okz<߳.Z޵MLۿ BۋzC r b * ] 2y h  ޒ uL (M>>T27I Wrc)<K L /& G gUW CQO\(O_`oY?G > ` S U   H B  ~ " ` _ Lq|Mp8 i~2V nb,ut3 {IbR56&+F?a (! hs  v Q#opxuvDxyw0hkF c>EdT`sIwM|&Y g ) ? [h|({d )K!;K5@T3[Dr=H<'E]L R3*D!u?}>Uz+Yc;pTKSKA*.1n-G-;Q_[8Bk~?nYAA*\ S G gR($zfqN$uyL\Ufb%qڤPq;)=0  l_!*" #\$$ %"&-#'$E'$J'2%''%&%I&%%3%$$##"P"! V W87{c K  ?e>LB%eTVcr ) ON)} cOV:h-sNT@=";YOalQf9Cg7Ok2[-{L6fmk2H'pS1T4JUp^,a>> deWX i2\0q8Ql1$uB8n'h{`Gr0/[};9+1 s >b %R2tW  . w/  / A >!l !)"u"""1":"1"F"!N!T!v!  M P. ! l  c(I* U   I rw %x) e/&X%0y6|b[q2"|*a720KW`w Iu&qFKSZ(7xf j>Y (J P  O ~#5UAb9!-J }' .   T5<# #!{""#}#$a%Y& ''(F(CQ(v(m'R'Xa&%$$##)6"]! .ba* tl?" '  W ] !  v ( 8 .qi)o:SU#0 ;i Q&6&fRZ݃?.ܔ&ݙ/ r0dUmRUxieSk3DMK'<c8|rt l޳f݀^\M3 0 ٤ + ֌  I k n j p K_  ժ D% ׌ 1 ކ k(#_TrPA8+y.LKU~2w1\ j> U 64'|NZ99/3Lh}`Yy~ [w p$w! Hyq585l5rSP6r|L@fXFD*.ZS{o?F%43jD;s+>18N2{{-  W Cl -6 K;]j07Z>;A/>36ORyh$m{L -<V 6z^n~t2k ] Z a m vmC <!D^j>Zg8 /m~<+f\lc\<C)3f6&<l ;v5v Sz1k/\ R!:!"F">#8|##$SD$h$r$f$9$>#h#" ]"q! 6  = kD y    A8   E@ B  . q (  R  , c b/3 n&Z Av8]E$jڶ٭qDՀ@6s]DcҍC҃ҮyҸYҖ'FmѸҐҜ<= խn׮(h wWܺuݮ/ޝސl߉($Qi]1_T)3.8F5xH$BvFQMhE2Men  ta,h \tC !" #h$d%%%%Q% $# #GK"!; 7  E  [ >Q S !"#c$%_&b'!(( )!)B"Z*"*D# +#u+$+@$+D$F+$*#3*W#)"()"+(N!i'N &0%$}#n" =NPG,! /n W$9W 6A?U8t *:e&~ QIiuUDr+J BZ, ed'zRd3 dRupqGxz(w^uHB\SlZ9,_wu{B?+L^I!*!@vW -^g"M[#T='GXlpU&Y/;# Wv}!U= 7WF5 1TX,e1W^I" r6 1  C.b?DE2lH*U x  C [> cEi9FZD o&o'/h  u \X7FxCo`m3;b7c}&zVJ@hmژ~نrouEZծԦtW%ֿ.׶IhLh$'ThK$W=}ID bO*%zmB eDO9E9p V ?  =dK#fO YRhK2;|)9^  j r!- " "#R$O%7%e&& '('j'&f&&o&z&r&8o&j&[&C& 0&' & % % B$ 6#! @gUuVY|`P&+ I % W  R:x)88l )a~(DNu=JQb8 bQ3=oߟ_usN:NU'PIhS[,IHs6a(|aLx1E n K' E L ;, q s Ո+Н]!cH;Ϙ%=zҒ  FޒDF6H`,!R@@f      C Y Y =  f f R K Z w Y! ! ! s! ! l J  U#WT]'`"I?y],zVr.pnoF2/\4'2DH_ H2r (!IAvc< %7j#l!x ,-   ; G =.(fdc ?C}z]_}O9E;&Ww jT='1 | 7 M V% ^ m = F Y,Tx2mXDCpD:4AkQDt 2;T=PQWP,$0S\J  !q"#?#? $f$c%%6&q&&&z'6V''H'(x(B ( ) 3) ) (` B( '&G%%6$_r#`""3T!p \G   R  & u   4 t   t 7j  y xE.RblD8A1!I(Z݈mC)-pAFkB֮NpDӅ/oz9Ϫ^7(ͼDJ˧̞k*u0'ϖo8tӫw}siNVkJLsir<5A4qS:G(M_nh; ]McGFy.jU3u r OLR:VtO S!#i"}Y#)$ $ n% %l "& 2& &m %%K%$9j$ $######$J$,$R$l %}%&& C'u!'0"h("(a#)#* $p*"$*$*#*#*#Z*>"*5!)i)(&(x&% $o"l V@+ 3 h3L{@O  tgfy6;qTS)h;Au^[}t og&V0%I_96Atb.u~DY }YV+3MUTFX#MR O+O Gb-jOfH/ 2  dY p [ J V y :  rX B 7L7DD02^E] M;[Xy=H U b!?j  E  W_D ?Z } | Hl j 3x   r  N C' A j %  a i  rC : |6YkI6  ' J  g E?Pd \kdow5]5#E_w JGkܚj5K1*HՇjodg%Q>֠אج=pzmVd[e:aC8(`>5BzeP:>i`y{DO<w J A Q f QkR):>,dpFZd# F!z " a$ %$ 'g:(R)g*Gy+^{,ET- -l.P./g?/%/.~..FZ-A,$+*)4 )( '= % a$"Q 1m7%f  >Lx!}B$^)P;gWRp3(S/" 8aMP9F6ߨ߉ޭaOrOp#g:R|7}o`ssf)> e 0 d  Ms mS t> fB aT r\ V A i )ֲ ) '֎F`r.# ڳEܑۙݑUߘ; qiLej6 r ^ b /~& : uh/8j?"$&W@() *?e+;+++7+<*7)(7'%I#" v  y iP`X\ 1[y N B/ 9? U H>0 h#e=Y ! r v By XjR^`&</Y 4 ` y wr GwkS3X߬9lf6?r< 4MP"f LvIa|n:w sxw Z c W aJ W; ,:4N@5QN36Q_! l !-!M!~e""#EN#w##s#$p$$q%8%&#''R(()7*r*****h*)r)((C'V&\%g$#"}!u!` + Y U    P i qR   B   SR  Y   X G G][%~5=|_[23ް\y-aJ0Y +lϯ,1g~̞~&}.'̮N (FQԑxNتSڌxܙVj}{-R|tDbk,3fNI1}=aJK#t 7j NQ dd<mw='fwS  g G!f !o "k Q"i "o#b##;$$3% %%%%!%c%$g{$#hl#"""~""#~#$$%K4&&[&& N&3%<$!#"!"S .D u [AWCf ] Y w^ b"nh\I+'s.aE.@lkU:bX&Q|h:pFT>G"C7Zv] B x@SFV) 3sepF0%c!ti{9o7l vSh2 MUF#5x~h: S V A  I(2.2TO# E ] d <   U {W60q R_1[H&Tz8\+ w  g%~RtaHfdW#ZaQ`er1!>@~ J; M8 ,  O T  9<(t`   r \    4 9t(#tF:T8i[`cj+J@k?~ <#a.ٲررؠZEM(erukUlKK@1_zN .  ! C#q $W1&:'(4*{+,2-'./v00nU1vx19_10M0W/.\,*( 'H $"|* )X7( E L$Z")":TuX,I?*3 Bd{a?u 3R}6%[MU3OE>%Db{|UR5 Eotx#s`{"D8 Isy knJތwSK8 5& # # ; Wޛ f;tX޷>~ߎ!K '1 q] = 6 98c"sw04S=q W M  ; L{ G R-!c#[K% &!(d")"*&#+.#,"f,"n,!', +x*)('&%|P$a)#b!t - L!'+#x)E1m w 9^^O;uu\ S O &8*!! 9 [ =f w> 5wJ A e m bV c? dZFAߍ qޔ ߃a2o+(V5[[O$lG(>7^/ZW% AKzmw  _ oZ?)"VH79+u)nu-l="k /> t b K [ !Y!X!]"####$&'m(<))[*y*D++,,S,,E,m,i,,h+}*Q) d($'%$ZL"  c3vy^E,3m,' % a  3L_/rjV/%Q&GD2x (D\.dT/ߓ6q۔L-ٮg1l5ѹЗ}ty̎9̲"=ʮA: 3\ͨYO~B IۀB a}i]MK-?D2 \ ; ' S t rJ L  q 9_g4Jv.R`Ar'1GcH$n D  3 DBC1a/ 1? WJ S Z W < `)!rY1 P   91!l!S!!!!!" "w " !!!P!!.! # kc2~v\ C =  0hlo  \  7v, i&d0EnceQ+*[|X ^(m> ts@)/@&^Y4=KM<3. q\ @^BWn3t, p?k9W?j2TuMJ=}=33F|8fK/!@Q#JA9n rw I  K m t G<|oP;#d \ c ) w  cUTfv>!swD;(CAaQivJ %Fv"pBltV2_gW (  !: 2 L }l >    06 d O  q   Z { U 4l @gw6#(l$ m<-4L|d VzJH [/v<&V<ߎޞݚNt)eۮ۹gܟU݂RޡcBF Qq8>/loPA!jVE o ^  _ m  ^ t . 1MvF[o]=}:/ i![$bS*w:M @ C 'D ;6 U-0.!I"#$_6&'C(^)X+<,,-/<.r.V.--+q * B(3 B&v$!w:'Wn&-T  PtJEJPBsq5P;E!f19BDJZlI'`F1"~qj~gei?yyM&RbCM- PI= e ^3+6_)GOz  i{ M @ 7 > {50'Yj!qfG)2B R 8 ; | Q U E O mcK0g1z 7 lM}8S\A e! "d!!$!R%!]&!0'3!' 3(c(jc(A(('}w'&&0%J#O}"K !T ln (6I \XKGR o ty`P,8)f.a)`hݴu}B}.or sޟ-l߳+@ s4t MnIX m*M@"t] >Zed&bdu m`dLB6xw=98TndPVq_!Jr,?x%R<[  # Q  oBdO,v  <zg 8!R!.""s""-""d";"4"!b! !!!!!?!!.!)"T"";w#~#$E%%&E'B'o6(() )C*{x**+1"+e**)()(&%f0#" !D[ &o7)':U u Y $Se`NY)/ecP9W d4MrJHf:_ )IۊR&I ֜՗ԼgЄ#ξWOrllʆ)˧m̖ͯjԺ֥ؽ js`GmW-C`-;_m   t  ]oX   U  l0Ut]O6  YE+]`|&vG& BWLX dP]hNߒް@޶ݽkPi.v ޿~u--ydvXyG1RB`#>@i5+@6iY -s  Y H  y 1O ! -  U   %\i L`Z/kG   4 v CYgV*D !D #E$u%O&'()l*2*/+$+*(0* F) (! &$%J#!g{P0N Nkbc|"@ST-" <DHgaQ`? SvQ,#{MY#"?cHGr%`yE,y? ma  } .iU*hvFi0N!#u Gzf^:^t -t0 Yu g +pwuQ)k  >;*` , !@@!d!(h!B! Y !"^#|#jI$;$$$w$$@$#"W!  r"5xH  3 0R,Wݪkۆ1٤!hYD,>+kWT*֒6e3ؔAَ61ܠ݋UUoexf95+`zR7@!S6LlC(Fwo`T5c _ V S >V <x&9W<~`Q>D-= "b 7"#$%&'{(sx)n*`z*I*%**(*)@)(8('s'B'+'''j!'.'B'=h''R''2''p'.'L&n&%X%S$ $`#"E!!;$|y`RvA% S s~x^D1&$P!,pJ@LPt$CXIE O~dgJGi|M>A+ړY)Ֆ8o UTaPXϠpOG6l Jg*΀η ϼoЂtrҗ0ռ׷f-re zzSf~/)w% Z w J xV2D#VCjL9AE1f \  QX  p  t0*/!b$ Z 6  #} 0  ]   l ;  z G    B  w  *  w!  2 Gx!5q&  P? C F  BluaOP]oG x y d!m k4EH-q " 3>FUEp,tzG( j a>ur%I_;=Va'\;(+ WRNWi72 2 7lB\tYbI;95.IX +so&~Kb9CC4W(t)/G_m'woOd@7 * U 1 $ /EXQ'1H=P?[hQjZ-dL11)R \ ? >Zk=)k <D+* $ nt7uln5&FK)+mu vimQxrD ob~I } 62 *  @~|-N6.n%B ^-5 H`3Wr LmhW6߼އeJz815Afܷ+9$$P%)Ut)-Z"MagYrk7  I Z]\SW .x z  \i"gi wL 3(O~M$  p ! 4 s s    N Ccxj$Q E!!"# #7$ $-%%V%4&k&& &o 6& %$#l}" ,Y!J4A l( \]Cޤm4t۬+ ڔ7۵Sۛۢ#P\ݟN%yIPJQ!q"Od)n*_C #qd N}LRAln |z|u O $  _py9fvab~qU 1M,, |[?H'[u V#|U k k V 4  q +a ~ EdiH|(wc P Gw 7 8s=@;pr35i*Z\^|I !e +L P! +i(  v Jka40fߝ%[۔IS٥{Kֲմ\ 9Z#Ջ+֍?=؏(` 2sW?! [*z`a@I oM*ww5f w E%"s/v;^!eDcbi|_hJ3/ S)^r^4r4~Ntޮz/3'%ظ֡Ճ\_E0`" ḮN#Dʑ=/˺bߪ1߳'ߍ_YTgz7OT۸Y" ZM>' iIsHJ Z {  ; * nT r  + J K &  ` e U G 5 # :1 s  MA  Ezg]Nf+!-.V[=X`H^     bp  yBm{&8{Pb] Jm 0 a  ~D /  I  " { s e 8  g?/oBUl8 Q^   T! L Z _ i 0i LX a=  , _ O nx ddla0ne2u*{q|m|  /_} @{wf( .l{%DZq=>"_naN)|^D&HDU`z BY 5p SpJ@-2TB[[+I{ #' ?s e kPRX]@& q 5 Y k  I  T  %  8 B ).   ="  # Wys~!uD\KD8;Q  L  N* eE"Ze:0%e3F S VI+jrSYaa.u"kW9f]k;*!oK@/ c%?&A]W7\9Yq!%W 8oVmH h [s  & n 9 + k fA7pg Bb ;A}.9ܭ܈x܀ܮ0]޲999MlN`dWlJ 80 ywIEui /  Za  j ?Q}1s{4L`dG R!0xXGBS<ccQP Ui1yG.yY*>lm & ?!, ! !# U" " "R "n "T5" ! F<x,rsn<]T V e2 Skzߐ"ڠ9gך0fjp"~O*S}p\Fެ t Uc w4sJ)W-bL)Ooh5 tl>|97  K" =.xo iTw';Ol  y gM 2FmRZkW'h0 n \dxBA)(D:L*[cQ $5]oGA xk ; ) R W 6 x%H{Yc$w * E : dl)BE.P4l X90M#۲ٸy9U4hFk,Ԩ>fԏ}Vl@֎^־rIJguߏRDK;u   a  V  d3a[iN =L2= +B\IS~,]oQDP('9XrX :dUNU/X6Q1!<2s  d L  ~ C J SB55}2~[D eb28v6-_<8VT RT{s[6 %.( =F$(Q w} U)#f V'^D@!`%/Gj+iKUy!e]qK_Wiv_NH?>&(j)l3+S 8(#L +;T X9Z?dlJVJTh>!Q!p % o  oe7{D|1#ja _ (   h" %o  u ;   g/   Y_  $pV Jb$ #Rvq[iT5& h 5vl-WgSI,X|dCh-MyT Ic#/y0&U{6_G4jOh9 u ?Bn.bth j^ Pc c V 7X0`Nug^nNa 9 F cbq!t5S.u<2 cv b/TW>*@~BN N }w \13%m  | U m]N%<F./QAS{VH^u ,Md9lqw-  gQ ,  ] m  H    ( #[ &e @ ^'Z@r-3%j+, ~- " p\R}1N2֫8@M9Jօ׻ytG6!:|Nގ/m]@ir-{l#@ *~r?yV&=Pdjn\* XU#-Jf zb}'I. (r R ;C Lut) uuAl$`Z IIP~c98pFA7X'R$8dG_lG-J}`RJW7}F6Ui|iUS-"/i   <  eZ x t b 9i@-X]W8)? F/ r `JH_w<-q GմGҮ0zdoklфџҹ}!1Հx(x؀>F܂ݥ߷4r( ]xGHzg#Z_1RQ)D/JO  x C a;   Aps:?~ l6PE:T-* =9 I 7J   ^ h !P !A ?"2 "0 #H k$s .% % j&V & !'B 9' ''?&&6X&%_Z%$$<q#""W!q m5 \J5*o7US[tG 6 ?!+!"o""##% #"~"M ! B! Y QR84.{2Lp70 gd2%by Vy oefYHY<*Nܙ ڨhڊٻ@|6ڤڽd۵ep.$I@>S jݒhbއZߺ`=dk߆z\)Dޗ"ݕ'5ݟ>P"e ݒK=Er/h DU}\a;~wP#TPlk3EBe -,    . ?Zi.o9I)Uk'Y x Z I!!"" 1" <"!2"c!"!!!!f!-!5! B  cj$^up N|Gk/rZn r G  J  . 8L rc>qE/PP+7wd$.*Zj3Onlc|{yBUN!qU! wymN=6IfEB4 _O$:{hoJKW[R;( 3 J L j GkG&Klomn9k]CDYu AT}ZLQ9|5V1/b Ok`  \z/RkNT>vmidR 4{  < n z }^ ),  f  8 PDIflaMh4rrkepa24  6VlIERs66K.`W*  ogKrfGE |kf9yAWbxA`/ 8 E 0( @ SE^Z>F2qx+G)Jbs A t ] ^UlZ3bu]"v u2' UEe'XLqQ9[O J z= P   'V2+JG 7X p.WgQtI0] p]wS*   # gz[%PKZBS][!, q#02jZz] %N F J g 6oޞݶܨOl. Gٓ9_بA?Aj0 _߾:gm,@h.{jtuAFt"OmlEg0%L0h=q0f#._,;N N F 8 $ d93eUHN  ?of : Le V jf{R:f c X. J, Q s `>+jS+EFHTqx u T > ?9 C a  F > O^ !$ ) Q q- } uj Y +    @?.dfC K    8  |  _=FߋzK|֍ӕ҇FҊѕёoP4bCZԙ'beD\ "pfQR"C1H> )hN%6s]5vp2!XHN9Oph~$y H Rd _ h J , (h0!275xzBj-\GAGf:jx !}"^#$+$ %%r%<&N& }& &` &i $' I'='&,s&%H%O$H#"U"v!!8d!&! @  "Im3]. =2kk8(j0   mZK} 2 H 1C\ [DSD1ߦcuܚݰAHM*ذXe޼L0>578@EPW/O1Q־qiC݀Fޗޏ|&gR0Ke!Z=;ߤDy:ޡ#|4{L+[,h8+/xmC:R (vQ!FhXL T w  q ; y E3WdU3 GVV !KQf 7 = L!P:"b"0#}##&#M $f$f#Q#(h##"y"<! !j sr< IPx]Z){t'x;p   <  : -!8^I wK#%#9er8y#} RlrTN;UK'TfM3WQI$BHi6SmK{7I #rdDL Q9?i*4*4 M:T{# /jSkp|*d 6  ( Y $ GT - J W  7  vA|n7dnDEe_04Hu/iaA>=nX5= y >  c & Q ~y   y n k   } z   R   H   b ?cnrd3(u8=L{7ruVV$t $ Ki  1kljQ-;r4"! M.Hir6u}naRcr +:Pc^;\1NI8}c7_EEHd\_ 3 ?[\7sPN,;DO}>$|Y)|)lfE(i,Ne~% = ];hKPk4.^F ?i?{W4qP  D w7  }<   =P*P#%oZT~R A 2!.!! 05 h l  #_~lczv>2K1BywH= bC fQ -4 ^ E) ! : d ' Q w ? ^ p X| y )f D 7 7_ =UucWeߨ-,^߯b)#MJx5^u(U6s7M6/' (A kKZ4vl[]d03!\9?{y$l12%pW6DF w  d1< r mrM I  gF,Fhvc8Spn lG )  GG]zm|  ~ I r n & G  6G GTj2 t `6& ^&9 [JzybFpfۦUט2ez-(ӡ:]Ҳp yӐ=Ma֚]+݃T# P*!>ZxYAyI,:8E&jl\irG~# : 1    =  r |T{O`b)v4YU 3"Z#5$&&'''h'1'e'H'21''&2& 6& % F% $ B$ #,X#h""*"L!!mJ!(   Sq>UP8j|P<RQ6Cq  m y %N _<UYf ^ H %ju; e_^=R&Nh i B ;.G} |=DSAu = ,FBqZ}?&t7+_} !O*&w %UnG"1GNq  VupdD? G$\ZOG,DHpMI|6 5}  B ( K' { )G H b~"2f l[9\T%Eqn{d{G)"%bE: $2FfPI?7&NdOr$Ml (i Xx n < 3I ~oaJ8YaY q85 ;  1 BJ f B'7 (Vo+l3xm 9 L YT$a"ZT  a H 3%mYs:2rxvAn t  ^R" c&Nz97 6 bN ($   5 X u ~ r ^1 @G b i)8[ N; _ T  sK*V77X\s|AvCP-Z#2hV1q-"GQt g6*[}X?/ E  R'185l'E67 G(kXz0 #7pf}D JJ7] W q :`eKJ D K{ r D,6Q 9D)!]   <   5CWRY_\ IP C ? G #i=k9+]m?+L=O8X .7}%`>}'1 ~$'Yw(v"2DHZ)fk%a?:ߺw`>"߳$aK߻O;B-kfT+\Vn/O:L9W1g""IP(-F_o 4  a x  Z  ~ @ 5  >   H ' :*ZbVy $ - Q 0 Z A  C N | 4~XP & bf   ^  R \ l|%0_exC8}H;+g  j  v W*Js|;xxZ9xgU*  G M    a  ] ;  , E  Hb7v +5ha"1- T>ޘ ރ[ߊ%# $n j vq@$4eim rW1;&[JkRpFj#NyuHA< kZ\x^}99qiy}* :krQ@%&LJkB/ 0 6 b 1  S,?G"WL hP%F}u?  !V!T|!!k!h1! h Dc84 tRE"eJuXp  C2 -Qdjo  2 b e G~ViV $siQP+`.'FwB}@tl1nSLm?|PzdTH%KDGn ;K"   u  Z@gE" E n Q # ^  eX E|mgX \ B  {  q 8W.$ {_I\Rs a L7ce!$.h9{D1E P @ u ;   (4_"Q(}A3,be #eI[p9(dl " Jj ?b,si )YV&57 i0YgoTUG-9cIM1w&ujuEX?P[`fM^J)%6w)a 0 3Q  d?t+JwL?OaG)2&*Z | N }RWOCXuqM[x0| e # 2?E&m J/[ y K p ?sT53S7>U:-~F[:D e c CJ 'iOT1q)u> H  Q!} F[ZIV%*`@1<:VyNhP,m9I# [c2,pt]PJMxUl_ko Dk lzN:-[vy&:_ L4\zW9hV }&&<dn7.>6u-.9Th} Vw0Tn3jy_p ^  O<T`|WZ4 &  9 . .  -   Z   Lk d e W ? $4 4 . ); ""+j=GUBlc3+TdP 9%Ma[AJ$ )jYYF3!<^tg4bV>(^}3].3qZMjk*[atu!_*zBU,#;M] zPX  F      *b G h   /    $   t g .   W L5 c ?M  ^ B  M   4}je k m x  =]6lG2xSTrge=m-x|8jWH7~ P  _ s 3  A!GS) vNU+&Wa b  ) FK Oh =n h_WP-47UU(A?kQ6!oPXUdBPyc!S@B;TK&;c.DeZ#u e?c|y6|`1)@E\(Je},O`ccYA~r {h5in@%$ { F z $ 1  kZ  p < 6I\00 pzK<~\H[-|g 5&sH}'=TnhC `wS+|<@5j0q0 v   c% - f8 P  i @d  W/ +  z py |O 3   k > q  4/ @ 3O _ w a 2 < y~ '  $ d v y " c 1  M z ; m<s{&UiY !:cE\ % 1 [ W2 } B"^6A8ZY92.On@8:hR@   ' 1G T [( R D B#QTrw:&"*I W CF DE V {`^\Ewz*B+*u)q9ZmjPjmd,% hY x$%)s,F,-.-#.XvoAa&H'98b Jn]n P & U Oog$6||l7^1ng%L!|4$k C5:  '|Ed D\5@h V}z U E sW M E Vu,~e_r  K : lvw# *&8O/  Y~^n9Hs\7m m 9! : kB i @ Uh G .  L   R \  LGPU<a@ocgMl@4U~`w[Ez;Io7a!gN{C6p->t}O r 2]] hQO$:BwsfZeq  ); @6G=) E?sa   V  s (% h P; 3MVU \~  N' M7 8# #  ~ , \i+M}E\%og~Ijfrt O#+"xUiu olZbf=!8mM4V M0v-b:N>I5x)/Rw ^ E  1 C  q   K   8 /i Q S ,8    '  7T}   t  S -iM wINNe}^AGj{%XNr'H p  # j 8 b " C w,  "  8 q B !   T6 M R R6   A a  3{F5U*de'Q"]rlD $=n P mx9A t!}H!>v1\e3 Y|H\ U)^5jNN8(MRaNwno~P#wqF), +A yd'@8H`slYER-|<?B3Tz| 5 ? h { d <:A>3EG4fgC EjR^N k '  {\ f#8%)SpYt&a >   v-*r5hG"z  * D N K@* a&{;%WwO45T lx/S1 ]K. 6YuQ k /RGk(}z PD x }i Q  .0(*)')rt<^SI9  ?d # y  > R  u 1 } ` T l[ r}  ~S -   Q^%B  0 = 8 2   N |N\$&i)}Hn/zn+u5a^RM  G | " Z jnbVJ9%T$0. 8 |r   $ g  +n}n5j z P6AQMIs" z-]/  gH p  0 f}yj[Wfi5vpXWMq?xv $d  { %  _. D8OJ03?Nhg0O\5 v2vAFNu R3Dt615e+|b *\#I{N6dULO%!|7H6292qP{68"F{*)vs!qu {>]p(+w/`<LB?+ ,  o a )   X^ "LjD1ESY}MM${rg  Y7rO| s N  UQ%A~55Bw , k%^.#$+~aQA1guE oC DzBy6:mD :x:  j~ Y LS l b Zw:eX!0 `1w0qIK> @ _ ( 0 X } ~ #=4r XP"OjtiQR31W (Z  ] " x + }#8 a}yrVIDC(Wy" ~ ) e3 u = G  T Z 2 . /  , A Y ^  [!4M[;aQedls{% :-d0yR?FnkE$v 1Fqll/@3y+8jJIKm:a[ f=ua ngA7RU>eL M u IX & z  K9XF=OhQC!j: U N $ +  9  >u V 4 x  q  q  b Y 3  /   ;  0 Y/  ] #kN& %e' 5 i {  v" D  {  p S ?U0,<T)i(O&uQ3R b_"4M i31${Y) 'I5kQj <c:{x  x L   m "Q q } Xl :  e) :  + _&?pMs$4rhYg|t)c[}_>t |\.8HO= >y*PF/"Lb#OMX!cv<-I: Az"6\Vz9uf dln\:u[T][n|\N%+\n/E# uDp_W>Y\qs Z+lKggMM%} r ~ E@ !   /@ D< ^ U +5 %&Ofj7_Js2?&U ) N*>LWsf$mPtvTqk 9q Dx-(\2Imk ? Lg     > y g F  H c   X  i ?Y     r 6| i m G o r 6 HC F 1 1 d   O  U x :   @  cn  ]  {j iVI|.LoX [  `3 H [ d [ 7 E e c L$3( dJC!$Jb{V9| {G%Py_Hj[PV/H&:bU2qK=se GTOX+o%d9p$.e@B[c@)$*B5?EF@2.~LoUH>Fjht]xx rthUVN g   q_  : L 3H -  :?SO*A5Pkbe6Uo5sDYux'K  1  c Jn4%*&$! & W  S Z"?[2kp: }rC6w340ww%WC;=DQ#iK)_o|,>U1RVVLP N "   | 0 C R& ` qV\**9+?l?>8&DV2o'1+CwF8OL} ) r < x 6% K a G e= !J d  x W 3  m . I   r '  $t P yl   P t t #S F k z   ia 3 a ~ y\'7^6O #>L^*(jztJ]1Xj ) Yc + p 7  U N  |hCnkSn_=PE 4gd@GaTT`bWR~di?s|u7DmkW #4@@Oh]hp|[=5}<2!"}b:b|,$e_F< 9 / ' L< ? |5   &   M = p    O x         5 N [ Z (B (  ?   Z ~_/O1Mwzj]cg(vFmM~RcnN74w$-dQ yxs&.oi= MZ)a~^}: Zv"{u`R6/.Nn Pnq<)H`   C \ x  nf    y N, Z  =W [ m- x R#$Z"i UNLKNNPTVdx2 6=o5b}uz_(V'9z9G~j9K3rWh""_^|g5Cw% IF HNO]S0HL9 Ih PwxOc pT | {  <H   W  Q  t  * = C U G % K K A ; # T  f  | ,} d    u g QU <  ( g z_q 1C!PSTKc<6-(8mc 0:, * "  q kF }]VmX*g$ULp0Mpn}P`C3'@)?3@vPew}sZ` F#E`B-&'^+44A LF'*EYA\GL".K/}(Mjy~?0g; }%=@y*:Y6 `[bV!anK } 0 e g  W<   1^dM[   a  W  3  q '    =~ H n  Fz #  >  % |:%9MyaQd% Fx > z NPAjS-"o~XsA<,Kn*TNM@.%}hf]cy~{t+ElZoDD!\G \ e V m + h j U !  mF bw c g `< E{  e 0 e KR kX   aRJ|E0( *GBbv:XgX%oa) } m  = (V ` W 1 c E ErIP d8e;D,\7tir\>1#ByD^ -\el Iw/2oBEY c6Wt%5  J  9m: ]tfL.?F$BP3qZs%}|\p6g ]VYtj-4I\igv[r^,W>cQ$^ Hr Kws aIQ, dIgnbYJ1] 36[k pWNT7 Q,k9;/       P( b   P   %   v j9 f b ]= UY Gh-lia^,f}S9SIqM% Ags O84W 2.GVW#H29mG)%d;@**3-1Y7;,g"b Ul0 ICh9nR8B01c4jU[,'=`KD ^ i  j ` 3 \`ftO\GH5QW7MF >{*@~;  En9u9Iw/Z&93A4evDqa6P@ 3w)"Z"&;/9BKJOS]Tj{T3_3nc$eDynLu:V^v()]|F$#m*\K@ zu F+ C 4[ h p Fu ~x v n ^ =  P>)g" Q  &p Aol:/ w 4 $ + 5 C V q  A | - 9 :U t R  h '   S=  @% !   h  rMkvE[ cI^H > s !   Y  9 O R @      t Z @ # K]L ` N?utk[9u W bWF[ C)(}#)&M3wvue H?adX?pM)` PxM? MJ}.E{ bG#p]VzX_jrw~t;SjZh PV$Yt[n$zv UyFfWKEOiEX(Y'E_1SJ^uJ'{H + & \ ",  ] vj`I%aR[^"0 &,r$8O OQb8JinBS/He|{k d }d il P 7 0t||yAreRE1WG9/;{_!w7rX,C8{yfVG ;2")/7`AIHAG=D9</,!oS0O]3X sJbD$2$B49 /z 7r]K&3b!a  Gy1'*"Cy2(otbE& t[5)OQ! Kx@%xyv(t[lLa`>1tyRcxo+ <ZL( % }0  41 qD E : "  ? J a =aB _I1l3jZ/27T;b@TJ0cHpdm wWK0^! ;+BMfycbd`@2+* V:ebha Y;S4>Z|loSh`o^ bl,@0qk+c+It/& j C r   ?p ?  rWg7r3G dw VF <q &    - DJ \ouQnU.:M2Ry NMjbwt-op 4JuoX_S2FK=B *ZsH-?w?@es89?po5Si<y<5zJL#>KQTTyYl>_?s#8 t_F9w. P n - u +  ` S' ~K  TI>DB9O^b6U41z je\F$h$]a16h9 yEr_lXe>+S:n+b &l1UeX6(,=k\7RCjRu *] ^$$U>NY^'ZhOHLO% ? K  j i * l R C S  4   .[  W O N   b    8g oB   mRoYc`RcebCS:#pK 1@JPYku;t</TgM1     \V/e|bO M)Y- ! 4 f $  2 b t _ > ( da4i,>I:_m{+:| \8rRA:z:nxP~B|Qv<rOL o2P`_V@kxX-iZ13<<@p7Ge,`oPt"{~Ae(Y%i3CtJoUD3 h Vo Qz0gwY!vT Z<*oY\wMFxECCv0S30d /g_"u%Tw+ L:]27d0"'27XS!?Nsm}8RXRG61COTEU MC?BSkzmC9i` Dz9=|P(J ur&j*XKNjP1+D N-PNG.Cn k0>[mn(e'j<2BjqGEl=Rzl.;et/+/UyD6Y#pHr${8jzvgi2`br y0R*^&M9Gk@!|:Q=5 ~#|)`j RnXGXX%2Oc {S &CXb, M'~GF 8=)W@>4<0/D2>{G,GFL\aoKGZ%*s HO^vI=AK-l=IzTOc+#9Pe{.CPJ  0 > [ q N v o ' T f )   # _ ( = r  K    . Wy p e gV >  @  a  r A7 40@.eTyQ\F5+/C|Zhmo~[-<4 "   p +Z HrI< a j  s  4  a A # ~   W  R  C.j9>1[kFGR|%@'NzrdI,#I&p`tGC~XvGCVnQ Zf(Gl/otyzBxVw8|vN)oM*mg.V \G;M%NB WjK;sTv&{tQf6g%{  bHc&mi4?yoFV+ n 63_:)9 *7_B2K5 h D  o  .b F[ Y C lI| wlUm=yP [ lhi   u! M }u!JC!0F]DhhvbWE{*CWp+/|#&| B:u9uq!j#9A<V,0|Mx\:k-o PN{VR:,aPTj=[Q<|ep!x%2BX^bN)kx']YQXp 7e4j S>j?q0c7g9iO ok2 Au_W/ @0fZO17[> t*.UDe'*Wj'k_ ?B A w r t ` K 8 5 a  { *  i$  oF7Ax_CWv<">B2~yV2;H'oQu3~ uHnd!IO'w_3G^5w=jt::569);7~+*z -A~eM7\# %_yKr to'cc p ##< xu8g=QHq>  K~zBAp)e}C Qfz (rF8mpO)_Q`jJ e$2+4+  b%&--w((#[%UMy .@j/qvQ Cq#b4^A7un;Qz>gB7^Dx xNYOcJ+R5 X]mM="ws 8Qh$ `  a     # w' - p*  } u d q ?.;F.5B8V9?=_6@r#~L&wTP? B [ ! 7> l y 3u m ] z9  t : B -  W&v JB a {   T T { Da   sk:P-Q! f?H0 'Dl&4:cPj F;bxm[lWRH7: i 6 2 n#  6h TQ#uHfu'ZZ<OcJpE=!H$r4s3Ov8]?p:> h%%6A@7/x,w){*}9{[yy|sO&f!d2Dg!e8e`6 3PT{RTcH*AW  M [ @@ OK=\8j>q-vTWOccv i$ _  '  G ) Wm    F   % yD PBSjC?m2{NYQd5b8lZ~J{gKu#4XO4 Kt_RSPWjkE*!&?bK Lz.GCIyIj##Ye7seCWF+2Y/MY+S B%{o^hJC>!?CIXq$G*k@GO[^o`hki_C0\C,KrG5J-F#L(Hxz-+#kS+QS b# 1k8Bl)o^N7+  L  2 I qS O V=  F  4 0eE)x+0Hz7 qa3PYo$OO {6}:c+';x3W#XTOGw=Y<6RnD|{oZ#CN(q xwM[.5"&!t\?h.tAy  Y+@Xzzmkjzd;h;P;lHJ&%GkW"OA|}@9 @R#FfQ, gL     # E _ ^j "e Z B h 1 L O 2 2Gr 0%b[ gQmH73Eq |sR$(QS7/kg oc<>AjuFZ! 5J [ P 0  nSVB 85nE`|d*&dPF9xfs,py'bb i#e{,8D9GE9X(_FsS/0`\Tr-Y]o\Zy^DadbWC*~z^'F-K]1|$K?/=8vLTUc!v8 %&Y]z;%\6tS:a=N IY%TsyBYa"9^1NsU"N+as6GvR-#(v2Q*8 / #J?  v 7l  BMQ`?0 V  rc   20 T jg i Q ,  X a 2 eH : [C}N%vpGl+.h C r=`$)j5o5l[: G 0 c K   g b W J[ _Fpxk<<9Q$'AXdmM@=BLbGu9VVV\B<.I;e/9=D$^F]he n 0 4 T < $ & 0~ r @ /&md ~ [^ Qc   q   u c 7 Y  = , B RD 5  l  _\  N 1 P B K Y W{>sQ.Pi #y4^pE($-444X25:96-)%D^}K_/@gyl^1Lk<0% F '[_:#T }HaF- ,Gc"WX% $Ebe9aI(t9n[PRKKKP_DxAHrr?XmV:QZ qCx?5o4I,97/a~5-kt S3v-|T#$j .-ec_ @F{K BAAyR$6.>9\z><f%Dy(7?'@5."#c]mU&Gq17_3yM#}Xa'; js3pvJz.Ri[;t  {O. n:FYH)c9< #( )Mt  /%TC|f % D d } i : o F DRM^}I )cK  or*g>(TQvy'6`>+k,;qe\0Xt-fU nvVqls#9?/f" = T V C ! a*S_-#se^Hm/ 0X)#I=c +<N*a<qBu=n*^ J.n-5\)4D^:_#v4Rp.W`/P>ps"jD]L4h/Uvg!<GlwnJAXW2n + 8Ih`/:}'uv9tL'c5n>X?{jj"XJLRbY>kSN(qqPD;&|-lbRV"rfo\.L4YoK:b/2  y    zL J  E g o B  b ?{ -) 0 Dc f   | nO@=DV|saF.-M" n  u &  l R  ^ J2 G =  m ; 7yxF]i;hQ=!*,5C[r-UG~p d\hmi ][VWb(zwb-\8a+g=L.Yj*.8uuXD5NH.PqO@\da\M57 j}dT<7AD[> : c3SG>k~;h CRR I # {~ $  ~3 6M V T rJ ,1   & h  x # ( h U y  lB,h)oMJ l p 5 `  | @ x ? H  [ I - )Ra7D1'xH ~~^qJvACGM\o0S` o ^K4uUz)qyc"gys-=tv8F)7E{flp$%89'M]#n/pG2XL'cr~Gw%+p>{Z*F@HrVepox{|svcEX"0d6\6l W%Ei&St-]~W(z~_/Ht@y9\&6La}wos3;c0blV:4R?Y,?;JRIWAP7@&%gE:cZ!|/*s7C)$]@wZ "6bO$q"T<aoDJ$2?X54NQ  H% q6 7 .  q >T &  A5nsMK&tgNV 9]hE(^m+&j|0BIYl cp*u]GuoF,"!B+WNb]R,G?<D:;E3V`fzu}mT>35B&V-n(x_C"}hP.ss;7W(iFr`*p yj 6?tidc\`'IIDl[?{U@Ai/V:Y9tR $H hy   5 x     a @  o?G#3JP*aPu,@}R9%,K&j"@hkt[$@&X7 |L`6Z,\=0fV ux8Zymg+s '9 Vp[|-[+&3MfFz5*r=L\{ $@^Ugz|>`}Dz*tMtaP=y,S?0%Iz:Of6Ir*hgpsn I ;%&J#X#0aATg m W   I s      } H  s ? \ ' d  p &p , qp`[[ gr0 2 P p  ? c% u 6  H p} 3 t V k K + , k ~ m~ c\4TzQPE32@HKJGD{Bt>r1qfP(nO&=TrBR$aE.nR#${Qp }n x e' O 4 d  8   `  pzi[@RpF3,a8.K9 N R F lT Xd y  u,)PabI*<66>bN1e@K_r PJ#I]m6Ef# wN2PG[uw\(fY UQgGs7E3>RuU?`%[eiK/5mBlv8bq[U<&%Ja>s*n=w] Lm**\P9A0WN'j\} #.+Stc5_c[e]vN 7S eNF0"'1:x>j=_/TOOUeh~1.v`N+ dQ?PHaBml&!ZB<NV0TMLA-?rK-  E p-CcAqmIHg-/YR < (g R e ] @   - i= #J U ^ We f Y = R  ' <Vgqm~$m'sMQb??DvPXNnx~AC M.{*ER8O~H>)s KySW3|lZGy4M! i2|=O o'mG[?806G5dj RNOn<v CC@|gu9s`<j:h;Dr?X6nk}mAKy t L  O      q ?    9z 3  m ! @!fLlelkH- 6}ZrSU>N!#I wN+%Chi+ g",'*,*#[0qfdl|;[ a%<Z-]AnTiF;9fj\H]0AsF@:y>5Og|6{}epM>5:*eB\pr2X5{qiG\"N;!RdB!4_5C{eQ<@7;PKs%&{`H,$y,P 'G\g  \   > \ c ` V L ZH E @ u5 +  n  f k \N -  8 J P y $ o ` Y \ l  E / I_ s  * S~ ~^ 5  ~ D l"0EMrblk^B\ }jfG?\ :jV0iEi 5^V+qLO(YPZC >Zqss}j8S2/^bSUd6|^U(3u  ->B`Tchb9V}H=1+%^!0"ACSZfjru%Ji?h _x\q?(% x   _   7 )s F e  & @ V c` #d h [g e fa ^ v] R {3  e | 32  y[  &c ]&sV=&+6=?Usot8S(bT6S\lK F \1ne(| TG8dBlnD~:< vFM($Lpl<mWPY j0]a $z;VTr9>bf1 .DWeYq* 0Kyqqlj-dw[RAE"gL'|l7o5Z ~Tzuy9/1=?=2M#Y_;kD+`{;%n.gly}{}]* cP,A+U?kD<,nU0DM\V=2g8KQB{Mr2 ~k0;o3;t %   __   * R v    ^O   6 gq  , Y  1 W e X 03  0xlB&SyxiizV F}W 7-v=Wn? !/La)pI~ytF%1m41(;Shw}n~:ztqoxhN[+; r *r"CwZL>'9xR6%#u.NF(qE>kp& Nut*)3XZKEzS-''kyJeL"H+dtM- 3 p X   " g    q4 &N ] k &r p Ug P )   mA " E | KT7mn]QTG<(4.1=JW1]^S`em8{sA'SkA'.26;rFlUnc{mlZ7 j6 +JveRy*qY< &_lF/AP\k(K#x\7W*[o5O~@ g8QDGKBUEdOsYygti[H*^/hw"C*wQN1] /tVjn}i07olS:<$}Hp|HF>~5hT{]YR5uCI Y   = n   q P 4   u =   G ! . &; E [C 5 s X !b )   X 4 c C 8 > R o) 6 = K ] Mn | I / My _ j< l'VmE+qmr-YMx5wqW+2zUZyA(,gyJ@Bp:Bzss{&Mxh?X[!tgclBVCh4E1I$e59h.XKv(Tpvv!F1- }jT$(8gWS:[l^LNz,Z   T  M6"PM_e^I)<arbZXOJ*Cu6# W 9 l d @     Q( 1 ; H 9S \ wa f k Sl b M G0  t 6& B`"02_,WV}hSkKPdH Y+. iwZ+eD ^7go$668,bqlBa=QrexbeoNz}xxneW^WPhC&, x> ]:W:v$M%Bxr|BrjGUOk(!GAXSd^l`l]^Y?TTV`Rpfpw!$1dDYoHsU}-YA2-l5?Kl} FM 7]BT/jL T%+C_K.2z_$:YA 6u6@@JONNPV]fp0V~H1BORXWRI</ b$wXs,I45M{}lk y`#S_*kHWC "! * # .   % w  % {   , x8 q. s |  m %  mt L } Q W*K3jj@3[0svEkxNW6!%l;T_A3&( jcd'DkgY%v u0osZ{NCiD3&s^q(1k< 9h!zZj[5p4.rXKS^%r`,Aw6?t(Q;c_K-  g  mH D  `   R % J Si   4 u  z 5X  z t" d iS N +SM1 V_nxvXfHhOksmqJL2cU{w*   ;Xu&zM_rG5Z :$5F!K.H;@F.R]jv%PU7%N]m j ..Q{+q: bnV/VmN;(x+ 1o r  1+ uI Z ^ X =C n "O xzB|n"K[FKRDxC Mm)E*-Y W6,"Gn%/yUH eI9^iafz] -Nn2m9 DrT?lb[}\n<""q- a9Xx,![ZP #*/+e7dsS9# &KwT&`o0 o Q  S ; Lc F [ L I G fJ1#F <d3;Ss!!M}z9_(])6DV,uUxM6bq=x=]2%Uj@/  #c bU](,xC }om|?hO rC9ZD6&{/: Gv9!J`g<gje^TF5 6k|;MR@ `- @HL@,dco%N,raEp:Z,LDP|@HYA'j|G';vHyKq:Ky2  ,8+BQIG>3P&>`u{bM>q7f:`B\I[N^TgSoI}>3%{sqt{,O{Q+h ;4RdqA~L ( E ] )y N | # 5U    T   x 8  m vDV:9<#f(BSD^vb^X7ZbpBf%5r TJOH(1]>d+!!#0K2ttX+Kbr2|O_zjjrO|*6"*azS6o"!EvpWD?yJFcIF {8l`uJWeO% !oL>x 3o3=4OA {kF  B + yf     5 ] !  C& 7 7 _& 2 N c + S c/u1io Rw[1s\;U"d: l<7]1O^XG,~R,*-9WEPWSE0Cl IMI50,xx"-Zyd`j%V D=iG5k - 9 QC I J J P Z Ch lt { { k =H } yq,R~c#?@Xkiy#s(X|p^Ku6d'e7V! 4i ?I~bo>1S }(pYst \6j#S7 py { v gc S 8 Y   e0 f p  o  Dv L c  n B? T ? J E }O\( m! 8^d&4 :`5e=Ioz2A$84FJvD5 .~w?> c 'y]\` v3q1`:uZ@':cb>'cjR2;{(_(d>b dIt/^Un zt|uglbxTC.}zf:7?N rwR7%  5\vQk[K7ACOdc}>0`G~ `6pZH9M(V`P<h S`pRbGH 4 L \] f i m_ E Q ps3|s{:s$tnzM,'7%EThS* ubQhA+1$c#swXU:/`V3, gC`I;;HZo~"=il a0^C=bk$z K;c8Pdx[9nOW,'ImQ@[<BPHhH=xU 3zo"bRhUpm,\KGB>C=ETskPQ4Tmk2Y-scR?T-_*sY=!$Ky*m@_NyC1KpGP>Ifd}z"SCbrm]B"|Ned>}wbK9ht_ SxPR*Wbrn h,m85' Ihw{.}}S1/ 5f\US1azU a;dr\H:59AM\ov[A%&&fC"X"|C/Ibe}NIUlHb,UySTOQt1~!YA$sn@e=I#  >  9 # 6e , # 4 \ ! A 7 S 7b c S / r  4 e Z =7y{N@e#1^2fo:+[a49[s}|p[@'3;:.]7`/U$b5 ~j X=Gp.Ir4<czW N'] \A!p7DMNU^egm{*Cm    sN,x<lU.BR8dxD/5 .AiSct-}jx>   a3  ! (_ w % ` ( a N7  J R ! X D3og?"J 2~dY?-=  h<g C\ 2iu5j6/JU^hp~quhpSr5r ocK[*wt8MfX 9[ v^|r2WF=I; >@<2*& #0@ Vo'I,fGdF<+:qS [ XRfzAvw{1H_w1MkLbu=(YS%_ LN;!+<U z1 A A 4 f"  t1f%8<~.A>(h^W<#] _mOjmA[Y\bmw}V6/\:4f9fJ(HWlYVV>R%TX[V@'1a?N`zmJ2##)k00:J]sEkCt$Z:s^I4*6@KVboz &Gl>.4+LFd}4{-79"69.N c|G 5~OAjmZK7 l r8`O; $:;PrL!ST+ f"7Wk:`d,   #L|i";*=](|:{`E%&[d4 ?Lu8L9 *cOO0d|_7Wo<VgsvtrrmbR:^ZQ5Ayl:j>od<#/xmM,}7^4\2kE!rK1% ##->A^^i+")*i )*uxaNs>4_-OS)j 8Y ; R + . F ^ c != K H 5 k X T YL h   m @t"rSYJ0^.Hi5 7_5gA%.J*c/t9zF{RsacoPv8tgN+}`A#}laX=@-!d+Hvu8iRr,9/u>, F uH[V#PYv k C   w  ' y  S9nj2S$B`_ }X`O7DsCkmad{k.KWki Y'9D d I5]afi{ J-F,YdnqpWqt+~M!n#O"n{*|hMa, w ;  f !9COe+XkBmBgYWb|jC,ayj\8cDu8q(ov,jD3^lwwroKf,_ZW SNKD7" q{?Bo)DGlXkM'oN{ ^E{h86L]\aYH<4d% &-,]+*$q_}PlHTD3EM]sDo] udX>5o{; ^_1 WP y  Q   4i I # :WTWw'Vo!uoT??2)&&$%'f)&-,$xr(|!F^atu^i%S;% +@VrqX)Ea5&  %Dch}?tDt`(LP.}eW" oh?1bc>~dH,&JueBZ4N eQ=bBdr`K7(n#SH3m d!*PKn^ gp!<]Lv23j+|yspofs|*cdd-}f&LW,q wmS,b";[.vgzm\ "a4AF.F=1[$) /Lwrony9mY.p?tSK4X!8U,&) If zi Fqw];wKzDI n?kJq3(U3Skg^ZUNF\j$tHoX=$ ~ShVJjB>&<:<,FzXo3Zx7WxzqkjhcZNC)<=6T9lDWm"4Jp`1{xL*Iw0oR@BSh0A6B]yyUf7l-O.Ei_  x  \3 u q ;       g |* l ` \; \ cw p & f#53EWo`L!VZxDKr*NoL-vlfc^~RhCW8N(G</D2ov%(KfH8ae-&8jWKD_ABFL$[Jrl1L0&D]mVut"k[ B!"y,*v!PIqB$#cm&;h] 0 +,11! /sNoR'J~x0j@lPB 3Ytl)uA2cOo@#kQI0p96(oM&XZ ItxE5MNV!k9n8 5^S>y"doWOC.# _BwwQ('WdD .C^r~[I8'Ki~kXP. MzlEI%ej*``jv{A VhF./If  &@b"+.-\,4C8]Gx#'  |Ki7 7`+PwDveV*GQ7s#UBL  Ud$ Tkz1piJJ%+tG|xxxN|-/acFawS~;\ !r? ViLy-! > $Y 6{ F Y k       z [ <x R ( pT1s.bS@f|}41\v#>L6=i/epWd][[YTI9& 5~Qg.^t"M+ 4?HVygczQICCINXcr3Vx#\~_? kvs@O3v<+EhC/p  YO%>bM,mL7]ThxAzGlX <l<  R`  V } k \ W+ Z8 c@ v@ : ,   %V $   @ R  C} 1+j<(_jSV9![=+"#''$ %%B3_EMMF9'(Y&Wp?:  M"<fWu~ :LjC +C!u%6Sw $5 >==o4+#*z&A4Lga<preV6SqB -Pdmpsic]ON=<'/ +-9KN[goxt&sro2np{rrs&x{/+:F@iCq6(HKt e;A*{3>n e'h 6 o %*/0|.Z#1cJt1Z9c)m>dDr/0%!"S$ %(-D: SxrAIr\6&YpDK Hp ^HK3%=KPFw/lgb\SLLFCCGSN#Vamvu6xqbqI4'wrP8(w2\e4 1F^u&S>Bfk (?RbfaZUSXapK F4Nm4H:\Xtp @%Ov =s%60_49<>oCKEVdPvk *PD^s 4 L Y ] U 1B l% .kTc2>uD/FJOVr[W]FX8G/(*!o"EEAN of=ygn4hRt^LB?GTf{6h3OiS*rE'xPiz,t|sdeP8 XP4 _nc m +xfZfXLZ4_g q{,-Ged~Cjn0WN?;G'R4kDs?k# m   X  % , ,' 7 4 $  | ; M  Y  Kyg6!zg"vK%'wj)a:y.ub`%O@6//{0q9rHz]u!2KkvhWD'6L.k+./29>DA4 s ZD;BTmnN. %`MJ vpQc]0cu t52y5W%~T~54 1XDSblzc!]Qx.x\  D \ o *  U o @    ++ ON {y  N/ H P B  M | p )  > l<   = e[,I yrI5OgBoB> ;^ ;o+%Noso),8:Y3)P/Ur#7 ^f0 f76iwK?#[3%'=m(( *-368i9<$>xAFNYYes0=>4w#_ : |#}ml[I|>>6 2236S4421.421E0/3@[W+v fq80 }X)R^#dg<3\Tvs{:aNE^(b]M/ tikwP\3v!E%,5=ErKQS/Z_[Ox@.+ %x/&T8Ja}U u'>mW"Cp,>EB6 Dt^F;:[7q56=HvN`PAQ KB4"r @ E^4 p*bw+hYKAe;6::;9~5R4)1-&  *-8YLmF4k3d#TxNC"ScK6!%7@CB8+kH&s? wbRFABN_p#Ip%Ov%;Z 8 7,PJ*G2 k9 E[=*5va!-Nq\hG-  qI&*,'qQ4k%/u;P%fE#B,\yZY:D~huFy+ ,B_\7(idL"U^$ .62 fB|<ur@1^hboN7.l0ykT[,I 4! rJqf[aRCH+;2*&*+=6SIhh|XSB @j}^,5T ;^}90dKr[K;)g@{um_dKb:h.p"~ylak7v oA7pVpI#pasTSP.V dy~g U/HRBrFTh4(PTl~%?]&nC:tpT3 :e0]=i5BPqh* Z]8|!B^+ t\       h @ Q  hq)MA~'Sg GN<95]t4ZFi{r%O4l# U32Kg@c~|})V+= GIJOZlc>_oQL5v ,FijTFEQ]jT85|Qk-c>/` WI:^~`$*7a @YPDf &C q   ^D w " = J 2M qC /  N u DA s  t  X~"1y^4E(/10pE.^!w3R:.u,J2&@UrI}X <Zp*+lU-g.8/:_cV :%)X"}MY#zM*v? X)1N w_B@p,&/E%h_C 1Twtq d-NFlU 7U j'yE~l{yvsmaS@)U"|Fxah[VtY`o^JAWu 6S#/Lv\ Go:16/34D5567+6Q8q<I^v#>YNn}zymV3 zl|1b0Fc/b(@PtW_VKP>D35*!"  H=ra6 UzX4n'*i((?w.Me>v~?rIs|Q'#27:=h:;4) ]$q2iTEn;1404>RP$f}uQ6%!-Fi}o`M)3a`l/Jw(6ozW5J )BxRf^Me0h f]Iv.H|Y: |"i.c, b*q9Tn[% k? i:/WlZZL?X4 -)(m'N.>:;JFYcj}o9M {s: %s;QCcq }f{o]_N7"!Yw,K<B9'O$q4n)pS3DWxkbe6cfmy"4=A?;@A_O|i (1IWp~ 3 ]2BPY7[t\ZY%^Xfq|wU/_ :n}FH[t\b"G&nPx:L.#0Eit)G{*|LZ{d1WIPWP]TY\Oi;u%{~|xodZN4E_:0+'L$"Aa#0Da5FM*Jf>- 2X8f-jsfZ-Ms>-KDzgV4#A{cld`]@an~2`0+K_h&H`jfV\@!*LM|cEF%ILh%Oi/4Ie;W`zL|D VxfwXhM^B`7i-{ Nm2S;$L0^A_s{y'rUonsN9~;>ab"Y\*gVt7#P!^QOHR|J Q ' ie I /   = W *h ;p Ps lp e X @   %~ 4; = E JM MJE%A7^0+%9#$h%((&%+"!7/ mcz )b5?MZbhtnwryAs(@YwDo:{-3AlID61WwQA|D~ K f^ 9G)^{-.uwQd@^?bJp`|%&NRrAMlp j(MwS _;aSS*|9;Kaw]x/S! 7Kwd2sC!(e14?UuV7~M oRss^P<8 FRd|<s~\:4T teEI){(2=JVbp}b;jL)p:c/O2+2W|/wH${"o/l8r@IV`m8O6dwy SGq "-|;oMbbMv5Bix*}}sXq2y<cc@:Yxw@T+:sINW0ew-bX2R 0fIHd,4ekWF9>-z$#>.=Ww%Rx0b (DO[lw#ztwp%j|d]X]NE=7*8U:{>;71)$! ("H$o&+/331/ (  c>}`E*_ 8l;Z,6]F<! V[(qR7" *5Q@MYe?nuu~1V{<wF0~rbSO:$4]{jqLK/*svq&X9R|ony ,38d>EP\mBf.Kg"Bf5IWad!a$WF+zFyM$c@T)}th^QC/K V%  nY?B) @u }P6dk/5iT#%DetPiYJ|@>856{==HWkc;?]{vX7Du?h,<MvOC{k4]~QOO]QU[, fh p y  / J b o s i U $9 D f } < !R.5:H@FMAXh|>z  y'r W#?iDr/T "U 'sBQ\,qsT:#|_8Wl H%[=}VG-ca=."&3@N,Z`bef5hnz*~&|!!Hty P:X+6REYqd>Bms ;L#Cg"XQ xkUD23Pq{O" 'HRna.1H[l~-C7P}V[]g^`c/i_px>WhmeS9I=q3A~Tt(4ww8S8#{; ~H%0V`6jE-!=KWfv@!cN9|0CuW\mB( m>j K10Kl}.vKz]hprx"X (5:`CGIK:NmRTUWY^e p"JuvsKszuy 8h@[kvw2pJi^^kOt<w"xuolzk@i faUC'{sogq[:K=0"JtGakAG* rf]Y [`j$x6Om!a'f3d_xQ:(Ant?Y)z5X_E5f.O-:4)AYz,Rp=hxbL23m  A6jTyt(^=JO9_#i nhW=lVG{=5=CIVO TToO'C3}X<%[8}zyum]H1#M .DB]y\" L_q I 7Wro\NGFGIIHF@;2#teT>&U!\i5N  v*_OK|7%1h"lp{3z}g1NA )4@zEgDS><6%' Jq>s(BLu/_|1O#=9;pND- ["d y?{{ 50PShs}&X{reP99Sm~*S|*\W'XXAf%P#{7JZi uFp:w(.<,%L 6Ts B5fYx* E@ e^ t   v Z 30 DUgp{!mT!<W/sOP9%u__QGr@494348;@HTdx3Kcw ')#&Dg&F|]geR^>Q(;p7c@rEg*x]9p6n:\ 1 !7Nf-\:!ZW{ G$Ox+`G*q`2.d1 =~3gDMq60ZtY=1VpU$9b#dS"1WzlTLSh$\p]I3Q" ''4B>_C~GJOXa4gThuhjqyoKk&<8I MNFr|:5Zf ?%p!+4E_xdPFEGIK%G;7n3915;FDP[izS)1rn]]N@0R)f!B`vrdP7X3 |2fDTUCf1w" /D`3@C=0$Q | ,11-)&$!!0;ER ` r  &;^'<RhDh 9f)AZrk7arEW-:n9~hU]=#[7S%t`RHHSg3FU e(qG~ld~TvmdCZQG@S:61-4(j"{#W)/0 76.{aK;/m+A1?Vn[(f< +M]w4/^kQ@7*;_ET`mzx9;~"z4xX6wmdXE~.\9|y|   #A\t%Aa6U3vb/c@]p|)Rzzm\4Kk=/"%g?fs`J4 W( )P=Mbw@{;8|baQIHF?-<d_7#i5W}?c @t &)#}dCxJXg0N ]?DpoD9[,p}9iH+wYA0&" !?$o*29;},JwahenGu'^#>V0o]8[^9Bd'J.tKkI{.(;MFrKNNJA'9N4s13>Sl&@\z%C`z(?UgpoeN,+{F-d{X& NnwO,"@$C{g!}67VixqcnZfX^ZUaOmN~ORW`ku]27Uh. %_>/Wiy~qPVf>U3sO OlQ)8b! )U~oN. "&%$&Mu~n&c4]CYVXkVX[ZVMCEf<3*$c?Kf;U ipAMfn UAE3/s/ 29I?CHpM>Ualv((^Ny-!]e_TT/.jq6/qXu #r5UF1Ue|E{61GRkU%N@-Jx:lNh5>lG VBt>:wB1,|V 8 eU&%>YzfK1 %>Uh|tf^Y[emqlaR?"/&,25872*o_TR[k$Gaw|rjaXK38n# ,d/Lk5VuL#}-14577%6,3205.4*/*#+++*(%W(pBkBO"~Gw|Pm/aRF=3+#+"?$X$v#!&/);`La}SFTt(l"Gn -BPVT L@5*oDh)~fUoJ4GFHLQQ!XbhixkWg;a#\TJEA@= 7"4B/n)  =juK{;r-#h8,Mbowumi_PW)U[ajnn>ncP6fE*qXIA= >"BAFaMVe~$U $>[|Hh"r0nK9yK!Ki=}b~viYH5#] /o h2;r.T#c{1J2u6?]*\(wS]01 &T}o_PN?2'5Q*A_'U/aX E{&,, ,7'c/AvR[^>j$rzHrMX"gz<w~}A[mu obO;"'6JenH WN-nDch H/m<A@;4J0/42?Oe69[ " {j``huxjgq -NP{u'J8mYs/[#2CSyaDo{qr#f;\$7Wy[u'<bM Z+}xw5|c HM8#~,25b2)PMi3[,v2rX5 ~P"mc7BR+esxxrh(]4R@JKGPGQHMLDT;^/i#s{   :Z~gL0%Q|>mXXmD}1 yo]H2mK$jo:Z A%o3q~1i]XpX*_itH|fn?{obSsFY8B,0$! '9Qr S=cc+0]X`XC$hj#Su,MrzeP9 ##L Y 6/}iSP7}\D7n/L-(3@Tn{T, ;mdE/Mx-&?WUk{Ct]: RN ,W~Fr$Q;1RgzzaC"cD*  r ^ D '  $H-pAWn$Jn}C-M>YSgly<m!Hj qX@+d>vU^86cIt3f$WL@+9<5T5p8@K[t %? `:n C\w%AIpe~    m=Txr_MEjIVl[t12}@ILV[_`ccb^YSI :2$Z |^8#)0:KJ^wo*OV&mQb65  ^%mP;,":] ",;#M^ec(^=a"%@b\y(i )i)5>2EyD;+I)KueKr{tS7z[9/G{]Us%n+\f5 .E[ujL04fU4^9`Gt4Pl  1:;5'dR: 9r:t8S^+T wb+;a&zfYRkTJ[&gz~spv,OzV.D[p'R~K8MX^V\SC1N$ 2]~%UB.Z m||m^QB4%Ctz o^hgb*XxPE9v,!"v  Ex*9IYhpqhfZEJ#7% X!.[<JWresjX(*Ku>L/`a!l*JkFX' naXUZcp (>Xs$/7AI5TXazu!O~*QxkP6+6?EF^D8<.`- %B`[})fG-  )Nu (2=G7QVYucow~NvjW:\Ek9P=ca<_C 5cY7%Der` L49[(&z:aKJ\6o+"!&1CWjw}zttYc;J*oz7W4e4o`yUGOI@8Z, {+ O  sI sg%_9_O_ecfksN%5MutE O IL.b1e9R)mUz&Wb74KY}\/VE{-\\v]D-OSU0+>Qf} !C)m,)2h@Xo3 [4 [-~U+V +a8'DLPKBj2ZR MFB?;62..3=&L9`K}bz*Rx((0J8i@JWfu9M_n{w6uYvxz}.Nm'>+P:\GbOcPbK_A^1agpx`F0 {^>g<<0^Hc 8g .Rv7Pct )49;5(qcUMvIAC=7r/ )$l"!#O+18>=?B`C%CA>6+|qgcdju(;xLW`4qi;r7y?#+3p;=> BFInG<> /ron=ul)I`+ '[;u X?k*Y;r 2/wRqC Q4,zhB>yn3T}(G9IWajWq5tqj_QA- :Ueq4`/#@Yn~oaP?2#.ba59kzR0Gt7Z!Cg:\~|Qh!?f;S#uzGR+|L{!G{aM=7.r_G-a(Y Z56Lf_.$P8M}d` 'cW:3[M fn^YY;[^dlx &,4:>A>95, $?a(\#, 01/,'!  )7EQ[aiqrugx`xXpPhIYCGA4EM]t2Xz -8&>J>n5&>r}K#fyM9$ o}O!R+wlV8!8[ztj a ZVSRVbrrP0:X~wS+4Pdt}~|zxy{~ve~Qn<U$4  ~Pi$BwK!g={jIZK<-s< TP7duhF^VRR_Vcu1v X?fS/hH3 j&B^|+T| 1;BjMU[_deinvr?9LkpU5<!{hXG4t[=xW:'Jk"FfmN,xEx@QQ &eE2blN0  ywz!0@OZdmv&<To +IF`p}>y'x^l_P=)7\}/Oq .U  " W    '(36;CAMBS?U9T.MF @92.,*u&e ZNA 1 zsni e`]YSJ@6)%=Yx'5H`y%$*@-W+j(w&%)~.q4[=?GQ_p_+a)%R, /38;V:#3-$[/^A(lL%l8`q.^G`}i)n@Rh31ktYBT2**/;9M^e =q;a&Pz,PoLWn>T9@vc 43Y}d.`(/;Ocvh5sdt]d_Pg>t(mE .A^ucO7*WvG :ph$Ca% 9h*C\~t}~zqcO$91 ;?:2'vX9qW="}kXC/qI "sRy3uple\M8$ , U!1AU-nWK:yWr9iIq|W2( MroG  7dY 5fo3 R)4AQdg{@+D`+C'VKfou*=Q ct }jR4k{5pg`u^7[\`gUsx@@I0N?oN !Cgc4uC9ay]G,4Q#tslow|v s(sGxg$HkvcUQU^s+#lr]O@2(%T  '*4:7J0]!q s\H3( -/26:?IVetytndXJ@5w(eRF<62,$fK3^6 xdT~BL-m5R%m]uXIYdwf;9cvWC*9f9>G9NT\]ddkwUO#\.Mp)[Dz +BUOes~)Mj~jQ4}dD k:xms_CPA1'"V$'+3=HNuRhW^WZOSBF/8* lYF5#"2CXm #'a*6* ,-.[28>BgG'IHHgA%<85Q:>EPG^p[- @b (sA`UNd=n2r,p+l2f>aObfhr'[ -HBS]cDeaXOEB2 Ir'Db #1?W]y| =Ytvnc3YQOkD;3,# }riazZRW+X]dmwX'rU@1++0>JZo 4DUht#$$" {R(eC #)C^x~Q&~O"| C f6~eL3{ Q(x H b"%*2B=IZxq? `/DL0f&~)4Gb )HskdXK@&9_314"U<p961':i @rrJ7kQIud> $;Pf{voh`YRI;( h$C(",-,(mS9 tcTE80*%w&q)l+i3g=fEdQf\nfuuz}~zulaWO1LOMmSbyE-vE]x <m3_bB !'?XpoB2}UBu@"iB%co>)=lQPh6   $=V$l;Rk"1;DIHB7+vZ<tX:oI&pJ %:M?avWo34RhpI//QysR' U 2I]wo9pWEBIVk0@Pcx$A_{  (?Yu (Fax9[|'.59<=<>>AzEhMQX:f!v|[9  )t8UL;f /b\7JOxdP<-8e   *;Nd{ 8VsiO6!kQ6s}On)\H4i8 yQv+Z?* zbN8j@ 6epN0 C{%\NFoNcR'H3BVh1}Vz8\t [A#(& $  dJ0 eF& oQ5yod}X_KB@)3'  sX<!iE&176g12(Al{ )+8NFUds{R.$7Lau,Y R-D3XoXY  @t <"j#)4>I5RN]fj|w8L]in$l2gB^RTcKt@4( x3bAOP8`ojVFi=N43-*)-3:d@<EDDHLT`n| 'Ff|cJ*c5 ,=O^e8[ -5K^wm/z]!{sgl<_TJ<0w"V;&wD !$$\  X  S'>WvfK8(Fr# *R08FVg2}Odrz{.z]z{zt0kgaXOH4C^BHVf u8f!.=NdsT$1S M.Xk@Do{D &t8EJZlxcTIDA= <4.)(+6Hv^]zE*<Scoy~n\E.JwxY:G~8QiudQ=&gM - c>qS4p]PK"I9KUPrRWUSPJG IO(Y9fRuo4Wy0E[r0Gax1Z:{oX5<e iH6'J\k{~DE #6FMNTWYi^,dlu{M_A* %<;Q[b{s pR2cF}&vU4 y3JH`x|FV+c!:6K`u`;3iPCl9{jk`YW9Xl[ep}!C]my }+{LxiwxxxsngZP-DD8[/s'##&*-.13G:ZCiJsP{TVUQMLMORVXXTKB5)  w\#=)2<JXoi?|pO&4Hl ;it5feYJ;+#G dw|reVF:4[ } {1eJS`Ew9/(! vX9mG#sM$jOl;R.:,"0>WwxN$9\|zR- +R|hVTF8+ $H"&+X5@Rh,Or(Qz-W &C_2}J_r-Hn_Qt,d4 rxZc@S&C 7-& mN .v^tJe7U*F9.%"#"+"0&-/(;M ]qzk\PE5  xhnV?D/ |X1 kBv06*B 0HZc,~y-s>uP}j F)HeE M*CZ\o `M/LjOF +<#KJZkkx %=Rdp|zo{cxYwStOrNoJnEr>w1~$lI%pm^]JR3LEA;5/*'!l\O$G-H>NUZom9O`gjllmk`N4g5]'{D$9FMNVZ_]d"jqzM[&QwkZK:+rZF6%d@{5XR6s#Mp{T:(Z +<8tJ`z+Oq5^0g0<EWYmo~ },SA%XuN/XO"1yH[`7{P#,?Qf_{E2& $*5DV p/Yi G#/<DKS_Z;`bgnwhJ,,`F:_v (v.f2S8>:'<;=BFKjOEQ#QOMJGHKNrVb`Qk=z* +Hay !=]%;Sk;o8h #;Rn0I]jr uNrj^P<A"n$jEHa%}y>kv+t? i1f5  t)V0=7+<BIP [k#3CVh{"*2;DKRW\]YQuG_9E+) |`E1!{` F * %5I{_[w>#  f5?H^spM) #88%/$v"Z+>2!>LU[`cc`ZVNB4)vj\I2$0BUkwcQE<6*6T8@GM$O[QPJB.4`#$9IRV|T|J8 j)GF&c}vi`WOLGA:0  {OT(l%K>1Uj  ,kB=\ua6@kYsU#9g7w,g;a6Ng.Mnc9 [(67EQW[][SD2utV`7E( vg\XZ_jw!*5|AcKJV+b nywH]s4\ B% mK* }cEDRCK U%(@ZzpUAE3w.-2?TRk 4Y|@jF"q[\&f +8HWVh}6k5;c] -(B=XQlb~ryfR=)|z |nU<! ~{lX>zoc_W?G%8. # !#(.2@>RJeU{`hr~(3:=:2& =Wq\$_|UromkZkigd`_"XQJbD">5+X  a.lXD2%#,269?JoW\fBx& %YoXD43n%E~.DZHtp)Ll#9Ur/EYiv   t&c0O;2IWi~yQ' Gpj4N4J_ukL2%~6qIdZXkL|B=>HXm ,Nrp^I4  $7HmUGc$o{s^K7" i?t@f?#JtEw3GVdr|eO:)   ,=Q&f4}Ic= c+If;a 9h ##M,u24775.-&E\s^ 2<Q`jWr}DZ zmo"aSCQ2"k;nYE0 $c2`,j <)LrX*Exx]LL@:9%7Z9:>D'NYZi~ 1V}K P>bc&/OlwT:[x7YtsT4xmaWJs=V26( 3Rnzk[L?6/{)g(V'G';)/+%2;FT c r |"3JwdjYF-+E`{}cK1uGWk(U ~}b6I0u:s]ODBEM[j| #:Usq^OAAm6-&&-(`+2<I)WUgx2Pm '39:8/#  $l6PL3guN1)PnY/8\~o>$5CiLYQOTISFPEMEHE@F:G3H,I+K-P3Z8j=~@@>4( +Fb~yS&%IhmAxl~dwapcima|\UPJA5%nGukvbQ]1_et&Fh0b ?p}wsr(t:xMb{+8DPZgy2Jay,Ns !6N;hYv'Kh$n8SG5Wepw}R[x>iYJy<>)_#u= {nf}`R^)ZYZ\dis  5CHID9, tU7qeWK=,~ytmq8onowf?9[|8`6wKc*mtBdgTE8,#/H"a*y2788=CQbwiL01DYliO2_ *y;L!4CSalrtwy}/F\s)8HY%g;rS|mviYF1nlVBD7-%jB}X0}lkJW*G 7.+.9dJDc% $V.wlsqn"p[u{/Pm&Jo E r 2_~W,Dsl;G~4Yk;   )@Q^hrx"3DVdr{{jT<g7_*s_PGDHSuej{ZL;)  kM1Z3_:nL(pV;# Y/|pi`SX9UZevg?Qb9Kz)qU_SKE>V8.#J %X$4Kh7s; S_3.am =-gIbx*>MUVTKB;4.&  lT<"g AvS3kXD0 nV>(1Lcu &8LbyrX@$,@SdshP7 .wBcWMi3|g3_/qdZQzKOC%;1&aF1$#)/v4p8l;k;k=mBmHkQf\aj^{TI<. "Fk)S}+Sz-CU!dE6N'UWUQKE>9}5k/Z*G"5cC nM/ )8GWh~2h,uI^"_7VvBdzhYI<3,*-5=^L<`uw*b;JJ/W bjpynL,a:z^I6 )3H] n  &(*3+C*O-W3Wq\G3!b?c 7 8QorYE,5h*"[ &:7VXyu6k:Y;wkDjSw_B$E}m4KU+t{k[K<.   &-10.% nV6~dR|Bv6m.b-U+A*/&! $+5ANV[^`enwvi]RIB>=@EIOUX^a cfik'i.a6U>GG6O"V _chlnWo%k^Q@c+6 {V2uhw[TN4F=7/$ysu|wV5DrtR4;eFu}sjbIYOD9G-#S!4AM{l'a#S/_#X Jo)9JZ&k0y6:<=><<:5/!dFu(Z C*kFzxtZk>_'UJ=0 "-5e:I<0=BFJPXalmvO0!My)Qw{dM5 CctW< yj[K)8@!Vjyw^B%yqkbWeJP>B27%/+())()($#*08AFIG>/%JasE,Ag"&H/q7<BITc3rKavoZB, )9K\nrX;"W5*IZjzvK!d?!& ;Rm #:Ql 7Olp@ f1*AYrg3m@zpjcn[ZRIC<23../02i3D1!0/.,,(" 2Rw{!nMcuYPIC>+9P2w*" 2hN}pfJas`bir!6BMSTPE><c2+$0$M*g2{<IWfv"3@LPPOLIE~DvInPi\dma^[[Z[ZTJ>. +6BLTsZW]:`fkqwuV6xL ~GW/ xkd_y\pXkTfMdEa@_7^.["WTTXZ]]YQC0zqjfscf_Y\KY:U(NF=3,!e? 7 Ro.;HV^Bcxd`\!SZI?4,A)y)*/3P5;CKXKiz 8c 3ZqS7 kM0tP,.BWco_w5~ mE s`QG?=@&DCK_R~Xblv %+./01-' ", ;FR_m ,KjubK3rLc"G,uIwcnQC<+_7h>%EjdWHADN^:tc!!TKvJ*xY<=^f|9Y|z \/;PqsZJ8-##/=Lg[Ok:z) |pf`asd_gGk4q#w{||z{zy{mW?% xmcYK@w7f-T&@!)#(,./~/v.r0r3w47<AFOYclw!! (|5R>'IPTZ~[UY.Q G=2&{Y2  ]5w`J5/IseaUH:-?k&Y}iT:@v,.jVwi aB`ufp0]:`.T|BoBf)D]r #;K\iwtdK- jId%I0|NnD r`L6xMKgP<)(B_9nN~h'MH3c{pO2ueVH>5/*$ '(',"DZp-BYthI,->M\s(Ii{rjd[O,FH6c"|c>$7J`sZ1]4 {]@( )<Ri)<KU[3]W[{SE1"/<GObYAfuWf+lYQ-7yX7yU-x^H7(!1DXr#(/9 F?Uvev.m2s0jS8o,Mg{5Qlx\@" !,4<FOW^eio(t6u={C~FDA??>@ABFHJNV\bhjn{pynzk}cYK;."i@%sEIc}uO* Y-{X7yeM6r^G2zeL 5  !-9FPWYXVSRPNzQnSaRSQCK4B%4#nU?,  ):Pf,}7kf9^8p^^K7%tT1pC~O#{X6gM5! ' C_w.B[y0Ni%4?KXeuubO;%}vmcWG5!{gO5~U*uXz=N$!]:{lc]x[X_:hx!G"q>[}7p$T.s0Kj D<xd )+,'%:QdvlEeG( tcTG7&q `S1DB7L*SVUSTW[emt~\5 kK1wgYL>1(v pnrx #w<kRYkA#sP./: ADB<x2U$3 nZ J(=057.;+7(0)#/8FZskV5>\& *lHzhXG`2Z{`<F\.z'7I]/pF\w8[C|m8`9Qi !3>GJF?6, yZ3 M|lYf@=$s5nZM_FGK|U2cr~^ sXC2( 1Nj&EdtcUI@< 8,6P5v2.( 0?HNPNLD<1%|sld^\X*Y6[D^Ubdhvov~&Gh(&B9[Ms^r { h%R*@/33&9>B FINS[gt}eJ/&Ec}uM$ ,d:>BISZa~g^oEy/vW8l"]2SCLPJZKaOgSlWo[nclplmooppn:k[gzc[SJ>1"c(~t]fXF/@R!mL/wR- uN&p`RqMgJfNgSs\kz%Jq#7#OYiV 30^{WM1z(LIc|6d"(/1576}9^<A>&> <962.)# ~} *v:cKU[NlK{NV`kwkHf8  d8 '.39a>;ACDHNSh^Cgqz|}xmu^fKT3G8$|N w~To9`U MJOR[eoy}ph}at]h]^^V`LeGpAz=;50*" 7L`s& -'2H9m;==948i3-' "=j!"Q+3>LWG`wgimpp1rOsht}stsv}#)--( $%q%M&rP-ybJ2lH$uX8qbSG>967::\>BGMU^"l=yTj (+4<<LC[KiPuR~QMC6'|ule^YSL?2o[E,`=hUjCH2'!zjXC1|~z{2bAG}4%oWX&Ik,] 3DT)_1e:jDkNi^do\~PA0mRy8i\QIEA@e@@?=:60*$oaW RSZhy~eM5! 0FZps^G2s_K8%~_>xbO@-]9 7uS_rH3 =\{kVA/ 1H^w *;PiyW5$RIzqaT#F[7$ %Q}qT;,$G]p~2H^r)B_~5\"&*84JA\Or]m}'7nIX\;ra<tN pVn=%*AJY>T!f!;.?RewtS4!;Vp :S-i>|L]l{ 5Mg/F+^Sx{:_+?Seu"0B}VdlI, f; *3;\@)GIKPRV^ceikmGp$rtvx{~t`F/  #>WnugXEw0hYI9-"V" z@R|aFl*8 {Ro*aWMF@951.+)))-K1~7=BKQTap/_%U?~AG*\{8f~;Lpq3DUcnw}}suZk@_&T J>2& xiWE1!xgU@, ,}Aw[pwjfcdgmu%1672) nM&d;qM'pK$dlHX0@ &tP, ~rh`ZUSSV]goww`}PB955:?DKNOQUXZ]3\M[kYWTPLHC+=H8d77;DPbx'R :gs)fM[rTOJHFAHhLNPQOLM*N@MWPlSZajqwr]F* ~Y6iO4nU:eG,wV6 ~%t?l[ixinu'8IYhv*<L[iv#-8ADHKIB9+ nS3yms\RH82$ wfVF:0+)+.07?K^t'R~>e1_8Q7h\y1Ol lI(o^NB8.x%_K:,$#*{4jBYQGc4u! oXC0$ >YulS >+ "c<s_yKV85" vbO|@j6V0?/(4@L^t}vr'p?rYusvx{|{-}Z}!Q(9'D9JLMcJ|F>1!9Xxy_D+:_+OnlU=$ rcYRQSU[!d)m3y>GTap  & >Un2Ni:^/{AiQT^Af-jibYI7H~ voi?ikjTkkiZfebr`-^[ZjY,YZXyX@X VX]odAmvxZ<$ "8Mbv"3G[u@b';Obw'4@JRZ`fkpw)x2z;{EwOt\ojj}hecdgi n*wF_s3H^/pLg~4Jc}|n [$G90L`rvL!l;teWiH/;/#LoXB0  %+2<DN[jz)6CQ^o~}qdyWfOQE8?951's ? Y U)|dI,hI+ulgho|}um>gfffks~(Kj#FTq MA{]/iM 9h6TlE}j~s f'XCJ]:u)eK2s^H.^:~{wrlcYmOUF=?$<=BL\p (#=7SHiW`fhfcZQC0""  b>hE{O$wfRW;4$ jE xdUG=9679<"B#G"PZf r,=Rg}&<Sj.Kk#Gp,oParVNHGGFEE,FAKTPhUz]irx~~}yvt%o7mEnPoUsTxP}D3 x^E,gM6!wcO7u_bMC<'/ $ lL0'0;FS`my%6H[q&?Vm9To"3DPY]accete^bE^,WNE8*qYD3v#V; "  $1?JS[dmx 8Qi&6G(THain{>a#A[twld_[XVVSQQNKD:{.dO <-"hO7# %x3iDYSCd*t}rdW%L5>A2N&]k|~kVA.sR/ o^J3bH,cH/ymcYQLIHKR\j{~4St2Tw@j?g N~6IW"_G`i^YRI@5+!,6@JTalxy[7yQ*jM7(!!%3D[v "#2-B3T2g-z$  9R~okZMA92->,]+|*-/342.4&J_r}qZ=|w^t*rqqtq1sw~i#Q L_!p8^C* ->Od|%2>L[m8]4*N?jVq ,M j+8DLXbhm,p@nUjgcz^YPID=72,,+=*H,R1Y8]B_Na_aq]VLC:0&  7Oi6K\jtlJ#_'|C xePc61sV>q*`RIC=<>@EMSX`gox'0:4CILZUf]leqntwtqmgaZSOF?8-  {o`O<`)=`9p{VX<7zqh^TG8(+Ii )Jm+:JYm ,Py(LGo~'Y;c6W$vFh0?3FTDu9)6OaqraTG;-"|mYI2~ule_rYUT5NGA?AD[F5JIKOR[bly%9L^o|hL. cA!rXa@=%`e9@dD,  '.-5>9R>gByDFJKKHFEC7CRBoDINRY ]*`Icjdfgilpt.x>}MX^`\TG8# #Bcz3pSirc^XTRRUYais}#6GZkxxi^TH?:30-(#~n`TE3!oYC1rZB) taQC8o0O*.'''(+.01210.+**.5>L[jz2Ps)%=BNc_p|6Nbr}yhZ~Hs;g/Y$G4 |q~g}ddfnz(2;FS^l|.AUi}@b q$^8NG@V1d(o"x zk]QF<j5P,:""  /BuV\kD- '3?LWetojz]N=*vYz:sle_VKs<W,;te\GE,0 ueWMEA<976 :DO_s /Ki >/^I|g4;Tau0%WGyg-E^xxj^N?-*;MazrP!f=q`M9#~{{7Un xr,j<bO\cTxLG?972.((>$U h{|bD"g-s4w7}B tGvfZpPTG=C+BDJS]gu ""71MAdWzo"8DXgx+-PFvax8Rm!-6?vDiFaK`OgMuJHC>3) $.6;?BEG}HrKkQe[_eXqNG=5* +C\yuX6d:xcWF9%yg]UoN`JTEHA=A3C'FLS[fnv*A]uxeL4ztk^N:#t ZD,lvVm@b+ULD?=?FP^zphXH:.& -K!i%-9I\ r.QtA%dKq4FRrp!-,K5j=EJOTX7[ZZzVSPMLJH EC>&8/16)AMYft||qzhval\`ZSWBV,VWY[]__a7bbcbbap`Z_Ec3h&mrtuwz{|{wsole\P@+$*/x3i5Z8M;=>+A>;5(wR.iQ>-t eTE:/&i Q<* )7CP]hq{ -D\w;]0 Kf#*/21 0%/>+R)d*t,~1;DQ~_qnc|R@/! &0<HVbm{ $'*./268:;83-"q`P>-x_F-vW6nM2tf[TQMNRUZaiq|#8Pg!2CT1`Pmpy &0:AGIxLoMjNfPeTfZi`olwx #8Lz`oob~TE9+! x j\K<+  /E[tuY># -<KZiw~xqk]M9! }vog]jQTB;1"oN.ugYL>/ ymf^XRPPQQzQqRiSbQ`QcQiRuVXZ^_`aa f(j@m]szz 4\ 0-PQqu9%T9nJ^r#7JYkhK-4T|q_?~eO>1%~ jT@-zrrv{'<Pdw ve%Q1>?,O^ n}sT.wDs@ yM"~qtdZTAG*=3 /--15=CIUcszz~0Jc~7Tm6[?^6|c -Nl    *8HWco{xoia[|WrPhI\@P6D,6!,& "$*0<KYgvycK1| aF . yhYM?2'      xmb\XVWY\`c~csdlfhiglipmtpyq}qmf\M<|'vojhe_\UdNIF-?8/%}w rolki e$d%`*\.T3P;JBDN=[5j,}" /Or %*C;`O}d|,7BUVrhv<` Hj|wtty#/=GQW]djr}yodZPC:1)|%q#c$Q'?,&2;EMT\cckJs2wz|~lS~;x&rjaXNC7+ypr]jHc4Y"PHA<4-%p[H4#xaI 3   *@Zs %,64S;n?EIMRWZ,[D\[^sbfhknoq r8tMtcuuw{xqnymcqJs.v~ "+4<HUbp   sY="xne]WRrMOF-= 2' bK5& s i ` X QJFCCGMWev #'*=2T>=;:4y,e!O8&y^C+|ung^RE7) *:KZk &2=I7Ta]elrxFt4Of+{D]u}'p6^GIV1fxnS7  !!$##$!uk`SE5*zs2jC`PVZJb=f2j(mty  (05:<82)qQ+`6 xogr`SZ9V R PPPMG?6/){#j#Y$L(<..6 CP^m !52LHbbu},P;s^4Y&.378:7<S<lAELQUYY\^^`cxhpnhrbrXtPuFq8m+hb[VRMGA:1% !%+2t9eARJ>T-^i vn[}G{5{"|o[H5%  tjaXlOYEG;2. vhWF6&%3@}Nz]{iv 4H_u#=Ys$0=N_u  ,L"k(.3:AGNTY1bIg]jqorrsrmh d_4YEVSR`NjHtA{;2(xiUB-~dL5o]M>3( v}]jHX4D"2$r[F5'zvu v z #/6.**,/4:=ELS\aeiikhea\VK@1 yZ#=.!7 ?HOV]agotugZPH>8.!zrgZL;* xqi_RB-kO5~y{zphc^ZXYY,[<_Mg_pp})2 9>B'B/D4G{DHMPTVYWT+QBLZHsC?=??@CB@,?8:A4I.R%X]cehjjid`YN?-|pf^TLcHBD$A<:8642w4b:NB>J-S[`gjigc\wS`HI;1*}xtsir^oVmOjHgCe>c8b1\,W'R$M%L(I0H=GKE]EoB?;63//29DQc u$-2443-''7GVduzdL:)-Ig #0>/ML`go~z}{xx{s^E-l~[mK^0 "  $1>Nbu +:CIMNPOMHD?7/& o_K:'pW= q^wKu;w.{"("D)c1:EMW a-mOwp/Pt#4(CHUhfw-DZrl'Q79K _qvgWI:, wZ>w"_H1zbL6! {yzx~okffhhhikkjjgedcd$i+o3{7<>>>;95/*". ?Sft|vna^KL3;* zY<#   %+/27=DKV`kw ):M d/|>LWcp}#;Rgx  *9D"L&Q*S-U-S.L1B263*69<@GPYbhpuwwuroxjhfSf=e(gmu}~raUK>6,#|fQ<&~tg\SG=1&  "$',*2.6-6-2.*/ /.0/+)&"p_N ?0"  y aK5 %,3;DNX_fl q2tHw_zz|+Ea}"7?Nccz,>LYdoyyk\nL_<M/= /!  #0?LXeq} &6HZk{yobWL?0 zePy<o$f]UMFB@>x<l<a<Y>P?H@@C7F,IKNPMF>2" lN0}l^RH}Ap=c>V>LA@F4J)R\fs -=M_r/0;876336:@tHaPQXBc5l)t z |iZLA965569=CJV`p "/ 9B%L-T7^BfLpYzes~{p`*OH@f/! %/8=@CFGGDCA?ACGLS[agjklhd^VLB6' x]D- y`I5" ,;KZhs| "'('$wgZK<, ~hR<(rdVJ@8666:?CHLS\/dFnaxEp"Mu 8M e-}Ml  )6 C'Q+])i$u zhYH5#/?RevxZ9pZF3 vi]SI@6,w hX F8)|upmid_\YVSR%T.V4]<fApF|IGD>5+  ~ i P6 x ` J4  {vrq rsx#,3;CKS[fq )4>GKNO NN N,L5L=LAKFJJHLERBW?\9c5j2r,w*|+*.3:|COZer}4Ld}v~}$9M_m{{wrwqeoPn<q&rtvz~xn_NB2%zfT@,zfO4 ~.u=oJlWhcemeud{ba^\~[zWtVpUkShScR_R]NXLQJJH@E2E!D EGINT[bxkfvWI=2,**-29AKVam| !'.,5C=[HtT`m}'Jq5IYgs{|uk^P@-~ysmhc^WRJ@7,"  $+2=DLSY_-cCgVfjd{a[UJ=/ynl[`HV5I @ 5-'  vhYJ=0%{ m`SE:2*#}nd\URU[ajt~(5CNYen{)=Pcv  $&%!!-7@FHIHB;6.& #+7BNZf%p/|9BN[dn{-D[s '5"B.N5Y8c9q5|-"jN2cwEi(ZG5sgn\QO3C:2+$tg[PF<2)$. :GYk~ !)06=EMV^fotz "&)*( #)Hf $7EOUVUQ JB7 +$'$    p^M=-u bN:*  ")29@KVaipx~}r h^UKD ="5!-!&}jYG9,!  "/>Pf/X~+Hb)zAYr '@Yp+>PdtmU=& !*3?LWmdOp.z|dO=* xmcz]lT^IP?B34*"    uk`SE4! t\G3!  {utuy/CTeu'09?HMQW Z_(c6hClMqUu]xb|f}iilmnrw"4EVgt}pdZTPTZbs }*|6|BKS[__`_\\\^`gm{qkwX}F3woia[UOJC;3&jQ9%w`H/  -;KYhzwhYK>2(  }p"e(Y0N;BB4L&Xdp'7HWgt!-;Laz:Vp}wsomnruz}yumicZ~SzKvBu8s.q%oll lntz }{"~%*,-.../.--(!   (08BKlSY[Hb;i-npsvvwuqng_ZRKE>:6/(  xodXL@2& yj[M @4'!% $!  &5DSbmy #,3:2 #rbkTUJ@@+;7443345u5`6O7@81:%<@FKS[dkt|  0AP_p  !-9HXft%,3;BGKLJ(E0B5>4:4815*4$1.+ &#nYB. veUE7,!     # + 3 : CMU\fmrwyz{z||}}wog]TLA81+ %  yfTC3&%/:EP]k{ ?]~ $3*P/j6>GT`lx (4AKXfr}"2APatpaN8  ,;HvTbbPn?y0"q\G1 si]RIw@c4M+8$)   ~odXJ<, |hS<)  ,;L\l{ 0CTgw "+4=DKQ U[ b js|#',26=BJQX`gpzugT > (7Oexxogc`]ZXUOH>1$q_OB2# vl_N9"(1:}DiLWUJ^?f7o1w-*%" zp c4VJIa<}/" *C[o (3BRg| $/<ITalwxrokjjijjigfda^\sZeX[SPOGGA<;15$1/ '!$.;L^q+:HPY][WL@0 q_K9&+:FS]bikjiea\WUQMJ|HuEmAe>a:\4W-T$SS TX[ckt~eM6#zk[J8* .=K\m| #'+049AIR\gt$-4-><ILTZ`jl|y1Kbv%0=ELSVWmWMS/ME;.waH3ziVBw2i$ZNC80*%~m&^1S=EI9V/b$nw ~~ "*/3441-''A[t 1AP^jv %+29<>?=:4.($! {upic]YXTQOJGCz<p6k3e._([$TNF?94/*%#,4:BJQW]aabcaa`^^adinsy{rj`WMC5,   teVL@9767JPUWVSNF<2( '7HYk~}kVB, %0:DMVm^ZdIh8m*kfc[SKD>83/+(%"ui^VLC<2-!%%)07?GOV^ekpqplg_TL}A|6~*~zgTA.mT8 )2JVajrysdSA-'3>JWevreUG;/#ymaVNF?;4-&  viXG6# !+28BIzPsZmbfi_oUvOzH@;4.( )5BRcwyof^YV"U4VBYQ\^ajgulrw~ &4?JSZ`dzjtmooimfjbg]eZbXcTbQ`O`N`L_G\AX;S3N+H"A94- %!  $3BSdv !#'&&&&%%%"zhWE4%ylaWPJD@ <::%='?'F"LT]ep}teWOFA><:642..026rV~p1Kh! &)** (!"    z#m,^5QBAL1[i twj[NC 8,.4%;AG HIJJIGECAACFKS]husbSD5%wyqnl_jPi=l+otyqZC-s^G3! (8IZk{ $2BQ`o| '1;IVboy|m\M?1& ~~!-;IVcmy&2>GOYcjrz"0;FPX]chizirhfdWaI]8Y&YY[aemvnW?*xpic^XSNJD=6-~(j"WE2! &,7BKU^flrw}rf\PHB;8420..-,+)*+-.28=FOWblv"0>IR\bipw~ }{z$z(z-{0}2}6};|=|?zCyDyEyDyAz<y7x1z,x's#m eZNC8,$   )2;CIOUY[_b$b,c6fAgKlUq_tgzotw{}ypexWmJa>V/H!9, zwutrpmkiefghl puz|}zyvsoliij kmrtvz}  '9#I-]6o?HQZeq|+9IXkzo]J5udVjEQ19" ydS|Bp6f*_XPMH A > ;<>@G$L,S6]@cLj[sjy{}&3BOYdkqvwwtqplggb^ZUSNKFB?==;;>ABCCA(?5>?>H<T:^6g4r3~/.--,---.02579=CFGJJxIqEmBh<c3_+[$YUP LJHKNRZ_fjnppqrp~o~q|rytxwtwo{j~c^UMF<4* }vmc[SH#?.2:$HWfvq^J>1% &+27;=#=*;08438-<'@ @AA??=:62.+*'$ "(380,% % 1<HT`mzwj^RH?7.&%4AL Zguo\J7&~w~slm]jKh:f+fgjmrvx{q\E/jWE"4,&4<AGNV_gqz,:IS_j"s*}39@HOTX]__^]]^`addfjjjjhgfdaZTME@;|5r1h+_%ULA 7-"  )6)C6NEYUegq|}(9G S`%l3u>~JV`inrtrnh_SD3 ~kXF4${{ttnpgmdi_f\aZ\WVUPRKOFHDEF?K7S.^#ivxoe]SJD?<88878:=@ELPW\adeimqv} &-49>CGJLNOPPPPOOOMK IGEC"B'A)B+C/E2G5K9N<S<X=^<b<h:m5r.u&x|}~}zyrlha[RJD@=;;=BGLQY`dintxz } ~   $%)('%u!i[L <+ }wqmliiijlmjhe]YSNJEDBCGHLPTZ]!a-e8hBmJrPvVzZ]]^^\YWQJC80&~ yupiea]][ZZZ\[]aejou{   & - 7?IR^lz "&,17<B*I7ODVQ^_ellxsx||}|{ywurr{nrlgj]gSaF[9V+LB8,ybN<, ug\RLD@z:l6^4R3H3?2:74;2A1G1L4S7X;\BbJgSk\pftpw|{)4=ELRUYYWWUTQNKIFB@>>>?BGKORW\_abcdcba` `^^'^1_<bGeOiUl]qduiwn{s~w{~{si]RE;-~xpic^[WUTVWXx\l]`]U\L]A_:a2e&h nt x|zri^QA0 !0>JWcpufVH=3* #/>M YdmxzndTG7)  "*4>FQXajnvz (2:CLRW]agnv|"-8@DGGD?81*" '.5;@CINUY_hmrzzri`XOE>6-(&7G TboynYC.mw\mFd0]WTQKJIHIL~Rp\^iLw:&*=Q~auqlaYRKDA?;9:<=@DHLQX_g px&+/369<@DHMPUWZ_beimptvvurxosjmbg\aU]NYGU@S:O2L+K#IGG GEA<60,)*.3:BOYep{$1@Oa s(6CP]iw  !! |zyoy]xLx<x,xxvrplgc\VMF>6.'# }xuqomjihhijlotx|  '.266765400-($  $ ),0446 543&12->(K%X bjr x|~vohb_]]aabegilruy}{vqkf_UK?3)zsmlhdb^ZWRMIC=4-'# %/"8&D*P,Y0a0g0l2n4n6m9j?fD`L[PUVNYH\@`7c/f'i mqtw yyuqkd_ZSOLIDAAAB B D EEFGKPXcp#"'.(9+C0M4U6_9h<q>{>=:4,$  '/6<B JRW^&d-j3p7w;|?|A}B{Bu>n:d7Z2P.B*4(&&%#$#"# jYE3 {mcZVSxVhZYaMfEj=o8p8q9t;t?tBwIyO~TZ_cgkortx} &*/269::851+&!  !%*.047:=@CGNTZ`f lp u+z5{<|F~PZcm}ux|wqlf^VKA3(zj]N>1!|ri^VMF@:62/,**+-01220/-*& (6BO]huvfVG9-# 3H[ov&m1d=ZGRRJ]Cf<o5w.})&! !&+18>EMV]gr}&2=GSw[mcdk[pQsHuAu<s7q4l1i/h.g.g,g*j+m,q+w-z.~/~1111/.,+*(&"  $)*}-l0Z2G559%:;:61-$|hT>) 0vBoSfb`sXND:.# %-3 :?B$E.G9IEJOHZFeBp@{<841/-,())'&&$#! !%(*036:<>AAxAkBaAWAKAD==;57/1++*#(+. 16:@FLT\epz #* 14+8<;L@YHfPr[yfoz{upnkifdb`][YUSQuNeLUIEH5G$D@;70)!|yxxwvz}|xuroid`[UR"P#N"N$M$O%R'T'X)[)`+g-l.s/w-|,*$ %0;BIMORQQPNKGGFFHJNRUXZZZX$U1Q>KND\<j2y& ~ysnhb]VPJC>7/*!yofZQG;1& #&,147:>ABDCA@>;:72/+)# "$$%%#  #!$$'))1+90@4I9R>WC_IeMkPuR|ROMHD?84/+**&(/'7*?-G1M5U9a=k>t?>:62+# />JVaisw{}{ulbWI;. ziWE3wnf^VPID>741.---,.,+-/26<(>0D5I:J<Q=W=]:c7i3q1w.},+)%"   $+3;CJRZ `ekp%q-u5v?vEvPuYtaqjoqnwkgc]XPJC90"ui]QH@92+% yrkcZSI?7.$-;IZhv~tj`XQHA:2+% ,;HU ao{ %/9CMWbk}sp{f[OD:0&  $-7@KS[dmu~(8GUfuzribZRKE?83-)'$"""#%%&*+.123210*&!vj]QD7-#vfXI:, !+7AO\hu{l\M?4) '6CPYbkosvwur$m1g?_MWZOhEv?7.(     ~ #-48;@CF KN S,X2^8d>m?sA{GKMQTWZagoy~woh_~WuLnDd=Y7N5?11.#..*('" ~vkd[RNGA<7#5-464>5I8PCIOV^dijlooqsvxz zy'w4rBkRacVsI;.yt n iea^] ]] ^ _ ` bdeeghjlnpsvz~zrkb\TMG@<52/.+)%|pb UJ@#:+45.?*G'Q#W \accca^ ] \ZYYYXWTPKE@:4/,( # " $')*-/269?@DGKPS%Z._7b?dGiOlTnZt_ychmqw}#}4xGwWugpunlhea\XTME>6+ !,7CLT[^a``]ZVRKC=4*"  }iWD1 {ncYPF>5.$ %-6=CHKPTWWY&Z1W;4-%wnbXOF=5/' xmaVLD:/&  *6CSbqraQC7.% %3@LZdoy $.6=GNV`jry}p_RF:1*&#!"##%(*+.---.248=CKPV[bfkpuz}%3AP_ly{skd[UNHC?>;7668:=ABCB@=94-% {peYOF<72*'$! !$%*-0445u4f5V7H87<(>@ FMOV]dmy}vjc ZR J'C0@7:=7C7H6M7Q8S9U;X?YBYHVNRTO\LcFlCt>|:62/*%!  !!   )8FR\cinps sssst&v+w/x5y8y:}<=??@ADHKNRY`gov~s{gu[lScKYEM?B:69-5%2.+&!     ~tlhc``^` bdfh$j*h1j6j;l=nAmCoEqIsKuNxP}QQPNKKKJMQRTVWWVSPJE@80)!  !&+17?DILLNOONNOOOKIFA"=28D1V+h!z  |rjc\!V#Q%J$B";#1!)" %.:FTanzynd]TMF?80*# %*.--+**+./369<=BDGLSVZy`ocdf\gTgIgAg:h2j+n$sw{    } ysnlhd_YTMF@5!,#$*/4 <FOW`gpy #-7AGOW_fmty-;JWcmv~zpcYOD90'  "$%%# }~ "),~.t-k+a%TG5"qeZPF<4/ )$ %/7=G P V\befe ca]X!V(S1R;96799;>@BBCC@:5/% !$&' *'..033599?;F>NBWDbGmHyIIEA?81*"    ztng`XQMD>;7521001257o9]KXer} '0:BJRXcjqxyqg^VNHDA><<::;;=<=>=>>?BFKNU[_einsuuuuvuvxx+z:}H~Uerxne[TLFB=9652-)&#  yod\TNHDA?><<:730.-.0~3p7b=TEEM5T&]fnx|sh`UJA6,$ %, 5?JU_isz   &*,+,+'#  %0=JUbkt||yuttvv w{} %(+*+*'''&&(+06>GQYdmr}zobWJ>2({vqmhdb_[WTQMHFDDvFhG[JQKGLM=`<q89:;>ACGIJJG DA>92/*%" "#%'((* * &$!"%(+/249>BJUbo}    wne\RHA7.&&v-e7U>FE7L&PUY]`bglotwvzi{[|M}@z3z%{{ } *8EP[enu| !'-37<?BFJPV^hs~wm_SK>5.'" ~uojeefhox '+/5:@D'G7HGHXIhGwGEB?=9520.,+-..124556541-("{uojeccbcffhjkllosv{~~zvspmlkjh{gvfofgc]aP`C_7_*beiov}{pd[P G =2 *   !(08AIQ\dmu~  !&, 06<CLSZcjqu{  +8CLzXn_agYpMtCz<~3~,#~} ywtuvuvuvttrqoop{opodmWmIm;k.j$hhhggeca!]%Z(W0S5OV4\*`"gp{*6@KT^gpyui]RG;/#}vngaZ S LC<5$*,5<CKPV\`hov $ )/4:!@(E1G8I>JEJKIPHTFYE^BaAfAmAtB{FHLNMMIC=3(xgXK=}/w$ojd `^ZXVSPMJH FCB#B-B;@H>X9h4w1+&   !&((+**+*($!|tkb[SJC<4,%       &/: D Q \ hw %+05:?BD EGGEDA<83 /$*)&-#2 7=?AGJ JKMKKHFD@?=;<=?GOZft     {rhaYRKC?840-s*d'T%E$7#'"$ $(*-05;AHNV^diuoguX}I:,(8FS_k v#(+158<ADJS]iuzrkd_ZUROJF@95/($ #',.-=1M2^2n0//,,.../0///--,+*'&!}uofa\XTPMJIIFEGEGIKNPSWY\`aeilopqsttsssqlh`YPD;1'  ysm hd`]\\]`egmrw}  %),--,*& # *4>FO V]chnry}}}{}~}~{xtolgb\TL-D8<D6P/\*i&q#}#" vmd[XSQPQSUX[]adhlpuy~{xvsplhb]VOJ B> :(715:5A4E4F4G2G,D(?#94.& { vs!q,n7mBnNnYocqkqtq{qrromjhgdcca_^ZVRNJGCBA@A@@AA@|AuAn?j@eBbC_FYHVLRQLUG]>e8l1u(}  "/<GR^jwsg\PHB=9532v0h2[3O6B:5>,F#OW^ iqw $.8BLU_gmt#y,3:CIQX]bddgfgfeddfejm{qsvl{d\RJB8." {pf[PGy?q7h/_+U(M$D!< 5 , #%*1 ;BN[gu "-6?GKPTXYXVUTSRQOONMLKIGCA?;855|5x4p5j3c2^1Z/W+S'Q#OPRTY]dks|!(1:BJU[bi mpvy#{)~.}8}?{GzQv\qfmpjzeb_ZUQLG@:2,'!        xgXK<,{unhgccefhmsx{obUJ@80(!  " 1?O^o  )19BLT\epz{uqjc\UMG@:4-)&" &"3&F)W-g.w047:<>BFIJJJGC?:50,'  ~wrnkfa_[WTQMIFC?<953/,+('''(*-049 @CH&L,P4V;ZD]J`O`V`\``\eXiRlLmEl<l3j*h#d_] XRMIEA?=;8852.(#  $',/0345453/*%"-5>FOX^gkotwwwxwxwz}~}z~u}q{nwktjnjimdp_tZzUPJE?92,&   ' 5 C S _l| |ywtrq"o,n6m=lBmEmIlHmDmDl@k;i9d4]0W-O)D$;!1(   ~ ztrpl j"i#g$g&h'h(h*g)f,e-b.`2_4]6\:\=ZAYEZGZKZM[N]S^Wa\dbeggljpltoxqyrzs|v}y}z|~{{yxwusqmjhc_\XRMG>6.% &08BJOV\dlv  x}h}Z}L?2%   (7F"U*c1o:|@FNTY`egknpsvx}}qdXL=0"|wqkfc`z_q]i]aaZeThMiJkJjHjJiNdQ_UVZM`Ad4i(os |#+2:@EILOONNMKIFEDDCDBCDDFFDCD@;951~*x%r oid_ YURPLMMNOQTW\aflqv|'18AGLO SV&X5[D[RYaWnT|OMHC>72-&! wl`TH;0# xi\MA6," !## %&(%6$D#T co} $,5<ENWbmzxnd]SMD<5,$   " 1>L[hu #%#%%$$#" ~wog_UK=1(  #,38>B!E,G8HDJPJ[IeHnGuE|A>;62.+)*'}#z!vpjc ]YRMIA<5/({pjb_]\^_belrz  &-5<CINRW[\[\\ZW{VuSnPfM_HZEV?R;S8S3R/T*W&W!XZ\ `dks{%6FTcr #(++-.,*& ~ysnie`^\XWWVX[^ a(a.c5e;g=gAhDjHiJgLdPaRZTSVLV@V4V(UTS SPMHC?80)"|vqie_YURQQQSVWZ[[][^^]][[\^adhmorrrrqomi hfb"`'_.]4^8^<^@`DcDfHiHlHqHvFxF~CBCABBABCEFGIHFC?:2-" !)07@HQZcoxviZJ<. |wtrsssx{~'.5*<>AOG`KnN|QUY_fmxzph`VND:1& woga[WR|MoIcDU@L<C6<28-6)7%:!=CKU _lxzpg bZW"Q)N2L8L=KBKFOHQHSHVG[C_>e8i2m/q&t!tuxy |||{vsoljgdc__]\[ZYX[]aflsy (:KYjz  !)17:=<;<;<:650,(! |sme]VNHB<5,% wj^SG;1(  ~{{} %.8DMXciqx}'-3=EMV]fpv~{tnf]UKD=50*%!   '-7@HRYahpv}  }pcXL>6+ #,3<DIPTZ^`dba_ \YTNHA;4 ,!&"  {smfc_^^_`afkqx  ")058;>>BCEHHHGFECA={:w6t1p.m*i%e b_]]_bfmu"2AMYet)19?DEED@<6/&{zywusojfb_ZXVUVUVUURNJGB=:72-*'% "!(/6>ELTZbi py~|vpg\RH>4+" zvqmkhdc_\XUQOMLLNRWZ_dinrz   "#'**+,,,*'$  $(,048<BEGKOPSVY]bfjnquwx{{{|}}~{yxsmg_TH=/ ~{yvpnlijjlry '.8 @H#Q-Y9aCgLlTrYw]{beedfgghiihffd`][WNG@4'zqiaWMC9.# }xt%o.l9hCdLaV^][dXlXrVwT{TTUTUXZ~\w`pdhi_mVsLxA{6- |xwurpnnmmnptx| ->N_o~ ',0200/.+&# yskgc]YWTQNKIFC??<640+'$   vlcYPHC?9630.+($!  &08 AHSZ a(g1l8q>uHyNzU|\~cjpv}{yutpmieb[VQJFA;5.& #)/5: = B E H L PVZ`fmv wmcXK@6+! %*-259>BEGKNPPPPPOMI F@:5 1%.)*/*2)7);*<*>(>$>!@@AA@ @@>=<;;;;::874/+%    !##$#  |w'v1t<qEqPpYobpkrss{vy} #.5=ABCB>;70*$  ~|~}{yvtpnlgdb^XSMG?:3-(&!.6=E NUaju~vneZSIA;2*       # (-27;?CFJIKMMOORUW[_bdinsx||xsmg`ZTNHC:4+#  #&()))*+*(((%#  #',06;AGMUY`gmt!y(/4;@EGJOOOPRQPPPOOONLJFDA>9~5w3p.i)`%WMA5 & wnf"_*Z1W8U?UDWIZN`Uc[jbpjrqtxwwyxxyx|}ypfZMB5+    %)-../.+&#(4?M[hv  ~ vqje`[UQLHDA<62.)&"    %),,-+*(%! }vqojgd` ]XSM$G+A/<5:;6B6H7L6Q;SAXG[M]T`\cffphzjoruz|}~}||zxusmf^WOGA:3-'  (08@D J LRUW\^bdjmrx} {tle_WPF;1& )1:BHNSY]_ acddda_[V"R%K'I+C2>7<=7D4I0M-N*Q&R$P PPKJJGF G JLPW]dhlsw||uoha[SLE>5-%  |uqjfd a,^6[B[LZVZ_Zh^nasfyk{oz(4=DILNLHD?;72~0{.y+v+u*w)u't"ttuutu t q o mi b_[UOIE<"7&3,/2*:#CNYcn wyskcZRKA7-"  !"##$%%"    %*.59=@CHJLNP S USRQOJH D >81*""( +/49<=ABBCCBA@><;97431,+)$" #(,27:@DGJMQTUY[]acfiknp q srrss r$q'r+r-r1s1s3s4v4t6s6r7m7i6d7_6Y5P5I5B282.1%/-)%#"$(,y.p2i6a:\=W>TBRCOEOGQISKVLYO^NcNfPlRsSwV|X[^acdfdb`YRLC:0&   (3?LWcp{zrkc[UPJD@;:51/*'"    y"u%t)p-o1p3p5t6w7|8;>?BBFHIKNQSWX\`bfilnpqpplhc^ZSLF?6,#"+18?DHLQUWZ \ _aceggi i ihfeb^ZVPHA;40+%"  "'-49?DILNRRPNKG'E.C5@<=A<F;K7O3T2V0[,a*b(b%e"ffc``] [XTPOOOQSVZ_fltz{vpic[TPIB=72,(%! }wqlea\YVTT TS!S+R6R?SETMVSZU^Xc\i^nata|cdddeeehjlnoqsst(s2r;qDnIlMkRiSfTdSaQ^O[NZLXJVHTGUEUFSERBTBU@W@Z?];`:c9c9d9e7b7_8]7Y9S<O>G@BB<F6H0J*P#SX^ cjpv}}vng^YQIC;3+" ~}{{zwuuttuvxz||}~~~ !#%%'(((&#"  %*.2455442/-+ (&%#!    !"#""" !! " &(),-0200/.-))('')+,./011/0/-+*(&$#%#" !$$'),2459<>DJLOQQRQPOLKIEB? ;973 2&0*/..3,5,6,9+9(;%>$?!@ABBC B@??<;;::;<;<==<==<>?~>|=y=x;w9u6u3t2p/p*p%o!nmoqsuy |  &09CO[gpy yrk d ^XQIB=82.+)%$$"   !&,/39;AFKNSXYZ[ZWSOJE>91)!    !%% % %$$"!!!!   $*05;>BDFGEFC@>;964210..//138=@DGKNPRSSRQQMKHDB=8630.+*)()((&%##"!! {xuqppnmkhgdcbbcbdddca`_[ZWUSNNLMP!S&W(^)g+o.x-.0//11246667886 6766$7)7-6073:6:7<;=>=@@A@ABAB?FAG?G=J>K>O?Q?RATCTDTGTKTMSROUKWG[C\>^9_6_2`.^+_'^"_bafikoruwx{{}}~|{||zzywvtplid^YSMF@;3,%  ~{yvttuvvy|||{yyxwxwyz$|')+,,+)%#  "%'*+,+,,))(%%#"  ! !!""#!% '*)*++)%#      !#%$&''('%$"" #$&*.159<=ADDFGGGFCA?:61 - )$!& ,369?CGKMPSSUVUVRQPLKJHEEDEIHLOPSUWVWVROLGB<6/)!$)29AJT]enw ~~!|#x%u%o%j$f$a"\!W QMIFEFEB@ ? ;60*%   !"   !%)+/3469977621/,*'$  "&(+./..-* '&$  "#&%&)****)'%$! !" $$'&))+--/.204/6/80:.;,:)<&;!::;; ;>@BDGLNRSUWWWXWUUSPKHD@>;976632100/,-+**'('&')*++**(&%! {xuqnkhcba`bbei nu}!$(,.259?DJO V'\+_/d3i9n=qAsFsLsPuRvVt[u^taububsbsdqhniklgpcuay^{ZYWTTQO}M|JzFwCt@q:m6i2g-d)b"aaabcdgjlorwxz}}~}|zxvrnid_YTLE>5-&   !!  ~ }%{({+{.}///.,,+)&$!  %*-//20-.-,***(('$%$"$$%'(* ,-0!0&/-/4/:-@,C,E)G(G'G%F"ECA>:73.+% %&*./125656665210/-,++--,,,*)(&%#""  "#$%&(+,-$/,/2/9/=-D*J)M)S&V%Y!\ adhmrwz }||wroliffddeddddddb`_YURKE@91(   #.7@HQYbirz  &*.39>BHILNMNOONMMKJJHGF}CyAv?s<m;h7c6[3U/N-H*B&:#6!/+%!      "!"$  "'+ 0 48:?BADEDEFGIJLKIFEEA<:60,)%"     # ) .48;==??=<<;;<!;#<&;(8*6,5,1.,0,3(8$<"BFKRW\ ^ dffggdb`\[ZVU S RPNL!H#D'@*:,7.2.-.*.&+%)#)!(!'$'$'((+'.'4'7&<'?%E%L%O$T%Z'^)`+d+g-j-k-m/p1q2r4s5s6r6r8o7m7k8f6e4a2^2Z/W-U+Q)N&L#J!EB?:51, &!!$$%&(+++ + , +*)'&#!    !""$%%%$$   )1;@%H*O.V3^6e9l>tD{JQX_hov{~yrlf`\VQKE@91}+w!spligfedeghjjmnmppplhe_ZWRNJEA=:40.)%!  $'*+-/..//-+*(&$ "%*.06=ADFGFD@=942.*)'#     & .5;@D H K N QSTWZ \ ^ ` a a ` ^]ZYYVVVVU U VUSO M$J(F+D1A4>6;;7>5@4@4?3@4=496784;0=.>-B*C'E%G"FEDEEE GIIIJHGDB=:7210//0102100-)(%!   (1:AI PW^fmu {#%&'))+,-0000/+&# |{xurqnlkgc_[UQKHC>;71,)$   %.6>EKRX]bimr$u.x7~AIOWZ`dfikkjkhffca^[WzTwRrNmKgF`BZ=U8O3I,D'< 6/)#    #& ,#/%3$6%:%>#?!??>< :52.*(#!   !'/7=BHLOSTWXVVTRNIC?7-&   (-28>CHNQTXZ\__abbcaa`_^[YWSOMH E B ? > ; 9 9 8886543200..//01 1 368<>"A&E*I.L1O5T;X=\@^CbEeEgEhCiBj>h9e6b1_.[*W&S%L#G#C";"4"-!&  """%%%$#" $())(''$  |zxuqomjhfdbbbbdfjknqvy!$))22=8F?PGYMcUmZtb|flqv|~}wmf_UOG<~3{(wso idb]WTQNKHEBA@><:751-,(&$!     $),/0221222236789:;:99997676656542 0 / + * '$"      $,3;CIQX]cglptvxzz{|{zxwvtsqnljfc_\UNIB;3-'!    %+29>EHJOPRS ST U(W0Y8Y<ZB_HbLdOhRjTkTmVoXpXqXrYpYoWmViReP_M[JTIKDE@<<26+2#,%     !$$""# "!"" "$$$##    %,28>CGKKJHEB=71)"    &+17<BFILPQRSUTUVUUVVTUUTQPNKKJGCB@=<99641//,+)'&%&&%'('(*,-024668;;; ; ;<:::752.+&"  ""!"!    wrkd`[{WuUqTmQiPdOcOaP_N^P]R]S]X\Y]\^a^e^j_o_u`{acbcghlptz~ %.5< BHN$P.S7V<WBYJ[Q\X\^\c^k_rbwc}cggfhhjk}lxltkoiihaf[cS`L\FX<U4P,K"GCA?;7420-+++())()'(%$#""#"!!      "&+05:<?BCCDDABCCCCDEDDFFFGFEBA=;71-)%     %*.49<AEF IKMP"R'R+T0U3V7V:W>WAWDVFSHPHMIGIBH<I6G.G&D@< 83,$      "$$&%#"!  $*.5;AHMRU[`acccca`][YVVRPOKHFEB=<:420-+)&! #%(),01579=@BDFGGED@>;72 . * ' $  !##%#$#! !$)+/368:;;<;::8752/-)$  |xspnliggeeehkmou|xy|yvuvsrrrqoppqsuwz '-6<CJN!U+Z4\=_GcOfXhalhonpuszw~y}~~|{zxxttopjleg__[XURQJLCH<E5@-<&9 520-../113568;;;>><<:9731/.-+(&$"           "%* 0 48>BGJLPRRROMKHD@=95/*&! "'*,/258< ? CDGLLNPPRSSUTTTSSQ Q NMONNLKJGB>93.)%      %+19@FM U[ag"m&p-s2x6z:{=~AF~G}I{NxQuTqYl\g_ca_e\dZbVdR_O\JXGQAK;F5A/:)5"0+&!      "%(+."1&6)7+8/:385898=7?4B0G-G*I&L"LLKKJ KKHGDB=960)#  "&+-0478:<=======;:853.*'#           "&,39>DJQW[djouy} ~yumgb\UMH@93.*&#!   !%)+-1 345777#9$9&8'8'7$7!6530.,)%!"$ (-13 8;=?BCBDAA@==;998655555568<=@DEIKLNOORSRTTTSSRRQOOMJFB=71*#   # ',06&:+>1D9K?PEUK]RbXh^obrhumxo{r{s|v}w}vyyxzz{{{|zyxuuqqmmggda^[YUVLRCP<M1I)F!DA? =;;9987652/,)'"    !!$ # # #&'((%"  ####$ "  "%%(*-044468631.-*(%$ # ! !    " ' -28?CGJLNNPOLKIGDB>;75321..-*)&$!  "(+/ 4 9>BFIMPQTTTTSSQQOLL K I IHFCCB@=:521+(%#"!##''(-/124421.,*'$ !"#$$$#"     %)069>A EGILN$S'U,X.\0^3a4c5f6g7g6g7e6e5d5c6a5`5^4^1_1[-Z+X(U%S"O!KGC?<841.*'% # # !   !$(+#/(2.32476;6A7E8J8N8Q9V9V8X7[5\3]2].],]*](^(\$[#Z$Y"W!SPKHA=81 *"   !!!!   !$'*.29>ELRX^dinsw{ {$v$s%o%i%e&a&[#W!T MKGA>8 2 -)%"  "%')-./122355889;;= < ==>>>?@><"9&8*2,-0)4#69;; ;997540.,+*('%'&$%')+.237;=@CGIKOPRTUWXXWXUSQNID>80*$   %+05 9 <AFI"M'Q(T.Y0\4`:d<g@kCoGsJvNzR}UXXY[[ZXVSQNIE|Az=w8t7q4m.k-i*f%e!ddc_ _\YWRPLG@<60*&!     "##$##"    "" % %&'''))''&$#            ! % ),03689;;>@ABAAAA@??>>=>=<<;842.+'"     ! " " %&&' & & & &&&&$%$#$"! #&&)+-...,+,,**((*)(''%"     !$*/27:=@DHJNQRUVVYYXWVTQQMIGEB>=97532111000.-+)'%#!  $) 0 8 >CGLNOP P!Q!N"L JH F!C B!@ >!> ;:;999540+%    "'-38>CMT[ekrx}|yvuronlgc_ZVPMH D B < 96530/.-0123356689::<<;:998887876643 1 /-*'#  $).169;=>>?@@ACCCFDCB?<860+&" !',29?DINRVY] `bbehh!j"l"o#r"t"t"u!w v vutsomligeb`[ Z YVVUSQQOLIFDA>962,*$            $##%%$$"   #&*-/456;<=@ADFGFHIHIFFEA?><:72/*%!    !!"$&'*,,,-./0235688:;::852 0 ,)%!"$# $!!  %-39=BGJNPSWWYYYZYWUSPNKHGEDCB@==:875420///.,+*('%#!    %( , / 157;::;!:#:$9%8'9&8(6*7+:+9*:)<):);)<'<%:$6"1 +%   !)0;AISZbjpv{~{wusrqrqnmjgb]XSNID@=:7 5 4 110.---,,///12444431110.--+)'$$"!!""    ! %&'(&&$!!!##$''),-.24699778754433233110/+(%"   $).049=BFLQUZ^aeggjkjkkk j j i h hgdb`^ZXWROL IE@>950,)%"        %'()+*+,*,--./2357788999888642/,(%"        "',047;?@ABCACB?A@??>>><873.*%   "& ),0369<<=>?><<;::;:<<@AADFIJKMMMNOOOMMMMMK L IED@?<:832/ , )&" !&+15;>@DGHJLLNNOOOMJJHEDC@??>;:7310/+*)('''%%"   "',/35789:: ; ==>ABCFEEGFGFFEDC@>;;740,+%!      !'06>ELSY`fmrvz~zvsplkjh f b_]YTOIC?:50-)&#"!"! ! !!"#&(*../0/.-+((&%%##$##""#$%''' ( '$#"!" $'(+-/1458:;;;;:8642/0/../0002243368;=@@ACAA??<9730--,***)('"    #$&**,/247<?EIMPSXZ[]__^\[[ZXVVTQPMJHG D A@>;960-)%          !%(+/48:>@BDGHIHHFFEDDDECCDDDDEFEEFFEDCB@@<;:741/*&#   !#%%((*+,-./12255441/,($     ! & */368=?@BFFHHGGIJJLLNMOQNOONNLJJHHGHIHHHFFGFDDAAA> ?>==<;8842/,*&"  !"#&((*,-0336878:;<<=?=>??@ABA>>===;;;::9753/-*'%"    #'-1589>>?A????>>==>><;<:97 6 3 0 / , * ' $"        $(,/48;>@CGJMRX[`ejmpssuuuusrqonkheca_]ZYVT S O M IE@<72.($"!    !#"$&%%%$$#"!$&'&&$"   #%(+,.246999::97441.+)'$##!   #&)))++,-,-.//1211334458999::=>?@@BBCEEEGHHIJJJKIJKLOMLMLLIIHCCA><83/*'"  #),157<?@BDGJLNPRRQRRQOOMLMLKKJKIHHFFEB=:853 0 +)$!    !%'&((&%$!       $ ( - 3 8< ?CEFJIJJJJGEEEEDDDFGGHIIIIGFFEDCBAA@??>=:86541//../-//...--*'&#    !%&',-.0/245778889999;:<==??@BCCBBA?=<96210-, * )'%# &*/5;?DHJM N P OOPMMLIFB?=:85211110010//++(% "       %*16:?DJOSY^bf i l p q svwyz{{zz z x w wvtt s q pppliigda][XTQNK H EC@=;96410.- - +---./1355543221.,+(%#      !"#%%&')+*-0125789;;<?>>@@BCCB@@?=;9987775643433444320-+(&"        " % ).248;>>?@??>>=====<==???CCEHHJLMOOPQPQQQPPQSTUVUVUVWVUUUVWXXXVSRRP NKIHEA?<63.)%#     %).4;AFMTY^abeggghhgijjjlllnnooonllij gddb`[!X$T$P(L(F(C)?(;(8)4)0,,+,*(+%($)!( '%$#                            ""&&(*+.1134342211/-++*''%"    &+06;@CHKMN O!R!R#T%U%W%W'U'V%U'T%R&Q&Q$N#M#M#L#L$K#L$M"N!O QTUUUWVTUUTQQ P O O M L J G G G F D DDEFFFGGGHGECBA@>=;9740+(&"   %(,./2477:<>?AEDFHLNPQRTVXXYZZ\\^]_``^_`^^\[Z VUSP N&K*G/E4D6?:==<@;C;D9G9H8I7L8L5M2M0M/N,M)L(L%K"I FEC@>= < 8 9 9 78 8 77 7 8 8 7 7687741/+*'%#"  !$$&&&%$%##"!     #)-28=DJPV\agmptwy} }}{xwutromliea^ZVRMKHECA@>>=<<<<;::;;;9:976320-+) % $      !!##$$&('()))+++,-,--./.-0111122343431/-+*'$"     #'*.2469::=>?>=<975210-++*))+,+.//0145667:;=???ABCDFGIJKMMNNNNNMMJIJHGFDA;861.*'$       &+05:?BEFILMOPSSRTUTTSRRTTUUTTRPOKHE@>;753 1 0/-+*(&#"     #%())*)($#!   "%''))*))(''$$$ $ $ $ % % & % $ % $ %$#"# " # & & '' &&&&$$#""! !"$')**,---..,,)''#!    %)-25:>@FJMQTWXXYYYXXWTTQNLJGB@<98421 ..-++)'((&$$#"       !&+.269=AEILQTY\]adghkllmmmnnmnnnpoonnmlkifeb_^\ZVQPJEB>:86332/0/--,,,)*)'&$"    !"$"#$"#"!  "$%')*++-./.,**)'%#" !#$&')+-/0347:=?@@?=;74/+&!   $(*+-../001123345554654333//-+*&%"                  #).269>BCEFGHHGEDA@>:9620.+('$#" !    #(-26;@BFIMPQSUXYYYZZWWVSRRRQOLLLIHGFFEDDB@?=;88631/-+''&#"!   "$$()**+,++,)(('&%%"    !"$%%%%&%%&%#%%!  "%*.068:<>@ACEEDEDBBA?<;;9:::<=?@AABA?><:8 7 5 1 1 .+(&        !!!###%&&'))***+* ' ' % $ #!   #)-14 8 : <A CEI K K M N MMKIIHDB?;:642.+)(%"!!   $)+17;AEIMOTWX[]\]_^]]\\ZXXVTSRPMLLJHFEDBA??><;8752 1 0 . -*)'#!"&), - / 10346779:=<====>@@?==><;9751/+(&"   "#%&'''(()"((',&2$5#<"@EHMRW\_chloqtuvxxyyxyw trpnmjhfedc`^^[[XWVROLJFECA@A??A@@ABBBBAABB@??>< : 831-*'" %& )+.136:<=??@@>?><::997431/,+('$$"!!  !%')/1379>CGJNSV[`bcefgghgfgeeca_\YVSN K GDA;841,(#! !#$%%% ''()***-,+--///012233221//../,...//12559;<?>>??AB@BCB@A@><9841.*&"   "&),-013589;=>ADFIMOSTVZZ]_aaabcaaba^]ZXURQOMLKKLKLLKKJJ G DB?>;986653421/ *!*!'!$"$! !!     !#$$$'()*,-.112 3 46555!3"3#2&1(0(.,.--.,1+2*4(7%9$9#9!;!=== ==;<!: 8 7 5!3 0, )%!       "$( . / 27:?CGLOTW[]__aa__ ] \ ZWVTRNJFB?;852.+($!   #'+/35;=CHJNQTXY[\^``abccdcaa`]\[ZYXXXXYXWWVUTSSQNNLKHDC ? < 753/*'$%'")-158< ? @DFFHKLMOOONNMMKJIFDA?:8732.,(&$   !(+18<@EKOSVZ]`cehknoruvy{| }~~~~}{ywvsomjgcb`]\[YVWWUSSSRSRSRQQPRRQRRSTSSSQ O LJHCA;50"+$&' *+.02568:<===?????@=<;:96520-*'#   #&,14;?DGKOSWZ_cfiloqrusuusrnl jgb^[WRLIE? :"5$.&*'#)+.2 468:<>>>@@?>><;::96754334334554567779:9<<=>@BCEFGGHHGHGFC@>;62.+($      " % ' * + / 1 378;=? C E HIJMNNOOPRRSTSSTSRSQNMLK K H F!E!D!C A? = < :86421/,+)'%##""###$$#%%&$%&&% $ & # ! !             "#$&(+,-./2356788 9;;;<<;;#9&8&4)2+1,.,--+.)-)-(-(,(+$*%*%)$'$%$#$ %%%&$$$$ "     $(.249=ADFKNPRSUWWUVUTQNLHEB=852-+&#!  "$%(*.0489>?DFGJIKKLOPQTTTUWUVXVXXWVTTRNMKIGDCA?=;:98641/,)&#!%*- 1 47:;=>?@@@???=<<;86431.+(&#      #',-0479:<?ACFGIJMOPRRRSSRQPOMKIGGC@@>==;;:<<;<<<;;<:;:988887674332/.,'$        %)-138<>CGKNPTWZ\]]\ZYWSPKEA;50+%         !"%&(**+-. . . / 0 002 00 /02 011 0 0 - + * ( ( $ "          !$&(*+,+-,++)*) % % %!        !&')+,.-.//../-,*(&"    #'(+/22589:;=?@BCCDDDGFGIILLMLMONNNMMKIHFECA?=<:8542/,,)&"   !"##$$##!!  !!   !"%)*+.11135546779:::9;:9:;=<<==<=<<=<=:::98766421/-+*(%$!    "&*.27:;>@CFFFHHEFEDC?=;730,)$!      !#!&!'!(")!)!* ()(%%#""!        !"%%''(+(*)''%#! "&&)+,++-+))($!!    "'+/2569;<===>?@?AABBBABDCCCCCCDCBBBA??>;9876531/.-+)(%#"      "$&(*,-1122122223345554220/-*(%$   ! ""!$$&&')()+,.0124757879997775411/,+(&%$           $ %(,.27;?CHKOTWX\_^bbcbbca_\YWS M L J EB?=:52/+($        #% ( ( )++**-++-,-.//000"1!1"2$2(2*2+1.3.3140616392:291;0<0>0?0>/?-?.>->.<-;*;):&8&7%5&4$3#0$.#,#*")"*"(!( &&&&%#$$#$$# # " !!  !        "!#%%& ' '(*,-./00232554677678898 788654310/..,,+*+*()(''%#"!    "%*,036:>ACDEGHGIIIIIHGHGC@>:651-+(&&#"! !$&'),.14568999::::9865 310.-*(%!"#"& (,0247; < @CEHHJKJMKJJIHFFGGEGHGGHIGGDDCAAA?>=;;:8675443100..-+*)) (&$#!#$(+-./ /.--/-+*'&$#!"!   !#%&()+-.02478 8;==?@ABBC!D!D!D E F DFFEFEDDCBA @ ? ? = :9 8 5 3 0 /,*)&%"   !###$&'((*****+*--./0110/100000//..-*)&$"      ! $ ) +. 1 568;=ADGIJMNPQSUUWVW W W VRRQNKJFA@=:731-)'"       !"$ &!'"'#)#($)$+$*#*"*#* *!) )!(!' &!&#'#%$#&%&$($)%+%+%+%+%+&+&*%'%&&%%$'"'&&%%&%$%%%$%%#$$ ####"!!!         "$')+++,**)''%%"  !!""$%'((*+,01333789:;<>>===>><;;98643/.,)'%!    #%(-1279<>@ABDCCCA@?=;9541-,'%#   !"%(*.257:=>??>? > = >>=<:940- +#'%#'+-/36 : ?ADFIJKLKLKKKLLKKIIIHFDEECCBBCCB@@><;86311/.,**)''&%&&%%%&'&''''$ % %$%"#!      $%')*--0 3478;=!?&@(C)C-C/E/G1G2H2I2J3J2K2J1J.J-H+G)F'D%C%A#>!;9622/++)(%#$! "#%%'()--./01111000/0/0/....---++,++****)''&$$#!           "')*/23356788 : ; > ? @ @ABBCCAAB@>?>;!9#9$6#1$/&+&'&#'!' (())()( (&$"         %(+..023355554332221445556667654430-+(%#        "')*-.022565677641/-+(%"! ! !&')+-//02333210.*)'%#   #$%''(''(('&&$"!    #&(,-/13 4 6 45532//-)&$ !#'(, 0 0355888:9::999877666566666767774553320-+'&"     "%(, .145788<=<< = >!<"<!<#:#8#6#4"2"1"0!/-,,*('&#   ""!"###""                !!"##$$$%% $ $$$#!!!    !#$''),,/0000220022200101000..-,*&&$                    "&(*,.../ 0 1 0 2 3 35 556 5 4 4 32310/,+)(%#"        !#$% '& ' ( '('''&$! ! # $'()**,---,.-,*)((&&&%&%%%%%%&'&&&&(&&$#     !"%( ' ) +**)))*))(()((''&%$#                                       "###&'&&'('(''(&'%%%$##$##"## !         "%') ) - / 0 1 3 56878988888766 6 5 4 210.,*('&%$""     !#$%%'(()*,,,- + , + + + + ** ( ''%"!  " $%&(('(('&'''(''''''&&&''&'&%#$$!!        "#%&()))+-//011333 4 4 2120/.-,*)(& $ $ " !                       !!!""""" "     "%'+/035699:;;<9:86853310.++*'&$$#     !#$$%$$''%%% $ % %%%%&&&&(((('&&&%##"     """"$$#&&&&&&&%%$"!  "!#$$$##"!!  ""$&&()*,-/01247789:9 8 7 65221-,*)(&%""          ""#%% % % $ %#"""!!#"!   "#!!                              !# % & ' ' ) *+--00033 4 6 6 6 6665677897899987542/.+))&$!                        % ) - 1 7 ; < ? C E H J K M M M L K K HHFCAA?;<96433/.-,*'&$"   "#&'&)+,- + ,++*((&%%$## $ #$$$$#$! !   !""$$$$"$"##""!""!     #"#$%&'*)+,,-//.--.-,** ) ( &%%""                ! "#&))*++***)*)!'!&"&#%#$$"# #"!                                $'),.02234678;;<<=?>??@@?AA@@@@@@? ? > > @@@ ?>>;;;997 642 1 0 . , - **''&$%$""!!         !"##$$#$$$&&&%%&&'''&&&&%%#""! !  ! !  !   !!"# % ( +!- / 3!6 8 =AC GIKNOQPRSRSRRQPPQPOONMMLIH F E DB?<;9841.+)$   !!""""##$%%&&(++,..0221010//..-,,,++))))')++-. 0 014446667:!;":%<(<)<+;+<,;.:.:.:/9/8/705.6-4/1.0-0/0-.,.++****)')%*$)#(#( (((((()****-,, - - . . / / 1 100/////0/.00021122211//.-+)&$"!  !%&(*,--..--+*)(&&%%#"! ! !#$%&(()++ + - - . 0 0 1 1 223 5 5 6 7 6 7 9 8 9 9 :;: ::98987544 2 0 /.,+*)('%&'&& & %!%!% $!$ $$#"" ! "!!"$%& & %$##!          #%&))*,!,".$/%.&0&.%-&-%+&*$(%'%%$!$!##!                ###%'(((*('( ' ' &&$#!! !        ###&&'*(()))*())')('((((((&%%%$!                                      ! % % % ' ' ( '' ))('&'%$#!                           !!  !                                                           ! !! !      #"$#&'$&&''%&$& % % $ #$""####"###""! !         "#"!#$$$##$##$#$$###$$#""!           !#%')+,,-./-- - ,,*(''&%# ! "" """ # #"####$$$#$%%$%%#"    """"##%$%%$%$#$#"                                   !!"!!#"$""""""# " %$$&%$$$####"!!!"" !                           !#$&''())(((()'!'!'!&%%&$%$)$*!+ - ,,++*)))'&&%# " !            !"%%%&''')*+,,-/../0 / . . --,,,*+,+***++ + -"-$,$.#-%-%.%.'/&-'-',$+%+$)%'%&$$$$##$!""!!!"!  !"" ! ! ! !!!!!!   "!##%%&&&&&'''(&%&&& % % ' & ' ((*+*++,+*++++, * +!+!*!+!+!+!- - - -!. - ,!,!,"+!* ) '''$##                                                   !"$&))*,.-./ . / -- ,*))(''%%%&%$$""!                                                                                                           """ "#"$####"""                                                                      !! !"!! !                                                                                                             ! ""! #"##!                                                                                                                                           !!!"""""""""       !!$#"$!!                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       ukui-session-manager/data/weakup.wav0000664000175000017500000244056015252713362016513 0ustar fengfengRIFFhA WAVEfmt LIST<INFOICRD2021-10-26T10:48:10+08:00ISFTLavf58.29.100dataA c%Q^rTbxm}|sgT@2h4y3?oFS~wPvYQo5LV"}E:8U:,:EYixLrgjf?P?7Ij :Srgggc pF 0 & U% :v= J D s="2n;<1 : {tMd\.mU T 5[*~Y8o+Iat  8 _>E)"]4aj'p  #KWsG? Os.,n 4+ڛ!`ۍ3܏=ݕMz~! O ] ޹ { N $  /U lH*'TZumfvqWDxCVwwr `Y`e NP  A   , |x   1 (92-d  \Y[M2} < ':u]WWy]2fv/h; E gWl;k\F8F "U$&" '6 )O )d Z*G [* *r)( 'e a& $ #5 " c C  &1flF #yV'Y-w*1TfgT ;8q ?7)8 Dn   Sm k1 n ] " tn }!Cr~gaO+Wa[{18x~/3U (/ze6!Q_ otq$]`|  & FZ Rp5mEg e U  EPO ! 6 } ]s O P{ Q*JbL:THTo=-BD Y  '& g StQ$G a!!_8",8"!!,! k %% }BzbgKxk< ro "!:'K"@atV~E 3' %&t#,M : f WL<`F $'N|3q&HX$X!1U a8O܍ݚ]j}g1=v(b6}m,5 z^ Z1*] 5"R.]o}!?6g\: lI } ~S{b_r+N&Ewj6V\ + G K Q 7 w KM =o 2 =# T|2WJ(]H2xHL l"#G $ $ $#*6" }+M,7 { O B D *O3|6_dbFUfnVUsVH, YDu>$C{3br+[,h ~ Q7Gq > f _Fg=0   ES/,W a*,q@VGgDM,"Iz!g(jLl2j3  K  cB% g" # G qwH5 E(2NSkJD 4 "r%.l  a~ > *  ' z %Sm@*M / W k @ : ]: X Uk~S^ 2k -  mUK9f-yp\qk!H:KO0-bV M: TJ*u%9n-` j|g#}|g98jh 'Y 2o Y[4g:JWSe`K( . 7OS';1zHz|_Ip $ "  !Jto ": s Npt~Y@FR  R[!#%78'8r()n)+* */*Ti*)l(&I$c"NT+zQS B kJZ4bue8uCA!G)bvhrG'BF)x$+#j2C3!jc&Q|5b2a1r  93I    |:ZTnI\1G_ {^Pewb}g`Df` !tUr8 L  Or;E]7 E 1 ZFQIXt!#p&()l+M,---,h+) '%$d B" o Y ~fo+F s oRjrfk`#7/5Zh`~'~5= Jk >XA)bQ*BqX8j  ( SCM6~ -D ) " "t v0MSx  o @ n]Qcoze;s R~|Qs>BIuGCY|b +yU&qv(ya'jKy l2~{6IeIM|k8jx Y I7 g   } '  Q V   t  )E  of!>.ac   1 '    0    \weC\`   /w r 6  G x TF E S T $J7u$J_et\~-+V 7+`IjzP#-s/oKzXotyK)  uDe"RR  } * 5   %K5E|)5mSq>y\icMrP@Q$cPv*< [ONbHo509xe` T  0AUtANk9 >K{g.r)arT}   U41". 9 D>  > {bFA Oq)oOPQ S|KE}+\s0"4 %P{R c!?V^VK^&UhlfYm#-sPKwb4&73P;~Z&AI$iܢ۱{s<KӔӽ6Ԕ׀5<~X ޜbtqz?YHsw5l5\ B a{  <YG!\!"$4$e%z%&&%d$"#"!}} :Vx)t 0  & cps i4 FV"i4v0>*>S} /l L Z m hnI/*mNt U *s zNwC| <0*pc $+ *CH[|8tS/? SY.-S$sM/]5 X ePq `SNy)LR`q3VJ ]  ( i @`Z=AbX j"S5^L$?`TWd!-Q]PFB5 +[:<=8+0I(icT~nSR1+6 R | ~w X J: C~ +Bz)$ ^m3. p D  +N R |0 OH 0  ! 5* ZF  o -  5F 7   lc &)Q z, hioHS$ XLT kO@6t`a_f%Vb5iw/(7>B["Q6 Rn0jdHra / N '  0{  GdgQQ!AxV,_ V|\R(;0Ng7 IXtKGL5Q kH!$'N)!)$ )&((C'z*#++(7'}&($))N'I^%"K1"v b ; 2y x[D=  d e+ { iq % S |  #" { f" w%1mS?Z^%ILp X' 7 : Wr9zU_/`~5*o < P , )T ""#%(+r./.n,)'%#&^!9V !-ks@ΞʐV'yH $ռ330"#\"$t e6bP I% ' Eu{ko w1 ӉW2ӯ'Ԓtԏ֩5ٵ8$hX{R Q2N7fFnWz(1g6Nq{ S~.F1E@|T%@[@ Ot " wX$ 0 n Y}"tkGm~<u  s%8 2E1nY]a 0$.^']))H)'3%0 !n"0$p Hj|s = T xC% $&`(Fg*z-/9.,)&":x,G[ y dxT Kdܓ[ѕьVղڀ6 @]l@G?Lduh}q;xIyAz]r7ge&mC]\o9GPr z! %L swc ! I *x  M \  r & |C  ]W ֒mxҜ`Θ ϳҒh>R;x2I = !vP6/#L!#W$!|&n()6(?&?G$W!4B0R ;Q&l~O hOD(x~Q #X y3%~ t, xpd%H_|[-[0z (Dh2\8t'J) T8Nit |aߙSSXw- &8|dQR.v % n9 ~H>HDz^Xxvt6L:5\T#t $// niH  3 j8p>2(' b 1f$>P3 .[ OGbjӹZ' Y56eڬ|vU7ԸUgF?79x RpVAG ^}7 I`Wt>e!%"#>$C$#k!,_ ^i:6@   6G G #Bjh< Yo  t?+   5 & (/QsGi/O~XY2#I? ! S#c6 U /t;s  ]6nLL+4& C@ g z "k (2t9)>lp{Z 1J6.nYp:|Z-_ٕa`ʫ.T ˎL; .7%Jޏx BP1k_")')**I+,,---U,.+q)%^r!Nv?  m/dqysd `3/ n(|x=MNw cA 9u#xjHd!"D"qL 3hr1 | U,]NL ֛|խԷaݗ  jxh}5YN <,G "_$ q'@*pO,y,+o#*(7'& %I e% $Gv"iRs p"%1'n/)**@)-))[(%' $^ =o !RGo, I&x AAR d c k^  Yo 76YhXS(8 Btf , pI xy-gpWyY5-"IA^ S , pmNR[j G D / +OwV  =D5j+ߦ K߸; y =QP.V oe( 6#=[&/V/u lG ,m[n~Bpq5RU&׍iJ fطMwS=J 'l_DKz8U o$cn[{P(:WL ~DK2P>lU=`B*@&0  H$ ck/1dn<S j5@F'{=\- + b,   * &,EX t {q+ . d.{,Rs ( ! 1 b- ,QdV h   Y -)\)vSVC׍Х oc˞p͵c  C k9* ? J S % dAd`\UH!- T xD  n , q  [J\+pQ?+8/]FO $ 0?F.J#5Q6߯z݂Q:ޥ߫I 9 okV!_FA avcc|&1H"qQ3I5uAZif_#hkт>Er.9nQ_G R  y ;nv V^h !(V"t","!u:]g?2} / Q `ntv Q #~\Y%C g$_w(L+;N, k+ %)#&q"Ha0S 5 8S#P 3k} ?(@5[6bM\MH:8a8XPqES )QU mk G .J [8  v W T@kbr/(! vU lV J < OZf@;.^b?jئ֕GftXMK tCQ-!5z\ Y Mz :z&<j85A2ex ! !FI vWr2-}8 , E>r z ` fyAkxO}w47NWH(qQph ,  >~9v r%5tqa })Hmuqe?gyR{D|-3*AQ; ? R.wK  A i "hpFk<W8}Ro62/e!V$ %%%1P&Q&sR% # ! k ?-#  Z > tj R3Bh7aUI^uk,C i_Ni8~cݧ_,YHy& : *Sz:6Xnh$Xe%^>  HRwm[C36 B(]o&|kH2De_R6B,@;.*hF 6qwd7b2+Wi/  p E  x (  F ] t 8D  #NZ/ {%!J ) 6!" y !B# e$$$-#WG!?We   *  k sK    0 ~ TI&hF8خ$؀ڎݑ  " V 8 q P 7O \  S USd+n=qzM _  v & |V|4v m@B*]1nm5[dT  h6  F n t 7  #/ 8 mXkK6?iwT }hەyא ,ڳJ\kޠ7A K:LE  P47cRYZ+_Rfn!bK ;7/DtvwWZy  r ^ jIRnKGwBx|  1  g } :V  v6)8N . f[GGG~(b5y5 \ '  |`0\ 0k^5UNFM  i 5 H  o l RO w GCd$8$ފ+=h ds.pڿ^pE:hrqVN/zZ >v  ~ L  Y V Yx <0qaw;7|>?q->U&E  B$C 0J./St n )9bC|> _  z     ^ p R;12Xw@B0{9 ^"*ZDi,AJVDE 6 4" \M   + - = %? N{\~Vi@.# WSxHL,a"8gޒ܇EfLJH8>PQ? H S N {  % 2 ?K^#\Zyjb2H^{'.H_eg\Jshz)}sFטM?{eVqJ 7 n $7Mwd, o @2 y{cg!3>o HE 0K@{Aan<81"n,Uܞ[܌v+JKY,Pf#XJxn3v>2[vF:qݼܾ )j,sq#3rx/ViHV Fr`Md p!VxO >B N bA)u K .M 5  F'g a (  c5   h <> x h8es6 ^ 1{G3;C"gI LAEX:]01  > K  j<qM'r>4'k\pVh ^G/U`i{--Hw["A% 2 , y[-Vr8bbY;I~V5 R [ .5vg}^B#Bf 4dnEtXk". |~ ;  {]NYd@\uI!C""e"""3!Uw!*2! [e?xK #dv GJ rV1]moe } f/z$ yki-w_u3'q g i| *& dtI3! /@:? ;A |r,2$X3( P Muwl llx>n` j L n H" e.^  n ~ RpG F. k o Hj}xb^ l>L? 2?3`S}5]W0z`:?Dw4=0-o݇mE`ۆmݔD-b{FGu6,lO |9k?!z#>,c |V/2|wy R3[3.0CJ ) {} -MAT ew  0 `Xb_s*dn`J|egzM/<A4; ] V^s   f`QOH& 6dq9h|&/.S^@' 6 j H*;P_R744P]rRS4w`1q *#i߸F S#Lڦە?ܺv!߶#xE@HO%U 6:"1#$]$"f }WKzu ;s{Wt]~:@j"nKj[;7Dg\Di_ cddC: u p y r T3 n wT:2B@0$Zޭ=e* A6o09g?xb; SS (  . (iW>h6/qD8UvKN Q pT9T c P 5 \U  N %lb"pFPg o  n 0 G 9  c5rha67~)f,ys[]"2= f ::6[U(&IwU nd 0 bS Pu]c, .   uY:6:fux;:+_~R gr8U~ `18] =z=h#:uj.j. m-_]mw B :g*c ="S##Rq#~ #U"p"&,"7!j GH{ S  <i < 9 =9 cfKBSwON a / v8Q8J e Z u 1 b g tF(iCEs6P49 O*NCa/Up q!cWTh8 .Uy/s  E]aOQTq2P R  R T FQ@  @!wrWS~]3;VT!|r;{EHI Q&|!%{e2rJz #MxtZ`"0BW>=QWK P-<w)&]{,Zqk/6%Zjoq h  b 1~ E @l)qK 9F$}3= g4_#i a> K|  j A+hh &p @]x%Z!#=%q&9&!''I-(( )]2)S((B&.# 0 K  C  #  / cXt3z Gby  DYif  5 oQ 0   k  L )  i rbsGch+U n{u*3BbG1kj_oM n *`#cm\Z]JRaNe`\ 0hp4XTM'.lUwgxC'O.R_}z$x|-= g9  Z y' K U Fnv$_cy`nE WAp Rr]}gjPt*' g E J qyq,0   ,   3 H 3 Xou"yseajsb -  ; [ H  TA]  k # `I !! /!m V  AJY  |4\o^i v[ EDE   7!r m yn7 *QA x VHC-=Rq(z_DyFݱq X۵ާd4^!]A;1]r/moZSC9 U8#vA5~-Dw , ! Mq-s0 |-"IspAn>&X  F2 % Va  D I a %^SN%)j)q iN XH Djq@&  4   zP B  G " ] M  *P 0Q  gX)zrM3$T QAOߺJJ' }-V6+g7a]!%Y 4aueU"]iP/  # rma% ^ ( ? V p9Y< !MR8Kw*2z26D(g@=-ac5 %V^6'/vtܬ?i1Q.+ڄ''ڃޙjzV2?#@iky+sDB./ud@    |  / i  :lb@p\ {  PNGV *Lkit CPvg9CPT>3LTv0 : [ t c nJ  a  f  ^ =^\  c 4  M aR : a v$K~^.ByuNFMf3kk\Rw.IIai\~_m4u/N3w3<rUJ 9q_BxC]1sqJZdqY4~=cE,>H7Muz * G sO>lLw~ ^v Z`: & X 2 N) 2 '  | & 1Kd1 U t bTJ 7 2 F  Cgq-Xd  91w B_ uJc0p5&%?``@_)=f'g|%]  Vj.'o nE   F n  i dD/tMHr T c Y J  CIU#1jw\Ovch  20E[v@k_g|P[U/J 1> a 0Q  x ) '1b [o=GY/%r;< 3 | Z  q 2 + vr'xVsQ73uP!w%.z|j% + d fl . $ (p?   P )  d i Xi   *9   W ! M(  cL +  P b  [   X s Q`I5e">$ %J k% 8$ " &t  # Q P m j 1/oYBPZ06x A g < d 6O{_uv~Dzm}J8'&ON]g_ &KcALXp&<$LcO RQ #q%z}_rlQ]Qfe1L5YkETd/ k 7  b H x<aXZLY7 ^9sIsn]h9.LLPn:")MVH0!|29/o!lv \  h  ]x  T zQbj.q;\RB:kA![ }? w 1q Fsy1^%a+@b  4=zwGj x    * 9 q<PEWu  p3/ W{%fA mF mu ) < {hA1a" , {z^l >Lj: SE0pM@ވ[%:YgIfAkU~_j^D#j4t.^ m0{A-[bRv)/tP>k,"&cSUr;D `=:\V i5  J7/{<xXes8vS+HeFAO$nZM D S yxcd& v3 X 6kll  +W , .ql!LLA-v  UB+nU< 9\ @  3 m aq H ;  - <Z,|A@rBC ?bqF` znj+xr '3,!%3~b@Yroz`ri3@!-8/01PAel0j1.&|0S}CwU_7*;Pg n9~Q{y_P@:7}05#v^"O%TU(1nEI,~i }=  g$VdQBU!t~X > - &v}c'H4sG*3Da, #. 9 =lW9-x%M,zX}>W8%?Mcw@ZH0p,qc`BCb 6C[+wcjNs(=oVx06yA[bjV4 & 8P&"fh7uGX ' O }1 `t h lMe7= 5 l % h s' 8 u U  |V,c]V_.t4f$i L  f>   - q    ` E f   LX b ? 2: x u4 U I L| x ?& g' zob & D $ 8 oh5%@pk-\0n:'6Z*VtOJ!_ss4(4J] Dff y,diBp  y C tr!{KjP> lO h > :[ /VmRgW;3sq"u3YQ6*b\ a   N 8 & 9K m  6 n t A ^ # m : \b-exH?tm7r H *pl<!_$t&(}?*s5++zx++**C)x<(g&6I%^#5! W e  P`CoJ Ed qB T+ 45]H$rrO=l)g<68 eomUKvaxy/$L,2`Zhz"TI.J MP#ThCi$&?WM %  l}UB m F %   'D =\ @ s  r>P qT,BrFU~W-{~^6^JfdfbR.XWwc&E G  9=XDXVBZO<2 i x:2> #b /M'0 *]|Sk?   :y  R py S n  'h}'Eo   Mrl^n\+c - 6 M Z2 .7 T 1  f   ka  Fl | F  b "  0erDe-O%t|&-Ln/4~CkgKV}Ts"h(|,vr( ^no:ZbQ=Ji~ەxۘݮFmB)MdEnt:nT Dm{9 N '[E%DoI   g  6t >$ I((  f&+ F ^E jcrZDV?Fr}^t^\,s <Q  78C P !I x^g! #mJ'  : +D?J  d 4 < 3 14 [+AJh/9]N{s:)&JL/ _}7.`4>  KQ7?yrs,O=R FNR(*`  W}HGM |mV  .3 vqY[g[*nI!n{f=SK^EM[+;1X / LWmA~  #  UasA37Lm^GC :pJi(k \ #Q{! (W3]Ms0#g}V ifY#i8ky85?U, aE]y h  U+KrJC/0߽K߹ R1NF&tDy{!7K7^,XPS<4_a(~ ahK{DG>#75 5W.hJ\Q V O fPvcfk"u"= ? .g/6,'w& ;& pBuqNBLAP r  V &   iL"Pp   $tE&=NT8   |A  XA^(rf) * zm;(l2Y; o@Y  {RJJS= "r$& z(5Q*,k]->J.. .B- ,+)&r#*=s# miy,\*?Th%q" f+ Y 6wTg#].c4RmdP6KIښ1ڊKܠMl 26 I?Z]{a=B|[,c)MY-*3n8+ *I'DO@gTvMQUt *U6gWP=w`j /1YW{{ VuFS/tg  3 p ^x_*  ^n5*F Y ; !nG 5eBBf M' <G=9gikd-( J U p: d # } P ]l M} 6tFQ . Q??D3: e > eXJ.riqb$ax9 N 2w MfxQu )V O=rQ.Y@~Nh6w1uL@o*augOp"' H&k<1Kڤ2ۆܟݒސG޾ܕ3مz3.sDٖڅ!ܮ,mkls`NU<t x` y  w K% !@$&:(**+ z+ @+[ _*(%&5L$*f!$_ j _WkQ7ZMHV  * 2K b@>x~%prN J>   w =jH:LeQ(  Q &>iH*f58 j d Z3 Z~   '& ^NCe6R{|z:>>en4!x<5)cgd>w:gi~x1L{N=njVU A 0-BeVm#u ! T3RQ:MP]Jj U^bKCf ??6j O s: h$ 9 %]Y{k w 0 4G2BR F ri!ViDMx2Numm T, d Q F ' A ,  ! x9 q Cm =aO ,e  F .>VCt"rIXJ YB._xezT: JJkh%&{( [ " 17F~>}}d 1*0M3z/*kX{5 \ c F  9 5 V) M   ^$ L q*%3BpY\m CmjtbCk4&:[N3 C0Gv e""k$%&v1'''A & & '%$m"6!1PJ*~(R r jMCY?bOtT"J)4[):mrkNS[  { D2E& m|* & as _*+""` w; E  Q  h.h;y~,Pw i sO]pQeC=*v:_.4LBN Uf_&]QbUwEZ&E*.`b{S5Ycy0   MVhHY5l*b  I Nze34Tq~c k:4yW x u  yO  A N  A _;  8m|y'  $ n  _  c   p E [P } .h f *8|? C~WG xc J\ M`dlPo# \k k CR-3 f g!y"c###4k# n"Y $!El!u9! j[z 6w  P- 2=?A}0B M<_!4OJ}} 9 (t ة؟I٤3OeC\ދ[[$882beF?!}s = "Ve<q 9cu= j-&52AX3}-14i1= 9TgDYl-TiL~e= "R - -?eT~9 HiRIh "*T1g\V{w)tHsH1K/Az$  ^^Ju6/qC~', n %6_ ve b u ] H+ [ .\  # !Xs C M'F6[Hv  H Et9dx& D + LK B+:GA,_%9j  B yh-6Vb 9 W a }K a_ :G  3V$^ l/O7EhIۯ+aafާDحXxvگטBK-5Y5R_1/eK7~yN^  ' HTfOE6  K  3 }\s.  x6LeH9 I O h D <~ I, y  BL G[H}T   d  &*rh8?Ai_ \l,I=b # N R 5 ?e2vNhh0z+zr2O;X5j~)xrNe={4V>'Y|g >#)d@&[V!uFzYt X  X n P 4 " s tv".5|v.#'QD3X[%=IM,_&A#`hJ 6 & Zb64$gj*"/n \ 1=MIr,PD%ZO  ]=:|Pz3dO A %*  >  :9  0W <)O}R B^ F    S |!  x2 V   = 6A  v  `B+\%FEz -eY2 1 "l&{!Wo0ajHA{d8@@C nZ2xeiVT`d^QUo+c k:TY1Dik7si R xq{EPCp0~zH5.-߻cO5 ]N@K3hMg)M8%J+ MZ uF?oWh{#wLMT+    +]P&X" N {l)Oy6gS<K}p]Ls3, < L L x C J=![F8H18JL^F t  !qr |HpQ !mt  escKc@/p{: `oCUS&!os{$%\t+`'sB[{wje$n kOus5pEue@qq&(ZwmS_V8r{"}(k1EdRv@B1#mO04w(_|K  C <G5s!B"[$ >% |% %[!$" we} 348H{ q  ~} < V 0v ? ]k>c FY O B0 X-%}v$ g T Rl  5 _:vmEJ    zM`L!8k[!1#Bj$`%^&&&''T'&&% $ T# ! " 0x5!W > y #~Sbz(yK ~l%a-.އݧۑNTU {s6e]"5<8 *%iFG 5   ` _  *vfv = GqLuOqHMO%=B! 4 4 ==fr i , @ >   E 1 ; I? M o+(/Fb  / p F  Fk ^( 8 6r&  WG  -a?P.^auJlMJ -#Z:#e.Y3g+GbO?thh,^r#۹8@߭V3'#}G?YF_QV  h l *?"s.>umY^q,LbLp hff=q.:ppi-5 \ qYm WmHH%j    C* zf+$ m7wq;rma (~)!t2/uSrn_'{6L3j~v+ a>},  f 5   -~ezZs,  6   'yGg!$&t'N(a9)('h%e"w V  jb()=cbElN#3bm\ i"tiFgps+iDNl~&v2--N6J \W V 3%h9cFAk q ) Uk~mnj>#]T+bbޜ .,3re 3}$?<`.MO !gB:_`XqV4[$s;qC z f/   9g5Hi p'=UMca XQ $ L ( e @ d   \w x m !!BzHR      ] 6 n - 4n_\f# v*  V : J D F#AbYkgc]1;y;  (e[v$*߱N0,{eHdw ? $]Mz k21-: 6 Z t  b2v2>8*_`{t1_d >f* e(74+t ^P \hJ )"Z#,$uA$ #) " ! }i]/ W  jn[A&bMpa_,z  : !f 8l M': D G V h R V$ i  t; d  9M t > z m o = ( 2 w,J*qe o!x ! ! !!!n 8"~ _=]okn1   HN  Nx M)3H?!>qz0F<dS%k=BAMZb4x*jmK)2>HYaIax0 ; ! n'uN0a&Qe5Iv1ܧIm!2v/O4mtc ^g b.Xeb7b ; IzapYCa   H  9 + 7k  52QwC*] &m h } ]#5yA > 1Zr$a%QG9g > !!!!U! :  J yW {  lM0-`) - B :6 'E,Mi@g3oA7lO6F<܉jE<޾7u-B[Zi0KKLa/jn?oH#  j7 af U P,&mfL3NcC KE it N\I9-S'NZs#$(%(j]Fu]J:~{5D}TO@ Z y ).  T  5  N I A Y V \ h$ &?{Ay6rw ^ ` uu  ( * 4 ? 2:   w<W#Kb ]8  v -nFYD}$@u w4  _ v  0 4 S(   d K  [ &  D S   v * 0Ek{=TMOzuN<-:mܹZٿX3&$kL{;i,}<4Pg.8v}K. k B ) B,  t 9 ..w=i cluP>sT!Q}$^*Hh%[pE$ ^ x9`oXt._Q5d <  R x ?Ly L)_xhNwFk5>o|&<frE^{3" Q iu+ 6  j?b Jn w +Z np;FT!n #$n&g'% Y( @(m g'= %% =$ 4" Ye 5 GD E R  CW//  i86SHCcJ\,'s.1w6d8`>]!1VF}V&^a_D0_ Y(c~QZ>sxQhxA.$nay6A+v;^9&;"5NUUJV ?1 C> q0 v `t 0 FP=S{en2|,]e s t Of.dT<   _ k R E Od X j i\ - x   rA"\(u0W~p?[VojV&k+o,H8N%s    P   C v  L](\kE+i} }Li[k6czf%5/V*6E"l|jp;Rbޅ)Q/Su3fvQIQN- * \  >_h Z  } L  Q] t X U:g]0 !QڜjKkB܃+_M!#'4]k4b F r c&:# " $&' r' '%$c!C   76 kJ t h61 b XCG mB/;n}-\6G1gX OA-   1  ,1l 3I i % VhSs)v#H}p    w U 7 " 2 ;*mg<8I~Ck  Pqb Ec/b( ,B 36{/3dG*7SGq^_fCOB20.mGqGm JSY TXr!9//8#Ib'Y Y,#L;kd 7ٵ];'8 ߰HpGUN6*7 15etG]!$VLk, \j(q&OoJrH F   /s s<   ^V-a  + '95TE+2;g/  P S&'m^n1,IQ 5  \{f:  ip-v o !q_1`)s!/k N?]Mc-h6w t wiQhQ U }T9:N51EUc[k2 #v0r00![UZ x`>k*-NS<!o@|8 zU@gE a VTD_UDq] =' "JPF.H9 JG t : *v ` m@%?e f zQ   A B  Gz # { !x    C  , ! ;K B$>G')9+++1+k7*($'6%?#S M! U O =      4 n  6 a qmF.ma)dZ_[AjRP H}W V*q{x!3s|2oPZQi* :7!34UN,hx@olQF_XT1?{ Xz*?;rK }*8_O$Sq=k % ! mp wc    n = %Z#;yMW 7 6CnJ|>,g[r #-"UZ4@u)M^c0#,"aa  l.b?   nZ  7) D e- K Y! @"J " " 5"4 k! s h S3 1k)`< N f :7 2 HazSf;@>I?1I>v>3CXj5Oc6#wLL]_ALQxD@kaU!fkH?_C:[:m&< )-D Y?z/f>OC+' >cf A GlR?Q3t3|HaoOrN20#d3Xtcxz!i= W$&rWvlbbty+ & m i + 4 yg/:  ,E(IX=:J} 780HCK?UOM4d^a ZvEl^eaO q 82MAH.5E  g_3p| Z   C'uy0-n\_=b U }vY   q Q RWK0C!^F94)C *  Xq 5NF K FCJ*,1Y sP% ^    " \y  x c '  q~ ' a! B 7 R]>(%v"kFw7'`$8m>4w, v n *A+lD 'N 1*i$e6ڲ؃.j@wFM*r8h *C^Wa.>k''eI##{.LG1<;#GdPIo[TJegvfzi8l|'I&["d!  q  Mmvr'3%K E) L  ^ j :Bui/ m ,  b " j 9 \ kS + = y ' l/  x!(le8Gqh>D5P#%]VvX0Ek- _0% z} jI][Q8+ 0/sݩۇ؃L؉%ؙnڭHۄܓSB:7H d [,I-xP*y.s] c X! fN=^9ECu\b;:8M)>[x*M5cCPtnߗY߾E'.iFR. #>'uv2i    D (  S<   |    + 7  f1 _ c*k"   k s  * > l 'RU''V@>9!"#g$A$a$#A#H" ," ! ! >! Y dxdTn@ J3 _  X $193*R%X,T /PXB/zT[5okXi\C9BYb[yE@@ l8y4FU9 GklCS%1$` 5sj ZtVn]CI,OToP <\sR/9n )   *; C4 ;  4 ys b ]C|    sR0T~k   v  dSeo 9 #q - p] k4g2~c\0 _H>*ewYw2 O +^9Hw G  K_!l'jy N R / 9  /   S B3&_ys!I)x`:,1K4,-L`/^RI R k J   , Q n  j"OUi,:m!s Yk2YA>G~]&n &HZov 1H4"FL?0sy"&u9!.g}p z]Tl@6)IvuEO9\b<)C GMr/ -~w*&!% 1\  b`~*p~`'O? 7D ! TY l Q  M & (42) |4h$5` 7y@ H knos`07 >oBzJ72f+(uh43N"G%L=%^oJqWN:*mT*4et jggs$&!kHuN{#;>4ot$e:rg ~?_tE*VwdJSMzhj/ 7 w  )~&}[5|ecbB^ k z,!h^!,W! !a f(;N=Cv  G  jiO*a% 5 VXvsJi$@sz|4( Y<_dz 7  }._BL`(G   OA p A h L dJ UO/::[KT"D#A{9} bU{-g`b  ?V}{?: & yujKSz|Jr!L_P&4hBd:uM}{w&ut~'Fd!AnR4(?Mt#@;>9sStA 'v_:Qe.f@ |  DH UU AK !a  | y V $k \%^+e  LN ^ 7FfG5`6F@V! E  !   N " 7 } D)]+t!C#^$%%%$#"!a < | KgI 3 kF/ &avt^~&"Y(,PdX ,;|{UWk( Im W1y z   = j  F;j#UrCZ[ (Yb r7~Bm%P.@6UJr Cm G[  A E  T { C^F}^SX ^Cn>v7 2KJ  P k | > f   p  r x1 e ? yCAw6B5k` U - _h5=YIfDb47C|X}\U!!t"":"" `" "N w! Y  (  I < 4F   F  F& vZ* 2&~nubj(-8  e ]  < |Fts@ (f  y e  h o;R1 x </+}E]Ti70I9= F PFn:NN 4 M B  dX  ~Y&6 ! bX j<;- @ 9:#u  U   j @ j/h}xkt<+eCUEv^>}%`leR01vtN0m'r'~Gi A ({ (N?[ n%[< Q 28   1 U   =og#L|Dv$S<d3 *p  _ FY   ; aYMRGz cs ? ZvmH$#aW3m.r$>',Y@R)3tsW;h!8 |ql%HmB`Kv{" 9d+c|=7xxJ-D"i<m*_B<diEX:(/8Y'v%#6 *_,^\$JW*v{4MR'Hr&W  p V% 8D:Mn]=7\CodQb $ tl: | L . S l X  K  Z 6> L_ 2  f &?A|  J  Ka m b |U>O" E{K j  -H~J("9tN6*;+Ug1oR65_ %1 H .$b\Ue no 4k X=rvPmL*,( {f&#')W:uqD7)~&9 {k4P<t%|O0"cL.R*dgdR7K=BI"/qv0WGCBiEIU|!|_,W y n P  AT o U 0    m }MUC09MNg6[DdT m e \  3  G ` D - R _  "$B$T%9%{%2Q%$V$. # ". ! ; w ` 7CX u.FZ 0< L K9%' R&H%D!]nHWBf8V"gXd%dQ[\j5}lY{gn%t![( Cj8VwF  jP 1w4/{3k(HIn~u#XBF:.,:RBoVW* GMhz}js_ojnE3@,kWJtg+;1.GlA~e.y0): * ! ! >a ] Kd  <  u ? &> bU .k+Ju'  V |   9B !  . ~ oHu/Zo EY C)jg.:MIH9pfy$E) ,!:G6hO7 f  Fk  J8 h ? p 1s_1A s '>p^~ `|])U8* O.mcJ;dQ~ $A\`J )&~A}rE7nBeN  M  n (yJz Bl0t~"H lsiz ([o1^ l .Z!9 V  7 8 2 & Qno+/ohQbpMQfZHMn-&_nH<Eny}}?io#M` 3 w 0 q Fz`ft' "t  g  P &< !   h  ri  { c ~C    ;29)eI|L~"FM 8 '0* 4:#[X;>#.5t?;-k~xM(BD6VRlyu= =A}!es!W0mla|DDC4! $ F }4V7 [a  &SOiF"  Kl2MOIJ(  L. Y  $B!T3,4-f09v!\ FfxOn<In"}SA{;sc6d oSNq^6j X/T% }!  7 q}A _  OhCpv 9 5 y t%)Z)TxW2Cexv~ M  ,[bH4?L | f( [|B7IpVW J  F{Q1}Sb~ L~ C }0   H j8 =  J  n ?T  K J _ Q   -5 ~ %/\9U-C?m+ FM^(jX C2 _ B S ~k c 8i#jpu!-U  r y *NmP>5 WywBWLKG8<}?U b]($u#\y;:7d]|=~?6n'| \ByQF('F0vWyiLa:~* -bvv(:AB'`a;q_; i {  2 a W X  ! s @P  F'o"p  Awiw    y  ` !  E  S )\  0  PDtRvZhVnj|&f>h!a)c .qM[[vwf%eL@g DiPlcL/UlPgoV|HT@rB,d(` 'eZIQ ~aU%G S^XrPPaJ]GrxN|i$*` icF5""L j7:&ENRC k & $H `r P  % `H.7/ Y _ u  rY Y 4 $^B'P]~%|AVel 5   {6#\a"QHXz)@{.*5 uxzPPtlu%.e8BT2aDtx@ouZzq4UU]DMdm APRt;j/bvCa.$kQVM?:T!-?dM/8Dn]KX*LiB:[Q6p4 14G)%  -bp?`ld p~Mof+6[g\Q~5= 0 c5gl#q$  P< +0\E<C'0ObWRu`QXxqty+9[:"p %  }= : Wf  b< @gv/ xc=>vK ` A T(3^#Q49  G )LH0^%  & z~h+.a j @ h ~*@0nTyQJ(,"DP.S{2WS|nEX5Uh<'fwa"]f@*ja0{ $VNili~S ,+510IM~$f5(HGm6cSYZx91NkbN ye c  ; .4A0m!!: 9,q E 0 L \ | ` _   I    ,1vbiyRJk#@iFw-Mqk%glBM)\"`V{&_YLO.W5nY'Z)qTQ1DU&+h$EHZnJ -b e (bkO L zv  r ^1 *Y :d;o0Y/<># z O z{ R%>4At(f}f]  ) Ts @%#%J=Tj@l)K~<(  n  9S' L +J *U   ,   % @;RQX`x$    _  <  !  I   y P  pt  >(H}`\{$W;%I/*D{{I4h$ p  )^ o }  q Q ~?-rn M f  g:F]- hX'c < $LQ5>}3ejIOJ]A6"hPCnPX~1]X(imlQTf_]B3kbV&~ 6  C H1k * t.5!-S4p";j  '  D+H"9Jc z9 C r,'Q?}/"X*."%qXm w EE $s ( d Q % [4 p)6>y@A 0a U]  l 5 ; ^  3 V~  5 8 / ,_k  &  ) 42k|wK=UrCNUY''qX>f*N.IKI/K0b!&JMH }mD~e?5%iyAT*YH+~Q]!QUcbThVhid]<T\_DSH\Ld\?!]LiHy~G:{MQQ<y9 NS r } ! n_ B W M ~ w } 2   Tq  Z ! x ?L uS u[%y2 f n 8 CD+ P 58J$B=K'DKM?D  ` vnR}> |}~0\%wSN17A6=l3#(^O>Vv~Y| g7L ,OWB_^r$;{yAv8sh_-yElOKDg[|GPI81=: *pn OX= ; 5_ W_^ -    Ld sr=Mu  { l   n    j 7 D  ge  N y V 4|$35[P!]2CZ2IJ`27FShvyu,;oe 3 * Z V uEKms6 v 9rV8nq0  (mlc9[b Z h  Y b  v E8,:cCH2/ tV e ]Lhz[Oa(lE@ & Sc&;`/7z.VB@&9Tnq%U@ Eanh/WEV@RUX d 3p2$>[]E Bti% x L ; @ >   dS6N|'>JCd u/A<:@ZpD^'  T n 2ev1SC  y %n  ~ lg c s i  &r C ]  9 ,  , 8 9 -  j ?fa:zA0o~M+0k)lR .:l3E_`do+(^nNAdq3[&[ j]sTUA812~|F  jXQ2F<U M   ` % ~  }4*"P)KMHC)j3^sj &v r <#YUYWB. # df :E@8% N  i d /%V F C orQ?L  R & ` j  w8,Uup}g'/  X q `E]W/]7a.c + >4z)X"c.\GceN Xm%R$bRMe5kp\*y(   5 d S( i a 3 C z HD ^ iE L)xx"c0-<H 7 wB =J;t5OhEL2nUٽ؃Y$dBۘڜڃ^zݞP 9de"$p&T'D''b%g#L" $t&U'?(' Q'W& H% I$ s#""\"tS"!R ^G )- R*q..L+u 5t(<"ԬLҁѩ Ҁ\ח.ZjV\)*OM2/}\|MO d\  HL   / M 07R  ~qi[ 9v XyZR7?p<7,eQYBw+9XrO2ov. >>yIOru5C" P / Wq ]6ht N e j:7% y (  9     O>i = ]  SG &mR~_E?[i2 xU 9 Y @ 7 % >  /,8XycJt wVgxR$T4j  *$uHU Z L8 fP.M[ " # #B ###p#T# #"!$!\" 06? 6GNf Vdv4"sT6Gw6O\% څկp]Iӎ(h' ^yBo;b X2:~! wNp#  wK</E! 6 ]\<LTT 6 Y A  gNuv߯Wxa;1AG<@bKR5bb_MFH@q&x,` MQ3BqAYkj .~I_ A-u87OACeJlz7<M[EdKs$   n: ph E  !q~X|Ca@/ G Yy $YM kX& 5.1Ooq([UwD#]x/L,n*"J = 6I "XkY m!#%A^&s'_(D) ) * e* * **w*)r(&$A"@9TmA(Hh;Wi % l BC . K uIz%$w2O~63'j%H{Tpl ) K   cI^A nF D } +   >f ( T  g^\Vn;sgE[+5 8   E   ,Z&d7^E e\=5Rm~%_} &a 'O /, zbR't # r { ] o J  .# 6!m]^wS3B2Tbp(jw Wmo;_7? N ~ T @ O CAP5myJ|V<*=Zv#4k_-= ij(v L|u);^v*iY6l}SNo:}DVv D g Qd 0 j F+ 2Q>^#9ou1NRx` o2nA r   h n  A nfvyO(Q<'= !M"0#"b" wK: vE NG STE :;\tLNN23_/'K0SOaFZ2;) _]) Py9"+SUNX^.(ecZkFp {N4zcV7Gr M'8dDZ7? ]  T A ; w kpxdu"o)Fk~ U  I v rU EJ `W E -N2@jpp_8 & x / Q8 -  !  7 ^/(B . C +0 _ 1K"o"d"3@!  Y ( m =< F mN8;0 w3 EW9 !߹nvC3BGN?htGX>*sUe{&9P0qM|  "\><9]u0nv|pGq[qIzXeW >U$gQJpY 5S J\8&2cj? Z  j ^  6V y\w A!!">&##@$$$N$#af", 1-6k"rj(   K6 E xf>$FZ  ?}N{01j+`/ZSw2  t L ?-K4{) /r_v*r@jߣBg߀<߳޵L޶6DFI hKhך@٨LCzBJކ xd'I$AX   ! "rZ"{"t"'"\!? M6 ~( l Z  R{2ELz q3e(E8QLNj3P հK&{S7nV eGhLkVv9.f1 \S _jmQ b Q th_  U:5 5   --c ^ cWY2J 3 xB< {  v;^E@*4Z|Q^HHr݉ۺ,ڂ%CjjX 37چQ (r܊CPކ&ex[uVB{{D9|!}V;f&x} yh O z zi=.wI(w#DV80J LB#%' ) ) `) (w 2'@%#g!3:nQ4>m I ? kS kA)dJ6(nOd']Nf%LUI : K.H"Z ;2`rx  ]  "$U%:%"%q%%'%) $+"+ 0,,+{*)M'&a%${h$\$$ /%` %\ %+>%A$"| &(*e ZzQDdtesq}<]?e߭.Cޕ2P1܉Ecݫ[H1+4(iIO. w*C#,7]{Z } WSg g>/ ];'`!LyJFrڂiLf^iY ҷ ׺,wހ{N_-lDq p%&B!D G"iSL=u5/{AQr5{]m7zyUo+HD.?12^uo41D$r n , LO E  + $ _ E{+friQ[ O r-Rzh/.a}C6V ^Z B |]5V A! 2$ b&i ( )")(o'G"&$6#!A `IJ;r>F^" "0*Yt v 0#'R]_\}-E3a "_N1mkM5HI*xB)G$j5$s)6NiZR ( @J)*Pv.yFR8hN6<?+ /;:QQ!%s)+,x %," "+*/)^(^'%#f!nkz=/Y&u ?{C=moKGN|{@x8!\yL/$7$  | W $W{(06 3G=R:$ Q!?"=""6!# i!".#" " Ob ]H* NgJ(F;;?O- C 4t'E(U;l0C10x=ho%7NDG_}_7rj]wYTXqFfx]w6<.p] MLG\>Ru7J f^P&9FLO=9TA &w}*M N-FLOlincr,[/GiwT CPJt{Dy>kߙp7]sX*Mު iݽ(5_-e #2qN)GK\h Q%t Tpo?{Og P_ *  W u`[/?(z::OVVe޸ڤS6֓ O p: N8=R!~ yaliTC(H :k\ tR bf9&7N5_6MCi6\xCCn C x!  #$ y ' 3|  x G2  Gu Ov{ (Q5'Bߠ3uܧڷ3.8d*GL#O \X$ "t j.fyEGSjq P V\I" $:JP/fc"Cx{XP=.ge 1P1`r^;p^sFyK_ [qӼZ.YgE5 ON.1zX*DD:v+pW k m 7ill8'({#t (5SX }Y;!:""S""!N!M 4a^;x xRm)OP'0 &( mK k -{{U  %   }W T!x  z!!I"cb#]# # " ."! !  [ Y! "{"6#v%~ .'! ) , .//E{/ Q.$ , f*C (=%# ]!*2GtA rS  oq 6 0! @! !N )*  -t8!/7<<~ )B@YF9 s!"e##}#b"<n!. w#sb< tEj xl(/% +-HEz  Yq l  O*lreAxX6.HG]B ց՘W;;[O/;+C} h x\bx > A    0 , w P ]8 2  / sR^K $ _ ;  i^O\VgEsAVL*8uec[!ܺ׬%H17wн!lЗO;2ʏ~ˌЛ:ؑޑL8 'd"UzP@M Ty^?>S&Dt:0  # _Y   9@ n _ , J  0 4  D 0 ?Y sA7;K1%}F?s6F"5ܫ;ܻS`Q۰ii6 &Sڔ<ծxnZfs=c1 ߆+&8qRcu]w[4{4 64F8R     Dc !d " #`$k$$#"c("!;O!! N 9Uq  ygHP ^V{D[gJSeB ޑ qܼ ٍ +׿ ? z( <` <#ALPzE5̘ΈurQ7:>ޔ{2={5 B/ti & 1>Y<^x!3|J#*G n~٤y"z>rHݧ 6N``$m;BF I PL CV_aJ2jU4z+QHcI q 7ix & cZ (/ B>^b_TESܠ @ ݯ  ?L  *N H Oc0 pO/" 9 e  Wo!N#9m$$$t$o#]k##"""="!T AJ9aUBC#A ` _Rp"^6AF/q3?d݆VڔׅA՛ 9? SzA|إx[܎031_z .\?eTI:PlQ- @7 `J_#03+lO:>1\d , E eXh+Dݙ jfeӿ bKˀʉv hdoЄ~ն= xr;;c3u'W2C {"@ c h E >   S Do7I w g lu  j @ CZ " M ]I!; 8 I8 T  k ! T<|Q-g+?szH ~ = C2.?}+sX55+^1!{hj &$6}AAqr#Yk9e C4R Q k:\X~v : [@bvRH0^.Bpc^`? + 9 7,u+~ Z* ( &$\"(J:/wh]5x P u J:  pCrITYsNFO`)H Z V r0 !  ]NC]3"pl    M8YF5> o^ .TOXa .ۏ f] + s WnZ{$] Kdqwn q UT  \"{ES`CD#^w6r A\ b q 9D1K o^~D u' f~  r eY>PZ$ u e,C  }t(k;M 7  Agtb}yB [!3M! ' AB>_jR; V c<@d)M ?A GXe~( H {Qڴ;չJmmԂf{r4ۧh?dߧI4?jhjUMBJ!*z/Zp3P# x 6 7?IC\(DW'S~]OT$}. j A ^ 1-wo~#V~k ]F d U GTM(_SW< oFR\6 IX$i^lji=^Q > 7  8 1 f K+ ei   ~   4 vm 9 n x J;YOWAvgn  =8 R HqHM~DTCmyby$cZiuJCQ[ c<fS L Y  ' 82l;GUn} Wz# F $l t 8tm>7 W 8{'T~':Et{_Ha/hEm4,I00,   | UL y: _-H1*W@werS1b^zr, `a v#  P uv 9a_ %c8],jIS & Nt{;H'CB L4 8- \ Z1K  L ^ G : T" vb \KU.-`/ . C9]5<~p ` 8+ Xg\ Qa0(2![V?;o/t5L.'C@b{J c ) _PKlxF$ &  6 `z|j~CS } N0!!!! t .,3 lltG'z2_:=;*\#/JxtU~C D?K:CI=5bS\   4IX*,>} } zT 1}#I3sUW-lYrH  -Fk :2 ^G 8` eCVyakmvK> <5Dr`NmF7Q5.NU|[?P`[Jy5 h ;vm  \ EX     ( $~ov-  8z9fC8OCklJk'L|>\E܀WcP./S[lK 2@ / Z ]I   ] NV R T S! [`a ?3 [ B &d/liv!7W  aL1[h=d(VFtr3rEFH'5 H , J b t E t} ߰ EX 1A hI ' l  g@ 1mg(@s  Xu b h a Z V޽ Z | W 3 ܆# =8pGw#SK' 4 P9 + duR'MOK !w#%@'(6 * + +x ?,,wL+*('7%S#!/Nh${4  } F J v 6kwAa!UTnu  ht\h"T 7{_! u k DK  W :   [    ' Q ni!Y.44 fX d K ,  ? : . |L n x E a&9SH8 ?0Y!}n_#-`iޙ'sR֢?׷` ڻugrKsUMxzC;RuL46~K*] xX { zQ ;fD s5uBQhZlWgn  Q 3O)4 Im%Zir $Zo={uw@5{vi<&;'E=|AB::BGSQYD.-w 9@z2g w  ?d57  e   R $B0Qm= u VP.~%e lo9i2bUw'ܱ=܎ۆ۲ ܿCܧqܺܬI3*DS1[" dPk~=We6kLhvFm m e  E (  N  /B  z' 8 A{oNKT ;E tFpyu]k:N jV=aC~_q^w$ZJ'=e*R$FLoY~~ fO  iP}yiy  'wkuYG,pH0s80f VJ;B  \|}{( y k&~t%W_ig Y5BV&O}&p~ @3(<!]$&U(CD(&E$(D!f uQP.O 9I <qD u#5*3h)iY u  \n{Tp٭9٪zoe'U>PH$_|9 i g-A$;OR-{W@ C m}/5>tTV=  gx x}p4)2Pz^4jӾщOёsӦ_HJڗ*ݯ jBW.P"{ w ^J !5#x&<$)*P+,03/24?5O5v5"5$5C4=1P.X+)&c"l_jw1Xܠ B$1Wpݦ_ޛh_4S~A/ " !s7 Z ./#U  Q8cwG`6 %!+'7+]/v1122\y1zA/*,(($ '~& Eb4*I#Ko v- B + o ܋ ܰb~ zT4DHamwFd< >dJX  +na.q  i| !vJ  ~ (EhS*qf0q9VO"!#U{#w"!mR9h h GD+ft Ok+!n@"Z!Д Gq}T2ڭN߻is F + YdrZ ܘצKk҇#y(Yҕ,)ҫ/N2;c455 5P5W2P/+4':"mzD;; `v [<"I&F)$+L*)'8&$X"a` y]rD7% ^yC m/2"\p'DY,W=0)233uY3 $2 0,G(dH#iA7 3 M&,  (BFPۛ&XG3* q vIR/vlt  ny7;c!V!k7!? ,{ -~^   !&++902B\3W20Dr.L,2)&'#TAxwH qS7 !Y>K;W   g!mA?arCj90$BpZ4 y4*i n f]]!)&!#*ڞ-S0J2ե3{|4_44244v54t2d.|)"c 6 {]d!^MDCY-:!T"ە$%VR&<&׀%$!f'0޽a߻6߷ dZݞܓqޛeLuyRQۤ $׍y@- HU`O'F$E@+߉sZT) _N.-0h^ *,C"V'$+A.-M1m4\4d444Z442.*W$R J"fut rygJMi *ԳЬΌ ͙ e i2OUX,2^/Ecڷ_݉cWJ6?) 5dqS_ + [K '`PQ G"jd#<$?*%&+&@&%D/#q Zi6W W3I7<;[m 0o&܀ؚS] Q"$%L'b!(K'?%p"Z{) gJ:]mpyߎ l+a@̻vˮ K7,˚5ˆ 9!2˕"1˨"I!˙lI <r}8 G`" g0{1 ݮ7P>#$(xҾ,6]14\4ֺ44ܲ4c44 42,'~"@r ? bLr >Oy!`b%?(I+--!.ڧ-ۀ,k*i'޼# 4to{:@ FQMr`#@"7 =\'#f'(*++-*:'=K$>V G5߭,  o5L8X ,` [ T ZYr"ZmD4 F~=ej"2$Z&'(M(g&"u <~ BM]D X z T V3!;"$$iٚ$&-$ُ"ڛ|qߺ  .L  1K!M1g۲ֳ ҇ 36"ڶ%@''&%M$" & o5B/? N g@3"^'j-245 555055'5543M/Ej+G'8$/ _C< w , 2/a9Kfv!L"w\"k!?E  Y Kى {! B<ޠ=V~Zm $biRGbٮ}] ߂ >mY m ( ^6.*po' 1 ~k$m(9E+,N-=- -G,, ,2A+)'M$g <ZMr P E w[ީޱ޺ !~ tj Zܟ ܾ ZBߌVGoe[p*imq\ Cv4QP_jf_$2** .G^2 $ ,)Y<-.0C34aE54]N3y1/-/,h*(<)'j%Q"3 yw| ZAb`a?H]% u$qMEJ<CCׯ WGwt{&x׳p$ ) @e 5[[6L> @TR 2%)+C-L->,9*P(}&1$u!:ܞI6]o iK _uqa޷ ܁ۑOG4^*چer۹cn݁ l 4t%{hcL z#?i sFl1"%3)a+"--V....,-h,EA*';$O s'Z  e S ` HvsK<,G*[mHXA % *,c= &a/VGgp6~i4] \ v  ` d]"&(T*x++@*w(e%C"DwuY$>AgvG# vAH?P2M.:q ۸t; oxLztvaK f ju $.(H}+J-إ/u0t՟12iԐ4-5i$52$5(55ݴ4 ߙ1-( ",ngL & EW5XJe K:7EQO W OՁ } r #q @.%|+} tU n ; ~'3 g"$0%7&L%/#q=!h ) E` xI&F . {  D G !A $&d))D,-_.0'.-KI+(%!6.bm s&?/= F T 8:+@  36u~THSJ~| ?vcl?,!d#q$%%3%#" !9  q:~ RRTyTPy ۸ڙ>܎Bblc P R }{h+Jt@ ~ W: G "$`$h9$:" k0 ; Whn#Lzr.8)#ZCk]߉ FK :sjoO7Dl-[Dpy]  }X$ )w|/'4&5c#5#55%5525 5\5K4Q0--l(8#mw~b  x:/;RZ5aOvMݍ٩ָՅkW6;;I֞ nךm0PrWN+7DQ\Td |nB Zc;2pR IS _:rspS'M*kKC@+\@q@c H(TA /"j###X#R" ^5T=#_)Da c UCp:+T,v& R . ! &q9iJ!*ziqw$ IEP~Ox e v'zfvnW|? = < )i?v! f%z(*0-8/0U1X10>-/6-\*@( %XY!~3 ^ u.=M v 4k r Bn~3#E>  dw i+ "[,<5z -ب]LU!!"n! - y w \ I G!H%)(3m*m(,-g-%..@-+t(%rH!iBwG @ <=wa ] /=@ GLs 1 .AaD%o\LVm/ a O, # L&)(w(5)(p6'%"M]mY62e k j^  p^3" !+'#'#[#yG"uR d1<.KI|q y 1ib ?5($ }#=/M(( 2TG>c9 p`/x&!5#Z#~#"!_ aj7 hm^0KCd(;qGj eO ܝ b]VRu K 1dk8  @eU o#%x(*9,-o-5$+G'x"X]u_D2   ?F$[{V>Jad (['ރ2fڽ[)xHּI.1 ׉Hu3(MM { I.'318 hH'2TS*X#F  J5Hd u#$P%$#P":@l0  f UOvD  S 8_eO7 ܾٴ Uzէw4Աmԛԧմ9lUݿ0Zl=[*pKA_rT]Sݒ &x%bsb8wKZ(RAJ N a  'B KS"fD%1 (v*=, -1,cN+}s($" 0{Gg 2 hrIlM*Vw/n9q n܏Tۚ!tLׄq !- թ{Bܖ/5;t_ y)ݣTݩV)W-ޑv{ fHTJ./U}("  *IG$ o(]+,!-`,*]j(Fn%"1?.Y- Z %J;a nh ޡۊ ڜ]F^ؼ O pڷmfR  p@7S~I ]\y{ )FTb o Pyl xkMB @m \|B(R$L?#+Cp $V,PJ / _ zy3XI6[  ]3#BR=Oz  *' ? Z L O]@U` U 3,9 Nx"]#s#K" !b ?WX}_9\ rWW m; ^0%(j+Z-[.]..:.-d!,b*s'$0!n&*b {iSRz u`r ]!H!= p^ ==%ޡC zo [6i~e& 4@4-% _7 NzG)&} V|"1%B~(C48L :);A ^VIQzQGNd?zpOOG+/zB ? ^. M  qhU f ui{)WHiMt3>S}AS2 & i'U:Up~^IkXWBM<tW S (0A{ %:*4Z/ >3P 35m 45UA5&>5<5<5[H5N3=2ty0.?C+H'/n$  ' 1* X) 7zIoK*uu /, S \ &ޯ  = b<2,}#3p}&Y y.c!c :x%pU<c,*ݯ1+ l pA L2+Vv`H4߄ U ger)Y!!tDoAmc'gN9\HWyPB1A j+ko\S#)R@ R?(UT k!L"|"""O"Q!~ != Rn|jM,9R]  /p7%x\<6[ c=0I8  m YP p GMk2D!xTH&*L~] v q qAD L4x &qX5t{I)Ll (! ,& wD}q 0~ ' h U )i! - :Qax!o A[z2FtF&6 ߰ D W,mߥ1IM ߤE|^v 1*X 0p; Sz݄nږniC $ jdS$(ېWSakt Wxf X]kibct1R3B$s9F&. ! '&hWr {  b6gOu O" ;e3;v !  ! 6;  ( t | *1DJL>-Bn2XuG65sU$jL6 y8 S a R S  8   A y2 /   p }!{!#(%@#&lQ&W%/$i3"t  t v,T'im6R K '_;Z9['GL֮ٺޑeaw7$z2Q%ۼ Uن ؏jSH~ְZ֯HbMf~SHܘ Aj z. f TC/!V!i"|W#6#n$y$=$8$:#8"!wo5/pN e  f H   ) 4 X  X )f > vp 5pFxq+ (qay.E>~j 7 4;f(1   ; I lcnK  CT<&/o{_ j=C$JA 6f + Na 4x/B&@?.-{, >~e|nH1)%,I$} @ZViOm z c :hjowaD(;OZUM;+ B )o|oj 7 @ QNdrE%j D!;!!K!] me 4 :T9t  7\ " b * Y|Wz0 EHY i5 RI %B.ahc6G l l' !Q KPK8 5) % h5U %x 9mXC m o!]zK4M}cv v X C D,^c hHtk\/:+pZU9=Gc7Prs{dE0 E? n Uf@X9?, e a] nmoR 0%(.,.d:1q 2Z 30 Y4 @4L3310.,"**l&"5n c q>KhLW! Nc=ԿьJx؇ۊ6߼1p"OWGi@)Jd e N(^RbPPߛ)=߶w#E,)   V\=kS11 n"#$vA%Y%~$d"Y5 VCXkj #G {h=h*6<awi`.q3O\ڡqۀ|݉p$t1hMf W6sC.T5pt 3 j P :Y1,FC\]7 I +!\ ! !! Vd1*Jg n  `<7ek1 , - !  a<A;LITxx$Vo * 9oKzhzG{o$>NbO3 _ zML}4Nb,RW?VLN}s '\q+Kn*\ ar U}t8 D2Ei=jgY&Gٲ>#*?m dl  {9'';^` K Bp]@,ga''5*] q)T#YHNi: 3k }k1B1eIC^<   0 nJ "  46v;$dnI @  t23zQzCKUE0ofFg  ^  :   h Mm zS ";gW89Hf' n6f@ o J ($a>(W_S   %  /  HE !R$V%6&O&%$#"yq [Y'I(% TG+r9;ܴdL=*n Ԥ Ԁ :گfU0tXV,9&  {Lx2eߗ ޅw3YoM,tc8 <  -cW> "EelRPJr6x`P\O ds'w)vp3 z=6_~(Xd_-6^s+7 ?  Y f] r Hx / i& M  r `   yj E7X>TOa\ iv!deysS){B:~xU%ۦ$6 *ج mٝ R JݝiKU/. /  *B6t_(g @& R Oj i 4Q*NBC T T7#sdC|Xd>%; D <_8 M >Pd0p'Y:m;4h=O Cn . Q 5 < + ] djy % 2j-e{ - HX4(G(0h%ko)%} K8 uc[G*KZ } =,^a{QsG"afoYU]4 6: < ) Z O Ag\# ~ XI)\;S Z=fjdXRWm *1 <2nvg.78mIX 9j'1!) f"b$ &H' ) -* *1 +*B)S'!$HP"jpLII-A@9 { (r_O  7 L o ~X t2 K٬9xހ+7QS|<) % q) <u}T݌W`ڤrV'Z'l 5>? RI7t%F =YgzY1(U5f&S_ ;Rp| R?fQdn jb1Af< -^?#U`}gC]\2 7 (: pIxr*!#aO% W&&&&%#k!3@ 9  !8!C!| !o l vj$Qo &Q}h;  B Biy5KK"Ie'H3RF  * | hb\OVOQq__<r t-%lduE.+eBEJ)Ns}9  /|\0 4 Z~< MnW{ " GA 0D  9ZfA y#JD"zkj#B{V\C1*50f}*C Q yh GMk ; C d, _}g_gu B8]C     3C5!7W > w I : m ;{ g< ^ (S  T& : 9 }0 > /w UYnC;9J!_W* o A D T w ` ,B^<vFU6iv$?%VX@ r ' fR Q  ' ` c N K G N # &| gn ; S P    -JfbQ$cm#OEc_ w a )8ZY2\B`F8}4Tٗؔ 4{ښxtR t "1fP|B;,3gG۪ C ڄ ڀ\:Q'#NguxQ2GY%OZ ; ? $"/tF1(QKr Dum   So'!N9U`&l; -ދi]I/K_]Z6p8>#8 "O6KyP]N , Aw8{S#Lt &2  B g_  2sG! iHX ; ,I1`VA*,5ev܉z | @ 9 (T Uo ` s MN M $( -;$Y!k`c 1 E Zs S r mjvVbsLRp L 6  Z  FAXjZV;/v u, z N*uNA;Xo*`Ww5?#kwSZ+C84L@5r4/<%/Nu0A"v(( ]  !  -  a v   c  <,>N_#oM8E|+2 ` h2;a:!:;$.& 'q ( ))))6S)(k'%@$Y"%i EN^ 6 -^gE'YK1*K3|.--W`s<,#q/iL<t u::jF'q. _ . r|$].vYT{e0g(+( , @+ L B p yupj(mu e8v~sQ`1T\?hg UaL?iY2 I (dk[G.M \s!>"# $@ #"}!}?  mD zi?7nN 6^)\ = -1oW='G]QF |/UU{x~1s,8 { \3dkPBffH,EC>  k\+ A9 4 W ; n I  ~Y z: O J  O f  w< o)?%tjyzsK|{:6,  Z  U    t\  i$9%TS<cS( @rzmaTIH@  3 f  :"LAJJ]65{y^ E $ 51G+jnNevofTj9@߇=~+ 67 g`*UE|U$nw)*{O' TS OH/Mxf[qH4G ~.iJ-%<#|T|GLB!?Gmgo]X Y 2 P   ' R  ( J ~ `m&- > N 9E C h|  wk-c`S') wX o  m j ' np1CZ>q#>p [ r-  (/HE6$=@/CX #} Y } `b KS 3S!BDYbv)@ {6u_~W*mrCe[tmt~^>f` * [ *  0 e E    6 >W9] s pZ}SX4: YKQ}A=qqFۧ# ڏGdFccߧ6=9WzZ\ytqEzt@  y c2,T+it E3!E!x! gk%#QO ^  P L_!w{e!"m"~""("8P!s! RmzU 9OsZV~g^y޴ܰ}OfuݚG q  > Li.m2Np8MF =m"qB\eTB? 1Z  CGeg8.3r G N %d +^hG r s BIj,  'XOIPt8rG-NDYB_)YR%9Y~ 1Lv u |: q6?=mD5PcxX-G J 2;  $3%! |` f^BfC5~U 8o  *} :@\}.kr 4 Fs-\+H91j y hJ m# 2+80VyB IXKS~d'UhsLcRG/J `fTak  : R < 8Ga-@ &  q2;h8w A; ' L 9 c  : - H9  C gkGw&wMUq'N>4xV b7 m ; " =oAny)>P9f/X`p%H  "}2cFrh(=]  ' 2A 7T\2SK1V cm$wH*J#p':O M#8[DTR Q)_mK2u Qp0fn=Csi,C7S<[ O.8?{P1 7 ' LV >4 zo WC`j9_mq4@mWRKZ[ |< }%0y.k8m0*"zd =b > % Z+ۜ\r g ]i S -g@}q U*{YIi  SPle   yQ 86= 0 [q=O2!(D jUI27b)x(  9 fFSN;5T9edxpEXݱS{Eޏm.<.}7)&Y's  S( 3` p ;  , % r vw Zo^ {'[h~bT@O\.{ 8 w\ t /bg ; O  d `2S= '[3k%VpjQ; ! 1qf=3\`.N[b_$}u#'@{*zC D_s joeQpZb>zazMt46C<-TXzl]K'%& ,>p3   = O* % Y  - `~A Q U } 4 } H '  .l [ Q &  1I8.y6>dKMH80PeDؚnqN;#EYSVN`85a!] vaXxyH   w z M  vM@2P#0fdn F I V &  G 0_2efE qNۚQ ۢ6M޿M^)\ L.h'f#f:L" `4 , & S \ D0( .8 S  2}`   B  $*+?%;?;& mX'|y*WE!=r+ *ݘ)1 7@n p . ! E : vW5 Z mcxX9vWGw N  I  J d3 ~] f;G(Cd (\(jNzK+  }K >b 9 B"h      9rh}<!duZ4_}  < :E r(q.3'Yly#sf|FNg7?874"&$0_ a dY [ d ~mIP[J(y8ll k {  ? $ h,Bz"|vwk(Ai 7 jANH9&EH* '05.M }o  $@%<Pb}mg e F S  n [.  & ) \ l ( nD % b   Y%YRKqwYB S s  7> ( b  u _ Hb O[@;08']Z|v8!!&)2T18ch01\U2ZoI Z; :` :Bh(o VS@*\$ .R@Kw dd`h C _  * 9t2$ gTowveGu&oUB)t*iDp && vy<O ^ t'BI-?FT*vMiri^nw(-yx k| $ e 7D @[  p  d  ( I  Mi  r`TSb5?r  Oiu2<k91!}S< hO m;7Wt_\^BtL[1H_gdNMa]Wra_Y  zK zINdLN'm <1@=Bpd1H1= ` T ? \ 4e Z4  a  _ ; #V =0c0ul*Ek[[Q4( >c=;Tynh">:frQG$s)Y@gMaRB ^ R s',oD!(6,)zR! ] - D  x R7w,|2O\5H:(gTSOZ0g w_/tbXVkiTj zHh=YEhN|`x)8 8sCktW,g)ݤ 'gv^݈D l0ًW٬?6W ڭecߋbd!{M9m g gJ X k z 3 =Q) H2It[?l?# ' 0C+3cE+iyCc w 9 MN2md'x lY4ud`t)>.1xRkPL+~b/1E\_?T y  f 5 x : )$GR -R d >C 9#?Q Yl^\ Q$, i#+<[vA>nsPw ~Q]X8pK;,wP\l K W}i?4K ? R f S^%slI'Z\xs!# $| %5 B&d&%J%P$#s#j #T"U<"c!  5T&{~ kI va1 Y  #Y{Xrlpwk@ L  CH@urA$$.TCS _7  3iMH;lvo;L |_ ? $jMwE? y: I@B D~[<- !` `  W{2EfT8yA_OWWt <vN + T Kc_D: [ Uz>.;Fg,aP>6=enO2.jA}M ] e  L 0 R% `~\&kxoLW ^  R    0 T J p ` <0Z X)q / X1YF5H VZm~_xm[W&!f:IxY  , ' q \ ::>y \   j  iEitv}^ @ :s > 9QJp7y?F- )=!E:r34P;@qm ` M01_N| L 2 hP    r =5  %  !Ze /J>z4e5pUSyLs (2|Cv='T5C9UUkqc=3w YqJ&lh 66Qy1N߹VO,ێ~aIڥݡ/!k5Gzj,2ywe > yHv~OmUa{|m|x : ,uQ|b&QVf?4E%9qX\b s/i@b|/T GrJe5H=KSc< IP&a8[$fE{C0  %69iPwyyO6spuot-S P 8!ew7vsQA@[ TBKJ h 0U;lfE[w v>sS-{o5.CK @!w[ZaRS, a  3D  s &  S% J P sH9z`+l.-X/dS)~i@dB^30Qmx :l tT-'Smti~Yfwy6Y.>u#|D0X;jP2`n=>_uXC[ d7hn{s/CZXFw> 1 Q* x . ]|]|!Rp_{` T  uA  3( a = u G    X g W 3h  _ 0 ?#~  W  e L6AF]f|+qsdn1 A ; , G i da  D D=  9g"v F  H xE |  #QvHQ%km<+k>YuIB&!yARltZ[?^P7BD[w>*#R72?%mX ]V fs Ve ! f G2/ v^.2y4CUL kC1V K ! a " N _ J >i x} H `i>M$lg| 5  I ! }nNc<) yk;h!w 2  I    C ] K  cG  E  i   %   X >P  q2S {(  ; me_AEb;I,s1 * kqtfzihX@2'd@\ClH!4y}Y/6lW*bE- gZd  [>jap0W tCo k) ^ b'e (Y|l_Qql}'8 ?bQ!MGoI%s02c>+_yqP!#I;L0 8 $56e2pF%M)#Wr^81j0T(`]Or &  T?># s(MDP/Z}_ 0 % '%Ce m8 ;B&7#C  c * T m+5U8 t#{|qaUIjJ.?\;ZF,&  ^ @9 := +4 S2  -    ; ! " #o |$3 $R$x!$$#y#eg#":!d?/*  + {  Q  qSQ.l: :GL:) Nn 0sx"0 Q\ @ l1Sq   ,7 8b*WxfXP =&WedQ\&[ _ ^ a y +yEl=q_k iy{ A  p k  e N7#42Fl6&{<+1 vG8:2_4I,XnF7( D &I 0 S-| Ae$P?YmP   , O Usp09K?J50@0&-E X d z uSQ;o24^GZ kj-E8E GY'F-o?\R7zKu[e9 u2K o@[Az :T=e^!j|+G[w ewaPLtC]! - L S[lLF>2^!}l[ 4' 82qJiJAcP6$ ln/M  c W :8  ; RK~(  :   X3P* e ` < Hy d + pM , r tk L 0)@Q Op7d&JUl% S,k,e !N %g%$fs_m\D, 5~oeu3*z|#w_N!T qnEP*& + S; pWiTq\B 'W&ky3 :uS9IyS};)[KgRPuDfWe+!A|QanH[A  T -!mm+/mia)?!gI /&sI q e, - ] qB0hR1![UW- C  %o Vg^0t{P\,3199XX3o/7Dp  '#CF\"#+4_0{_R % V {so6="#]!5o p [L :-L:3_+lNz A).% "bbn,'jA?gR&RiO(oPev%}f!K&*' /df+2{Y@sn?xf8Hy/Rp@7k,P\oN7}d8h(=Fi[C<  - Z$|q6QHgXxU!9a0Dj 14Q/I<@3)e/hBKBh-X;2R`85fB7g 8od X_,N KskN]'ep.t@'[IYzIpfox4hO5=I>=mBu <z. &9 WI x $ Naz0X '\R _L)A2'~ k+jP-~eL3DX.?[~*L? .5 - o a{bZ+3lA%5OediUk&}W._Xu o F  - kh/O / 6 \b$|@x>cEKj nE)$7n#7)?5.j)Z P U G # , F 2 m/ u# k 83&x%=%sYqS# |~g9i 5  / 5%2Z?CXYVM8%<- q NX'tT^N%LGf]YY   \ ka.V5x1!q"_##L$V$%$l##s!B""2!$2&'()'s**/~*)2)R(t'&% $u# L"j  xAa( { 8 cRlENXXZcW ' +K CH d . j Y> = R =agNC n>U#0X*R?&V]M:qKBPs!CxWk 0 ,, U*  p D N5Kvu03^,>N j-kY}gTL^T T6*pSlHyb p/ e ? P iEyza g  ~  f   a $S f \9SwVxJ;-6E 2 + tE  0C89/ $ ( 9v .1'( m /  sAyfb^ t_ ! \: /#N'X1x)dOX> m? uT ] [ = X%_sc%8TjS 5cNJ#Li-u%MUO}H9wDCZa~|Q@ n {c $4  6 c k 6v *_c O3 JXZG; z $ 'p_T\nx+$>9A>XS _ r x U0 a* ,D7am9Pr6'U~`Z:~i65|o pC;y v )b . .@ J :  !  Y  n ;_ 1S : 3 q @(FLtj1M-N )Z F"  a q s 7M.q3Ob S    5{f~YC[+9kq7A*n, SSmxlBc9"<^.T;ru2cH$X{$9n)( 6 ~FGcL G099v{~4 G~ vt" 4 T4Kfp17P=:lH3Q|-7T@W R  Cgzfm</K  { mt y  aU)u'  [ . T (  N d s m   CI 8 Z \ W   nhfdT<{5Q0JM]Xd{P}P>a_-NB?8k8/aA8"L7c0k}S , R E ^  ) E g @ ` ' v w < r   ? V u  pZ}#Wy`*_h7 # N  laa z  @ M P2 4 "z LC [m3=D?vOXq X0 v ;(t[sje^qn< : m_ !Rz/ i$W+KWzYnMs]D DS>P=q1H/8|.l Y 7 ] ? m o I t z  ~Iclo8?Y qcq keN3@~T:S^e Ykay@34!i5r7hZwpPxL?m/P s r h) 7 = , S^' )fU`49uDQ2JYs{pa4GtcF[ShjdUkLKAMssP_;?@oQ95v; _ - ^  q ( y +w]ppgjK 6]dVm d  m ) Sf   % J2 % o`[;d'bR[9Z|"q*%{ [L = Toc$)T@(+xSUp|RW;zE]l*-nuY}0 Q^LZi`B}2"XS`F2%q06iS  Gr=g=nM iz}c<OThY]RD|JO\d~2|x||f: a  6 ` 6  ?R  6 m2#6l [O7^D<tCY! s"KxJ`OA/a^puAAs;R+X []? RT ~ \ p  3/^ : k G m T  #  zl  h K Ro lG #   q d d z   q "? fp}\u Vu  a =  ax X  K o r! S *   ( :P 9  3 {X7!2^hdLxq\T){;lKXw3E % !4 =xrN*nA'YTIm|l$kq r R ( z 6  0@NSL 'n6I>)m1qHRiG0A>yQ47lG,EbjBtE3 ~ `y u"}A6 YbHR6 M Jw"9iDM 24g&,l*L:bb  g {j{"3t  *11=k{ xGnrvF Pd n2>|)z +  hS    n   ^ Me(iJSnh+Q[B2kJa(%geh-{ߒKx f;R{zx* +X| #y )k1i q0I@" r F7 ~ ag6 _ q>tc4cu1KhPx_O 2 m m  W -  x 5`]2:*.H5HW\UD-|H r PAim?"t , y6P UM0!5  ?  (D)e    ]  w;  ,F, Ec pIz(]nJ!^~ { i^  z []xPQfM0#(O0j_mN8s ; K =20A!8XL'a0 uz<iD!??QgnVC]\_;! mJP'xu> f> f KtA'zt  H "p \t XO  ?N!pa(tM+%y U.NGm0V[)1p:[h~`zO5/coB !r[nJMWp] |F ! tVQ+x k|wpLB p J& )@)?<CFGxN # [6 : 16  <N[ B~v + n | m1n:YWR2=OC#lC))4  n*/^x# f { W ?VekB<]>sIyq6)OTb4MI@G-B'V{3<} lSޝw b3{:% wH92<|[)D D- sXfA+.zyc{Ro?h,O$<*-K 2f=b,2]Ub' j 5  )s aNV&Q6|}C^q">kS "`j3#1M]g`g54SH:kVF z &2 B p z5MvlAh ;YdVk 6> f3) L/\W< ,5gPO n  rU {/El#q    q d1  y  QRl~Ap  Z @ { :PUQEdB( y 2Dt3;CQ%r(lo%Ln7o"L-`$ m eu6*hP icjC8sn|,q}7P[*ZM=T&  N2Fg 64m,qa#n[=@,Qu(kj#`+'GOI Wf8_=8tL>S x"$y_T3 JK  o \ W /SnL.XNO p!"f" d" '" ! % 0l=KRs4ngL>ye1O n&n # C m   M,rb, M ,so0}ui _W]1bpEp  b :"Ov 5N0OY0zd `UTl"Gmh"M#?B~G}v{qO"Ce* x<!:z*JA U z A  E7 7 SkkPMVkX&>  , @ )  a"   *; g\ .(oe>h/j cAXw@nv5L;%mKFgjcHY"Q ] ,Hs|3gw(C>8D1ذr|}Ԥҵ'`Nҕ6Ի+ֈ8Mܭ0 Gq>]"'Ocgd>XrVbh#0q1 wIL `Uf@BE/8>k # /  r  ecULR&A  a7 wnW,;Cm;}E R-<)%lA|kB&# ScD `   a  0Q.E Q=HM6(c ^  EP<t XElan]l. _@ LV ,V 7 2lxz5goyxtx3,_p2 \ DK N E 7 _   x| : k e G 0 . O    c6 < ( d  )! ,!  # 0   % } 8  D~ A : c+PC7H +iO4z+4Rmk!3jJ !^p K g P   /2    X 4qqv:f>FvMsc}uA;MI ` 2 . 457* * , ] . I M3 9vO)Fc4,/=-, s nv.!  & $,pa1 w_H7a ., [h~D^&   d f t %; |lBd[l<lbh;#\6 g6B %  .h '  8.|i6n;mWb+$lb + P\2%@4JpZq&۩=۝J2ߛxda|NuGO&JYkvDFzQVl)Yt4wN0{a,^zL2# $ S "G0VT& rcaiet5g`fN Q v,Rf]C] MaO/}~!<:IV[i(&6 ^ s F/j#   3`"Ke q kd O $Q4:+cB3 8- f  p 4BZ$6D9:9NVUe:Ud `[?31'b% 6s  " { Q { C >| F K ev?\%`oetymj$ w 084=Euoii !i  }3VG|_^8 S^G\Sq7Y5f~b gNBf _3GaO"2&.y6UwBWoP*CBHLG;&e(Pjtk1Y1(qz{:$?"VR[ eA  8t>  ^C   w o!+"+y#j$$$%z$Xe$##]6"S!f }c@h K t Q\U}9KdjG3'N | $ m| n f0<'8KI#0l'<.) \z:8NFeq -@r7lsZJ6o|cD@%0> m U 1 wpYd-{V[$ )8   E V ||'-]Mp$pT5[G@lm@z77~V x*$iSgb#Hc%jm  ` t+ h L :$ Ih z <cs$}75 we y  $7^,jLQh>iIWM2q5WcQ g*Jewtnx_T@\   TR  8c   n   wV  | ' D f B . h 7k c nBg7V#U";~T/!"KR$%&'-(/ ) >) #)| ( 6( '1 &* % $ I#v ! G  !q sp'c1yx   &D9!FtUy!bYY7CwON^m}v*su{I[  [[ 3 } ^J ( ' O+ _ 7+ b Ea [&  l} 3 V % x0 w-}IOlBO\}Cdn9uv i49dxl   } + #ZAOYQbG." [>a! ^6 F?z\f$ R A X } o Yz $ ,rGD]eNt|3[c  =Rznc2Ty*= ^{''t11'ވܳXj܁ H@g.)+ o`J7 \ E 0 [T\\4| i o_ rtgDE 6U"x'm o-Q /V  (J}U@'T>uZnfnm l  & GYB*(Ue2o6Q( @L[V?C  "w9tL a -(z'_ 8 y,p;#,i"  Y & oCaHU*  ' }N(8_Bq>j>1fZ)0*x!bD>L 1yD+M/sjL S8(&LV <|j N HA<jM. * QHV}BW4kxF G 1%Yi.),Nz|4<;1`0/vQt>q8_' z7 st/V)7b1[undl  /Ae.u= &z f q T KTw6!,c VeA8Hur<3bHy   % RT Y   P O ('|?JYgWr"}pdhegmt"fCP,sjN<, i T X q,      # 0 < 1 o 6 K 2N"~Rldf*{16n-%/لxկ*~fmGѐиb=iУhң$՚#/"];B~QV.m%U#va2i([ YP-sctck6^AUx*  y H?Q`]N#"7 |=Zz?0 U ,ED#H]rw~ySyZnLg z0(E?Yks$ x] ;Evqi<5(GBQN  w & i ~ c& 7C C  }i C  ? Fb!;^RPe5 5DvThke vT*+B[39 E x 8H} g_oNju+dV^|7 5  cz X[(+: >]"#&%(&M&*`'0'K'j5'&%$#g"{! S)2 M j   = Q ~  i   T= h0 n,  qr0H A|THx BY 1x?Lg ?j  uJ&B9F>(  W  z  ItzZ,AP34,s>@zK%qz$ VB%G `ssU- n"#$TT%%%#g%p$#"!HvbPA8J+#8    h  > q q %   H $  (o;& # YS ~Rl'~#l/YQG = g4 z Lp yP`S[&g>GeliGkhJXfY? 1 |3 T [N gZ k w r_zj%`I,6bamlKAF~A  v K >`J?$jna/3ftr"W +  H L_mTdB T D&UXNz|nP?S ZW^%S F6.3wJ$Z   q    .! `]G Qz8jw7/  S N|WRS*&~VP4j "J{    P - =7ki50LHf`FK<,XJ}f   x$ Bh 4JM[ Zwc%S&bwR-5 cMtx f M 'J%lCB|i;k mBwVduGL :R])<9 U:m5V.gPO 1 !d 0 Z c * _  ] 0 )UveA3<oyT ;1}6$r4XgGb9CINxSBh;6O<~Ex`1aC!c[  pbBia q!x#$$*%ku%%aV%$a_$#"'! wV`M3X h3; e +H  N5?oT {G:yf3#>H^7k PU=z|>B M *^`~ڑJuTԫ|Ytӓ0ׄ0٦tb ߛ's+?Q*?)e~4i.rU|4cR*U1%ElU' D- QoRu H ix 7X &?cGhW/Y E  Q9 ^I S 0  4 H *tX\{DN `E f" 4 L q,Q:4`H\lZ"=: "1,z,Qve>L\R [VKnTvMOBXD [l z4 X T t' o Ci & n ^ w zi _ ); dj`o_QE8 ~(n  c v 7J "   c"Q # _%8 & K' '% ' <' &%$1#m"&!vj@: !C_!@c"~#g$$$#K# ! 3 h gG 9 f8  y - 8 gG  (i ($BXieC !!dq""K#d#:#"%"Q!`U+oy= { M e#I3h=0tA'rH9 lM+oKR'd+Z%ެ Lk fwݴ5URI_C[M.0"T 3jaw*LglG]ancn0B6#F#_G5 A  a    d 8\   @ [ [b :\=|@q p"<#$4%1%=$#"@! 871lH\-  8z, Z]QoDp )) Nm   g  h  ' ?K g O\rMnKi^1,e|dcOiLKJH|Tv*|,`4uW<ZhnY 72   G :` :D] 3c {    wJ(X n._|!?"->r@x-:x~M>:'? F @ L  7 |W  9L" B    Y, E sM Sj]W3o `H8$=_ n j LeU.73\,[<'SS,k6]~ f)J}v nW0 w zp NF'bO!eZ:N  v X-4C_1Es  Oz w }6 [_ n niyinXp\2w.xDu#rJa;n[U-*,k+E]8 Wio['&w6WQJp`C u xq ]4 Q Y- pN ( |# -D % uBZ. p HInw=9-F^|*R1d'X5jMz= VC anO3% $ w  7 o  o F  @r <!rJ""j" !< Ta)tIgFe) l :-}CxdzY +)v{qwrO6C#$[E7  ^b.Z8 " vLe<+AytEPqe ~isO]FOP}Rp/K}4:%6Ivv9s/k{GI[]jI39QiLHkVO(^ EWH)NhxE'|`F6& ( (( '!;vm z.oJ !   9 ?  ?S=_HKe_xqRX,w$0=%ty8U7]l[nQY;Vcr?,7Ul bvj?8M%)_2fE{zWBB` o>A;\_+~mR*zh x9L>?- 5 6==mM26{ /   <.Yb    / { Rz$ | { '!!!!n~![ t ,We  d;!"""S"5" !Q q&m _ _ wwU\D`f}  +*8cq~d@ ^ JK \,npcZ<7y . 1t [[ $ >tPb93 yq)qyH@TaMb2K"|j@HO @DsYu!&ehm!# '$WI#Rt+4!gV~7C8>YY>!y\ a ' Y n . u ) ` V n<Jt| H   i" NL)V!"b#U#]$$$%6D%[%,\%C%w$1k$#V5"{ v48 | 42Z]EPxncgq}  X Kc II %    W >jsHJ w<lvhmc&cHi$yR( M)uh?hIkW]|rPNB8C@o0<(  =:  f*j\  / 2   ,/ m  +>$Qv5 \ [ O/Pg"h99]P+1R~v Q * g h < hJ a?D6/ s O /   n  -Hvo rwlg"A7%Iz2crRBbgLc2PN%h  +, TCu9b08d fv >   e k|1<4hj.EB\lX_.ne>Cm:^W_L H > BI00 6) D4 L 3 + @S 3@<  *  c  Ow $ 9 hC]Mzw HR 8EX!|g^.= @vu/8{4~Oy B  ~ S!BX Nx{Xha!CGdlRpa9`3 ^u8SDDHj$x0 ( 1  'g 8'cyq !r{r8& %kdk;wmKJj?0KzI^8CTCSk0b(]fmayAl vpFxW*Uk7 J. 8%1L52/84-6 6-0HWE2H9ޯ6GiSw!`mn!ib4wN4zC { O 2 JP K ?3-m-+<e3V u NR2z6g&T\~QI!! m 5 % +  | (      oy((cQV~gJ7>rG/+2h- ߹uވDz[Oe&u\ }HIP#7:SSei;4! *cuiO/3/TB'C k @ `޲ݲo!)i%opSRl#^o}  76a msVv' <5fnsF]m+8 L}gygQ* h o ?  { ] RF J 5  s O !U " $ n%H & ' 5); s*'+Y,-9---~\-D,+x*L(v&Z#1!QC G[=c=^  0n;"{T VV5`q]iQN/o U l z cm3sYS^1- > a 3|  _4  ^t_MK p oiO06NNi0^k } 84%N;RkH7%G}o IK` "  ]  3 e8  p T A {t4#W@[% >\=|EI@DU|f:54o$f%Lfq{6>JsQ$Vf+ s U3q?P-Ss`6[~*[{Y  k)^oV7$n1Z.YI_hX G R N H Ya B 3 3U NT I6$d?ZLWU8l`F_c~H]kG # !2 [ - 6 ?3 e y u Xc <  e M I qtJ1m81p+G][@$#BqJ\9AgTLeFO_oB{Ki>LHQ?YDzANg,JI4   :gy_{} ,  /-j#6 K(*3/d45% 6F.dK$-6D'O m9 z/ | | 6~ Hm(Y G pzUe{={ S A $  k z}HS*Md<4fZ/OnL8V b~%*=atcwv<)`  2 v B{ a_~(7B߱fh?ܮ=,U :{ C81 |AXB|PX.n{ As A D;U-"lKw5$ #C@J3QN8 o&S F H ~3+2fw ey go5JcF_YZAv ds ^ %  ` 7M ~d<>} R 4 R # . }4Jk!5Y[?w`G%d۩KyL,3k۶iޏ]DLkuEC6_]b*= # +5   @ z߶\W/4O byS"CG'jg or]   Yt!i7"$h;'e$eMy"i{dD)Vi,Sް:f^89YٍS 76۰5 Y| L .z* q  u,S s_E }O71<al877jz tu+qFi!?#+%*'')*,-V.//x/.-z,8+e)d'A%t#d B  oH: ^ ^RR(*^$yVjxVMyF x 7 ) W  / \ c < L !  ( hSx*jo@ ~ @ L g  J aE cz 2P 1Qqk r6$PZg2JhK=rF_z"zg*pJ1A ,  | (xl&f7 8 N B i?  8 w zde _H%7Eb_@}+|.  <?HBw3! duRR}eg!"]!v}c$g-<c0 r io9 "&lZX=gZN, l?'. F L 1 a eO l N  P @ c u k{0_U[[,"f.8B6Yk9zVygs^#VN}7(J"/; o D+b2rea6}Y^F$o pmh  9vhDeTX=-' n%_=2=fe eHcte^<pr E WikWv6e1L' w ?&AwHUBila3'=y[<_ d d  ( (W6?   : q T cM%Ss3 #  r? \N M; (  w l3p;8ZG" 9Bb7=E+F  (qeU]w@t}bGKik=OBS8iLmj=5Bk#'bR,/l? 3MTe( % TfJRx k ?%0X C6~P ; 5 6k7y).I"=&O }L P J `m'?= uyNsJ,w</ ;^r_kKBP!t " (i }c"PU=*~A:g|4S1^^A$n;t)OepX+[M<[75pj8# 1nJLEA eF`GZp@OC %\>UzUzhb5ng 8Mz`B}&  LZBsEt!H#\%&8((%@)U)xA)p )(P(^'M'H&I&d%$#t"Y!9Mg9 V   a 2 o N  3 F  hJ i vc >  j  ; R G { ^ X F q  ,F I   PQ    . i`z{NuxUx*`J=>Po{  _ 0 n|9Okee  G " 3X \U  [ : 8?=k]&xCmPY0Ig==mlX Jl5&ftX<؎+Z"ӥӅ ԍ!յ)#_%߆~EyPBd\+gQ GCMmE !**"T##$5$^$$$\$$r$$qs#F"2!H r*Jzgvm8?)D' Sn@ZPBj Q.MhMbt#w(8 j ! igy\< ?n&t= 1z8Bc>myo 7`z:q  5H olR-==V 7G:U   SR-9|yQ.h83#SF!0,9Se3 * `  D , (\ n  ? < { _Y# Ct ! < q  8 Z  N ^ 8 BxglZJdM@t!qntI^x}_QUi]O[NF^)/MKZC"7BU%I^\6Gik}g\. 9ZC >/Czpmn*f|v(74)Y4g{"g oO   {^  7 x     [ N    vs % { $ `"y;l"  W   Z q Yg/` $cl28P90l  "Zq\pcg~dKkC/]<gU;bWS#:u3#-(soG'gD^mA~ u*  4 ,  bjP3J{2s =~!:"]tXKB}8x) :S A I y 0ZYnu|1|dP p 7 q 5   G0  [ C g `H$*s@Ga6&ovOAW.qd2un[iZ}H"B&461-0rCO?*&efz(L :RW\)< YEw\>:b2?-18Z`X*N V D x `  x 4 sG i YUJx_ I4NqN@)&AAk Y DN bS]0\.J81xxXw7H/o/b|y{gY)k1xbO)] {o!8R&[MUTJr+JޗߕDwCr gICuaIDaRF8}d"KY;) ;p^ =OdC !P#-Y!5Hc:   m)\!!]#$%Dv&''.'t((Sa))I** * +*[*s)A%(e&_$2|"A B\Ab>J)l6b E e ^ KR aH 7   c3M7 & $F W B I  W  i X  +    & 3   Q  pj#AAs[wyM 1 ~ } V] n o @g h;  xP/&\NZ3g 7:*zH;R[#,q#va c_HhsTljfQ>fHUhj߈ޤR@?ۊF)(?e!b]% R Hd U ( :H x Y(g%"| ^ n"$?&7(k)* +K,,}e,,+>*)Z(m'&$[# "W aM# !^ @" j h  3  =+     FIUo+1(;m)g F> @ C A = 7/1C?GA4)%N(!4$CMWte*k@egcUVOaE.&F} {.PX  qqXK[|{\M6 T cF H f0JJQ?k66S! o2F'<;}yk;M - )E 9?     D :k;   W  v b % / f O v x E | [J   ~2 "/`N_zc'"AQw%>6g9x j,>YJt>4Xt , yH,^\G(i.>jy@?M ` r  1 6 Q8EcA;%]H8SQ2IPu`f7mj  g. : _]T{oc    V OH8w" t 1 ]IKlXQcY  N \ t:?LeL0X3O) 8m=wF ~e0'P~r7Z`PBCA@ZPq.*]s WNj:Nkw8uT?A R wDQZ:0{x##l;0C"ob  g7B=qyZpx|X9 : Cgra1 T& K[.ZRE>x9 H$ xj m7pKmlQ*cCF8!IT+S x*(scd1xv*~YlYp PY  ` - Tk#I6L!JT0jpg\6 VIkQ]&oYh } ;><<}+UmIZ~ j_xf+&$  7 %" "~| W)znA7)K#^[Rb{Ge!R#eAU5z>Vm;$:o$NhW?.Z_=@?.mawf+kjn]Bq/TkqT~CD c22" w8? # rB(d6$Z&~E*g]'Wu#ppa[wF1S5tD%FLN; L l   Uj  ;u zM   N , r  @a!6"##p$/S%%P&&&Jh&%T%n$"#r"P.!1Mi|%PdnC 9 I " ] t %fzvePN QPJU=?m` ^   t$  U ]2 / M   K ( Y /W d+ R ; w 5 : k ; N q z Q3   88ikzeo+ `}B<wYyCxPMUtL_ ):Kwe{ NhjN,xs<&7#Z|CR aCt(cEJ:n S c>"..$&'(4)l)O)(6L(w'{&*l%Y$D#U&" W!|v  # 4  !6CQc  _  33    J  h d y * 6 "Q{ ]H *~MoIM#s ' 9,F+3NwHA0N$TOpgmJ92E9yy,#zrZUEb[ VI   ] P i?iQdB`^l!#W%&'s(((e(z(f+(9' {'=' '*&%'$#!VXcbB< E v  uR G . m>V5.</ ; i 6 gY9MIFz?sZ 4 Z Q '   03 9 (yf[IoLp= n  ] Rn;[k8e%c.gxzWO&l|uW1UD#.T}sw  / ' (Y F6 ` e 7 n  A  :]}D<&_kK!F"""p"R!w Y'9J\_L *  A x9T f SNs[SDph,Iv*dDg  c   V # R }z  + 5 , ]  O (e A.sH >CL;2Za.QS2x@;x2{*c3j+IJg) / f # /Q x^ H  D   C /tOw# 6_ R w} %7"Xe U4d!V=$ \I   Dz R : ]  pZ7AX[E C lF8s*Ot||1^80#dugvPk~nQIEPxs g0) vlH5%t~lAxmBN6wA;VrK0{D+&Xxg"aJUctA4wXK3oMqIt{J:np:t& 9a=fb39(B$];:-=U]r iJm p;||8_ b| ީ'fܻj݆ ރ .POW5x&IIv{+!/Yoa\#m : & 84 hNnt4N7 wCe{ B y% 0 ? } k " ARf'X~b :b=W    ,x-(, )a{ :5[aEf!E-z#-;B 7 _  ~ Y  ! D    b -  W 2"T-aMW0ytf*:g_"3| ; %N   =  (~Q\k& ;,\IgWl Qi D^ 7@ ! 9`%~a7T;R\EA)l%,qp>y X[IO^XO\b}Y Qd F 2j  Q ^ *? W c . % , = _   7 { p E H  i q   D f A z -xq/43)\&Fu^_ S IIQXmR~? N'2B ZW[U4w)T("cFAL v1e,;^  +HJx zX% h31U3NnRE>J^rnR /h|7]UBY  k F~) (K]fuy:<YR.   kz vQ=);Tl"i&F;>0-xOLEpD }hPz]   Q u$ji7m  yX@l7)]Qc^@?VI21 C|9F+BG  Dp8<@ v .-8]*x3h}Iezav@hUP9|_k_sKge+<,W ` =  # u  8 D , ^  j %  K   * rH   >]>=iW\D=#]n\rma>Q9 !!g""" " B!M  ?%zD>i  %Q\3 AzhMeA_LCnwhm!L_Jbp.)phdZqbzw%XzPmEaA/6Z~+U;VC~j!>p !O"J^x/  d] J G p 6 > S E H P S 0M   `?x:UdG_E U)sr.)zF ,8yizJpB /  l E _  W n  H   LyZ2o.?l_tl[s@R  B  +kh@^wHYK'x/+RR-'xua1]==mXQB :w'VN= yg_S/2RD|n O  oA/_#Y#RcMwP|iP|O`B=Q =MgY +X| [O3:VQ8vM%z/UN@JG3%:5K2!@ f+ 16\Jp|D"9|NN30xM*4}0jY >FE[ Y A v a  / +9 LJ x':&[qC"~ _( r % 0 Of B { =-[kq.WB1rRMu e  l   s  P   { gI P /P ]n@!K  6  J  P ~ D~ L l X + f  *ehY_Ly4 VZS=| - k V 7 8u(stF2v_86jd*ARc&Ga  f  j9OucDYtf6PL) J)Wo?=qR>?$k Vy fu MV   R>& J   |O4}) @[?Gth.pd  M  ~T{)M F/ Q p_o4sYH5tyv Q/[7uxX~m :QM3%TDAlK0EyW}%<|IkLW4T8,].C%Og[rLaY ,x ^ U XVM})KfoQ< v[.?kg='+L`mJWz7  : d h  | A{$2oF%][Y /  : }  ~kV5 LkHd{86  F\ ; W PY%N/@ JYN|9GH *R1>gA%"-+[L"f9A9i}O/z|6$8 ~s%e`7`Mt 3w55SYO=EBm :OH |;tm2,t  8 X   f f#n t{y^[& =6 X   r!t"m~"g"G###/"&"Uj! | ?C"=Oq=J 6   iP95[ >p:mlUn|JLZ Kmc5e7~2&ZCMFW/`rT2U|z"[d+8Yl_N~`]M-Q{w(<*6 d[Uu`Qe,1 z`XiQ>,UyOo Z')E IB 7V{H.V.mQ t1 5 :h  He   ]`   $  ) j  g =={-Vd+nIKi' A Q  ? k ! E fn C   ~  w9k6~(/]C~K*`  W %$<iSkmyl5!gy}fxB};pD*m3f_Sg5 !c xR1E `!d;HK~`?T  T  ( S" V ` wm 9@,OL)*Z+*_ VZ,v$\I6 I*fb-H #5{}fY ^ d -  $1   N   o      6 Z 2  = -cCI #R  8 L ; 'Z m s ?b ;e mz v OZ 9   0c / e nte3jpcE}[ *M@R47ny 9Rv~0 +}{%GO( _%_1$5w NA /l  e d >);i  ]c P   5e  R',HO 2 c&   ?Wk8?*Z`>h&tF  *  J- s  ,M#t'99w*%_>V^A 4t6l7r ? '+ *  g `?ur:n77V 5 { >G }+ E%iEx d )0 V]'4VgQzޥ(#^߳9>1ku4G.} /9[S*+h* xv fKg\2zf9Ync5`Gf =X v   o   %  N Q .  B J 86   RuOT a] 5  S 7  9   g !  `  yVrUT v  !3 ! "L ! ! /  aDl]O BO ) y _ *r5)_b[1g|qS>+EM~e( ^="5+Wu#k)2\ ,_3F%vG3 `*=g<=xFUy}tutnl)RarB644F^dc,9'CUQ TS  9 )   r 5 7 0 .MXg_6 \]1=}` D4cMq!HlS3GGo6j)J>g&R]G   ;c     Vt '   &$L4 q S < i   YhG > :+7,BLZazZgLABjRpzboDD8]@.ERb5p*f$(6rl([^C=TH\4%H)xBe5m652g'U`JB?5R 1 O :, zo+Uot *+s_Gknf P  y 7 ," ^R;  )R eDF%(jS(sbI3"  3 y f A  DTUe~) Z) }| f `l  2u9c $VTm  | mK u  28 ~)+Hz $DH E y  g e{ , u ImYF8k#KnA,A$)^fG' ޻9ܟlLڐDY^3T^E)  uM*`,cpKKdsKXjO 3j119.q tG@'t N]#EK U P7 3 E 2?,~a4!_"W#;#$$!y%&&I'b''(<(('C' &_ % %* #$c.#^("!!ThvZ]G  ,! ! D" " "V " " "W u" !d <  S *   -F'-aOGCI2O-FF .} \ PjPrV~&JIe.4 z } t  E {.  'w s+sdim_>@7/\[S[6 <  W0^z  D" t H_B? ! !=!P#"@"5# #$[%&&VU'' '^''}'%';R&2g%;$"I4!lU6 c?z@J  1 K Y YWP;PUEd*{3 NX3'F9r;]%3pGg?7|u52&o۟dفIزؔ=د0Sظj!jڜJ;$h[ްPNPeA>fQP3!fqH_3K] 1Yb<S?gvr8x:M   c . C ~   F $ K Y N R h  I   |^CY# ,VU  ` r   l   *  5    w 'rN}`y E"#@$%5&c8'R ' ' c'. &%IJ$"!lR*WP%U Aq **l>/2pzBuVDeK7oAilP8ey~(#{޿j+ܭ_2e,܏\ܭN Zߴ8kd}{qyK~oZ.uH:6]\5XB$UjXurEu^I ,.},m{\k`qnxtrV_9ay@12 ;/y.nZE%M:s. t *c*k Wi]wB+[[kV({y<#w  X 2  y W O * t v  W t 7k C).Kfp0<Y`{A!1v]@VRr|H{+f W_0r3"TA6Dy~?Z@,kN-W6y$YOIFv>r M)o k=-9(;*fKc WP FQ    6_1,W`JH ) q2~  + F+ b) Fb^7}<TKdKFPXQ < * >  -zF_-\88CfN4s %   8Nt ) z v?$o-m E  ] $_+}* x; : 6  bI(% YdN{w9av3 t4VE W 9/R\nE]\x ;07f[p.=E33PLX!)HTz)2t ( \  z# V & < dzy'}/P=fO 5    Z"&,=F[JO]f e jp\ $!G!O"$"_##R$p$$4 $ $ 3$ #"9"im!y X+ ck `;fUHnVpC :!U!}!o 9  ^ + < J E[L VX t >N1v4a(bYt"`B,}2l ,JeKg6iw|B E^M muOgBW9)hgd %g32C !UOziW/'C^QG,{ Rd)   eg  8  FiwP!:L7y!"J$N%= &&'6(2(w)E)g9) (d(['&n%q$.%#! Q~|YFb)vJ  ^  ,   >e.T=u"^+t?!l#*\5C޵Gޑ\dBO!ڍ8Oy\Ш+S3"g:s yOV 1#q+&87)Bj+b6 n q .i    GSLv.^-nZFJ)A.{ ~  \ O r   O %cY|37 Z  P 6 Z 3 G   T~Aw`=a&7I9h 2B]"f'D()`:p#iD~|_wb K!"^##d##2#4#"! J   b \EMX s< 6t+<G6Y!n:(D C;G^wv' ދZO5ݟ0R(eޢ[ut- t`_4j&ߟ+jz> A^-"_ty~A 9yk`o?,c&fU5^FxgZN"1-i! d A B   z  G l # w +  a 4 W]v x4s~g{OW;x2;xIM-"!%G | #  Z A 0 4 Y  L g g H  ~ mO B =T^vFL0s#`S;O. @t1LQ2>OtX;t_v`&v?8 IwaE7<i K vR2W u(}/Q{ux: 7Qn?w&\d 1KZ]Q<$- :x2;[tm}8h+H] 1 F & D 1djX36 1&.s xI:. ` & ! s 5  k  # T p w D0}eIo'O]f2mml>|5?wCt"  -  ({`N c6     $ -< K %Q N Q g + 5 ` )[  c Q j U,cR_!Q"[Ayner5?(lF޻M7^O8c+"0"rhGPT(R%vISWI]![ \yla7jhrheh ] - o 2) c r FU  X(  St %~ztvD"Ev*  |1 \t i u.lu ;/4?`'cI !j"#$*%%%%%P%%>K%%w$ $ # "* +}$@x'}M3?u *0  ($ P E 2 c ,   * &3HT|@v=\I  w ,jm;X8(zWhYUxCk.B6uB5c|f<$e~]T@z0v ; wek^J. *8PRi-!g ;%<89  O  Z-qQ !s#%&') *++f G, , ,s ,b,V,+{+"+'*@*)S('0x&-%#ci" y%J6'?a O 2z^D,I^l#5QEW3c1ޗ23w?6thAk҇T*ҘW%ҵ-TӆqM7^LNHN/W4^8MZ cVC7]9DF=b7XT (J70u g C Z K Hz ( 1 m&  k$" 5f&^d2$ \   A4  j - r g  "| YPeY%c9EmNVH?.j _*6d'M?@o Z>?L,!2e}_3p&:]&C A5= o ~  y x \ # sbN)8JMH ' sI-EN0/[8NOMgf<}ݣPb$ZߨMJubhQ|:zVG5?Kl>o)8^je;~Qb ch>#D'{/_eKG9i `wQ-wU-yjR?.( Xpa^"  m 97ddq/' N  W>  D , e X    ( B = 4 < \  H  ~ W   E R " ; , PwuM]0wI`-P~ ,t:{FN)<߬GHߟroz l:-pG05Jl0A`,+` $ J3 w:  H- |(>#8.  (   e F m ` , *L~j'({V+f!dOq66@(sC?w(k;kql_B8 kxU e  < R E  u q $ u   %8>;ik3 8c g @   >v  i +wVk4o~9  !  K 0v7XNjjeP C a  X . N IifrM()X U K &( M p m N W  : b 0 Y '  o5 K }J ( 2 |^ h3{bwF"QIs mP|KߙEN 8߳,$kcFVt i);]btDt*hRD!"Br I h;  RcC)/]0#W, ];/L7jVJ q < $zti#h\ ha,."/? m! "St#9$$[%%]%:%$#"Y!N   5. z0 * "  4 C x    !+m#~;+v*H"-]wE b!)4I$k2R`jE BV Q G2tO~PiT+&Y;< nVtFj{PU88kKy=]X2wjszZw]<;CJGM,y Ubq>SJh2x K#D]U=5+&4wNCm-0RK h \ f7D] ? v U /!"[$&&()c+-/00712o23=J3J3 %3u2F2,t1[Y0].J-+ )'a%#M vl Rs  [e2L  \\ m=*:IN-;K,.~r&d|ߋVDK;NLe+Vی>ؐhփԠ;ԡBUԀW!5(LY2W}Af% KCb*B")qZd# B  z Xt 7  A  tDZZY~cJQi<PV  '  K:Q qayIU 'X e^/fI3/Id}/Wكq}ۉKݣ޷bcU&r5dj))wJ^(;  l] LKrn[A|io/CQ b[d*B;3u,(Ii  & Lx nr'%7 F fd {  w j  7  Br?qH8 U @ +eKbppq ՆKD~&*]ړ}uoxSoq!bD'lF56?:; D 8G+geSr)P c X   9 i ` a  \# e p +  f  ) mo e3r9]J]E[ H!WP_L %~T-  "F$'m5&xqlPk H x Yg f b O 9 4 E gb  s  ` % q Q H!N|=-zVowTAYme&*   t p H'O*YT:{FjEHEo Q:9__!D:>g $ c Q k1uO,D ?U 6 P QZ R6yK:L޲q+% ;-iܷ 5X0p)CC JBZ-T*Pt*t ].e G Z`/JJP~S4 Ew +#N0 #r 4A e< a a $ *s;y\qZy  <'N4&_;%:~ c D t ?8 "P/~Cm+@O3 } "  / q Q } h   (R|0L J<eCYR6xwR7,RXmf_3Bw7 Z8 ! c"S=~ H@g<8EB 1}swG.`r$T~] ,/;R{^R\"[01,sOVlx?rOa6?_|Tum<kWSpAGlqJ/'F 4  55k G A  $Zl "Gy$@&'Ne)*->,-./GW0^0l#1/100/.K-+)h(!&6$3R"X CAE<~p 2 4  l3>$MM$!Nb%;o,(gZq~3LDRc cA,7T"L@c:hpژ;OإH׋ օ$=@4&1}i)j"0:ޚGn,?NR~yAkEE;(%+x~*/ _~4e3 D  n B  }P +fU6-Fi4  vC J 2 ~>!!r!8!""L""!r!0! W:|5 `]3nH$7   !] paM+ln"EL : b  H 2 C_Sy9o R  V 6XY?_RK - Gp-:! 2"kDzBs@k"yxx U? &?eNT_mpwjR54fA&n7>ݪ,_$XKףq_װ]mtRX|l5_@ܒ)%`?!;{E@WFf  jRU+}?Oa(A?Hge+, br  %9 ]sa Mq>?G [ I F6 DdORWm$> iZ"m&j U߻Sݰ۬\ڷ2FhY8L9Z0ד-uۯr܉ݨ"B@;.8a$pw 6:x]*P T =   jA p < { ?L   = Eo @ 7S +  u2 C  &P : R   p ! D 8 aQw$D )@o|V]lA*)v4u 7m ;_ CE : s=Zb|A1g1bX40xu<1D  6] KYEi rQ<y'G0CS/Q Gq.-@SWv@ *ySJke~W*Hz<F m q Z    [( "$&kU2.2Q86RP@ dj    9   0 k Y w , ] * bc 5"?k ;kKCXF+(3 H.NSTkV|) |u *%^krkh21bfQMG6*D4(a:buWyXiodZ0{(6)QP$TGjQ)rI k) \ H   { S := 1 6" O ~ a 6E6x#N)ELDq665>i(}{/l ~0W<Qwu1Y+< C   N\,b\4}+]ys%?7zw\r1=!q].{a c \bB5{}!N&^E0Rst]MUT:LF< Q@jkgE>'FL =f   R  j3 " R!D"###y####w"("[+! -3l=bpx#,  s  _  A oqyA=:1v 9]   R XP&BT6SN1U!@ qXߵXސ@ںS{3mpWok05M ϦЧ@[//YF@zyh'7[%H %  e M ,LXLQf;I) 7!.;"Y#e#5$$V#i#V" ! !U 8  Q[C=%[W=*)}R K RU nt;5  _    V9M8S,R0   ET s;ts <-%|RCffL;7O'jW'_\/<aOfGߚl;Q۴x,QE AF%eדX B֣֙P!؅Cm]ނKEn4'1ZYOi %13Q@#A,' <y'&>%dUWx(+:[&s8qV  H $7 9DxI42AHjVk)y" "Ix]nR8O]]e{߬C ߷%ߦx)&?bzH5 |zX&5Y d+#W +L | Dn 3 o 9gTR  } e &   % 6= (N D u  1| Z l= aw 8s14gP"$ e41*}yP{> ~uBNBOWROU>cV s  ; r 33ojFq\i tb$}w4zVZ% iP  + TSE3;25M H f 'F   1W : ;(   f J  # $ n.wR6qLni;ZQ5F rRd.&@$4ZfAM p k   6  &+%(u4A?;e.t5 j Y P ]l D<R_xVqYT4mId>d%XjZ1 /C c . .udqfK~ B&g)cDNCk!5>l\6?JTfe>#Z,EOHV,^q;Tplb,E( &tV,~ MSZ;QOxIhz_"z+J +  a  + e>]_&u.vnI?x=nl#Aj$I;<j9x+ <X{e#  g  ;   3 \ 2}  y.)  !^R&L =b jm߭۶x&Ӿѵ:%Bp?MkH˨nT71y!g$؅(u߂`T6 [%%tKYnB7 Zi z =%QiGv!G`,>=28083o~&$m[gt:lq ? :IYY "V$N%^R&'','w''' L&r 1%J #) {". !boGD 'WX%z [ ax } h  z I  = U b  RO  g| d>^8h('"+?E3 Q \ 4 u   k[m5H xzG:s.EV4n Kv*pmhަb\J|ڌ,t}aoNC؂EFoEQ cNؓV۲܊}XH*Q4}VUFH<nPg    ^  W q A e  L  xwdp`ja`Y^<qo|y(f6AlG(NaA_]BjA11,0Yuh|:a8`z{^4dL}n]2P0Z/ZA>a%T(\L >z, L+-zs<UW) U[4{ m hK ^ @ I   (  A  qtp |}{J>:5NA' eA   ycE3SuVRV [Q/F"DP]:DU[ND{ $Z; 20 Rl 3h}q5jtJewLQ1Q{W"3fe8 G  4 t @ ~   C  p T .# - iOH,`T:xXg8Hj3Hq%b?%iw|0Cv \ 4a  4bJIzBM jgDG3GzBJz  LZo:3\"k17:[-d  U( Y/1C p=AHL0oy70rX c 6 8 5 1Q  T# ]p  Y  n{7XR<SW&{MSh  i H wR R y %3 w 'B*@[W, .G WP5L@zY MK(A|*,erl vNq) ({le1Y z  u @L"0U,daTTMphtj,Kbqh3pTce7_u$o -UY}E1;u'6 <ID$vgP,CS|)yQC`oZWthXsvTNjT(/IrQVJoS #U <  M do; NuWb> ,-!:!B"H@"o@"%"p!+!![!7! ' AZX!-45SY<=J3E55'_T i  # ; F Q c rDy#T{D26Oe1j6mو~kftМ]Tdz!ʀ0*LA>̕nJҙ1SaݪUY&aWP{II$ MM:Q F QC VPU3Yw Drf^IgK! r Z'bRz  D%Gc ?i c!]"x#~##*#>#"N!  R(   { . [ : 3 5 ,;   pd  n ij    1zno[UI  +n ~ F tq |  s    y  p   5% R) f  ] 3 y    O N   gu5(g~nR4-s*_eUA$?u<`8QHߏg~ fݔ+0-\ݛTDޝPߚޡ ޡ!ݐBsyU@4Hph٫5:[~w"q~[g5!)+W^?@uni!PX\+dC+0:4oQ pVmITB.k'@0ne"=FA.y,BYVD~2*m G&oeFmq%wrq 2M^VT[ys\ iA H+%73T  =p @ .`  y + B 5 m  u y #Y ~4   +# M v3DgwKSR:NY*2.NmJ,Mv k F9  ?b [ynS`Jx*߯_ݩzWFޔD+!acY*(8 p l b R F :] r s K , J ; E (> ]^nI#X .A}J P1&8p]L<qfKY:j|4`    e +  G   9 r  1 S   K )hqlyd(YP2E " 7 ezx,t@r:NXn%K9u\ihj_< }m N 8 d 5 h  `"3I/Ad1cQz;V Oyg_RKWq@LD8<k+ ER|!On|r'Ia # 0  V k E AYwT&Hdw"Sm }(,.W>{5-V,*~V;tY-G I b S+W%q C <}Dw K 1k5iE> :uh( @^dc\TDc%$6be'Y%#(>O/]d<`U2PXjjGDr\R^6kF HnF?cA R q #  t& o 9Z &d&DAH Z  R!8v!W! 9 y }2-sve~ 6M?0*P$:1DU [d n o `c  M A T xm*>q'EaT10]V&/\'ۛbӼ|C `в4΋ʹ9̷˛e#Zp !ԯ]֭JOj%xJ{$_1 &S#] L`>F k  puf6{$ zs&W:usk  % OfyEd}lxgS`.J3L:TB , sP   N  ~ V  )t *\ j    D> x b.L7thT6 FW M 6   [   | ^ G 4 $< l   Z   \d  l 7 8   T +  | ) P)anUaEi]Gs8s?TZZht.߈i:zhQ.~Jx=~L 7ߌ(,ޮm) iߍ*u:&hWnaA@?n F?b a d D r p( F Z6 PziYt--#2E{[j`. 7gIZR IR31"R$R1)Y'e_ED:[] ,Qp-M s 2lS Lxa'E{m/hm(6`V3FD4>*'O/" fJ}{GB   ! -Q$Ir9J0Z5b<ZE(q9;  M %!V E! N! I!, 5!@ !H O I 2  . P  "T -*0@{5oE^e%1EBv=dHP`yF6 Y c 0.qT!MHJ2vCvR& APp,rޅ{ܾ2lۮiOݡ+2?g0Pz(`6T=^D/\(/b^%& 3W8y f i[PHNp(97%an1GL>! yk  f  A   r /   <@ ^ z< o;:| mcypJqcx`z&y NDNx~8gmO!A{uU6GE$^~}7 ` V 2 e wJ/]s4F}"2u}@ r8g2'Tx,(E!;AD0 twUTTp    t ?     z\2^u3 IAoo@aV&6V&eu:wD5\\S-!q 0, R S8hZ6 X-ZeS9U[\WWn\dlM%EjQXJF9!LN|+A\i #V :uw>r ߔ<>>N;rqFL4eg XCF^T>&knF : :k DRSC':G J+ Z k % z Hp  qj%T }$x>WX\G HLp' +{ ( -  4 Q % S > i M    U  / x   V  z 6OE-5*    o s . L qs0m|go [  ' # [q  ;  # >I R]{Y@3iK2tUhw{m_Z7:!Z.vg oJIg)}{3t'o=N%D`dR:TG&1im ^VM/{sV??-K()-& GQbPQ|We|)~Mf:?; k M`_pFNaq94!]wv L U|P1@? }+&0dV^!|4*=BOoV\X[W= !I(x;UV<xp- s> [/ %   7 pC B L a h Y 9    x    [)   Z R /   (M'z q  ;  ` *H  a  vgfbP+l6_qS/zLdsbAt; Y z=?iPQ?& ^d^\s4? ~z4v9\_ܖAݪ!ޠ6q85 Ua O 'Y%(OrMYA3( l]P8g [hYyQ0!;@  Kv  g  O  I   4 : [' r+p3*vT#|fB)  tnbk=R?!B*YqFtA|%F0'kp {hk-> e CL 1o ;Z I\|0u{xOc')"we/Ayimg_i'1\8gKOic~GM*m{8b13TaP[ {xI8wd .mKi|` ):c;39Po5|-   4    _qVG^K_t"|u_=:^Q}{Qf>9,ma jO(+ ( U  k   2 I , ~'0"  ',|:?Wuw;9|#5CZs~ Lގ"d דճ!8Xϫͅ@r{ʰ. ;Ul̎ͪ{ _ T<ڹۢ݌z jWE{vEtbdx{jE%uYxu$9AF-UC0}:j4>y)\d1VXm@}wT^(f&X9rRhnl}(Jl(QT~}L_M=|N7u)JmAWR6O g  e&+*iDcCx,L -E  y S ? E  m [ D`LnhlAO]  n '  : 9   u f j  Z H  d^  Z ! T!d ! ," " +#> # # #e R# "X " !g=.d ~R ] ;S )=/p&SM rHK/6o mWk"p71?ߗU0NL۳n=ۻܘh'@Cb9lGf;g H=F{(iu5oHc\vFckO;I #>Y{<   O ?  BDgqiK 2n` "n}3WA3gj~[SM?y>?3[ F 3    Tv&rB , f   LS  O $ s k /  0 3X Mv Do B   M  <  R*  J MG~uHb@:Itv/>+l 2 l )/ = +g\zh%CF3wF  ap 'M   RP ),y8<(D\aB   ; w / jxde pDp\ " J gR I ? ASvj}<vb>c!q6w 549Y>_~l~'Nc/R@+;4^gbO[%)K{H+;U^\[`@-RZQ\P7y2 w%?dr4Ty17 ^^>)"l.Tg8 FP^ARux2{p4pSa/    ,A i~It & C %n nyB:%hW<F,P wDH)'BLz   H = 4    S~   B | ] 8  p 6kc'%) l)cH6[OS rI 3v!R;Eb6Gr_5 Kct;&ڳBҡc Ј hϐ t#&{JARf|k4O o ,_nԃ՛׶/>?.AۅQݑ9-}H>D} <9vIY=fqTjTqh*N_nG *pO$}zeK9z0B"Cr "` +LTxY*R4y%b~ uNfrA\""7Vjr{߄ނ{c%: |]ێj9ܺ}3;y޲1iN^GKe[Pb 8Qr:`{cWNg?0.o{Zc/,[sj6 2)Rm`n3{,]}20uG?]&*6J-DCj_hyehJC5$y_uK%@;-!%BWs5..r. / d P  \r+U2,n!=b|UV;05ME\2(DA.  !Uz!! " " "M " !X ! !  ) 3 ,I '`P-5> _ S 6Aa ]2L4_ovsmS|PjUM8 <_#{|>W-U=}VMKx(gBx[!Iw%+7/{kmUd 0Sv@.*s&oz!(ecAgrLLH'd|sjfJs&(}j-/tnBO3`Rw{si_"TI1Q 4-*7AEsG@HFFVOr{kN;SQ  k  h 3 , i C - b *2     "7D.,"&zA  X L :/o&^.Xq=' 3NFBL  w 6zw%=E&,bK*Kq=\ Z?} I {   X /0 ]c5v! u` O 2nuwt urm G9 D h )XW(1[DaCY7Yނ޾߯|' % $z9@-41W_5yr;j C U"TM]UQ79U/Y `a@^7Xqw~:W5qDgN #s/A=l'H>_nD(FesC7'Gio& W    f 9& G o  /L U4}9L$vngk9rW < <  ' [ w  X  : d-OfVO/   !h  | ( 1I7st9cJ+P(  W \gQE+q<*9+K{u$e3Fܦ^[l֕gT{ӬUFCѥ p6 2ѐp|хҧUJӔMJզB T׮وzTmܿ2]ݚ0tT@E`[122[U=G Zyfs.1]2R T #  J ( ~ UU ' +srHGjxQ  '!!!"Z!!NS! J 3  n  7  f- <r  m  e ){!RFYb)y_)t92NORSWo  Y g  e M   v9   @  L :g)(`hy)z 3   = aY}kK%hX1S0":$2Dj^J-   X   '.y1 \<r%3C$~O:n66L}y'LVE)Lޔj[ܠ'ڸڋI9صXٌ[?AYNt=, m 3=@7=lR"RqT `b- IGkI IvJK[6^(8LADH\6,`sTUk>.28uK,^t~ZJM?{6J\MSCpRJMk2e/AP68Q1\K 9   ;N  LOnW  !A!z;!3! {iFk9q  D Kx   T   FW :"  e)1x+, e .[&ZI[el<RDm2, W b )}Q>^o'aN.jX`<"S8 W\E%\p;L[}Nz|a?*@\pjceAY (H*dsw݂ݘ ޮld'Th(:PlZ" 3yPU;|1Ex#v1?Qgk16VQ4u* e~ ! w < p  ( l k _ f u #O ) X _ >3  J  nh"/I 9  6   S    NX  Z - R R  <j6-Y. =JhtnJ9E6 * n % %#:L,q Mc? ?!!"".#C#<#6#4#6#;#8##b " " !D $! 2   ]  !9"  x b L X )  c 19Gi;t[U]eRI`"G |eHHr,5_JPf_ -EqCS*E4 5*6u6#.I] sZs>^xgr1;7$:@  y>B.EUi\2637S{k2LvDAsD@ X^ X)=B@   W  #   l  $% n]Z35  > L  16 o $ sQH=Fx    . ? T C2B(K/m[aH\  n!!Q"b"8"##"t"!:!*= W.t(b1% p 30do?G)43|{c7n5A6HڔQoAר< o 2ҙX{KXBͫ+v}!bˈnnQ~͸DWa1җԝ/4׽NKn ޻T@r?!IL:JNejFk  |  D c 2 ]Ld (. ka!""2"# #E " g" !x z! e  hg ^ r j % u " l  no*_#(Nn%NXx S^  Y > " } B q D : O U  }I  ^ W ( P~d!] M P S d  ( ~ G  [ O h \  L n _^ m YgNlYqh9_S d X 3-'5mrSY_OJN. IQ(oL LG[gU E~>VC.k<}=%-(BSa~^gq1#(lh_hijj { 6 a Z u z  Qd*T /ii4S'Sny[jy 9_f5)\l"pC4/_1af'&8n,ܙRZX<t < G A Y" ,~Z =z(a@`=/>X]>;>6CD TfG2-i}@fY5bj1 %.#9afSa   2# E ]5 y ^.Yi4 s & | q 'R  n   a !G   .% Xo R ^ 2E^~)$ -A5}V<#a'Z _o"7  B +  J 1E  1N b l\L/WEa e   vS[E[T/dU  XdXWIgC=^KIZh*nA\M;*#oE#$:MZi = 8h6A:S~h\NC-1'6 g_0ya5iv!IlwDMzB?)IK4__Fp7YB% Ynx`ui!ES E7K T ` I  c     ) (  ] q >  T 7 u 8  ' r D 9   Y, r { ,g  } }[VbFN8>-^%/# !!"k#)$$l%% && &%%%cb$#Yq"3!UVWom,F' [c>nt8ep?D\ kܬ^z@؎BlҏaѩG/NͰN..j0#Tʷ?3˨)o`bfά VE6ԭժiJ<?+A"#}LM2>"h~%Cq!w8SbXZ =  u   e I  t .m<bJ  _  E7  r Z :w  & x S 6  S   n <    j g W .  m ! b  T t 8 Z   t U   * %  z P  //  J U p" Bz * # 9l=7  1{ C  f 7 ^u r  g  CK"W/JK^]VF &LAY#E j L  d IY o>`A2j#)qF23hK (Ew`D[(lmSP&[{H>w?C  # k 6 + f  f ~ i! FL y } W  rZ  w \  \S W0*rOy'bX7-.GzXjW BI^yCxp@okj~aewe&7Fm[{ 'q%wAf?1;HyD+g o % EB  % v     [ B 2 - s* . A T B_ f q  c (  $ 8 @ I 8 '   R   D     < f D:UtoZXU]fO(]e !1#$,%&'$((H)))Z) )B(*5'R%dl$X"3!Dw;xr8S M "dD'Ayyd K{wXE78w5B>aB$Zkz08l6s1Mݕ c;`ܺ2[ ۟OQܻܛ܇gvQJt * ] g L \ f2  Ag H YV8?*ZyG^Hr,hb8!8dR _Q'^)uM0 Z m .^ -      X r x & w/ 9 =dw>Hmpf'RxI/hd>-/zlY|fKB<2$K  , M  +6bb-0 GCz 2YZ*7OT7\ cp1K6Df~ | U< m 1$n/Vs]ci\+ck/8~ (|( E9%:r@IdiSW t_LHH8g~  ov(wv5G@^g]Ci)S%I p,k[xU|Wg_hlbZr]aZ\PkFEX OH zf0z(a/@\v4phQY%k@'Q ; e -] 8 M Qgc}!(>Av5]abtY+E F   C] [2Wi-n3R $!!t"HG##H$+$$-%9%T%ka%g%k%l%^R% %$#4#P"B! YKCHh)  D( RHfc?MV6dJ|`݉ وT֏3ӢgB&ѮЃYPz|1Ί?`̛n`w̢CBh , ѫ*=Jajnviڗۀ&txH{I8 z n   D |    P  - | .D?VMOB.3}U>u/  X~hP8{I i j    *    l   -  L      ' )W  > X CE< T]_prM(>  q }D X  4  k V GD d`oW@ KO]TVBBRw2l^-\ g8kL" ~ 9 q e PZgP> 6;NU][a?W GBc@83Est\W /!BE9R N @  a ~ ~ # | ` # 6 *.ZM#VeYG  j ^ >C 1wR+dJ<& EX@!%$3^v<58E&^%wus;krs#bd;L{.Mej."%Dkg1ns"d| ar  9 H W S E5 /m ( 5 ]  $  Y  T Y D kN 8@    r M `0   \ D3 EL^<PT.gyv8$'29%!0"Z#o$,j%D&&''[''?'4&%<%#"B ZZXp#S7Vp 3p L yv0O2v }3cT_#}w2MA"4U#^P~{ 8kvH; >ݝ4bۭ/eWݧ (ތw@O T] : !  & 0c !J ` :   r@^Wu+z5$~`;MQ6| g' pGn5M   r 'uxS @x%Z&cEGzj\!#aC )_BYiUeO73y3-hk=Y r  U K | N F  P > sY 8 /  75KO[Y (T }jY9pvENDeM; M  1{LKmy[Vbn{ v - ^ N '+ HC iH 8  T EM c z | I. L , h8Kh_kG*_P]pq2@Jb 9M+J &9]L59_/hlI+!_N 3gSZY" 3;oW v* |JT)wzPtW|ztKl-و9cشC^' w7)% 9]ѫ-A>( `л2;ѸѩүӾr@ :cw|}'݀ޓof k%Lw: - -]/y2=! qw .  r#rd X<\bL$P[BeLvAEK Wmd+ J 1  &  51 K 0h  3y\F ^m<cd _95Npw *7Ab]s#dm6gk \ ZJ H6 O e|u@ 2O0n<mL%w,nA-3xJp{}Li/j u*=h. u  % P6 kc j ^ 3  f )  R  L1h W+qwcg[;M_G$T> ea?(:$jFJ@{S_3P>OwM; z L B n {(G~V;H/ib`Me=]<\TL7]Hx$r=icU:yh#5YI3idv`k:  P*3&#eHs~"LGp d< z2l^R M P P H 3 oX};`Vw   tt CY ?5_;>3. C~DM?dy< q{9d#l u!8<" "#$N$XM$#z#m"6!";!/ ?^{  tqNZ`8yP )%(-,2@ߎ*݌c^=IY:޾:ߠw DT H YV x I ?<x:ga0ZkL:<_ ( Y G |Z  E | 1o-O_w[zNbhB]6]0mB}) g 35 r )r##l,7x]`I2 (F[eu-`BvqE2{ > R 9 Q Bx B'c5W"@M  *Y v^ y N># +?WTh({}j8 5%!\!!!!0! Nm1`REI  @x&Q    Y AEV!mN4{r&R).RZ 0 | vE r= 3stb?2%1 s?HrU i>@|rdCt'@Wc`1W1F&*si{t*,%TZc4xPz/dwnIFXl,*yA<"bGuVx5'6XC%FHt>d_j @f+a!^X = d  E g  r z 3 I 1r QZ[+[=>#!: FP $u | (w 1 9 A N o  2![!t!!`u!T!N!  ]-{l4Vbh 5Y e N09CA]w;3pO @Q5J@aQ\^W)maܐ5ܽ&Jir؟Q;ֳHG>qT;;"T6CUt.ԟuMAڙCz/ނ0Sla t B T`Op)i7>31` h 6! !! !X!![!!  88l(zdQ{r+V-Z*K  F.  g$.c%F$9U pxS/ i C m< 'T )=!`m+8kr1Q\:[{m; ?  p(sjec 1~ 3ymVG;03KFbTg$TxZ 7 9k'[LSTz%V ~\ C 4+x}Mv,SGv  S j }'pp$z`5q~ha-suT q! K6 4H #a }5?b$ no@@>f"CrV_Un FjW/-QHfy|S w-~hF }G;5+M=-[\a39$&3b70()5JTvepjD>uDXLv{iY.+[voSm%  4 6j   /q  E I!Q#$j    x 5xB2wF- v|Lj5t^$(CD|} vLzu I>JUpxyW0ioh- &0/ n  s vg#y)GSpcd86q K 6$bI;_p,MV"݀2m^W,Gl/ݵ0]ݎ5 L8 le ݐ ݮ +޼s޷ޒ;WSD"hLm.6r3=v6obP } ^ f -!Z>0eot9 B  { t @ n % ?% "`   %e^T=&W-K[GJ   ~ `Q ^ }    !$ E! X M 1  O!2L  ]N Jw q > # t  z Zk &  e / v A6Z3n '[:+Cn/je9(Rp9{Q2p:',A$j ` % M a a Q -v!8'\w}hRXTHQu$)e | q| :x m [|VVt!yt'Tߵ[ZU?YTKܮsLޘsZe&b\V\tT!R?} Rmy)K`b\~D=CfuXshG)4Di%T#F93CT64DOvzl=dk~:':vdGwkw|?.zf?ih ? mg,   d & (  ] a  Ep X +7  z &YIU%_SePGGTI - m| )y I y {U? #^h.k/1uzp _gG9&  Gu}!PKy+5=?:r4J,5&!.^.Ltc'k3`޴O,U۱DQع'7fj7u0D%X֑%ږ<$aܼI޸[pa fs n kk uVE7LLex :#n, u ! Y Q oi^&\"G`Tq9 :6hst&   y J*^1+4,3].!S$A}?Qx  z_"i(N?RRC # c \ 8 o l(k?oRvL0U$`/O#WGgLpFY^sueLH<[ ! 8 [ G|) u)+G}6^Vf*l[iym ~ ` AB:_]|qb/- = /" ] xh}&cZ'A`l]7 X{(UdhE  L   1 O^ )xFA cHNk>^ & q@!!"ig""Rf"""p!>! f Cq?8%}3y1w-wM7^,$L qH=R5T"ynv 0 & |   \ }%H p26}"oZ8N/ dhXr?Iz ߑT"0&"$nKc>S=Z]أ H * \u <|rO߁][*E2)}m.Kg`j N 7  V DX{ZHfJhh '$}%S; d0= , 2 o ? A |VN!yp<nx<M g p   e  _ x  + (v I \ W 5l  V 6 $ + g   - : X  < f  ryjQD*6\cREoi|S]-5* P_lJ$(( jdKg++P*A- 8U ` /  ' 0 - t *E:`(aNOx2#ytb R  X4 P AbdV6&@B G,^EܞG9?ؠ}ּ֊z֊f֪sFy_ٶ a^ݵ8!N:!;C4WQ2s'2u)/1O*K n4R65~ `+IHN5>'y%uj:c \@%^5~h;"[pUjB$W`3b8`x_ 8 qg 1    s Z X 6   7 x Y  H EU H ^+ [Uk<&QSf}%,LB> w S} Q  C?6k{ydu   P{#Wrxa VkacX}h7"~OM0b-AyO>DC7K0#^߸1qr:0# h>1FPH26P]jw}Tܨ܎ ?ދ  : zL?=u7F }bCos.X+ u  0 ljHs'SjldJ44MSw 7it w     7 # 7*jb{liuR8]rT 0":x76|aWD[3 h[ P  = ` E GU]Q.4 !R$= 3{l#j?}ww}>jVbthR ] u    6!l%%1oH[Z@aTaއf!ݭr k8ݥ. ߬,{n6 jMtFQ8Q \N  tCb?vod+|Yr+K { 8 h<_'4!&,&^.4`y(l)#GP|E #f7(* k o dO 4 )p"2#7[    # hn w = %  > F7 sG$\Owj _ O 8!`!!0"E"A="%""!!!q Nl<J1w BFGC  /I T    7 L ( >  8Owq^Ar`;Ob!R=qc%@tK!@u+|Y^N>304_E?߳~Qڼ|ٲغXYAךn ! R b [> hڽ+]܇i']O@K  W$ & %  `3I0`*I c"SLVyFhC_H:cJujq{uznJ._o}_5'b f ,  $ q  6ks+ 0 < Hn  @ $F {mPwpbqi~li%M}8!ݘhlqK) 9ds׎ ׆ ؍dfڸt=wp"%%5!"?UTp   FDhj{1IZr42UrprLB@Yo~<&@3/*H|h_9kvUXg|R 5 R > P NvE ( M    -vBCc|_Y@=Cz   q~ Ou-P:LBy<'i;ViRy^.JQ6M2)Gv J' t9HqcP(v5X%/]'FFo4a>VoWrC5'uU1L54rCQ`Pwa-n4yI 164m3ߠTEޯDEܛ' B n ޗ ~%-?>Cxg^G5@da5X' H  T\!YE)FhpJ WX   { ( * $  2 P e vA       h j  C 4{?5XAKX]Xi%t6o 9XPS!)w  O|hn7FW߷uX_dFޔ06ݧ%ݞݙ)9ް(ކ0_!xc=jGnDc  [ Pf6/& v2ilZEo3<cv= 3 5nHJA5YgC:7;N b7 i} [ @ - )# ?g}j\Qk6TD2Nތ\+BSۢۂ!ۊ/ܖ/i:ީYtg'_J; 8t  ae<Hcqc b`YB"nh N`  f s G3d7,b934eXv fu!$Dnj{u$*P\#!O@o.?4 6 2 F i7(b6 H  y  |  6^ N e   x%\t. 0&_(O=bc\9I{GH i^KSo4Q=&kH XL}IaF^~r &< g n s0 [o G  F,Gqy@r\K0hqS3XwFQK&Y=s<8'ު,$KܶpT6aه0ٺ:7v?׬ x +  VL֙־DرٌWa `  ݩ M  Y B+*n*!Px['GuH]5%6f<4t|Kz  w H :p!&#!u]p>*   =!3 S!} ;! * p  5 ~ w ?o2S:N^ D% z ( 4 M  k , 6 yL  {  6 rn C <V \ i/x;:wMWb+(W<L E| m&]l~`-Dc 5 l 8 ' Z *T i c \J % RO(=ky m^>"-[JdA,rS67%5l $ %Y=(roo3'[Dv9iz<I duMxS+9.bdf dc % k ZW|n/2)AquDN3+m8Vz&$ݨ~xFyפ,ԙWgq'P΃9QΜv{pe^Β]Ωχ3Lկ2ٽ6Krj85fSbN|f|Te+j$6g=lu/LjG&U   k  /f\_pK*YAs[4^# E M M S b] T M) ^J#    L~ (  wV^rW!ee:Zzae8TRBMT;f!y@S     ," B, KS$3h8v v5.f$6VZE[W? v R @o 8 [ Pw^7ph0hcd{hTFU]]ihTChB$@]9,AA="zf+Y(P(R ~masc8/]Ti6 e\S=&M}3~@9S4Os|7Pn:O xz#`n#::'}(9R9$ty1 W9H "dF& K  VmGq'!""w#-$##I4#X"C."!!H!P!!o  p % o /* hI  @bB(W.]z = Do.{'CF 1VI7Rj O8fk\cxaWAtBZ2 >foH=|w/vZFy~I! 47%12E_>n,9cx " f7Wkw`Ce Z 4 9 v XwUh'v0 hM-$XUxs ?   >n  7!=!! Sf hKilLbtXYEGLN~; 4 gT  w =  s [ }uD(9l u @ WUDS,7߿-qFdLT|޾SBsgWI f, ~uoibER:52+ޯ+w8LUޖFuߋ9 N k ha 3 {?l$$JH! Y  X )  0Zz^sU> r M )#l.I\>IzR+ t 2 fM9U2I+:z0eVX@Z=" @ p mCOU<:'v")n7%q jJ=G?|k"gIU e~ &; L DH 6]@&hA!]$ &n3|I-8}R+C(l+@C  } K X/$j#ly'~r LwDAyzOU3jpFxf9v U"Cjbk9e=JPt -.RUiy"Qpo_V\Ul0{vyEIU:  8~1Vi U)@*vgh"' #{g0e +JDRT@NTsx*%/,]͆w͗̄͜KpZ9̟̇#͈ͫljӳeGڊKf"4n,keSpy\J\EX-Wi IUEZ o}}- ; # iHmTq3?=B$,fi.; fJ=!n7 'w J    opLA  d*n-p\GB9+rRuCZ i  a 6V4Cuyc +.Bn7"  ~&5!N{[+SdV a x n>Hi-:h==BAaD,|/e'[^nlymA@"(W-XnhdK  t-eA1IMhc /;zh5!o'w<WiCiNo!"j*, )R%0QW b(LgO3#:x _;h2CJV% 8 ^_XK:z  S=  !"@h#$y$$$<w$o$_d$`$%t$V$nu$}Y$ ${#"! !^ L2XcrNbXU *C f  o }  T }n,!62bP>;^t,u9> H]jx@; ߹m }nB}i@Vz5 @h[ 4lUXZ q930~1f -9,KQQ}_c % K >gla*ahtc=UOewJby_b@<,9G} x J  c=  !X#$%U&M&'('&Y&%X$#"!A ' YS GV Pp]CI\ $ U   o%zU4v9 w f" ) t W  jL h X.xmF{"XDcAst~'#@!` SmY< V@_LBtߒ7 ޏ"Fܓ<܀czڒڜ ۈ5Vi ۼ N O  Q u us 3 ޹ H$ .} IRW4Oo\j7,Bm! #O8vG N :  5dI*E!|WGU&_ c O } m $  4 $ ` d `  L 4I!-1zK#Y;rVei4 O[-FH1@860!vnn/~  P V ! ZT [0}]bv8')p,(7CYy{=^j oq57" E; &.sp|Y&JlO?9C NhQC)8:/) 6/?m:teaqb#Jrse"^5XNHf [b}r'pHkgOeJ| ZLfL)E 1jNQS'NoHd3c{s$_{G1   aDxN;N)}k<-(`}4Sڰف>֣jH> LwҼy?XчV[#NH5T'Z/fLtуяA҅] Qw-n Lօrxٔ%v߂[@9 /cX"T#  mj+7=o+L} y f  _hpZg^]|v9 O!0$"""4"V"W"G!A Z> \TTh   h  [.s9 .!a!"#L$ %!s&"&#<'~$L'%5'~%&%r&%%U%$$$#""!/! pr1wX4x6Ek  "' '+ o:UQu>   V!Y.%$O:I;t4 `9/a.U_{yx8\i.Zk| @DJ$Qv$8"8dxfP7EC5]<cW=G__l]YWmb 'P!a  QuH[r9+N&|9^g@M7fdOFX ^  j BD';FmBknD  ! !O"c""""""^"~" !i!W!  A UJ 2?cZG5ba_^NE'C  [+   ?4[;9'PM=Jr@gNa/v0ދf^q ڌ٨=feڒ ۹] >)0}>o*Y 87H1H;avN&9X `:${VAxY , 6  & ` K Sxz5Qw2)yvcD&/(pbSM 'Vzz6 Y'ARPt.%.B)    $ .- +yW.{~AJ 8B"zZbG^)_QmfbJJ/VDwA&2^-e!t\v0[U8-b ~!!!i"""*#m###;4$`$q$m$J$3$[#%#"T! ! ? } u 2 l    ) ,j  $   & ! 0 {  $ fZ[2Yo%d#Ep;#7՞E d5^wz.sҤҺdҤ5`ы!їdғ ԏYנsPZ/ە~w@l]MCEEmRz((g%m='iM a!jAtlO.|1TXiJ _BKb> ^ ajiH9#O:!f|"#R$;%%%%x%$$ E#3"!!`  K  +  !"#$%e&P.''( [)v!)"@*"*##+#`+#+5$+H$^+#$*#_*u#)")\"_(!' &&L>%'$O"P!#rX  y\)  ib J5-P=iXmN+KmdB:'k3bwX:MPnGGG2u7|b{'(H9qxqpYv%z!wKHL@~S9$.UsT{}1t+yu0?**%2fC.fbIE*=7:Ki,9' HWg:F / _ ^  hNyX[)hG6nyL2Ja3ވl'#ڠيwRzոգԼXb9գ ׏!ٴ'C*/ߢ48 ,  > mM 9 ْ I զBqѮn3/c 6 ς%{n[ ^ {ݧZ> J9%cE)(~>d k e  f       Iq LT  U m >! ! ! ! .! w  j]]ue4S ~g<`w:oz --ImxQtc-:_hAimJZ4v'ms7,EO[ l 8 3Y Fc @K2)p 5-S{Zb\rT4TuUagK @35JG B' rQ G { ' w f  B>dD5+|;qY)fP 6O@U).lj']4"@* v!:"##$D=%u% &d&&~&F'H'z','(_(, (x ) 1) %) (r j(( ''c:&T%p$i#X"H" ! R  m  V-   b  7  z   j  ~ , c 0 M(b13RySlK9Mhܗbr pף+wӹbGѤdGSO̿\3ˋyM̛^FΪb0)SRզ؆} dj_#FXY;W40-~I`m&k z'7`~~WU\9)PH  %:2Mv1oO;mb! ""d##W $ I% %; & 2& '&? & %h%T$$$$###l#f#t##6$~$$  %3e%G%\w&] '=!'!C("(>#g)#)$X*$*$*$*#*D#j*~"+*!)W ))D(6'%%v$"1!i   )exG+? | O( 54pDAK%{\C:aU +Ob 4h0!w"A*ml VVK]R'L1j`6<:?'.T j1e8E#<]ji-S`PU Fx /    d R P  ^i!x\kK^Y@$v7/w\\;L{ @UOqEM fM  d N >I w S~ o [h s - U =  D M! 9 \ J  +B  ]  F (egM~&9<1 qaE# i h F 8  @Z!*;z*LadaC# /-WR 3o7GݹNdxmGLZOKղ},ֻhI]ـ6ۛܯ ޴ߚIDp /0H i"hg,n3IWsQr 0@twD   b%%E\]EvX)e[14!( "S $ _% &'T)*/+8, --O.'./E:/2/..J&.-,t+H+/*K)_(k Y' '& $h6#i!$n\%.|uC e5 % ? !6RT%'(-U1;yEI*;r'2QZpL%g1.}`BMV6ub=1Bv?O߽ ߊޝߖK߈߸(}[[P @f@{mL@*+.&FAc  "X X{ y \ B > O \ Y I 4 Q "ֹ9tև\׌7پڞ<ܒݑޓ_US?i #N 4   J0LY1GU E I_ >!j#&<'S)x*6>+B+++%X+v* *L('e &N$"2 x O f`ls3)f b\XjLGO ` p m QO&zQO (O^0N ` 6 d/ C xM3ev.xT\5[ P? ~= u A\:" lߞ0s88߈$E?z8?mY][lWV-bd%3^;|)&RQ ^ ] y b 6P *,yhHeobp /(>;2'TkXv-h9  'e!C!pK"""->#o##U#$Ld$$[L%%^&&j'a'(i(tu)l*@**h*****))N('&%$#""tR! qt r$  ni  @ Zg ] $ c + ] ' Z e E$ s + , dm o`Yr*|^5EHXO1 ޺T=<رJ0/t`Dџ/3%Fbh͜/-[ʥ& ˍgyΝ@м^6Ֆ0.su 1,-$Id eCWG{?&j>s~SY]E%X-L Q;O3*\ 1g 8 H_N@ Er2xI & #! !' !' <"# "'"4I#J#i$$%u%%%t%%o}%%G$$A##y""f"""Y##$X%d&&&&@t&q%%r$="! cT +  D9Pih$ wd I F "fKJ'-ch<)eg |sO1 Py|"zZC28*V&)r @ <M'p>H?y4R-L1Z-&3x:jDHzj4r?Ud9@#/f$IKF/$p    +"10.H{b= X, f M: S   )~K 9m!t3Mdz"QQucGP``9K Q;  r9nnLT%nrY8X_r`bu>!3tMw   ' ,  6$1q#'4   :  b+ 0 ! *LvC1/IRgQj#eYzJ'W35[Nٴذزا؉dHH^[sp[PLLsEI4=6J[rߣRX!+Se/mck,G *U`    Y   #l / H i6 u ` 1 ? fx  FDw; 'iDmcHg3n7 nP '!L "3 ^$%3'()"+d,-./pJ00_C1{u1Pm1190P//{.-\+4)" ' {%:#$ ]_GldNJ 0;#qAKBMOb@y#bMKB0L 4sOq-H rh EU`QH?S@W2TpB@ V7-r,3.P0M9KU (Oq]S; ( 4޴ Pm boޫ7ޢ-lߧB5F l [  ` T6zr#xO j ^ X R x4*C6 "$> &T!(4")"*#c+2#+#X,"t,"C,!++T7*8)#(q&B%$y#M" ! 1 Vmy T@ x 5 cR DoN D)|%^ L ," i h^ + x v ,v$}!qz'1߬=R߸ޝFFC+DP|jgVW nW@\EBgr2 /y(MPjN| 5s G Jc+/1;/D c/FTa YGI, g n N S A!o\xM f:9fI!zqyG9i/E;.*@,cDt Az9\H8)S>N=8cJ8 X4$ 7`} P@  |  F P 0&mzY12W p G!  cW f P ! %5qvsp ; Xxi7S}Y#"Y yq7mlo3<74 h   ` '2 g  ^  ^ [    (    CH 4   cnC:~O5#|6=5E.1Dla'<0)oq܅1Fۑb݄ܰޓ.@hslT&J3JXifH, >cb x: 1 { G T i Z ; k^%\'vE)K 9J U {BfC      -j !9#{$1%/'2x(Z)\*F+,-T.l.f.(.>Y--,, *M ( &$w",/ ~mw}G $W.:i}aM\.>E@`[s};{MC`xtleheg/sja9L 3p7i<[y :lt)qqUo ~$i(NNWp&AR }] 2 / ߟ  # w P tm@7E8f8o }  \^ 7 L . Gk2 < ]PO8osK t"H!#!%!&!&X!' (\(g(kL((x''E'N&]%7$" i!  :+Bdo F  fI]0@&8%N&~F ܐKܧOGQxJߐ &}Y#b>j6c{&BTL-\ `AxQ QA90]FJ!m@SfSgM3S$xZB i < @5rrI&T$ [nS  !{!"Gn"""Y"")p"G"Q"!}!"!!!!!%!!!"-f""#T#p#k$%%s&'7'c(((q)4)kZ**+"!+X +*,*i)^( '~%x#5!ZjL_*?  j 0>_vd+BW\1h#(R&b}M)QaJt^ ;yU:3xsSފ)NvٳT:C=2&4Ӑ Н=3s ̔ˏʢAZ˲'̗KͥWF+Ԃ`.mhڤ 7ߥqTiBHd&k< t W [2A}}PEv$9<  Zf  6  / 6X^R  0 N  T + J [ ;  N8?I3O^j  @~ :   -FSDqT=V=N^O8kyVTaA& D   Z]vH\Zq ; M lc B$DjGtlX\,ym%&__8IJ9}rrjC3!,Z"yk2e:ub}3\F|l24a Xx Ep{xkZPb\|dN*ua2W^7#Q| i U.  X 4oj KI:SMZak2jZM9T!~Aw4F   T XMV p4Z<6'22wH cZ JzZU8Wm9{g!aM'," 2= k Dx5=`"Hm ^9nq3ifC%;M=LBS N t  Q IYOP'/ + <!u @  O 2!V]!l!(Q!y! !"5##0$~$U$$$}$ _$e#"!  + + F ZD^%]*P. & { b8?"UCK߉>:۬&\ٺ^uL2Y! #S ֹF4~֥v#Gv׳wzb+zbۀmg='M@]L-b&V,M)z]_]SU;0rowW#n E ?\ Y 3F  # ,.]f-Q} D!p!R~| !(#e$%&'t(tF)p)ec*P*1**E*)`)(\(''L'0'"''~'/*'<'^]''s''\''?}'C'h&&&%a$-7$#"]2"\!D U7pQ7: NfJ!6D(|$#!A}<(=IF1J_ivS Iޙ[;۲ 'RלWՑe҅o {ϱ{WY=͋VͦͅξhDt3Ў(rX҆cՄ2l/ٕBYݚodJC/QP>ZM:k { Y ;: k x`j&_-?Q=dMA "K; }  w)   / Br5 . N r  }B  J   v J   8W  3  [   *{  <  u [ 57m0&ka_}cGz (  P P$2 T ? |5 +<_xtN3">.zBG5 ?mTU%V=w%c]Tgn?V lo/B4*>]. ); _{)ccVWVe "J\&D@eV);>Rj RBXP`3=m  Rha/ A2|Ve3j`<Qe3NT*ShDUN.~  2 Z`)uK T|F1-*(cO"!cs,K>;R/0M>}}0G.=phopPmpt@mQIU_J*ULrJ8p{ / t/  +pCtR&d6PfcjGk@ do>JIkf!'/bh9޳ݖ݁Cz݁ܞWs pL2TZ%ld!k2)q Pd}ou A  M & a a p<Ezh91-H{!at7O , R =  d q    8K IT<^=h }!!_""#$$%|%q%#&Q]&f&7& P&E %p !%T $"b!80 WuJ*Eb c @X i2)I_j$AzڔD>k+[5ݒ8WަvPl5Pu7 r;t.1y{o[H>u`aJ+ ^iTpW%Y 1` t 0Q"ijaald#P3T 0DW mQ" ME  M8 2 V  z 6  -h>35u#   v El9cu5Bag)D<v^ \ r ^ `L1 Oep3AQ۹7aJ1ֵղq)2O{iվ`ro(zd 4 T _EC4U"4hJX&3 t:w-Z*$6I&PE766E w\ q s(QH\fe'b9^L*qZ*:P;XV=}XA3j&O -C9E6[T ,n  !> ! " #a $ % '& &) &W .' ^' |' 'd ' w' H' ' & & &B & &S & & 7' ''''E'N'&%x$Z#]+"z 2@4.WgK[8 SM!RaAv$5;h_r5\;n-9E|X`"dx0k}9gWLi6mcKԯcӑ{euaR΀X͹2Buh ߡvj;e ߜ!Kѩ8)O9ߟmr ^rt\dD#DO 4HX9<Hw-k ]+  X  K Xk       @ k Y K : ' S( ]  a!  \\;&^26"p'H9N4RaQ@ (    t &' _-FXh x!  ~ ^ ( i  E V  ) $ U  o  E  vH0y:[`AnI  S  D X $] Ff lk ^ E & S z f &2 t1z%N~8WA*U:".*Ky(Y'j=/2?_^VNaiKg>$3 \K]m`;r#^$wK2T'&_+(4_O-E KG!r-Pb6 &nZ3   J Y{ Bc Y^j=qmkY>?$PLO/ B At =<a!~Iq^8  1 xCefZ*Enxu VU Ԩ Ԇ3[qZGMտ'{Gִ?<U܍f3vߠc":`#KHPj>FDe&uEy.By^DLFAO.L F  p I   H  N    H o  gK   ^ 4 ) ; b = f v C    _ s f 5![ W![ n!s ! ! ! !^ ! !( ! "4 !" !"7 "!!67!  ,O "  G 0 0 !c!!0d""#U]${ %~ %c -&0 t&y&k@&%X)%B$V#! 2s^8z   YfPn ,[0*\8tu#].-M?; S{HsX4M߻ g mާ+9Aݮ}5ݕ {1 TTvf(MA/~PDkYjћޙјݕZdZ_ԓݙ"חk tݮ!}-]<[mFfC^ %  Hq  m Yk`Z%M_GeoLLMCnJSLy%R*)0 'w*T\(E%r$vUV<OSraVP}c 6E   QC  G s 5ax`,`#Q(R#Sp,>n [$N)r'8{!Cuz7LD#os[d;<_sfcXMavM291-HE[I6p(yDs9?_"T+,L~3Y#B;,zRZ6 ky<SMoud#(!hDgf.hM>:V+/h$(1|"-0\Jg$m  T v z _v/&M!BnW=t +   u w 8_   5M  + O  A9   W"4_IJ_Xk[5GikcWo M  eX oF( 2Vri/2; w ; y u= z?$n36L}\GK/ZOߞ"h]4N9>RJFT<Y^2x ' Szw@x =r h^]x]:T.)5F9NI%j9c#5K4hLyQ  ?^ 5  1  c r b  aD W eQ mg `N @ \Z"#@A-~$  |z PFKfHR-و?U}2RՔP5ո -(խyG}K2Dٖx~}݋{޽CXc`[;@R 1iFyFc(~dF x#4Pn.Ko `R 4   !QaAgPWW}oZRMj=Oi=Epu'rdsfw Z.>{{A33Fvtz.fLWe?k[3]    P  0 1 # & I32e=3~K  AT2qߐ`A068wG9w a \҆g{gh}јѲYkijLּ7/gK&sBݞ޳1a93 n.Tq#T:& q1k ciU/y   U  XF   9l4 WpkZfc  f   . r U !E "6 ". g#? 2$e $ % G&< & ' 7' 0''&r& &2%${D$#"J"K!n !pa `P3;+{0YKUj{,0c ? 4h!!R" "_"o #O"" #"0 z! 7\p @f! /U d $_H4p~)c#2$Kd*@܁w@&>)|\P  '  E? j  X3 iNGeS,lwt."JN iC2fx-LmN3V]7(gV\[Go " !>9:B#Z g'h/eZB^P-+Fgqt~w_U  |  ^t1 ]@R8.}TJv@Sm9PZ[U @"(`j<\q0@g0. R] ; K hk?Eh3?<>s}'{oMhX <` # ' d { i A:   ! Q sk=`DmCeS<k$H  y F w$&69;Lrk18oxzzR0!='vF@LH.w=u9Y38[q"2[Q/ E 9   bjd_T3acTDKq " qv n*$j|5q / %?j 9JzG9U+?X z  A|n r_ t> 2.. u1NE(!rrJ<A%~QK6<NM R / V Ir"j0T8  -4%b>HVJ= Fz 6 #k4'wo~sO .bؘPh $Av $Jt?]RY7 wb>&)KO$7@^"|N;5&4(T(DpvOjw+#w  fMMwBM /[mYz  a   RP~T > n t g U =&,&fOKf3% _ A R9 ? X z 6 w " n 4 $M 6 4 %  @  TD $ct!  i    V ( s+t{A߳#lܝٟW!׬9ӝ҉d҈ Ғѕ{=G҆-QӐbJ}֏t؀+TUW"1*h XLG*=fk W"1"/Z{  k ? ~$4mx]k%tIAlFO%L F[!W",##?r$$r%%K&?& q& &g &` ' B' F's '&%$G%$(# #w"Z"!u!z7! ( 8 H>cLm; \[*sJX:  P Y5g]o2 h  # ^ZPMRRCP0Pߪ!Nݢ@p،݋- WU '֋Axrٛ?.ctޔޓ]߁mWJ[l KRzg j߇L ޼Jޭ"g):)<wwDBH~"8p MW(>O||z=j;t}x,  0  n l 6o ib$7!i3EX 6 Hh!P"\"|#i###D$a$i#Y#4~#!#"2"L!+!  L%a j|g:-Br"2:$@ A PCfw{ y   ith|r>fwJW 8:n0> .|WW"DWSK'DE]&oNnO/x30t*Y15A1pu'!3nh#=XPgX.f i p < P Em r < n  [e m? P /: y [Q"`J m_QKAZj=M3DLo%E9\A* Fs   M  ,[ Y ~w < (5nOg[ m N  oy   =   1   | 3 [pk<EXiz.RK';FW6W uB o7 Qyf.{bV@T[ehYdndQQ._y[sda7lu / (c<>a&/1Xp { K tP0%-P;+qNE,~CAtaiwF  k~ >(sS(x%i@:"&M[mDx-7`" d s R#%9P m  8*D0, ]Z0> [ '!(4!-! Y :!P_ G V%0I9zAgW _ w YX t t4 1 2X a 3 W :l z | Mm O V ]| G VQ|9 W 6^(tKbB3).1x'K'YKJn$s nV; * X$X8_,@I&1 fl)sp'?SH[`^Q?k@>E&& J ^: oUg=Z:D  FX!mu- | =P  qy Kp.L  p & 7 a   0] C Pc)3T\6 H]0Z8s%Kz ?h\Oi*Z?)%I Iۺll, سMFՑAQӳTp,҅*Rӳ/Ԓ9F.`ܬb*= x>]H>6So0$^ES^HVbRwt Vu^b T$bO    n h  { Q ztwF[<#,8?B>ELbpt) !gP#>$%&y'''v'A'o'O'K9''&H& P& % k% $ d$ #u#W #"C"0!!>]!! @ pbN4= 4;l&/ L\y([P   ZA w t Up(Y1 ^,ch,=",Z6Om۟H}DF֩~iײg=;چ+la߉1S] ot i0 Lz[{[ucON*+@~M\=Q{ ;/^vߞP _ߐ%gvG1 a]u/56"{H\ 59 ,d:ZLsv~O'I0RVRtg2Gz3STK[5Zcp d1C,-C'2p] r{^|_cD } qT vx  z  z t -h R &, K, yzH{ymsgIJ./), u_ @  f )/_ F  k}  z z M 9R +) % J   c  J  Bu $  M:cg[#}H8q1FmjlL=E?H$ kd[QK*OrX g X  Tm 0i 7c>1d%@fzN%KUd HGOEz+X v'?UOKBq8B7UzG}g6{ < 5V N 5 ;,  me7^vrvp DLs i J \;<<LrK.l~dv?&6^!:~|Z j j=s ;RL"@ u F  H$^F'Qc_^]I=ls #[ 't%N^FKm ~] 2-   . N o ~ w e* IA #Z { LMxi e 6 d % ^.0&j6BF Wvz6iqBd?uWgGl&H=G5F-P9aE3%Z  {$ -67+~ |I1+yjh6E73@qii7|c)  "(!q  %- 5 % = 1E4@3<   j5 J \ Us; }   6 a{VOq~J#`_h A jm 4NMq`TTB3w;_a![-lBVNckFfKYyJ ' v<'o_eXo#u7Qr 7ja$zUJSb}:,g :il\M4  A K  E   P N  e  ) y  l `ia7Ski   ) <   9 b ; $6RDWb+ @  G y4   bq ) }I:}@*!~1Q13#T/ N    !|-0Y'~vEcI^upp? m ^  - $ s 2  h F I 0 l   =@8Pgn2=6>zX1?QDJ1CAs0ާ6%ߪ>`^QD[Z: fio2P@pZCh 1TChSpKm/X)u*_ c 5<|{lyA4\D`74G&e[d1[840d?%   ,w?h^Z).Ydh|tut{  !G!<t!!w!TD!   ooCfgCBI<"} = j  (fl G f u8sOTf#'^I|\y+v]s6`>cr~ [ x`"BEnW(nl5L7kQA/*C-;E " ( 5(A a  P 4 3 u & s q N Xi/nM .   .l : +p Vj-LMh A / _Jz3j Uz(i`]/ 25 r C - 8 I|\X+iY>:`#-Y^E {K3^ R i    &s%:pj(L 06?M)2 !{ZKx6SmNHGg zzkp6+1cz&3 6#lUH> h (G 7    u\'{7%MJ4ZFKs 1 ]s )R>/~,>^P9mgB  6 8 RN?_!-8 .  2 SD jrMa *}v   d`Y fAhh^H \ / s(U$ ;bX\pO!1kHL35MvnN8<'v}vS.Hx-KXucSKLS\i)tO3F[z~ cHc;;DkZ[Dp@ I$I5Z//$VxGt6rzC}z7zIF%B,Rv>   5 L>  x e   p * !  |  O  (   U ru N{ u p iH gm}> P3csx3"N];qyWQhf o!VV+dg<Cpa]&L8k& -XgCe[GAz~Oz|" rv\'wT{-;)B4b~D|re6A Bp!2x@Z#\ & l     #v ?( _    |  ~  y  W B G b  bs L Z X .  5  p    Ud?(58$4 '+ . A R G-K9p,@6mYPh Qo GilD K  H ] } E D])%=9^8}pI   F @ O D w_G-HH05FP>)T^PA>@CS|B^wH]bc^I#.1=$ :lp`USE+o  I P } v 0 s ) [= 8#O&Z99(]M?miI'Ra}AJ|"7^k^'P ,k5^wC>zUf ^ b E " + 4 *G p u KM   h+ &.  q wY : !  N 3 ya U X  ( A< K aZ o D+ m  N   2 < ' < r   D>rU SIhaC4uk6=P] i r ?Q P#"k@STz~_*QFe]J.[e'  ?n  h"  m IodIEIc aQ F A Qp n* MB;a6%0JO*;:f $'FEF2FoVJYX"n(:+ ,-..'&O#!& #x I;hqM [ (  q$'QVL'UYlkDU.HGuCNr$ n I (  )Z2{qKM7:[ D\WG = . [ &O"t: QA v 2  FgrfB]s~Qn64 . D Tk\-\S?%gE>f]f?n7 G z Y  ~ E Jr O 4 i!  9q w d=sWa_P.7qROC8&Fup}1cJ<5BbW{Te[gUJR)i(9:_2*(//FpPZHKh/HgM)WUqI^j&z]+ )  C }rZTDRRKC\( 'Ah|Z-<,nUx\M`2;HVQ:zB>(2s%4}{ h h&ImN !   6 e  V   c , ![ J W :   .v   g* ` ; VO T 2X k@S#yj9]lE B]@v~ 7A9.9 [j 3  s g3 c ~  u J  Q  M (   @/ H T ;A   ,4 {  gU(NafY1^CruA.3:JMdLz4 He*hUG.!0;'T* 2eD6/hNU<"]1nSkY(%R^))3#G`W-dTQ/UH2yxR-)6D X{rR* \_  + c 7yH ic`w)BfH=Cf"]:i54 } :  t $ [|s=Ldy J ']  2`A]@r O 57 !f   )w/Z2/18CwT,gz.Nw ;{I+Hl8G#/N~1WA^&<`b]x6cxC C o ; `  R~L(M)BGzIc U L>) Xt 7 / R j  C  f nV .V %q L < } Xc < &t !uOuB     9vC] M ! < rg><h\5PVB$$^CU!KBu 2 | 4 [  > .:,hXM>*D!w- 6 <9 < 9T 6 1> + $ l  o I   4 e ]  K dM jk ff[SV>f2AT 8e/v 8'!IIvEMJ\_ %!,%CGg;W,+osp7%6[l5jb P l  P \  = 7\?..MOu ` 7\!ioD V t 8 F ;@ $ u ), T     % L |t Z - - z c y  ( T  #B C J: = - # )DuPPDN7 n]3Z NS ' A g DOk\~.YkZnvl2+yFB\D#y)Kcb:c8 x]b= )?_^2 d w  ' J ;W"t.j@^QyP/R"ZE{e? ?3^"RR( _ :/nH v4Z# "Hx+k  )T- * u   9 h $ f!Sj`M=UbNm&??a@$/9W{I_QGb8*.&,.bDp_r ewG;I_l*#q@*vP  ^ c( +Y l o j \ E  C]  oy? c+ T_')t/B[s~eP GP;r^h'83_s%D;  Ai  - R }N A =  T^  m>  vA   p   3   'OFwp   X    _~3!l"Y,BMGOg/[K@S 3 S~    XpEN]Uoh&[]X R  M   8J +7s~.Y='I`{L`@^7< a.na c[:! \H?FO Q'p0Q',U3+6 kxa.F=t M}7)dJ:>WZEIJK]7%~a9@kS67"f'$&7G<%  J > 9 As !,  #F,*@vQdXBR2H(L.8o"^   r ?  /|wGc\H'u ! ] ( 3 5 .CRz<H Lmy|~2! l.@;V|_DI!oh@(z (n7 o ~ $Z 7)6& #cbb-O S~N(W P%G /^T(hN S b (Q b Z %  &-X[}X)..20#{i j 8  h ^  P  2jE0Zi Z0$N zx Q .  O Y 6Qk+ u|].IAPn}a  R e  O  o $ g o<   r & ; Q s j 0 FJ,5GZXy`cjv 6|]rjnR.*rbSC:. ;Jn#5]eqP| `=TH[Bi3t\%r)dv[at{L LcPO&,MkWGI"+ ( U3 / R i `txRAW!.rcq/jyFi & a[ /      } _ = Z  N  O  A p  m O  \  , v1 %  Q[/Q 5 lz ^  !  e : !%  H,Iu5ZQ>[g0%)@Z;h ].FasV=i? a*D/lYvN  z Z i   6D j | ms K  * F \ A TR []$_g|ALNi.@zFg\\Nme&BBPD'/i7h)t s"1hh^ #C}C4HA_k; x1 x %!>t@U+| zxnZ23ix;P,R vcX3WUgmaiCG< B}O_Rt?b\iV0X  R S' (   *; >A V! v w _ o  e\W IdeNJ+ar X u&7mPk qDol4YB=Y@UJ}2 ] 2~ d  ~ c 3 ? \  m 8 Ot   @  u JF #     G l j a ~   / Eo I 7 : j    x  r  L   Z  I  6 " U ML=!mJki@ " }, C V c ` D 3 ~ | E" ,CL"Nz1t*Z>n0Y/W"?^^I,DoCkzy6 me 7 ]"4qM?i_/d}#aAc=s9rC#8%SUap)I s 1fq\3`BA^u6P3uSfvVRGG5+  > 2 { - j  U   ] }I?s{S-JI^f [c?{Tu >x  H# +  tV:5Yhomjh^=Fa! # uEag=O}JL mED]Pc ^wGh N \ l/<j%6>]??;,Ze9})C(:f^e$R= K D Z M : m  j |L 3> E \ |z V :    | ^A   9 A   \J  Q   B &m 4 Ez _^ . 4 Q {  ( h3 ? ;)AaAl0@1"K B6cUxZ`M:t/}!(ZT T <  e $ ] l! a(6b.oi F{%-w &QY +.;t7!4{69 y{ $_hd.~g`Ps$TW F0<7K\YenxG ,/k<6&d N,qh; nIK9p( t  #8 ? S9 & y    ; t0 b    @ n         . H Y \ %K *  b  9  h#>@T`dq/mcdSpr /U/? imdlr474: }XJ=~g7>}S?f7E;GU\l\(XMA972"`6+B=w0DDhs`x+5  t  m ,P  L (  C $ C z G x} W RY>/r[YMJN&NVOT_ra#J/ a)UuwI >],cN+}R9N fPz'pQM%;;hl:8v?Jwn (CM@ ;t(>).aQ:7XHm=Ej~H?7%aP9he*fFs pPPM l*jLaul ":;Vv5d HDzK\BFz,Mc{R8yPN~{{8v@/s` r$ u Y  %0 |  :  C  v ^  # 9 B a F 3 K L E U -  x H  #| b}     -x Ok [ C 5'  B  q{$Oo_wP)vmw?}O r  m  P Ia WhyP{kDE|@K)Ef6]l(I7*V!&X01= JJ2">T]]Oq-XY`'T2cQ2O;e7p=}R+wE2;r$_z2ZF0 R j F ~J  J  H;R3K%  e 9 \ < t   C    S  W J  . =  a  N U/_b 3$q|;<c a 2E <iCZW D|< TJaFJ8k'UU Sm<^_VuYR#?KUi*{/vKZC z *A 1 Y 3 b 0 q8 dj b g d) Nk *  q @ K )k  ? I 5 wwbQ. ^&;YyAY#=d4fRv+ f  ( 3 IP _ =] ?  \ n 0}{89p_c3dJ  zjmx g,{y"NIC8wE"W^1{4>,N]lN n   j WyxIl0B%R?E<(<u (&;BE`D8!Fi20fsAi_XWdBJ2Bmfod;Z<6r!C3N8h8SwgO&5D=anfGQ7"Bp$H_S6+1{C%I7<X4l  v  c  _ %S   a &  %   { lX g c: ^w X L6Du%`~>i&"a#F64e<#uQq`%A"SX:M8!~<]rE-),0-5;34 xe#!=er C.^7$0ott#V!]D~f9#6UglJ 5 J  Gp o/ } Lt|il}\2=0 fmqd\_Sf!ca 9ydI9l$Nw67 6Q\sgsf\UD76+#!%c,6,@}HNQIZfv;Uj~?Rs5?n~mpqp=7a]4kW)iwvzmyPS@Z9r%<5`9U`hZ4E 6Uw&4'_7:]cK l g '  zD e O 7S  L{'B>prfc!,R'!qiyCs4^g}+|M2')A]v o W >%2eH| zlti"Xu< Ks"Q|[Y|h~=vGS:s*$jkZJ>4% (-4i>NGBH>E:?31&w[;ih >i/~Vk*L- m'193Z$f l})V0Qp-k-S;k  u'', ?`1}X 8G0(bP{A-BDOB]UsUVHZC)O 1!ec0GKF{M * d g &( ^A F > f* n  a z 1 + |  W De'f]'|hj ?6Yp${M`[< d@#:tU6$b';jZ-BxX-7izH /! x = 1JVSMD(n86Raio3kbE^`wh|"\ZU%@gi Y 7 e   (| M  S:sEZXJ_8 Cf +    ' >\ V ktjr ]:RhJy2;i <&xb GY'I? +)BKQF2E @gOa}q>DV~JF8~.+iM#h8z58xIOoSTZVf'~sgG*K 7r0n" H )f b V > m m8 ^-A8?Ce$ZvYg5_w)a9] HB<\ X0Bhy>& IuFS!xdX4_{aB Ijh~(aO$#Uow1e=** 7TR|%/xt iUrf~4Cm1M}HzV   A c { C  t J O V  ?   Fs  w e v  >    @ pp L ( Huu|e`sbedVYA)zU,-<HNVf{iCLo.TV9x    f i&;fL}w2$&K8O U V L 6 j  y f )H ^ 'xiI=a|^C>,m>),a_%v"oys5`4k7Z*e0%H)Ih]apZGP$_k%o!<O~^+cd[fr= i=PTO+pKPUy+[H=?Q{ssoo$rlwoMPf88o2z-R$ptECB`_ytI*xdXQNGTiq5FAy4Yp>gn l 2 % > K! = {&Yc<Cy\9u mR*Tov/g=Nd Q3v= $$ x1 7 (< Ik$gWUWO[O.*9NF/QCSt3"y0E~x++#LjK::/U*+k/4>Oi&&m`"xA,*)r  jR%1z|s0mlr|Jbl+QI_N#-9/8(\S;3amz7e#4{KKK=-.   q+{v-@2PW.-dzFL)I^l:<3WoygP[J9F [7l/d Re " B d CJy\P 'u G x  'f { 7E%Z\[}|c36+G87WRy@\Y:n7e4vS0v&];!j x 9c#KQ ^G^xq;x#w=.7>3&e/Nw<1Cdfy.MXTK;"+?LTUVPE?@MextQ/Zx".J* l]2>j< K}a;|0 ]*2@!L'PCJw6'&SN.vb:t8y)Au(*Tc)"+ij~>0YB HJpT".Oz m{SP.Wfh&_yzplCb`l2^ CwX  p4DE*+L  @R0@^EVIjxP&@wGR& Hl$fK2B!{*Ebc8 +]8%8EWcPP D`bC6`1/d0:F@HFIVijPFSw[|'"4}A!$WZZ5|RD#zx/ 2I_v   6 T l ( v s  ] X 6   B l (8 r   Z %  + 9 N j { q i [ E ( S  y  OW YTB1Ln~'>9cL9l-,=AU%h%y?t?&p:8 (  h :  8 9t-6Y  H  N4  [S  F d N   J   f N WI UeNBy'[nD_1 jJi| tiQ3;{ZB]&!b9a%/J6gN65v+RE( ,zyT}a/I)eYd!_?*I6u`jAVtBu?Iie$:z[hXcfie4ZK3Q#c7B 3H Vj-cXY8*5@>b1:[$dD#" K5b$8bo-dspc!;|44 | COr PW `:S^FU5VcLR|Ti)Y*YA3]1d#U)Z*]`~C%A\/&-68TD\/Giu:\q3,c &Iyp0Ix6 VsDm"fw]  P K U E .   u % a M  SJ  $ Wx9X:U9C8v^f bY4/u+SbLB=,l t.BR'xKS\(SzhaDho/ V{%Sp9NpaQt. lA "<Y d#(8+t2AN W(b<iIiVefgvrzyuuw}lYB$&V{C &/2;Nim4lb xl-4[ H{> B 4P6_bclfl1{zTWlWyH?;Q659D:9/B"AZl6T=u)Byz,EHyuebkl&+h%oB!(5vS ?oR.y<D&5lO. =Ga:>8Sr7/S5/2#)u5",.)@%y ?r`'IYEd$\7pA K*| ZzXO4|h_\J'+yw{0+WY4<9P/ & q 2;y-JbH> } /Q  |   6  )! & , ,   w * _F_XSVfZr R+{OCE|GJ]B? R_ w z $- mb x w zo c YE  S Y ) U  ^! {E"f v7 Y ;t   | r  Rv " 1seW7"}I.mVP 6$!;a !'5WJc=&[zsN:r\1L<#stul E  1 * , V # rj <;3f-EssVet{&Po* 8{U%`Zj\ p,qVUT}|62?A:1{-v*z)}4|Py}y{gO i@|8 Re:] T)Z}kB,GDn7<miH0r,w< ;e a ; " +9xE-[-ebBd+3f-ACW  f   $A d X   < z   U Y  uZtxUI$|Ca`P]S~})`n*X&mT+;Iu bK_|djVPTdw~N0#"7X\ =tC34~_-1"V60tBOE'@0Mmv$FX*V&H. }scrOM?*> BFSj> a<ELX ^Y_fkSdL$#PyYHlkHjET*_"=kC=Zo je 8Jt"h[,|?\0v; q < t * D VR Q 4C # '  5 fc* _ $2b%A-lC9*]4A5a1{.w 5Ib%e@E39j4!.Jg1zr|t`ID0h|Wd5?" %$zcG&x>O{|J~ $;Qo~o jUuO$r{H5u&S0 j;bd1c1lP&s(z A=]7 W< s     < Y mi 3h ^ J w" @  ^ i R=Xc<$+MC|v!|c2'zP:3=cZzk\4 '7'"_VTlH!ASg&vmf >A Y V :  uZiF!:4?3Xus;Sbc)g^.yQ$/SB3BOFF=m-# p/^{[:J|l/i:?qq-v_Y]R`cc\J1zo56v7uBfbk`-['33; `c  oNgrC*m'+bh%yy(tf9tm%HpPhr(3]n,;}.9q@x5v`+%We":  \5>bo) p a T c  . I`sL Kbuz  L   L# L d k Z /6  2 m $l A  qd F~kC}<h `~QW2Y4g.lk 9lJKIvp` M 7 M ^   ~ % w 0k  _t  v` "iUj]05clRB=@(IVZyiG}|@{iX %zp10Y*7|Xfg([wI3A Zw(BfYv&+HsBCKo6  * _0c"bFy5d+l.znR  u { 7 & v k  e b '  [T\})o.S    C &  : d <  j " (> E : ."   t  r P s c n x w 6T}T^OHD<;CZL)NJA&_ y _7aic7PHFECFJA.mP<,!p;   T(8Qlf"v"l"6}T%sH!m$~GH~O/!+2,5M2u49:7 0"'<Wt =rk< 5\~ob#QZ@3(5tMjC"F~7hwN4#@Z{Hd4Y.di5GyvBp s~X!B@JdCM&EfxQ)4) nuD%u)! Ci&I:q\  ; \ v v G x R  Vpgq-JG{v$6< VfF$m=#msF/J+6MV@{EG!:Kiv*slgp!Xh3 P X J +  o:hwMJydN6K v BX5(W%8 I$\8nAu?p1cP7@Ll6L UhCn4Fe"Acr:0b#3at{V3Fu;#yjB"Lm5d._SN<'q@Hy _'5D^kDfaIW1q@xLpW6n5]MIcZ'|o1_mc\};Q &rd]H,b|1K1#@ om8d rO;  N  m  9 Xw " X  { 0x P  n G 0A - = \ ( 13 zUC=APihN5m0oO  M w  U ` ( p. ]K  k W F O - k$W}fE #7pBWRBc0oy@iE+:nveFfmlaKVV]rbP O~.U&O8GUe| (]dF0zt?v.9^ ;6VdD_Q>"QN^@6-?{St(t.Y},Is<+bm0[3u64 $ Ng   N) G U U >N 9  X   J F > p X  }+>uy;wbU(  2 F {   *Q   j Y > t s DK Fo kNJ5) U)fsOsBBFKWi$dR!5K\"$de%@xe9dr-O-f=b6uKbK5Z65;-ZH. TzmS"+gE3] o{X?Za J@EXRanXvz|\yiNE, "V -R'w]I|<^HlQwd5||k= :jRKq"$1F[qrp lo>IRa@3B;xQt%;1HNJWCS;E+-sVFz AM W_q {Y-j GG*VfZ 04VGu <Xu  i:9; < g3 8 2 !  | Na 2 ZN!~Xb0 yj^[B"y n; 9M<l-Kblj'&8b=Yo/9i{P2";&RBaw_UJn@=*::A"QVbuqr\C53>"P-g+~gL+ nW81LVuD Z+v='6z}5T1e(Gi7]u[ jy2,G>)xb F#w@$Ksv3)d47 Um   # f     j I & %RvBSumMxa%(?U \>/A'b$W zb=G.c?%Y)lAe9r[ (K$uv v.Qp VR_ w1N^j?cjK)) ,F_{8k#$b8HWq9qP(buNhKy1~Xy-fUB1\C4'!\K ^)O ZwjfDo{tP+$&$$ 4!,><ND e 8   : j       V $  N i 6 { ' ; > 8wcs[bx@  ) H g  6 Y _   = e`  d g t) T 4 D  - p f ^dVQQI29H_s~vr{rijNW04*x?Va@:DX\tb 0d70da'Hri}E~9UfCnsqoiLfl-)#9b3 9bn1/b|+1nZ,*]/ D\w %/B^ f%8a`P]1 cFi {W { k Uo ; E     E  Yn^0TdJ:JB me=yU 'q  i 7 v  {  4. J<m jsO9?75;oI?^ }S6 uS!2eq\Cy(OZ+Z-+jAVn>K}J~psN~:R3:Kjf((p5@OqS6&^ 5xgGFy6]BZ,&O 2dZ+iIAd',!  e@B%('K6| VOv,-  gzgQ_bye`R)>#ip]N*5%$.8|=n>b4V"PNS`wv@ !RY4P;'~75|q02o+6LX4=KTPUPiE3R}U5 ;c)=Z)eVP+*P "sNve9 0 \ I b b I "  ( {9 6G S \ ic &g ^ F b ( B Us 9W4?)&deVrXy"(\^O,z:g?P&QjJB0\;nc&a<q_L9Z&(xBN_:uS dFL23AP[!>e5H"[ %7k?\epUG#~S$sO6f1(I]YO4-i\ 8 } @ s      M    N H  7  E+<[Af  piozS:+Qmy~tUe$^Y3 :]x<w <%),+%f< vgdiw3Ru N6QuP~ 5bE U2}1+Y]H2n+*>F3B;;GI `v%glYSA8-.Z~]|#Dl%M~mR_,R A'CmK* wBz,kV%Dz89I<isbP+cq7~N~A  ?   1 V c a Y N kI (F B 9 6- "  / ~ % s sV 7  V l r 9 t d Z Z f 2 | "  ] z  9 Q p_ 7c h {h f b ^ ] W =  ]F / o ' >}  l7533|]:D,KX_4tcXP5 miVRwXg0}m/ I^t9-a-vfm%K&1200|K't6Xp2 BdJv[PVe&{PK^4N5jh 3E[s'?Ragm6{ *C|esmjfc]UG3-vz=8p|E|Fo n{vvSG *R=?6d(n u.(^XQM g>FHT{^~]@n R@z &<$P;eD{?2~cB-Zap'`C4r4QHCnHeiP|xS Iwlf  KD    G m    p; /  $ xc 3 C i & E t  d ;`   axM*#^}l$gOt64{!E)QbRD~J'&D\"l?zjY*!/V42+3Lct||~H|vrpjY`3E'G8W beE -Q[=)#~*Y=2c.'}LHCkB\K~5-3v`AkYc5Q3?^p"}^ # _ C    T    + ;H Y g ?q q sj X 6 8  ] 5 m 8 Y(>osb(TJ?P6/8/98FTO\^p_cjNwN!GuuM"%-159uBmQm_vknaBzD"B_\u5 v`D'PuP**=MYf{ AkK#=n {IT@zr*vn3VAIICRC`LoVxbvyl_N 3L yc63DjptX8m1.Lzqklxz? (_rZ@))l=e|9~p3x-l'Z>]I:9Z.v-B   - c   z Y ; #  N   `  * B8 C wD : %  Kr 9 ' 9 d = n I 9 ; L g% 4 : G X .N)qQ)  Q_2k nwZR$Xrf}K >AqnNx  E   <w .J@\qeaP32 W~x eGZPKF`:)E+ _ m K !    b$ %/ 8 D RP [ _ 0e j ml f T _9  GA dmL= _m: v6oWL-M^xW"A { YY:V&J)Z}G390v)3xM{%Va#whb7dlkx}z,qgo`YR|H73NhC$ H-dv# 8RcZ-P~H1|7?Wx@9UOa\j`m^cZJUTU]ek|*5 9#->Sj2|b x^8bF5-y1JD bU: mu.)f%[]c1&KCVuXTL?3$ r5|b8S72CnojtIp<DgrL/7# *i &  i   a   d   $ |7 r3 r y   9  t V" ,  | e35~ 3jvK" @m&d<7kdb>&!s4ZTF6*m IA A!;H]}; aDqT^N?-m7A wI-[ `8CEl UXuF H#3H\zzI[%ZHabRt7aH  y* O % M   e  @ ma ~  N 2 Gf , {; g fs y t TCx%7Miv2xlQ3*qv!nod} a)xK(p>!3PmCgiM:$d B(/BK*I8CC4NZfsbHyVmN$|=% Go^ /WS33\.) ho ] a " cB W ^ [ /K a* g ` %! aqMzimtkGRvzOO0Lt  c>&&?b",8PI[tA%@s%^yBSi;~!n5 &_Ye1(aNCdUE( \ S1Op!MJ4 -|-!K *X|[?)@k`3 L5 ^ p  w / oY | j y  ` [  a o Q8>"g bE+dJkFAfy.U} O&2AP!lJo @v)V~LOh?Cqw K&H =}"w,bk49 Rrlv 4]9U'1Qw/z#mcq/Z"qA\f.g^faWJ:"*\M5<S v&"<GiD2:`&D0{:dUGC4X8P5yh-/tsdQ0 lUY'1|(Ui8$   '5$?EHuHA6<+2YpiRBu8h8a@\G[M\SdTmLxA6) ~uqsy $EnBwX3Lq_n'{6 = V !p C o  "H ku   C z   L    RIL  gl U<HP|\b`%ZiY` ll~?6{5L'Ad5] fF:/#j +Bg\ H D]o)yH[}gppXx5L!E |iJ>6c_+G?FR[(w6~,_+]>L9w*zN"[uioQ#$P!{` _w_] ,  \  W &  ,  #+ R ,} A _ 4 9 n, =  a  {  ! G< u+a)gX M@ ~$Q/xM c/q E!z3ETx'H\[L5]5%"5KBvMVUJ69 `]:cqIc9Nwh`f{G:%^1}%] ) 6 CA tH J J M W 8d aq z | q ,S k# X8pij9R1guQ*_tcDP< $ ?rCe/(Y02lGW+^_M2OO[Alw']jH& jg z y lM Y @ C   w 0X 2 3 W X , x , z UL  k U  a [ Zq2!5.nW4{jqse$sj BS O=eFY 3LCJG.:&P B Ni7t*2D6vuv"EAkD~"aH. 0mWI#RpXBg,J%M7WJ7^z"HLhxW}wDneRXH_4[WgqF_\\=) -P~x<n`O#BmAK]Nv,n"S;nN&` J9r2HUQSB' SdH$XeNco , 3F Y d :i c N t* 2EzI:24pR pIt5IX0`efKk#v ?u )&4'APb{a4zgUxE<5'v3z`^B: ma?7qL)hN>:DUi{ 1T_I$Qe~).F` d:u 0X~1J_reB uXc65]vXCr<@Lb`~4b.hi!f7Mb*M1HqraO"C>"=BO[d|@v_)*Mg{|B f9 wgWEa2. o7z`D)@lZ7W7r-!3_2:~2?]^xtFx:ZppcK+\#nH!Y$b3|dMVPQWU^m;)'647,[|/}A{^9lwn?XR\rb: L/ZxbM=67>IWi|bH - $' qL* f1R(B[ouSIPe7wL!Jv^3<,f/RuX{KyU~@O9Znm c h ]  ZT O G ) ?Q ~ B ^ . M I_ d Z : , ' X) % .jh68uIQx`SMp> /Rn|~taH'#09;2g#An<b2nAo\0Lb5:uE w0o\h.0 vBG6b2AK6S\cMkwj6c    ~X6M 0q (3=NW_shXg*IsqhSl4. 7Iky}3ak70q+%|L]J>Z;=@>5,'"!,< Pi @$_@x\x7,qn*rb8 GIc$R~.vqwy *AYq*Eb>tJ[!L<}P >t9& r(7M o+ > B 8 R(  Zvs8"rS%0=A;0 %jzD)  euuL^#Y\_ix_?#PM{O .YaATsY[WES+SW[YG'%-t;/JZryS8& !'z.A7EXmUxMz,bC"xeN:$ '3>HS_lw>a+smu$1>\|bi (59731I%]vX.GQc~t^O=' ~6 --U~jS4PJhbE`}6Pu1G 0BXj   #!e &8uDHL\{CKgM. KMpf$/W0 L|:9 RfL-Oj ~3PcpvurroeWB$n+j+q`T NKCRA vd4OX14J j?f>vO*~ U6'")6;UUxxRx'*M$kagSA<0[p{}{ulrda]VXPUUXcZx`lx5Oh}4TqpcSC9#tWKSm/cJfIo:u%]SO \%(6=H?7&2nc,IF Y; _ @ P~ N 5 xs  v 26 I K ; q \ T Wc c y 3 +  2eQADz#w"R?9bYM,ULzuI2A*]-p6yB|Nv\hkVu?v$kV5iJ+rj^HG!1#v&/>h3#s(5>M tWX,ECE?loM &   \   c  @+~]Ch:wW"upu']K(]O% $'C{b"e A<&[ 2-QbEPU`-%@ Uakeqp;qs {x6XD gd}jo UO6  M  z 4OY]v': j'vMz!M&m[V^ttN$l@FdCC'JXb?z;BX itx~rUh4a[X TOLG<)}MT G-eez+\)B3])f;Ec$ ")3>PL_xj}.jL /GEXa]M19Y)$+P,z*& wcTrJ\E=DJXm8dIVB8 &_`"y M L) LE vo  @   r tR - # w iF'wj$=c/$.w[jD5<+&'&$5$'z(6,-' y|=7=xZqvqm2ZA+&:Pjy^JR:* ;[tvJ#Q!yfRE7p wG5 }TK W{mH#kP4@hnL 'Iw4N=3Xx7[ywfP<, t[>=cu4F_g~s#~)63T_xD%ZctqoQryTOJslTL5lwq\8 r42SGo / >EFG@4j(6  *Czgqmu*_ H](Y8-h:v? Ax_uQ8g|eEX&R_-{K qEO@kQj(|v1rf&fYq(}7T)u^E+=nZMOD? 87M8f@|Qg~ /DZCsW2=j ]=/u76_zz,w *5Sir?Kr W8Ap] / n 7c u e I       u ; p c ]S \ a l. { H E%1^ARhpvJ.7gfB^$yU5yohd_VnG\;O-I? 3W!b9qaI`qK: m!qs[N FNABDJV@kdi.<lWj;tvnr`Ii,tB-ti2N'" %tz6Ij%;LOSUG0&F fg ?n]#Y%P:$'qPmPa 6)ZG|f 4_Et <,f88-wW2i*i1]QG'dec0{E~E-gJGn%Rw]5H4!uE2j\3 JwmM+(=Vzu`M=,^,qrX7cvSR$/to:b_fvOg*s N4*A^}  8X~).-K,1>"Tqw8k!'"2Wy #2@L V_gki~c`[IQ # O[$Ll8m8O)8MI3n;] (oyG/zqL9#PjE zQ6w)**:yX$sJfz\XZdu,Fb~:Wx(BW)eYikjeb_ bee]L:*%/IvsS)@DLr&:mY 1M]c`O4'xPU{8 I ?c!*}/S08Kagx4 ,U{Z@0|$TSz\'}LX%xD ,U~!Fl3q{jZKGW&q-A8Qd'ul 7 R 2q B T f {       d D &\ 5  nC IsgA'bL9djKSz>z/ugg+_[[ZV}L=,#j_R+ R}~X)-1 pA < 0    $h &&   T  h   ^2RQ-eC<GypZmA'fD/$"&'%":/WAwLNI<-K~J}vMP;k4Pm)S<ywL03"h#0Jl2=0>a7-%c#$0E`j|CgPyB^?5[S"H`kpvlhaTRBA.2+,5G^W"dms<trpInoq/rrFwzRNXT &5^8c  u!?1fL(o0liq1b RV %`  $(.00c'=kPz8aBr9yJoL3C'!"g$$'+T6KmN =ggAK|P9$z7vuc7Pr:8HOJ{6nid^U\N#HDCF_L1S^jsHxsgQD0 [H2 Eo)sA,@WoFv27\`} 9M^fc\ VSV^k[U".Fd.C1VPmi0nDl/d !,.R47;=VBH%R`*qE`g#8=Xn + G W ] X !H [.  [g{'.;CAFIMTy[^]JZ<M12,# 7WY \_s)G$"Og|cPD?DP`u)Z +GbB{_8jFcv`}viNV@"Dc(T~/|"<k\nXSY:]"enx&?V\w6at(]FDb) Q$'2;>v8g%j~]7V auX;O1::y4s(j^ J2v_I:2/ *% 8BGKNQSTUSK<%k~:r e`_et\25hm3S  2CP\dnv~;` E/apz+l\~({~ :oy;%\7f 3_ X   C  ! + - $4 7 )   M d  n 9 fC),SN QdQA!'Dx&M B~re5SD90/0r6qCwWn,Dayl\I9B0c+-/17=CC8&zaIb@EKFVao|,:?8{)gE<q,`M@N83225a5(431E331X1/2<hP8l sZD~_; u @CPU2*TKpk3hIM[0c_S8yjisAwg> R$!)3;C{JZQ9X^]SEC1 >B!`3-EZui <2`h/5e':DC:' 8ffK1<S8l5|5;EzMgPJQ)ME8'NYj@>r|9l]ODqf1m&z ~oljCr|M($`G|zS- ud{W\P9S_rmZ&KHCjCOb|-IIes~7TvZ1s+|a]<.Y$Q1]-0HtgQMG|%i9W oO ~      q K ` " y:/hY3Al#^hT6XO{+MrZ~1~=W:&+`-:D_ ~7Y||}~Iz% 9 EIIMVflH# Mw Y?=k%%>p_YIDMIb>%-jIdT.m"SB21TuE hQv(Kz80wu 98 d 9 v5 "j  8 H !M `G 5  9  7P g   7 t '7DRfWL0RTS|QR"Co+1&KZ?0,U0/<Oj:oF/?a xZ>X(84 0Vxy)q>Z$(v%/fg2X2N c ;Ckj5Hd1&+>]N*'aKnRND$F*d@,Nev<~a|ywtodWE/c0U }rm/^VW3]ixb 4le #bl/s2~cLT=3/{24.5z5576G7h:DXn7RAiqw~|q^>{|zA k#MT5  O ;LyVeWPRAG5:,'$[X,y/!LppP (&)})8!1 g&E_+sp}0e<h]#0069=u;G7- k4DoYH=A512;`K0`vZ=(!)>^sdS;R  NvSd2 &``>;s"<~Nk[Uc9hg`O6T(bB#o5ZSDv*G?h 4&aI Or0 `N9%N$GgfG,c?! 1tF]VD_#^SC2p!;p:~Ij q9 S4 zO>lsr^PCn6 /*(w'U+A6:FAUYexV@oWV6K'_mzN|sHcS>'J~%W8)B=-\/E<w[MW'[c\ZY\Kcxny_:hDyQW(m,xlg1O0 wX?W1..=^Td#iY )Ji)ZCQTO]SZZReBr+z}}zrg] Q)GR>2,(<$w# 8Xy!,>X}/BLKUB2"(Nt,YYwi]Q`B2 9 x:^_}>8Yoea]._qjy#T|)CP`|?[ii\jF30`e jM]/ _ _z7hx7?TjqFx! ,dSh)~j|[lP`E^:f1t" ;tZkA*=u$R 6XnzztIpunp}:$l 14WY| ILRJvZwCrN:81:X';  sU Q 6 !  4 Q 'd 6n Js dq h \ H &  0O ; C If M KF@B:y1,'T#$$')2'&J#!ZT<   /&x1,<IWagvluqw3e":Rn9c)j &#=]HG:$&Nob!TSZ~i%C!bBj;BYhC_>`EkY}tCEit,{3RZTBk>K0Xx:> &4NF [qr#C g1E]EyN& 'r.B:Nlf)&j`Xb'\IX@7AEZr,ef2?Ljo M;0n$/:FS_lzkFrU4 Hq= `"HD(MsET- q,k6p=}FR]i{1J&^dt>:f  *6rHf\Sp<S~0?ubq<v2XkJ# 1QoOe%&6EXS8ar "nL@y `,*nBP\4x'Wp\J<.1i& !,*n8OnGn"T =>U}huz^xr kef_YKQG?88I9r==83+%!  !?$d%).2320*"lIhL1iCxIf9 Kf]D (j$i5yZ>( '2C=zJVb/lgs|%Lq-g2}ivfBT@*(StszTW7'C1w;`B#c)rmu(&5W=BLY h8{\ &C_~9].ES_db$Z K3 UY.k J#a4vkaUG6[e24Qenoonot 8i$Krz~"^8 ;!d9Nb{ +2;fDHI.JHFB:56>O!fT[7.HpwERpL.9 o C'{6CO7Z|gtF N{obP!<I(n p' @C R Q E ( t_RH 0Z)]S+|?Pb0Dbwfm^NBO:66;NERe|oE"6Us~`@8"g 3^'7H3[Us}Z,5AjXuH3d@hR8AUgm0f9.~oajSOOIPTY cY n w ( C \ m s m [ B ; \ O i+38`>DKYUdwV*86/" B6f1 3^ 7e' IuHw |;ZU6l~|\A)hCiv"Q.u V`[9 opF<(  #0%MiUZ]R^`b gSn{v}6QdlhYA!ZPDR`4EI\ >(M V "-9jFJV0bn~!|RcgI|/zKt S7" )Cb&wDxYenrv}J")6TAFIK+M`QSUWX\c m}?ixs>smux~+[7Ugsx+rDkYbhSsBw*x vpmkPigcYI/~ upj_IO@4&[ S(ivKP&1vi_Y Z^g t0HePV&WL\&3o 2|gKf7Il(gK9l/U-@1.<Rq Ih3\~hS9# ] 5.`Kn y"d7OJ>[)fnk\E#s\K?I<BGkNSTQ:G7% aC+eA ~{zvobN7 @t(>0VuqJANg8t-Okv`QHFGIIHGB<5'yiYD.d+KyC?s~!eDQp<*"YWV|z}|Kw5.p%1=ElDY@B9+,[~M<U`BwO[/`\]yXe6z =}%N|z.&IJbjxJ~|tjV?&2Lf~HqOG HLw7\Eo2EVer;d*f%-)-q&!< s.Lj9*\Pp " =7 [W o ~ z c -= @ Pau7(m5OJkota@4D{weTIBD;5437:>EP_r,D]r %)';]>XleXaDU.B&GmI'~Q!w;~eDF }Hi<1H_z!O2QHr6sCnQ<eQ%*V2',oHRZ:}E#Pvz`D'(Kuw\AQ$ S_0$MptYMPaLubN9A&{ #"1:XqlUHDFH KI5BM9i56;C P;afu .0cY$pDrn(/)|-%:dVY!RVd.r_uJc3VJ@<9|4H148CUNWeta3!_taERD5=#V9XpviV>"c=-l@XPHb6r&*=X-w=C?4#Eq)01.*' $"-8BN\ m  "4Sy#6Lb:{^- Z#:SlyFjyL_4B#|HmZlE3'f@`"1 {dUJGO`{-AQa!n>{aP=xog/]xSIBB<~72.$*\#!b'9-671# gP?2y+L/":Ohh6rF# $Chk?"QtWD89QBP]iwLS;Ga@zpf\K4eB~y{ 9Un9X}/M&mU U7VlyGo|qa%P\A3%V 3\xfP:$d5#a9!I\rRL-VgTJHGB32XhFE%8'{!pW-Mr4Zx1f#)%kM)W"h*v@`sQ`zO(0>Wg9 -Kr Q3`G5'# !3#b(07;9@uBEF->l27} |Okdjz:iO6P#hQ{ .QuhC8[} @&hCb:n*8DChJMNLD;D5i11:Me  9Tr;Xs!8PcnqiV7 #?C\y8tB l *Z45C ]:]9H-Oepgp\hX`YX_PiNxNQV^hr}49Rcq$<Tl~xgYO1:$m:`!+0<??h6A%d*y=l7qI?!b\, @usX>R'IsyW6  &&%Bj r e1^?ZQXeV~W[ZXP9G]?|5,% lJapHl|~3M a}v&[Fa6//'17b> BGKJR ^is~OCm PRGE{?Z_$$bNoy1]B<RauWH*BP~U9QD3^JtVs;I## vR+f(6fR &rP"ofC , Yb37QqnR87Obwyi_ZYbk qndWD!4$"*14783,"tcWRXf}?[q~uldZO%>])U 'Db,Mm?p+03567"6*4105/5+1)'++++(&e"4}N vM"\.VZq7eV I?5-%% 9$Q$m$!$,7QG[uB 9BgZ=c%>MUUOC8 -" yQ x;lYLDHFGK_P.V`gik`hBb)]VMFB@>9580a+# 0^W*M @y3 pM1 x^LC>>A8EXKzS`vHz7Ss1YBt$Iq>n ()J"y :g!O|yi[I9 ' ! ~tvRl)dXNDY90.4WCYr4LQ sME1s Z )*At^ ] ]8}'h;sA b2yYxyl]M:(h<6uAN Aa0v1F^JG Sk8i6]j:<G}scT;D6* m@%~:VvIw!SI 5m%+,,*)W!)<~Nb[Fg+px<g@q GT|)wl{8Uht qfUA)$ 1D]{xR+g*b (=2Z%d*:@A;=5f1/1I<J^MyPl 1nb_eytlgm%BFolA.dPm#Oy->O]Skx67tF%j40Noo&<0Xz`g7~yw*zU~8r@r& k*15M4,: 5vBADc<E d` )Ym.JL0`pxytk%`1U[2f&py2QtnS8Ep6sR^gIy6#{rcN9uU/wuG`H,DBn_YW=]fq]zz1{K ~reW{I`4XHu%Q=~K G 9^WGm$DhkV?&"#_!rPEoeW%>"eJ:w1U,21<Nf_7 ._mL4A#l(:IO~fw2xqdE@` LtU{Z4:LauiL,lL0 w d L /='d<Qg@d 1pY\J:* "*18<A)I9VMcet0`=a  w_F1 mI"]h@A"kPx8j'ZOC';76M5i7=HUm8W,y_5Ki4@c^x! zJd$e3QFG'QerC-=WH$TY^`bdb_ZUM?'*PvfC!(.7^EXp<\*d3uYn=A&n5vW?0$2S{!)7GN^w PP4V8QTqWX%2<DfF>07vC_Vp*y~[>" dB!)AW`m3=o,uB (?TmrS7'XCm K/U| ;h +Id-8;7,ncF"MIHc(l9h n?F"r6j\StRSY0cuups $Dm F)>UjFr;2yHV\D]VH6?'s &R{a;8ThxqbTF8) 6f~qMjgd[cRH<^0$ _  5k'5EUdnqko^NO-< * f0 *o9%GTa5o~)qGAi_l!T;!1AbXf4 sd ZUX`l|"8Pl-5>G+QO]qoBrGmsW=#'3=DFiEB? 3 m<:Xiu6oO3 Cj%/: E/NNWl`lu} ?y{m]BI".xG7mP Eu *GT%X}c?!;[weQ)>Q-v   4gGPX;j-|$ $.>Ret||{v`iDQ'3 ~F`=s@ucXUP!KB;m0&#@ a T+w j `3_I__axejp{@s$Bci2wBr9u=uT"W2KfIpJ|l D,EV\EYJ36ur~%dK3^+a,a9&9K`w 8'b,*"#Z3cc=e?g: `6 g* (q47BJPMEo7^$TNHC@<73/-1:!H4ZFu\tGn%.A6a=GSaq2HZj|| x-uPvuxz|$Ed!8'L6YDaNcPbM`E^6`"e nv}hL5# fG%tG!3*TAy[{,Z$Il/J^p~%28:8,ugYOKPE?917+%"(!"h) /6U<>AqB4CB@9/!tjdchr #6G`Z>m~uGG O )09K>@EI{HJA4v|nKrwRR4M+f I4_L-{c&dHi1s>o es1Jk~C c- $V4!ET_gbo>tsmcUF33NqjAo<9ShzteUC5' TlB+^\9;g .Pv: ]0Su^s.K rG`/S\$5 X,U"gR@|0n"bZTQU \4fKtk 6a"Gm*Z+b1I#[fitz)~i{o\H41_6ia=8ej0Mb.yV/5Nt:w5r%^*DH_qw 0<>91v$eN4o8nr/SE^}z.L m2G]5xy yJ+zN,nF/_xsaYY2YTayjt$+28=@?:7/" 7WN +/10-)#%3ANY`fovtjwbyZrRjK^DLA:D#K Wm&Oq*5=@?d8+1cY#TY&/p Z[.=[_@( -Rrwlc \WTRT^|mY92Os^7+I_p{|{yxz}{iWsB\+>]s/M&W-rIoX^!OA1"Kd*]- -Wyk4`wXRRKT_pcB 3\<Y:r$\:VsIq+-=]KSY^cehmt~NMbq[ED( m]L9z#b E'`B%Ab=^{uW6S!Pb#b$s=@ZytW8 {wy,<KXbj s!~6Mg"A6[rlz-i{OpcUC.,R t 'Fg%Jw  I {    "$029?@KBR@U;U1P$GB;4/,+z(i"]QD 6 } tokfb^ZUMC8-  6Qp$1BYr #(9,Q,e(t&~%(-v2b;GD'N[l|m9p8 #`+./27:d;16.'h ;gH.uU0zFr-0'w@Yu|:v6Z]<"[|` HE5y,*-7.HT^v}/c1W{Dn Gg=wCu)[tA%0hpB(Oss=n#=6 I^qvCygx^i]VdCp/wP&);UzuhU=#KwT$,bsMP,,\$=Un}~|tgU?.'9 ?<5+~`A#x^D* p^I4|"S,|[|;v rmg^R>* "Ju,=O!fKv?2lOk+\>ga<ChyR*+Wi/'YC `&,1=M_ruK%%=Xw $=RAbeq}%8L ^p~ pY=y~Ds ib^G\ [^edo.~PTa (EWeb:tZByQ .VdM!9G(kwmnuwt r>v^~?b|hXQT[l&7BGgXiw{qh_ZZoZM]*e sjX2GO=g8{3/( %LuwY;%Jrf1Me4D0qd`SD5(Hu   "&257F2X%k~zbN9&%,/158>FRap{upg[MB8{+jW I>83.'mR9 hA~iXGZ3%|D _1s`YUY'`qrG.X^G;U89M(DgM6k#<PBasp{Dc{pY=lM+yGzpcPUE5)#c#3)1:EMzQkV`W[QUFJ5;-q_K: (-?Rg| "&k*A*+-.m1-6=AxF8IHHyC8=95d8 =CMXYk~i97X} y;ePS`Al5q-q+m0g:bJa`fxo|M'7=tOZb3esb[R4Fr7%=g ;Yz&7MUqs6Qlxpf+\IRdG|>5.&ukc\]W5X[bjtf5{\F5,*.:GUi} /@Pcq ~"$$# ]4 oL+! <Wq]2\*!!SsBkS:"  \3  U#t"1$(0W: EUkNj'JD4_'x'1AZy!?yah[NB:O513:RESds1[)B,XIimz6{grg\MC;%1fU#%AnZ@wP>Zxh? yM(#-,"jXKC1?N=i:73*.[2}eU*)]_+<ioH% 5J`vyqjb[TL@-  q"M'*+ --* tZ@' ygXI;2,&z&s(m*i0h;fCeMeYkcsqy|~|wocZQ*LFLeQ]r8'i?Vq/`'S|kJ+ 9RizO (KSlS }97Zz}K $8tLXa>?~DnJXUAb(reB &}3]FB^(} "TfA:rA}tjVA1-#X '6I]u 0NkoV='rY>!}Yr4a N:$w F\~5bF0hT?% uL *XzW84lM=~;d<}N ;$40|>Pc%wLp.RwzbH!/&%!lQ7 mO/xY=|rg[gOJC/7*!   y_C) rO)".67u2A+ R3?'4`C!Q`o]72F\p!M> %>SliFH 1f/!^"&1< F-PHZ_fvs2GZfnm.h=aNW^NoC~8+ }.h=TK>\&k zp[Jp@U6;/+),19p?FD DCGKQ\jx>^{iQ3pB '9Ji^Cxf:/EYiCwo1}urnHcWM?3&_B +S #%m!. j ( d"&8OmoQ< ,:!f!'D/w5BRb*vG_oy{"{Pzz{v!nYdZQI(DRA|EQaq,Z+9I]yz];Gv[#)Lyv L8 cS!3RE$UgzhWKDB> <6/+(*2B}WcrL14N`lvraL5>jbC8$p1KbzzhVB, nU 6mG$y[<wbS KJ2JMOjQVVTQKG HM%V4bJqg+Mp+?Ul)AYr'N}(iv^'DY&rQ00DWgwTW1B]L#SVXy]]r~uiZJ29Q&t)kCXZHq<2*# ~`B wR- }W/rVr@Z1@,).9OnY//St]7"Grm[EJ<.%8 s!)J2{<Lb|"EiFo!Lv; X+uDZm|%AtYZn7 r@x~ahGW-G:0("vV6~dxOij Awn\@, I(-4eEZs!Fh*R!X*4@PTgiz~ &_;2Ql\(#Mw\.+AdZAs\/&:L`huL7(""(2@P i #NwqQ-+9BIQiYE^"afltqR4 %k?DY"p&y,j1Y7D9-;<<AEItNOQ,Q OMKHGJMwSg]VgBu/#A[r5Tw5Me|,a*[5K f)BXhpuBtrmaTB4*bs<RZ/v O/?Nx@ sB|'].C5/;!@GN X gy .?Qcv  (08BIPV[]ZTzJe=L/1# gL6%g M 2 "0CYcpF*q0IC#XnyW35RzrV5"Fjb>$Jqa8 <Uk~%Ed"Bd %4FLi`q|}9wcmZE,  #1:@C|EoF`CN?<:*1'} b(F0):HSZ_cca\WQF8+y"m`O8!,=Pe{hUG>76H7w=EKNLPQLD!8S(4FPV}U{N>& s!P>.[vylbZQMHC<3%\+a4 vS78Od{ &w;IUnk(I](F{]AT%%fW0Wy/G`z&DemEf#@3!ANUZ]\VI7~y_f?M!0{k_XY]gs(2>jHQS3_kvU$hz?bI-wT3kM*Vj[`c49 Rpx[ F86i.-0:EL{d~)O s4^:eKJ U(4 DGSbw(\(1WSw &!=8RLg^zm}~kXC.~z{u[C(~~~p^E(|rfiZGL,;1& !#&*/;:NG_Ru]fo{%08<<5*5Pjj4r,ft'onkjk,jgdqa2ZSLtF3@7.j#' q;q]I7( )058=GsSabIs.Ku^I%7^)7n)>T=ESf#EwgcN:%1DwQQ_-l wycP=(sKNpI$?i6j.BS`n~kU?- '8L#`0vC\x 2Y#A^{/W{,\ B*j146751'(? Vmi?5L\hhp)zX o}r6eWHc7#&yGt^K6#5*N=gQd{  }hN1xQw+l`VE2 `:c7(7FjSLb5t"W wHkeca+_b\TI:^(L~fB   !r_%Q*G/A6?=@NIcW}k<W?ng&Y +IpbZt@( sT3 ]/vL n^J9)  ",7@IPWa%o4|F\t:\} 6JTSG1wlebTbcebbVa4^__]\[ZYXUuSfJZ>O.D<2' |^A% %9St}hGRz7I|(JgCitZ09V}U BqO!Sz<Ww8T B>j^~/CS ]_#^+Q/B.,*! { O  $^2-@Qdw~_H5%   %q+S/711*!unjfghgecdhnt~\6 qJ"wL"X1 v]?pH$p@o;wI Bhd7 7kd=PsC;97K8:=CKLW}dx&Lr;v>4X| PD[l Ez2Rq-Pm{]= {pdZMz@^5>+!*Jfo_PB81+m(['K'?(3*(0 8CP _ n z.Cy\nz^L5 #>YuiR8T$f.|;h!jIO7  JzbRGBCJWfw4NjvcS5Eb9/'%'R*09ESJcts)He$08;92&  s1XF;_~Y(3Gfd ;.Ru|K1?oJ]PQSJTGQENEJEBF<G5G.I+J,N1W7e;x?@?7+# ?Zv^3@`z|M${ofybrbkjcx^WQLD9*xR(xmdZ^9^bo>^"T1cytr#s5vH~\u&5AMWc t-C[r#Ei0G3aQ{nAa{ u3ZC>Ranv{a)n)|Rm ]N@N. o3Lqha^^3[YZ[bho}0@GIF</"|]?"ui[NA1zu|qFonotrI( 0Rs .U$e8} Q[w7i^XI</% )A ['s0688;AL]ppT*8?SgzoW:m9  L [' /?O^iqtvx|)@Vm &4CU!d4oMyfxm]L7ux\MH":0'!uM&c;upS]2K;0,,5mDL[-yHzy[srooLsy'Ge@e9 e %Sb 88 fyH7s%b\C'":M[eov} /?Q`ny~pZC(tEn8ydSIDFOx_mu_P@. tU8d>jD wV2w ^B)e:uncZY@U%XaqqJ$CvmD>mvJcuVMG @F91%:u K ~/D_'c(mEuK'T\1%\B[s $9ITWUMD=50(" rZC)qK$];p]J5!u]E.*D^p4G\sy_G, %;M`o}oW>& )}=hQSd:wvA mRd{}gQ9 $-Rv!Df |7teohb\YFWvX[^gr,8?CB@>A8FXOu[gu*AWn   !3EYr#6GXkzT)m? lDi7b/V%vQ/th]TKC<4,$$-7>)B3@A9L,SWURMG@:6p1_,L$:% kL*xU7$4BScx $Y a6zKO/Mm8[zl]M?5-*,3:hGFZ#o |$h6QE7T_hovxU4lDeO:+"-BX j{ $().+?*L,U1W9THP\Ht=3'0X{!-8DL`Q=PG:&bD+yN$lHw$aM8&lH'oC1Jfy_K9W-!L ! 4-NPom(]2Q.o^9` D}|fJ,4 nv*TL3lp_O@2$  #+01/(u]?jW~Fx9p0e-Y+F*4'!" #)2>JTY]`ckuzmaUKD?=?CHMTW\` behk%j,d4Y<KD;M(T\cfkmdn3mbTEo1B`<yk_]Q=H@81' |ssz_> 7f}\; !0 Z :huld:\uRG<40z%A.1FkdRFw"RJz?e%4EU"f.v49<<>=<;71&lO|0bI1uP)|vamFb-XM @5# *3l9Q;6< @ EINV_iutW~8AmF|ojT<":Zy{_C( }n_ O"=:(Peu~eJ-|sme[kNUBF5:(1,)()()(&"( /6?EHIA4!@ihM2  6] #=-f5;@GQ_,nE}[pt`I2%5FWi|y_C$ b/7DVevV,nI ( 6Le4Je| 0Hd}Nu?$ ;RluAyL#}rkes^_UNH?75!/./01t3N2+0 0.-,)$*IlqAfk\RKD?!:E4l-$$Y>wsi>bh``gp|1?JRTRH5>X5-&  (#F)`/v9ESbr/=IOPOMJGDxGpNjXeha{_\[Z[[VMB3   (3?JR{Y_]B_%diov}|_?X*  V b:|nf`}]qYlUgPdGbB_:^0\&XU TWY\]ZTH6 }skgvcj`\]OZ?W.QH@6.$nJ# 0Jg)8DR\4bida]UJKB7.1)j))-2B5t9AI T>dqu,X(Pxy[>#  sU8}Z5(<R`lkv@{wP*xeUJA= ? C;IXPuW_js~ #)-.01.(#( 7CO\iz#BbzyhQ: |Wk.O3T)}hyVOB&0jAtI =p\\{KBBKY/nXF?zj>lL|21U[t 0Qre&DG#h{`N=/& !+:HmWUg?v-sia`ycefMj8o(vz{|zz{yz~s]F-zpe\OC{9k/Y'F"0!&+.//x.s/r2u4~6:@DMV`it~  "$2^<3FNSY[`Z8TJ?5) c< i?}fO;% 'Bx]fzXL>1 !4_KnZ)Ff2Z E{mb4`gdm{$Q~/V$Iq6c8\~ =Vm5GWfsxiS6sSl/P7  Z,yO)w eQ<$ Y)Y(nVA." :Ww*` @unU@:\uyW9! {iZL@70+&%('%$>Tj ~ (<RmpR3)9IWl@`}tle^R$H@;[(vm H$2EZne<i?eG. &6Lc|$7GR Y*]M\qVI7! ,9DLjVJb&qf,w;sfX8>"a?#_8eN;,! +?Rj!'-6B0Qgar\ a Z D}(a#Dav-Ie}~eG+  )29DLU\chm$s3u<yA}G~EB@?>?AAEGIMS[`gjm}pynyl|f\O?2% tL!~<U[+vY4d9 a@"~kT=& wdM7#kR ;%*5BNUYXWTRQN}PrSeRWRGN8E)8(v\E1! %5 I`)w5;?@?==;n8546Z=ER aCtzIx/I2d\{ /Tv-uTczP<* }\;|O \/a? oS;&  ;Xq)<Tp(Fby!1<HUbqzgTA+xofZL:'lU< `6 ~`DZ*-gD!oe^[a^Be%s <e6Ss)`Gz` 8Z}50kZ}'+,)  4K`qvO)nO1yhXK;+ ueV,H>:J.RVUTSVZbkr{f@tT7{l]PA4*!yqnqv~z5oL^dH~, }Y*97@CC>5^(=t_N%?.75/;,9)3('-5BSlq\+EQ-|Z3~}m\ LN8# J g2LT4r!$2DW*k@~Uo /Q9sb-V2}Kbz/;EJGA9/$c>[*q_qGH, Gt_PsG(FIRF_o{p0{^I6*"*Fc=[y{gYLB=9#7F6k3/)!+;FMPNMG>5(~umf_ ]Y&X3Z@]Pa`fpmt|>_!!;3UHmYm n$X(D-61)7=A EHLRXdpkQ7<[vX/(n7I@"GPX_eflKv5"~_A qa-U>NMJWK`NeRkVoZo`mll}mooop o/kShqd^UMA4&q9wpj(\L6Ra.wU7\7Y1 tdUvNhJfLfQoYfv@f2HJb|C'Rg}C ?tf:@|\u)X &.14768f<H=->=:73/*%!}~ &|5hFXWPgLwLS]htsR+sEoC%,27l=E@ BCGLQs[Me'nx|}zqybjPY:J<)[,]s@d&WOJNQXblwsjcw^k]`]X_NcHlCw=<71,$ 1G[n$,0?7b;=>:%8[4.(#0^!D(t1:H U:^kehkpp(rGsatwstst{ !(,-)#  $%|&W1  {Y7hQ8"v R. ~`A"ufWJ@:6719S=uAEKS[h6vNdz$'17:HAWIfOrR|ROG:,~wog`ZUNC6u$a K3jG&oZtHR60& n]I6" }}{z&T18lp#_I{I?bP -@P&]/d7iAkKjYej^zSE5! sZ~?m%_ TKFB@o@J?%=;72+&teY SRXdtlS;& +@UjydM8# yeP=*hG%}hSD2hC /zKfiN9$5Tsq\F3#+ BXp &6Ja~a>Ft;}qtfWJL;*Erx\A$*@Wkz,BXm ":Wv+Rv   (30E=WKlYhy $2sC_VCl%kF |Y-x]C:/ V`n"Pb/rF*:L`s~\0p5;@HCQv]l{#RG/|m/4r{He%Rk,@bh.@Q`lu|~ywanGc-WMB6)|m\J6% |lZF2  &;ySrpkgddfks|!.574,vW1 oF{W1 {U/kqP]6G$-~Z6ukc[VSSU[en}uf|TF;658>CJMOPSXY\,\F[cYXUQMI D#?@9]7x79AL\rFs.[v jC^hUQKH G5G^KNPQPM M$N:MQOgRzX_gpv}wbM2c@pV;!t\B%lO3_># v8mSipils} !4DTdr$~8GWfs+5?D GKJE</ u[<}q}aZM>8)!  }j[J=3,**.05=GYnFr4[$S1K,cRuv )Fd~ tS1sbRE;1(fP?0&!(1n>^LL^9p'v^I5 "7RnsZC0"mG!yeP_=>)!{gTDo8\1E..2<HYnw s!q9qRtkvxz|{!|N}~Dt #5"A4IFM]KuGA5&1OofK21Uz Eue[}C+wg[TQR TYa'j0v<EP^l|   7Og *Ga} 1Tw*=nMZ[Fe3ijd\N<& XxqjRi kjjjljqgfca@_\Z{Y2&Y) u^G5# #*09BKWfv %3?M[jztg~ZlQWH?A$;52*"M i/a5 kQ4qQ3xnhgmxwo3h[ffiq{Bb;Fe};1kK Z>u,\ -Lf:z`vi\<NV?o.lR9 xdN5hD!|xsnf\tQ\IC@*<<@IWj "71MDdSy^ehfd]SH6!"!lH$rO)[0zkWbB=*tO*iYK?:7 69;!@#F"MWcn| (8Law6Md{ 'Bb=e"sGeiYPIGGFEE&E<IOObTu[epv}~}zw u p3mBmMoUrUwQ{H7%eL4nT<&|iT>#{ejRK@.2' uU8%.8CP]jv!1CVj 8Pg2Mh .@MW\`cceyedcL_3YPG<. w`I8'^B) !.;HQYakt1Kb}!2BQ?]`jw5X{9Tmzofa\XWVTQQOLF=2j#UA1%nV=("|/m?^OI_1p~uhZ!O1B>5J)Ygwp\G3 {[9ucP9#jO3jO5 |pf\SMIHJOYfw~,~Kk )Kn6 ^3\Bq0DT^=``_[TLC8.")4 =GQ^itdA\4 rT<,"!#/@To.+=2O3b/u'3Kgp^PD;4.5,U+s*,/243/-)D Ym {vaF$~xlt8sqqqDsv||6e] o2GfJ1)9J^v"/;HW h.{Sw-$G:cO{i# Eb(4AJT_gk&p:oOkbet_[SJE@84-'+9*E+O0X6\?_J`Zam_XOF=3(0Ia~0EXfq}uS/n6R}jVq>?"|]Dv/dVKD?<=@DKQW^elv $.7.ADIVRc[kcpkttt}rohc\TPIA;0$}rdTAi.F$ jCv]aC@' |skaWJ<,#A` Ad(6EUg~#FmC8foL {0X-Nn=_*<)EKFl=./H]mx|fWJ?1% r^N8! wngazZ]U>OIB?@CeE?IIJNQX`iu  4GYkypT6lK* y_jGG,%joCJ$mL2 %,)3:8M=bAtDFIKKIFFC0CKBgCHMQW\!_@badefhkos)w:{IU]`]WK<)9Z{|*sKkjd`YUSQTX_gp{ 1CTgu{m`VLA;50.)%rdWI8&u_I6# x`I0zfUF:y2W+7'''(*-/0220/,**,3;HWev*Hi#8:IYZ}ly.H]n{}l^Mw>k3]'L9$ti|dddkv %/9CP[h x)<Odx6Y|vc3RCDR5`*l$u~~oaUI?p7W/?$) *=}PceKz3  $0;HTawllwbRB/~a|Cu ng`YN{A^0C& {mbOK36#zj[OGB>9868ALZn &Da6(UAt_~  +1KVl}%L>p_{'?Wq|nbRC3%7H[m\.rH ueR>){z0Mhzt'l8dJ]^WrNIA:84/#*8%O"cv iM,v=EH RS){j\xS\JCC/B!CH PZdq~1.G<^Pth0;O]o!%E?lYr1Kf*4=zClEbI`NdOqKID?7, ,49>ADFHuKmOfXacZmP}I@7- %<Una@pFk`NA/#  k_WsPdKWGKB@A6B*EJQ Ycls} $:Uo}kS;|!unbR@)|aJ3ry\pFe1XOF@=>DMZjm\L>1(!$C a$~*6EVk%Hj7ZA~g +:Jfh &)C3b;CINS W.ZQZrWTQNLJI FC@#:-34+="JU bpzt|jwco]cZWXGV3VWYZ]^i`Cbbcbbawa`_Ja8f)kqs uwy{|{xtpmh^SE2 ").|1m5^7P:B=0A?;7,\8pWC1x$iY I=1)!o WA. %3@MZeox'=Up 1Tv ) C_{!(.220/8,M)_*p+|/8AM[ujhxWD4%  #.9ER_jx#&)-/1579;95/%udUC1 ~ fM4`?xV9 xi^URNMQTY_foy1Iay->O(]Gjgv"-7?FI{KqMkMgOeReXh^miuu|2F}[rkezXI=/#| n`P@/    (?Um{aE+ )8GVet~~zsmaQ?(~xqj`pTZFB6)! xW7yk]OB3"}pg`ZTPPPQ}QsQkScR`QbQgQqUXY]__aad!i9lUqrx)Qx (#GGhk 2 L4gEXl 1EUepzS6 +LjgH(kUB5) pZE2 |tqu y!7J_rzj!V.C;1J Zjyz]9RNY.u|h`YHJ0@5/-,04;BGQ_n{y}*C]v/Mg ,Pw6V*tW#Ed   &4DS`lxzrjd]~XtRjK_BS9H/:$/'"#(.8GUcriR8 hN 4 }l]PC5*      {pe]YVWY[_bcvdmfihglhnlsoxq}qoh_QA}-xqkhfa]WkPPH5A:2(xtpmkjf#d%a(]-V1Q9L@FJ?W8e/x% 'Fh%;7XJu^v&/<MQjcr~2Vy=a~xutw ,:DOV[bhpz{qg]SG<4+&t#h$V&D*-08CLRZakiQq8v y|}sZAy,tmcZPF:."{vsclNe9['RKB=6.( uaM9' ~hP 8 % %:Sl#*/2K9f>CHKQV Y%[>\U^laegjmopq1sGt]upwzzsomipRs5u| (2:DQ^l|    y`E){pg_YS|NYH6@5* iQ;) v k c Z SKGDCEKT`q !!(70M9eE}R]jy, BWl!&%# 'A \ w!)06$<1<<=G<R9Z6_1b-h'i jieb`^_diooTu8~! wmbSD4#xoh]VMD@< :=?*A2G;LCQLUVZbamjwv~zsh\N:' !"$(,x1k5[9O=<?*@@>>=<;6/j%U>+eK1}wqi`VI;,&5FVfy "/:E,QV[~cjpv9~h +H `%u=Vo#t2dBOR8asuZ>$   !!#$#$"xncVI:,# {u-m?cMYWN`Ae5i+l!rx}   %.48<:4,z Z6mA{qi|b[\?W'SPPPNHA81+$n#]#P'@,13$@M Zi{ 0,EB\Zov"F1iTx *O#w,2689.<L<e?{DJPTXY[]^_bzgsljqdrZsRuIr<n/i!d]WSOHC=3(   $)1y7i?XGCQ2\ ess`~L{:{'{uaM:) xmdZqR^GL>81$$ zl\J:+ "/<}JzZzf~s~.CXo6Ql -9IZo $D c&,28?ELRX+`CfXikmqrrsoida/Z@WPS]OhJqCy=4+  |mZG3kR;" ubQB6+! }doM]9J&7(xaL9+|wuu y~  +8GUgyzusqomigghjox|k^RIC:(5>.U)m$$0"<5MJ[_juw &>Rfxt\D+ypic\UME4)(;Qj"&(D-[3r9@JWdp|{svasNn<h'bYPH;,d E$wakLQ:5( !6Kbz 0Sv+7CQ#`6rDQ]ipt|6Ne *Iezsmf'`A]WZmZ\\]\ZSKB7, dH.|vnbS~Dl1] QF<3(yvx| !($6&D'Q%[#fnt{ {jXF2 y^F1vcTD1#yrlf`XPIB?=,A3H5P7[9h:v999:?FMZgv>`/[  '"88MIcYxgpvzyundVE3 $2?JV`jvvdRA1!|wutspnmnosvwywxvls`lUbIYCM@;?(@BEIPV^`dBj(pw #-6 >&D+I.K2N8R:U:U;T8P1G%:*xX8~uqnhfgaR\@X/T OHA82*" "2Ga 2Uv*D`| 9Qm4FVc#n=uVzl||{{||}{{zocWI9w'lcWLA80+*+.29<CJQZ_dhijifc]XNC6"b E+(5=EMT[`emwsk|^RJA:2$ |tj]P@/yslbVF3qW<#yz~}sjd_[X YY(Z8^HeZmly| &07=A%B-C3F:HBJGHOIXKdErB<74100 3%5>9S@hDxIMNQPOOQV[bju~(!;-P6b=uCGLOSVYXU%R;NSIlE@=>?@C C@(?4;?6F0P(W\begjjifa\QC2th`VMkIKE,B>;9652|3g8S@BH2Q Y _eiihe^}VfKO?8/ywtlrapXnQkJhDf@c:b3]-X(S$N%L'J-H9HGFXEjC|@<740/17AM^ p!+1444/)!#2CR`pjS>. %A_ ~ ,:&IE[`lxw~{yxzxdK4q`qOb@U0K#C<3,$,=Pez5GWeovz{${'y*y)z'}%~ }seVD4!k V?.t\C+m[J7%:Xw -Mq ++Woq\E/paTEv8g+ZK:&qT5|vponoms\vP~GA@EKS]iv  -?QbvxgUB)zwp_gI^3XS QQQSSTSPPLF?83126>FNU[zZoVfO\GW=U4R,R%T"V!X!Y'[1^=cLjYqe{nv|}zuqono u~  'Fg%3C0SNahm~{  '9H[kzlW>% {vrpnkid_~]oZ`VMV9T#SQOONNyR_WD`,ioy #/9DMV\]\ZUND7* qU7|^B(vbO<,  +>Tj!-9CP"^Dmd~<^3K`u0>JSY\\\YURPPSzUr[m^gdch^jWlRkMjGjAi=e8b2[/Q)G!<3' )7ES^ht~ym^ L;&#+5@ITZr`Yd@i)klnoswz||{xv|rhmSh=c+^[YWUSQMIC;2' uiiI\&QE;3,~#bH2   -<M at *7GYm#7IYdkp"s5uGuXxf}t '2;BFGGFDCCCEJNW|_xgwpx{y -?#N*`/p6<ENXdq 'A[w !%''p(Y(=) (#"|fR?- jT=) lU<# bD)zpe\QF;, +5?IVdu$.(93B>JIRST]TeQoKzC:/# 8Qj|r1kIh^epdeipxxdN:&pv]jH\8N'B4 &  !-:I\o&6AGLNPONIDA91(tcQ>, w^D(vcyPu?v1y%!!<&[/y8BKT^$jFtg&Gj0 ?@P`b}r &>Tks"X2@E'Zlzk[M>0  ~cE~*f N7! hR<&}yz{}plhfhhhhjkjjhe dcc#g(m1w7:>>><:71+ $):Naq|{rgbQQ:@ /  bC* $*/16;BIS^ht~ %5G^+v:HT`my5Kas &5B J%P)S-U-T-N0E293-58;?EMV`fmtvwvsp}kmgYfCe.fks{ueXNA8/%lVA,wk_VJ?4)!    "&*)1-5.7-3.,.#/.00,*'#udS C4%   gQ;%#*19BKU]d kp-tBvYys|#>Yv 16HZ]~t':IValv}o`rPc@R3A$2%    ,;ITbnz"2CUfw|rfZOB4$kV|Br+h_WOHC@>|<o<d<[=S?J@BB:E/I"JMPOH@6'tV8qbUKCt>g>Y>N?CE6I,P!Yco|)9HYm +8HWco+y@Ues "' ) ))'%#$&+2:FQZbipv{!1CUj3Lf1G\$q7GT_dfbYN@-   rT5aC%o ^PC4$ti`VzNcFL@6< 9 764359>yEfNUVF`9i,r"x n^PD;65568Um#2>+J3V7`9m6y/%rV:k{Nl0_M:% wjv_YR;F<4,&xk^SI?5+!"* 6CTfy '.4;CKS\dmsx !%(*)% @^}  3BMTVVRLE: .# '%     ucQB1"{ gT?.  '/7>HS^gnv}uj`WNF ?!7"/!(  o^K=/$  +:K`x$Mt#@ \"s;Rk 9Rj%9K_ps\C,'0;HTu`Wm7wjTB/zpe~_pWbKTAF68,'"     wncVJ9&{bM9&  |wttw~*=P`p%.7=ELPUY]$b3g@kKpSt[wa{e}iikmnqu} /@Qbq~tg\UQRY_n~&|3|?}IQY__`_]\\]_ekpou]|J8" zpkc]WQKF=5* qX?*|fO6)7GUd~sm]OA5+!  s h&\.Q8F@8I*U`m{#3CSbp}*7F[r1Oiytommqty~~zvoje]U{MwDu;t1q'omllmrx ~{!}$(,-...//--*# &.5?HqP^YM`>g1m"pruvwvroia\TMF@;81*"zqg[OC6) }n_Q D7* !$ %" "1@O^ju!*19CN\jz $')*('"   #!,(6.A3J8S:\?dDnGyKRZcp~5Me{ #-: DNW_fjmp|q`oDn*jifa_ZSvL\AA5'(wfpX[LFC1<8543345z5e5S6D75:(;? DJQYbiqz  + =L[l|  *6CTbp#*19@EJLK&F.C4?5;4926,4&2/,'$ s_H3 zjZJ:/$    ! ) 1 8 @ JSZckpvyz{z{||~xqj`WND:3, '" ~kXH7) "-7BMYgw7Uu  "+)I-c4<DP]iu$0>HTbo z-=L\oteS>'(7D|Pg^TkDv4&vbM7#vk`UK|Bi8S-=&-    sg\N@0"mYB.  '7GXhw+>Obr(1;CIP SY ` gpy!&*14;@GOV^emwykZD/0H_s{qida^[YVQJA4( udSE7'xocS?)%/8AnJ\RM[Bd9m3u.~+'# } sg.YDM[?u3& $<Uj~ %0>N`w  ,9FQ^itzspljjijjihfeb_\w[iY^USPIJC?<47(20*""+7GYk'6DNW][XPC5$vdP>+ '6CP[`gkkifc^XURNK~HwFoCg?b;^6X/U'SS TWZaiq|lS<(~o`N=-  *9FWhx "&*/38?GOYdq|! +2(;8FHQW]eiwu*D\p "-:CJQUWuWVU7OG>2#}gN9! ~n\G{6m(]Q F;2+&!q$a.V9HF@>;6/*%! }wqkd_ZXURPKHD|>s8l4g0a)\%V!OHA :61+' "*39@HOV[`abcba`^^`cgmqw~~ulbZPF 9.$  wjZNC;867;@EINTY]bfkqv~!0?(K;WOafh{ovz<`*:GOTWVTPI?5+!  #3CTeyp\G2 "-8BKSr\_bNf=l.l"gd^UMF@:40,)&#xlaXOE>5. '$ (.5= DMT\cioqqmhbWN~D|9~.~! ~lYF3s[@&&/9CKU]grz%1>L[l| )6ES_lxxj]RH>7/)&#(-4;CKT^gmq-w:}GS^hpw~wiXF2#0;GTa{oj|YK>2& {pdYPHA<6/(! zm]K;( (06?H|NtWo`hganXuQyJ~B<5/*"  &1?M^r|qh`ZVU/U?XM\[_gerj|pv|"0<GPX^c|iulpoknfjch_f[cXbUcRaP`N`L_H]CZ=T5O-J%C;5/ '" !.>N_q !"&'&&&&%%#m\J9)}odYRLEA =:9$<&>'D$KR[ bmyyiZQHB?<:743/.025;AJT]gr|{vspppruz ! 7Lat%1>N`p %&-24?8J7T6^3g/n,t(w&w"unf_ SE6&qY<y!dN7" |dN9&|uokihggfggh+l@nUojnnlfaXOE=#54-C)Q#\!b iquy#}(~,z3x9uBnKeS[^PiCs7- !3DVes (,06:>BFIKLNOOPNMLJIGIJKMOSRQSNJD;3)x!qic\TNGBAABDGIIIH|GwFtBq>n8m4k.k)j%i"i giige`]VRKE A#<'9)5*5,4+5,8+:'?$D!LT\huvlbXPIB;#6%0$, *(((*+/02577640*"~ +8CN["e8oO{i*C`|  $(** )!$!    } q*b2U?EI5V#fq{m_QF;*02'9?FHIJJJGFDAABEJQZeqwgWH9* y{rqmckUiBk0nsx}w`I3ycM8& $3DUfw .>M\ky$.8ES_kwq`QC5)~~ )7FS_kv #/;DLV`hpx,8CMV\afi|iuhje[bM^=Z+YYZ_djt}u]E/ zrkd_YTOKE?80)o$[J7%% *4@HR\dkpv|vi_SJD<8521/.-,+)*+,.1 7;CMU_is} ,:FOZ`gou} }|z#z'z+{/|2}5}:|=|>zByDyEyEyBz>y9x3y.y(u$o!h]QF;/&   &09AHMTXZ ^a"b)b3e>gHjRp\sexm}svy}|riz[pMdAY3L%=0${xutsqnkjfeggk osy{~{ywtpljij klqtuy|  "4 D*W3j=}FOXbny(5ETfwtbO:% xiZqJX6?$( iXFs9i-a"ZRMI C ? < ;=?E"J*P3Z=bHhWqfwv{"0>LWajouwwurpmhgd_\VSOLGB@==<;=@BC CB%@1>=>E<Q;\7e4o4{0.--,,--./1469<AEGIJzIrFnBj>d5`-\%ZVQ MJHJMPX^dimppqrpo~p}rzsxwvwpyl~e_XOI?6," xpf]VK A+67(DR brvdOA 5( %)06:<"=(</9357/;)?"@AA??>;83/,*(%!!&0:BJRY]bf+i;nLpYudxn{x &4BQ^lx"'*-++'#  zrhc[URKE?:2-' !.9EP]jvzmaUKA91(! 0=I VdqtaO<+xtqoakPi?f/fgilpuwz~vaK5 p \I8)*2: @ELT]enw )6FP [h p({18>FMRW\__^]]^_addeijjjigfdb\UPGA<6u2j-a'WND90%  &2&?2KAVPbanvz$5C P]!i/s;{GS^gmqtsojbVH8%p]J9( ~|vvpqhnej`g\b[^WXVQSLPGJDFEAI9P1[&fr zrg_VLE@=988779;;=AEKPW_cgmrwz } ~   #%()'&y"l_P A/yrnljiiikmkhf`ZUPKFDCBFHKOSY\`*d5g@lHpNuUyY~]]]^]YWSLE;2) {vqkfb^][ZZY[[\`dimsy  $ + 4=FPZhv !%*05 ;A&G3MATN\[dijurw{|}}{zwvrr}otljk_gVcJ\<X/OE ;0# ~hRA0"yk_UNFA>>>AEJNRV[^abcddbba`_^$^._9aDdNhSkZocthwmzr}uz}}ul`UH=1" zrkd_\XUTUWX|[p\d]X\N\D_;`5d)g"lrw{|tlaUF5",:GS`l|zjZL?5-%+:I Uaku}}qgYJ;-!   (1x>=;6.& $-4:@ HPV\$c+h1o6u:{>|@}A|Bw?p;g8]4S/F+7(*&& #$#"#!o^K8%pe\WS|TmX]_PeGh?n9p7p9s:t>tAvGxN|SY^bfinrtw| %(.1599:962-'#  $)-/269<?BFLRX^e jos(y2{:|D~MWajsyywsmh`XND7+ ~naRB5% tlaXPHB;73/-***,/1221/.+(" $2>LYeq~{j[K<0&-CVj{ y#o.g:\ETOLZEd>m7u0{*'"  %*/6=CKT[doz #.:EPzYpafi]oTsKtCu>s8q4m2i/i.g.g-g*i+m,p+u,y.}/~1~1110.,++)'#"(*,q/_1L4:8)9:;73.' nZE. ,y=pNi^anZPF<1%#+2 8>A!D+G6HBJMIWGbCm@x>9520-,)(*('&%#" !$').359;=@A{AnBcBZANAF>?;7913,-*%()- 059>EJRZcmw !(04'67;H>UFcNoWwclw|wqnljgec`^[ZWSQyNiMYJJH9G)EB=82+$ }zxxwvx|}yvrpkf a\WR!P#N"N#M$N%R'T'W([)_*e,k.q/v-z,+&  !-8AGLNQRQPOLHGFFHIMRTWZZZY!V.R;MJFX>f5u*{tojc^XRKE@91+$}qh]TJ>4)  "%*/369=@ACCAA><:840,*%! "$$%%$! " $#&')/*7/>3G7P=UA\GdLiOrQzRPNIEA:51,**$)-'5)=,E0L4R8]<h>q>}?;74-% +:GS_gpvz}|woeZM?2$~n\J8%{ph`XRKE@952.---,--+-.15;%>.B4H9I<O=V=[;b8g4o2u/|,+*&#!  ")18AHOX^dio#q,t2v=vDvLvWt_rgoonvl}he^ZRKE;2& yl`TJB:4-&!{tme\ULB:0')8EVdrwmcZSKB<3-'!)7DQ ^ kx #,6AKT_hptyi_SG<2( "*5>HQYbks{ $3CQaq}|tld\TMFA:5/)'%"""#%%%)+-023310,'# yn`TH:0&zj\M>1  (4>KXdq}p`QB7, # 2?LW`inrvw vs!o.i;aIYWQeHrA:0)#      !*37:?CEIMQ)W1]6b=k?q@yFJMPSVY_emv~yqjbYxOpEg?\9Q5C25/'.. +('# xmf^TOIB =9!5+434<5F7N;T?YD]J`P`TbZc`chgohth}gdb\TLC:0'#'-/269<BGMT\bhjknoqsuwy zz#x0s>mMd_YnM?2"{u p j fb^] ]] ^ ^` bdeeghjlmpsuy}|tme^VOIB=730/,)&  sfXMC ;)62/=+E(O$V![`bccb_ ] \[YYYYXUQMFA<61,) % !! $&)),/158>@CG JOR"X,^4a<dEgMkSmXr^wb~flou{ ~/yBwSvcqro~mifb^YVOG@8." )4@JRZ]a``^[WSNE?7,$  o\I6"rf[RI@80'"*4;AGJOTVWX#Z.X9WEVMVTS^PhOqK|IDA=61-*$  "'*, -/0"/*0.2457:8>9C<HAOEXI_PgSoWwYYXUSOJHFDDCA@><6/'zpf[QH?71)! zpdYOF=2( '3?O^umeVG:0(  !/=IValv"+4:DLS]hpw~tdUJ=3,'$!!##$'**-.---137<AIOTY`eiosy| "/=L[hv}umf^VPJD?><86679<@ABCA>:6.( ~sh\QI?84,(%" !$$(-/345y4j5Z7L8;;,=?DLNT\bjv~xme ]TM%D-A6<;7B7F6L7P8R8U:W>YAYGWMSRPZMaHiDr?z;730+'" !!   %4BNYahnpr s ssss$v*w.w3y7y:|<=???ACGJMQW^emt|v}jw^nTeM\FPAE;99/6&3!0,(#     wmid``_`a cfg#j(h0i5j9k=n@mCnEqHrJtMwP|QQPOLKKKLQRSVWWWTQLFB:2+#  %)/5=CGLLMOOONOOOLIGB>-:?3Q-c$u ~tle^!X"S$L%D"=#4"+$   #+6CQ^kw|qf_VOHA:2,% #)-.-,***./258;=ACFJQVY|_rbge^gWgLgCg=h4i-m&rvz~   } zuolie`[UPHB8 ."&(.3 :CMU^emw  *4>FMU\dkrx} )7FS`kt||sg\RG<2) !#%%#!~}   '+.w-m,d'X!J:'ui]RI?60+%!#,5;DN T[`dff ca^YV&T/R9QENVLeKvIFC?<96699:=?ABBCA<61(   #%')%-,/22478=;D=LAUC_FjHvHIGB@:2,$   {vpib[SNF?=8521001247u9c;O>>@.ABA@A?BEHMRZ^guqhyYL=/! #.;HUbn{%-7@HPV`iov~|sj`XPJEA?<<:9;;=<<>=>>?BEIMRZ^chlruuuuvuvxx'y6|E}Q`o{{qh^UNHC>:653.*'$! |rg]VOJEB?><<:741.-./2t5f;XCIK:R*Zd lv~vk cXLD9/&  #* 2 <GS\gqy~ $),,+,($ "-9GR^iq{}zvttvvvz|#'+*++('''&(*/4<ENV`lqxs~eZMA5+! }wsnjec`\XURNIGEDyFlG^ISKJL?N6P/R(S$T VWVU"T&R)P1M7J>GHFQDVA]Bb?i=l:o7t3w,x*z%} !$&**)'&# ~x t qppnoqrv{ +>Rfywme_ ZXXZ\^\[YSMC6+!-r9cETSF_:l-{" $0:BHLOSVX\_dinrw{yqibZOF:." ~ytqnlhf d_[UNH$@(7,-4#8>CJS\fox $*1$7/;9@BEOKXQcWm^wejosvxxwtohaWNE:1%ujbZUQONNPPOOPPPSUX\`gov}ytoh`WME%<-/3%6640+! }qcWNC;4-% "&*,/112459 :;<+=9>H=[=l99::=@BFIIJH EB?;40+&# "#%'(() * '$"!$'*.147=@HR^ky !  yph^UJC:1(!${+j4Y}5~.%~~ zwuuvuvuvttsqpop~ptognZmLm?k2j'ihhggeda^$['X.T4P:NAKGINGSGZH_FcGfHhHkHlHmHoEpAr=t7x3}/)$     }yxz{|"4zFu[qmnkkiiihhec_[WSNKGDA=94.*'!   {$q,h2`:Y@PGGN@T7[-_$emx '3=HR\emw~xmaUJ>2& ~xqic\U NF=7"-*"2: AINU[^fmt| " ( -39?&D/G6H<JCJJINHSFWE]CaAdAkArByEGKNMMKD>6+ |l\N@~3y'qkfa_[XWTPNKH GDB B*B7AE>T;d5s2-'" %('*+*++)%"~wme\VLE>6.'      $-7 B M Z es$)/49>ADE FGEDB>950"+'',#0!5<?@EIJ KMKKJFEA?>;;<>EMWcp      ~ukc[SMD@:52-w+h'X&I$;#+"$$'),/3:?GLS\cgxmkt\zM>0" $4BO\h s~!'*/47;?CHPZer~}tmfa\VRPLGB;71*%   ! &+)-90H2Z2i1z//,+.../0///--,++'&#wqhb^YUQNKIIGEGEFHJNPRVX[_adhknoqrstsssrmic[SH>4)  {uo iea]\\]_dgkqu| $(+---+' $ '1;DM T[bflpw|~}}{|~}~|yuqlic^ VN)G5>A7M1X+f'n$y#"  yog]YTQPQRUWZ]`cfkntx~~|xwtpnic^XQKD?;&8.675?5D4F4G3G.E)A%:50(  } wtr)n4m?nKnVn`piqqqyqqrpnkhheccb`_[WSPKHDBA@AA@AA@}AwAp@k?fAcC`EZHWKSPMTHZ@c9j3s*{" +8EO[gtwj_SJD>:632z0l1_3R5E98=.D&LU\ fou}!+5@JS\ ekr!x)~18@HOV\adcfgfgeecfeil}pvunyf^ULE:0%~sh^SI{As9k1b+W)O%G"> 7 . %$). 8@JWdq*4<EJOSWYXVUTSSQPONMLKIHDB@<955~5y4r5k3e2_2Z/X,T(Q%P OQSX\bjpy&.7@HRZ`g lotx z(~,}5}=|DzNxYrdnnkwgb`[VRMHB<5.)#        }l\N@0#|vpigdbdfhkqw}~reXLC:2+"    - ;KZjz &.7?IRZcmx}wrle^WOIB;6/*'#  #!/%@(S,b.s/369;=AEIJJJHDA;61,(" ysolhb_\XURNJGD@=:630,,)'''(),/27 >BF$K*N2T9YA\I_M`T`Z`_]dZhTlMnGl?l6k,i$f`]ZTOJFB?>;9862/*% "&*//3454541, & *2 ;DLV\djmrwxwxwxwy}~z~w}r|nxlujpjjleo`s[xWRLGA:4-("  # 1 ? O \ hx }zxu rqp)n3m;lAmDmHlIlEmDmAl<i:e6_1X-Q*G%>"4*"  {vrqmj!j"h$g%h'h(h*g)f+f-c-a1_4^6]9\<[@YDZFZJZMZN\Q]V`[cadfgkioksnwqyrys{u}x}z|}{{zxwusrokie`]YSNIA80( #.6?HMTZbjs|  }}m}^}P~C6)$3B Q(_/k8y?ELSX^dfjnpruw|th[OA3&~xsmgda|_s]k]d`\dVgOiJkJkHjIjMfPaTYYP^Dc7h+nry!)08>DHKNONNNLJGEDDCDCBDDEFECDA<962,z&t"pkea ZVSQMLMMOPSV[`ekotz $/7?FJO RV#W1Z@[NY]WkUxQMJD@93/(#zncWK>3'|m`QD9/%  ##$&$%2$@#O!_ly "*3:BLU_jvzqf_VOF>7/&  - ;HWer} "%#$%$$#" yqibXNA4+   ")26<AD*F5HAJMJXIbHkGsF{C?<73/,))(~${"wrle _[TNKD=70+! rld_^\^^adjpw   #+3;AGMQUZ][[\[X}VwTpPhN`I[FWAS<R9S5R0T+V'W"XZ[_ciqx!1BQ_n} "&*+-.-+(! {tokfb^]YWWVW Z]`&a,c3d:f<g@gCjGiJhKeObQ\SUVNVCV8V+U TS SQNJD@:2+$ wrkfaZVSQQQRVWY[[][]^]][[\]`dglnqrrrrpnjhgc `%`,^2]7^;^?_CbDeGhHkHpIuFxF|DBCAABABCDFFHHFD@<4/% '.5>FNWakv}yl^O@1$ ~xurrssvz}%,3$;9?KE[JkMxPTX]eku~}sjcYPG<3)yrib]XTNrJfFYAN=F8>39/6*6&9"<AHR \hu|sic\X S'O0M6L<KAJENGPHRHUGYE^?c:h4l0p(s"tuwx {||~}wtpljhec`_^\\ZYXZ\`ejqw #5FUeu  '/69<=;<;<;752-)# ~uog_XPID=7.' znaVJ>4+" {{| !,5AJU `gow|%,1:CJT[cnu}|voh_XNF?71,'"   $,4>EOW_fnt{  sf[PB8.! !*19BHNSX^`cca` \ZUPJC<6 /!( #  ~unhd`^^^``djow}   '.47:=>ACDGHHHGFDB>|:x8u2q/n+j&f"c`^]^aeks|-=JVap|'/7>CFEEA=81) |{ywvtpkhc`[XWUVUVUUTOKHD>;83.+(% # &-4<CJRX`g nw}~xqj`UKA7-$ {wrnliec`]YVROMLLMQVY^bgmqw   "#%)**,,,+(%! #'+/36;AEFINPRUX\aeimptwxz{{{}}~|yytniaWK@3$ |zwrnlijjkpw} %,5 >E N*W6_AfIjRpXv[za~eedfgghiihffea^\YQIB7*{tkcZOE;1&~ yu"p+m6i@eIbT^[\bYjXpVvTzT~TUUTWY[y_rckgalXqNwD{9~/$ }ywvrponmmnpsw{ )9JZk{%+/2100.,'$  {umhe_ZXUROLIGD@?=852,(%    yne[SJDA;741/,)%" "-6 ? FPY_&e/k6p%>"@@AA@ @@>=<;;;;::9850,'      ###$! }x$v-t:rBqMpWo`pirqryuy{  +3:ABCB?<82,%! ~}}~{ywuqnmhec`ZTOIA; 5.*$#,4;C LS^gr|ypg]ULC=4,"     " &,06:>BEIIJMMNOQUWZ^acgmrw{}yuoia[VOJE<6.% "%')))*+*(((&#! "&*/4:?FLSX] fkr x&~-39?CGINOOPRQPPPPOOOMKGDB?:6y4r0k*c&Z!PD8 *  yph `([/X6U=TCVGYM^SbZh`nhqosvvwxyxyx{}~{ri^PE8.#  $(,../.,'$$0< IWdr   x rlfb\WRMIEB>72/*'"   $(,,-,+)&" ~xrokhea ^ZTO"I)B.=3::7@5F7K6P9R@WEZK]R`Zbcemhwjnqtx{~}}~||zyvtoh`XRIC<5/(!  %.5>C I LPUV[]achlpw| }vng`YRI>4)  &/7@GLRW\_ acdddb_]W!S$M'I*E0?6=<8B5H2L.N+P'R%Q!PPMIJGF G ILOU[bgkqv{}wqjc\UNG@7/(   ~vslfeb)_4[?[J[SZ]Zf\m`qexk{n~w %1;BHKNMIF@<83~0|.y,w+u*w)u(t#t ttutt u r p mk c `\VQKF?"8$5*00,8%@ KVak u~{ume]TMD:0$   !"##$%%#!     $)-38<@BFJKMPR U TRRPLH F @:3,$ ' +.38;<@BBCCBA@>=<:8532-+*%" "&+069>CFILPTTXZ\`beikmpp rsrssr#q&r*r,r0s1s2s4u4u6s6s6n7j6e7a6[5S5K5D3;212(/.*&$ !$&+|-r0k5c9]=X=UASCPEOGQHRJUKXN\NbNfPjRqSvU{XZ]`bceeba[SME<2)    $0;HT_lx{tme]WQLEA=:720+($   {"v$t)q,o0p3p5s6v7z8:>>ABDHHKMPRVX[_behknpqppnie`\UNHA8.% )/5=BGKOTWY [ ^acdggh i iigfc_\WRJC=61-&#   &,28>CHKMQRP NLH%E,C3A:>@<E<J8N4R2U1Y-_+b)b%d#ffda`^ [YUQOOOPRUY^djqy~}wrke^VQKC>83.)&" ~yrnga^YWTTTSS(R3R=SDTKURYU]Wa[g^m`razcdddeeegjkmopsst%t/r9qBoHlLkQjSgTdSbQ_O[NZMYJVHTHTEUETFRBSBU@W@Y@\<_:c:c9d9e8c7`8^7Z9U<P=I?CA>E8G2I,O%RV] bhnt|xpi`ZSJE=5-$~~|{zxuuttuvxz{|}~~~ !"$%'((('$"   $)-13454420-,) &%#"    !"##"" !! ! %(),-/110/..*))'')*+-/011/0/-+*)&%#%$"! #$&)+0458;>BHLNPQRQPOMKJFC@<:842$0)/-/2-5,6,8,9);&>%?"@ABBC CA??=;;::;<;;==<<=<=?~>|=z=x<x:v7u4t3q0p+p&o"nmnprtx {  #-7@LXdnw {tm f _ZSKC>94/,*&$$#!   %+.28:?EIMRXYY[[XTQKG@:4*$    $% % %$$"!!!!   "(.49=ADFGEFDA?<975210..//036<?CFJNOQSSRQQNKIEB?9740/,**()(('%$##!! |xvrppomligeccbcbddddb`_\ZXUTNN MLOR%V(\(e+l-u.-0//112466678866766#6(7,706295:7;:===@?A@AAAB?E@G@F=J>K>N?Q?R@TCTCTFTJTMSPPULVHZD\?^;_7_3`/_,^(_#_aadi knqtvxz{|}}}{||{zywwurmjf_[UOHA<5.'!{zwttuvvx{|||zyxwxwxz"{')+,,+*'#!  !%&)+,,+,*))&%#"!  !!!!"#!% &)*)++)&$!       #%$%''((&%#" "$%)-048;<@DDEGGGGDB@<73 . * % % *158=BFJLORSUVUVSQQMKKIFEEDHHJOORTVWVWSPMIC>81+# "(/7?HR[clt} ~~!}"y%v%q%l%g$c"^!X!SNKGEFEBA? <72+'    "    $(+.2458987731/,+(%    %(*-/...+ (&%" " "%&&()***)(%$"   "$#'&)(*,,.-1/406/709/;-:*<';":::; ;=?ADFKNQSTWWWWXUUSQLIE@><9866421000,-,*+(('&'(**++*)&%" |yvroliebb`bbdh l sz #',.158> BIMT%[*^.b2h7m<p@rEsJsOtRvUtZu]t`tbubsbscqgoilkhodsax_z[~YXUTRP~N|K{GxCtAr<n7j4g.e*b$aaab cdfiloqvxy|}~}|{ywspje`ZUNG@8/(    !!   ~~#{'{*{-|///.,,,)'%"  $),./11-.-,***)((%%$"#$%'() +-/0%0+/2/8.>,B,E*G(G(G%G#E CA?;84/,' $&)-.124656665210/-,++,--,,+)(&%$"#  !#$%&' *,-!/*/0/7/<.B+I)L)Q&U%X#[ ` dflqvy~ ~||yspmigfeceddddddc``[VTNFB<3+   !+4=FOW_gox %)-27=@FIKNMNOOOMMLJJIGF~DzAw@t=o;j8e6^4W/P.I+D'<#7!1,'"       !"!$!  !%* / 3 79>BADEDEFFIIKLIGEEB=:72-)&#    ! ( , 28:==>?><<;;< ;#<%<(9)6+5,3--0,2)7%:#@ EJPV[] bffggeca][ZWU S RQNMI#E&B)<,7-4...+.',%)$)") '#'$''(+(-'3'6&;'>%C%J%N$S%Y'])`*c+f,i-k-m/p1q2r3s5s6r6r8p8m7l8g6e4b2_2\0X.V,R)O'M#J!GC@<62. ( ##$%&'*++ + , ++)(&#"       ""#%%%$$! '/8?#E)N-T2\5d8j=qByHOV]fntz{tmhb]WRLGA;3~-y$sqmjhfeddggijlnmoppmifa[WSOKGB>;51/*&"  #&)+-/..//.,*(&%!!$(-04;@DFFGDA>:52/+)($!   # -39?CG K M PRTVY \ ] _ a a ` ^][YYWVVVUU VUTPN#K(G*D0B4>5<:8=5@4@4?3@4>495785:2</=.A+C(E%G#F EDDEE FHIIJHGEB?:8311//0101200.*(&"  &/8?G NU\dls y"$%'))+,,/0000-'$}{yvsrollhe`\WRMHE@<83-*%     #,4<DIPW\`glp!t+v4}>GMUZ^cfhjkjkjffda^\X|TwStOnLiHbC\>V:Q5K.E)>"71*%  !% *".%2$5$9&=$?!???= ;62/+)$!   &,5<@GKNSTVXVVUROKE@:/(!    &+16=BGMQSVZ[^_abbcba`__[ZXTONJ F C @ ? < : 9 8886543200/.//01 1 257;>!@%D)G-K0N4R9W<[?]BaDeEgEhChBj?i:f7c3`/\+X'U&N$H#E#>"6"/!( "  !""$%%%#" #')))''%! |{xvromjigecbbbceiknptx} #''/0:7D=MEWK`SjXr`zekpt{}ypgaXQJ?~5|+x!tpkeb^XURNLIFBA@?<:852.-)&%"    #(+/0121122235789:;;999986766566530 0 - * ($#     !*19AGNV\afkorvwyz{|{zywvutqnlkgd`]WPKD=6.)#    #*08<CHINPQS STU&V.X7Y;Z@]FaKcNgQjTkTmVoWpXpXrXqYoWnVjSfQaN\KVIMEGA>=48-3%.&     !#$#"## !""!!#$$$#!    $*17<BFJKJIFC>93+$    $*/5;@EIKOQQSUUTVUUVVTUUTQPOKKJHDBA><:9752//,+*''%%&%&('(*,,/23668:;;; ; <;::863/,'$  !"!"!    ysmfa\}XwVrTnRjPeOcObP_O_O]R]R]V\Y\Z^`^d^i_n_s`z`~bcbfhjosx}",3:AFL"O,R5V;W@YH[O\V\][b]i_pauc{cfgfhhikkzlulpikhcg]dUaN]HY?V6Q.M%HDB@ <8521.,++))*()'(&$$""##!!      !%)/49;>ACCCEBBCCCCCEEDEFFGFECB>;82.*&     $)-28;@DF HKLO"R%R*T/U2V6V9V=WAWCWFTGPHNIIICH>I8G1G(E@>95.&     !$$&&$""  #(-3:?FLQUY_accccb`^[YWVSPOLIGEC><;521.+*'" #$')*/1368<?ACFGGEDA?<83 / + ( %   !##%$#$!!!#(*-2589;;<;::98630-*&!}ztqoljggeeegjlns}wzzywuvtrrrrooppstvy~ %+4:A HMS(Y2[:^EbMfVh^kfnmosqyv}y|~}|zyxuuprkmfhaa\YWTRLMEI>F7B/=':"620 -../113457:;;=?<<;98420.-,)'$"          !$) / 37<AEIKORRRPNLIEA>:61,'"  !&*+.147;> BDEKLNPPRSSUUTTTSR Q OMONNMKJHD?:5/*&!      $)/7>DK SZ_e!l%p,r1w4y9z<}?E~G}H|MyPvSrXn[h^da`d]eZbWdSaP]LYHSCM<G7B0<+6#1,'"      !$'*-!0%5)7*7-9294888<7?5A1F.G+H'K#LLKKJJ KHGEB?:71+% !%*-/3789<=======;:9640+($         !%*17<BHOVZaimsx| zvpid^WOJB;5/+'#!    #(+,1 335677"9$9&8'8'7%7"7531/-*& "#!'+02 6:=>ACBDB@A>=<998755555557;=?CEHKLMOORSRSTTSSRRRPONKGC?83-%  "&*/4$9*=/B7I=ODSI[Q`Vf]naqftlxnzr{s{u}w}v~xyxzz{{{}zzyvvrronhhec`]ZVWNSEP?N4J*F#EB? =;;:9987630-)(#        # # # #%''(%#  "###$ # !"$%'*,/34467642.-+)&$ # ! !    !& ,17=BFJLNNOOMKIGEC?<85421/..+)'$"  !'*-3 7=AEHLPQSTTTSSRQPLL K I IIGDCC@>;622-)&## ##&('+/123421/,*'%"   "#$$$$"!   #(.58=@ DGHKM#R'U*W.[/^3`4b5e6g7g6g7f7e5e5c6a5`4_5]2_1\.Z+Y)V&S#P"L HD@=951/+(% # # !    #'*".'2,31466:6@6D8I8M8P9U9V8W7[5\3]3]/],]+](^(]%[#[$Y"X!UQLIC>:3 ,$  !!!     !#&)-17=CJPV\chmrvz |#w$t$p%k%f&b&]$W!U OKIB?: 3 . +&"  "$&(,./122355788;;= < ===>>?@?= :%8)4,./+3%58;; ;:98541.-+*((&&'$%'(*-125:<?BFIJNPQTUVWXWXVSROJF?92+& $*.48 ;@EH K&P(S,X/\2^9c;g?iCnFrIuMyQ|TWXY[[ZXVTROJF}Bz>w9u7r5n/k-j+g&e"ddc` _]YXTPMIB=71,&#    "##$##"    "" $ %%'''()''&$$                $ (+/2578:;=@ABAAAA@??>>=>><<;953/,($     ! " " $&&'& & & &&&&%$$#$#! !&&(+-...-++,+*)(*)(''&"!     #(.169<?CGILPQTVVXYXWVURQNJHFC?=:7642211100.-,)(%#!  "( . 6 = BFKNOPP!Q!O"L JH G!D B!A!> >!<:;:99641,'!     !%+17=BJRYbipv||zwvspnmida[XQNI E C > :7541/.-/113356679::;<;;999887876653 1 /-+($ #',049;=>>?@@ABCCFECC@=862,(#   %+17>CHMQUX\_bbdgh j"l"n#q"s"t"u"w w v vtsqmljhfb`] Z ZVVUTQQPMJGEB?:63-*&!            #$#%%$$#!   !%),.3559<=@ACEGFGIHIGFEB??=:83/+&"    !!"#%'),,,-./02346889;::863 1 - )&! !$# $ "!   #+18<@FIMPRVWXYYZZXVTQNLIGFECBA>=;875431///.-+*('&$!   #' * / 047:;:; :":$9%8'9&9'6)7*:+:+9*;);):)<'<%:$7#3 -'  '-8@GQX`hotz~~|xvtsqqromkhc_YTOJFA>;8 5 4 211/.---,.//12344442110.--,*(%$#!!""     $&'('&%"! !"##&')+-.14589878754433323210/,)&#!  #(,038<@EJOTY]`dfgikjkkk j j j h hheb`_[XXTPM IFA?;61-*&#        $'((*+*,++--..12477889998887530,)&#       !&+.36:>@AACBBB?AA??>>>=974/+&    !& (+/258;<=>>?<<;::;:;<>AACEHJKMMMMNOONMMMMKL JFD@?=:9420- *&#  %)04:>?CFHJLLMNNOONJJIFDCA??><;8420/,**((''&%#   "&+.24689:: : <==@BBFFEGFGFFEDDA?<;851-+'"       %.4;CJQW^dkpuy}{wtqmkjhf c`^ZUQKE@<61.*'$"!"!! !!!"%')-./0/..,)('%%##$###"#$$&'' ( (%#" " #&(*-.1357:;;;;:97530/0../0002234358:<?@@CBA@?=9841---****)'#   "#%)*+.146;>CHLORWZ[]__^][[ZXWVUQPNKIH E BA><972.*&"         $'*-379=@ACFHIHHGFFDDDEDCDDDDDFFEEFEDCB@@>;:8510,'#!  !"%%'()+,--/02246452/-)%!      % ) .257<?@AEFGHGGHJILLNMNQONONNMJJHHHGIIHHGFGFDDB@A? > ?==<<88630,*'#    "#%((),,/235877:;<<<>>=??@ABB?>>==<;;::98640-+(&#     "&+0378=?>A@???>>>==><;<;97 6 4 1 / , * ( $ #!       #'*.27:>?BFILQVZ^cimorsuuuutrqoolifda_^[YVUS P N JFB=84/*%"!    ##$&%%%$$#"  #&'&&%"    "$'+,-235999::98442.,)(%##!  "%())++,-,,-./0211334457999::<>?@@ABBEEEFHHIJJJKJIKKNNLMLLJIIDCB?=950+(#   !(,046;>@BCFIKNPQRQQRQPONLMLKKJKJHIGFEC?;963 1 , )&"     $'&((&%$"!     # ' , 2 7: >BEEIJIJJJHFEEEDDDEGGHIIIIGFFEDCCAAA??>=;87542///./-./....-+'&$!   !$&&*--0/144677889999;:;==>??ACCBBA@><:7311.,* )(&$!$ ).39>CHJL N O POPNMMJGC?>;86311110011//,+*% $        $)/59=CHMQW]`e hk o q ruwxzz{{z z y w wwtts q q ppnjigeb^\ZUROLI FCA><:6420/- - +---./1345543222/-+)&$!     "#%%&'(++,0124789;;<>?>?@ACCB@@?=;:987775653443344321.,(&#       ! $ (,137:=>>@??>>=====<<=>??BCDHHIKLNOPQPQQQQPPSTUVUVUUWWVUUVWXXXWTRRQ NLJIFB?=830+&#     #(,29?DKRX]`bdggghhgijjjkllmnooonlljj i ddca] Y$U$Q'M)H'D)A(<(9)5)1+-,,*)+%($)") (&$#                         ""%&'**-01243432110-,++''&#     #*/59?BFJLNO!Q!R#T$U%V%W&U'V%U'T&S%Q&Q$O$M#M#L#L$K#L$M#N!O!QSTUUVWTUUTRQ Q O O M L K H G G F D D DDFFFGGGHGFDBB@?><:851,)&#  $'+./13679<>??DDFHKNOQQTUWXXZZ\\]]^a`_^`^^][Z WVTQN$L)H-E3D6@9=<=?;C;C9G9H9H7K8L6M2M0M/N-N*L(L&K#I!GEDA>= = 9 8 9 7 78 77 7 8 8 7 76787510,*'%#"    #$%&&%$%##"!    "(,06<BINUZ`ekoswx|~ ~}|yxvtspmljfb_[WSNLIECAA?>=<<<<;::;;;:9:87420-+*& $    !!"#$$%('')))*++,-,---//./1111222433410.+*'$#!   "&),1358::<>?>==:86310.+++*)+,+-//0035566:;<???@BBDFFIJJMMNNNNNNMKIJIGFEB<972.+(%       $*/38>ADFHLMNPRSRTUTTSRRSTTUUTSQOMIFB?=8542 0 /-+*)&$#      #$'))*)(%#"   !$''))**)(''%$$ $ $ $ % % & % $ % $ %$#"# " " % & &' &&&&$$$"""! !"#&(**+---..,,*''$!    $(,148=?DJLPSVXXYYYXXXUTROMJHCA=99532 / .-++*'')'%$#"      !$*-158<@DHKPSW\\acfhjllmmmmnmmnnpoonnmlligec_^][WRQLFD?;874320/0---,,)**(&$"     "#""$"#"!   !$%&(*++-./.,**)'&#" !#$&&)*,//2469<?@@?><851,("  #'**-../0011133455546543330/.,+'%#                 "',159=ACEFGHHGEEB@?;9731.,)(%## !    "'+15:?AEHLOQSUXYYYZZXWVTSRRQPMLLJHHFFEDDC@?=<98731/.,('&$""     !$$')***,,++*(('&%%#!   !!$%%%%&%%&&#$%"  !$)-/489<>@ABDEDDECBA?=;;:9::<=>@AABB@?=:8 7 6 2 1 /,)&"     !!!"##%&&&())***+ ( ' % $ $!!  "',/37 : ; @ CEH J K L N MMLJIIEC@<;743/,*(&#!!  #(*/5:?DHLORVX[]\\^_^]\\[XXWTSSQNMLKIFEDBA@?><<9763 1 0 . .+*($!!$(+- . 11245779:<=<====?@@==><<97620,)'$    !#%&''' ((( )''+&0$4#:#? DGKQU[^bgkopsuvxxxyxyx u sqomkhgedca^_\[YWWSPMKGEDB@A@>@@@ABBBBAAAB@??>= : 942.+)#$&(+-0259<<???@>?>=::9985410,+)'%$#!!   $&(-1268<BFILRUY_bcefgghgfgeeda`]ZVTO K HEB<952-)%!!!"$%%% '''))**,-+--///002223221///-/,-/-//12558;;>?>??@B@ACCA@A>=:852/,'#   !%(+,/13478:=>ADFHMORTUYZ\_`aabcbaba_][XVSQOMLLKLKLMKKJJ H DC@><9976634310+!*!)!$"$""!!     !"$$$'()*+--0113 46555 4"3#3%2(1(/+.---,1+2*3)6&8$9#9!;!<== ==;<!;!8 8 6!3!1- *&"         !#' , / 1 69>BFKNSVY]^_`a__^ \ [XVTSOKGC@<963/+)%"  "&*.249=AGIMPSWYZ\^``abcccdaaa^\[ZYXXXXXYWWVUTSSRONLKJEC@ = 9540+("%'#( ,047;> @ CFFHJLMOOONNMMLJJGEB@;87420,)&%    &*/6;?DINRUY\_begjnoquux{{| }~~}|zxvtpmkhdba^\\ZWVWVTSSRSRSRQQPQRQRRSTSSSQ P M JIDA=71!,#'&")*-/ 1567:;===>????@><;:97631.+($!  "%*039>BFINRVZ^behlnqruttvssol j hc_\XSNIGA ;"7#0&+&&)+-1 357:<>>>?@@?>=;:::6764434334554566779:9;<=>?BBDEFGGHGHGFDA?<73/,)&!      " $ & ) * . 1 268:=>C E G IIMNNOOORRSTTSSTRSRNMMKK I G F!D!C A? = < ;974320-+)'&###""###$#%%&%$&&% $ & $ ! !             !#$&(+,-./1346788 8 :;;<<;;":&8&5(2*2+.,-,,.)-)-(-(,(,%*$*%*$'$&$$$!%%%&%$$$ # !   #',138<@DEIMPRSTWXUVUTROMIFC?963.,'$"  !$%()-0288<?BFGIIJKLOPPSTTTVVUXVXXWWUTSOMLIHDCB@=;;:9752/-*'$  $(, 0 469;<>>?@@???=<<;96542/,)&$      "&+-/368:<>@BEGIJLOOQRRSSRQPONLJHGE@@?==;;:;=;;<<<;<:;;9888886753330.-)%"      $(,036;>AFIMOSWY\\]\[ZXTQMFB=62-'!         "%&'**+,-. . / 0 0 02 10 0 /2 001 0 0 . + + ) ( % " !          !$&'*+,+,,*+))* & % % "         %'(+,.--///./.,+('#!   "&'*.12479:;<?@ACCCDDFFFIIKLLMLNNNNMMLIIGECB?=<:86430-,*&#      "##$%##!!    !    "$(*+-01124545778:::9:;9:;==<==<<=<=<=;::99876531/-+*)&%"    !%)-169;>@BFFFGHEFFDC@=<841-+%"      !# &!'!'")!)!* )()&%#""!        !$%&''+))*''%$"  !%&(+,,+-,))(%"!   !&*.1468;;===>?@?@AABBBADCCCCCCDCBBBB??><:8875320.-+)(&$"     !#&()+-0112122223335555321/-+)&$!  !!"#!$$%&&))(+,-/1237568799987754210-,)'%$!           # %'+.15:>BGJNSVXZ_^abbcbcb`]YWT O L K GC@=;620,)%!      #$' ( ) +++*,,+-,,.///00!1!1"2$2'2*2*1-2.3031606382:291;0<0=0?0>/>-?.>.>-=.;*;):&8&7%6&4%3#1$.#-#+")"*"(!( '&&&&##$#$$# # " ! !! !!       "!"%%% ' ' (*,-..00232454677678889 778654421/..-,+*++()(''&$"!  "$)+.359=@CDEFHGHIIIIIGHGDA?;763.,)&&$""  !#%'),.03467899::::9875 3 21/-+(& #""%!(+/136:< ?CDGHIKJLLJJIHGFGGFGHGGHIGGEDCAAA@>=;;:9676443200...,+)) ) '%#""$'*,.. //.-..+*(&%$"!"    #%%()*,.02368 8 :==>@ABBC D!D!D!E F EEFEFEDDCBB A @ ? > ;9 8 6 4 1 0 -**&%#   !####%''()****+*,--./110/100000///..+)'$#      # ( +- 0 467:<@CFIILNOQRUUWVVW W VSRROLJGB@>:842.*(#        !"# % '"'#)#)#($+$*#*"*#*!* )!) )!( ' &"'#&##&%&$'$)%*%+%+%+%+%+&+%(%&&%%$&#' &&&%&&$%%%$$&$#$# ###"!!!           !$&)*++,***''&%#!    !""$%&(()++/1233688::<>>===>>=;;:97441.-*'&"    "%',0269;>?AADCCCB@@>;:642-,(%$    !$()-1579<>>?>> ? = >>=<:961.+#($$& *-.258 > ACFHJKLKLKKKKLKKJIIHGDDECCBACCB@@?<;864210.,***('&%%&%%%&'&&'''%$ %$%"#"     #%&)),-/ 3 368:= ?$?(B)C,C/E/F0G2H2I2J3J2K2K2J/K.H,G)G(D&C%B$?!;97321,+)(&#$"  !#%%'((,-./01111100/0/00.....--,+,++*****'''$$#"           !&)*.12346788 : ; = ? ? @ @BBCCAABA>>?<!:"9$7#2$/&,&(&$'"' '(()()( ('%"       $(*-.023345554332221344555667654441-+)&$!       !&)*,.0224655776520-+)&#! !  $'(*-///2333210/+)(%#   "$$&'(''(((&&%#"    "&'+-/13 3 6 556330/.*&%!!"'(+ / 0255788:99:999877666556666767785563321-+('#      %'+ .135788;=<<= > ="<!<#:#8#6#5"3"1"1!/ .-,+('&$!   !"!"###""!             !!"###$$$% $ $ $$#!!!     "$&')+,.0000131012210101100...,+'&% !                     !%()+-../ 0 1 0 1 4 35 556 5 4 4 423200,+*(%##       !"$$ ' ' & ( '(''''%" !# # &()**+---,..,+))('&&%&%%%%%%&'&&&&(&&%#!     !$'' ( +**)))**))()((''&%$#!                                      !###&'&&&('((&(&'&%%$##$$#""# !!        !%&)) , / 0 1 2 568779888888666 5 4 3 10.,*)'&%$""!    !#$%%&(()*+,,- + , , + + + + *) ' '&"!   ! $%&((''('&'''('''''''&&''&'&%$#$"!!      "#%&')))+,./011233 4 4 2 121/.-,+))' $ $ # !                      !!!!""""! "     !$').0246999;;<::96864320.+++('%$$     !#$$%$$&'%%%$ % % %%%&&&&'((('&&&&$##    !"""$$#%&&&&&&%%$"!   !!"$$$$#"!! ""#&&())+,./1236789:: 8 8 75222.,*))'%#"          !""$% % % $ %$""""!"#!   !#"!                            !" % & ' ' ) **,-/0023 3 5 6 6 66656777988999875430/,))'$"                      $ ( , 0 6 : < > B D G I K M M M M K K HHGDBA@<;;75330..,+(&%#   ""%'&(+,-+ , ,++(('%%$## $ ##$$$#$" !   ""#$$$"$#"#""!""!    "#"$%&'*)*,,-//.--.--**) ( &%&#"                ""%())++***)** (!&"&#&#$$##!#"!                                   "'(+-/2234578:;;<<?>???A?@A@@@@@@? ? ? = ?@@ @ >><;;998 753 1 0 / , - **(''$%%#"!!        "##$$##$$%&&%%&&''''&&&%%$""! !  ! !  !   !!!#$ ' *!- / 2!5 7 < AC F IJMOQPQSRSSRRPPQPOOOMMMJHG E DB@=;:852/,*%!  !!!"""##$%%&&'*++../222010//...,,,++*)))((++-. / 0134456679!;":$;'<(<*;+;+<-:.:.:/9/8/705/6-5.2.1-0.0./,.+,****)()%*%)#(#(!(((((()****,-, - - . . / / 0 2 000////0/./0/121222110//-+)'%#!   !$&')+.--.--+*))'&&%#"" !  #$$&(((*+ + - - - 0 0 1 1 1 22 5 5 6 7 6 6 9 8 8 9 9 ;: ::989886443 1 / .,+*))'%&'&& & %!%!% $!$ $$$"" ! "!!!$%% & %$##!          "%&())+!,!.$/%.%/&/%-&-%+&*%)$(%&$"$!##"               "##$&((()('( ' ' &&%#"!! !        "##%&&))()))*)()'))'(((((('%%%%"                                       $ % % ' ' ( (' ( )(ukui-session-manager/data/logout.wav0000664000175000017500000364104615252713362016533 0ustar fengfengRIFFBWAVEfmt D b data-+;Eu'!n" J~!$.ơ-!8,G"$"G=!$"asϠŬQ!Fdg5\a ]FrbjZ"`=!qšL/,9™ :L";~!`;!XǼ!a!c"+ !D/8!5Ӊ@ H! +xqP!V "ZqU![R@(!GO)n3k, !!YN!ȋ: 0o!kw!3|| ˃!i9" a "p<#40ʎ!e!!SZ!I -ll#ai< fա("{ g!V!YIF>!>ʟR; #k!ji!]ܖ"`U!E>!+$" v!mء:""66! !Rš!">Ԯ "l!#"D!\/ѡ칟 1!O!ײ!a'A!LVEv)ء!| !֖n4ߡدUk!2!UI!ˑ" `/{С _!)4!". r"%g!k?}!Z_!I!~x (H"-ꡤƃ!6 Y!ݡC!P"p "? `!c%:Rס>hMӠݙ!8! b!d9! "S$!,U١"!N&fzW!O R桰$xt䡲_d":;"'h0 ,"38eҿZ|oOR"!tT NH"Ri!Kg!\!$⁡%}+G"6 lu)!Sɡu!!=X g!fZ!@̴~g! !lטt!J x!/!kX$*6NP!ӂ!gxࡂ!M 5("b ="\Q: e }^ ~ܙ!2V ](%"!!pv}!bz!J!G"y6 |!=s!X8_0W}/!Q!x`!hf!i!d k-'W!-Wp&!K{! m0!@28fE"v+!"x$*@Q/ȝF#4^Z5 (G!کQ!.!&\>u' EsDm2xv!5" sgw."!pL!US 屌!9sRҡA".Dlɡ"2-"nF6\ sg!3S򠹖}!9?>_:2!sOy", 5!!?!'CQ!$L`Z6=g!X J"d!.U@ X!l!d!V~*1v!K7I|?DOz{!" Pbӟ[ }+'ҙ8 60X0 1";!ª١@ucX!kO24֏bP95B55ԁJ5M5qoi5̭Y5۵+d3Kބ[6Op6bQ6ǁ_6&un6$*mt6o&K6?ǕQƲ6P6w+x M6P651i7b%6dS7 657Y7?Qd6^{755zy%76-5š6 %P16>3{7 +5)64vԴE柷ڐw0io9<"j$:%y`6d.6WV47у70Т 8=. 8?OL$8;s 8`79j"57Уda6i+n)ⅷE8f&8;8 Qֶ|38:|$8m|7 NR69VA?K]X%jH8[Xj|_Kƫ털;ݺ "FÅk^BI`D,i۷a4@UR7_7H7p8(#I813858~.8; 8q w8̸ʐ8չZ8+Z*8$ȸ67> 6V, >]? 8܆g_NJ  YNv*Ƕ C@K +'bz9#,I<6 `EyO8W1|8fkB8sM9fs3 9^ 9k׊C(9*69`Q9]8W988ٸ8c->C87I䷓0{V4YAEo fڹӷ@K乡➷ϹQ8`ڹ848ֹq9)й<=9L?[9gf鹢9WU8鹲98۹ 9w˹9͹<-9N,Lѓ8o6v ]a6ۚ7J4hy87ߩ> R6ĪW 7F񛹴7*$7'7X(iʹB#Ϲ hи.U'⬹׸+@(5&@ 9Aq҇kםc-FOhj$ %e>(yd@1Źcu.,a8$I)(չ(ӹ>viyϹ8H.{+&ac>tʭ h^o/X]CU#t-" 3K 0jD돹c帎V y9չ+иTEj$/[nHu踨_ X +h,`ٹBùڌ"V̡IS7-7\ð7(`8Pg8(QFj]cTa͸m·T$ӸF l#]ƸCDR-m a{FN?nz@%@9Pg9w Ź 9㹼8̹k8"~ѹ\77̹&88Y8VڹDY8w8kW8q9 1\<9ǁgx9Ț 2M9>=9ZO 92R-׿9Jڳ9^Hw9I䡅9KmB9e>`9781¹겫8' չsI7t8fx18I-$b`_Ng 5+8:18K9E9% u<9w9.J9ް9IF9Z>&99ŒϹ)9ѹOҤ9-й-]9X<9<ϹH#93۹}8OzԹ i7 P7ˏ]Pֶ8U߹L,99nƹ(8^UF8ܷ 82DG9b!9k}9aQ9❹.P9׃r9&E $9'P 8I8re8â^W8ps"1wh %C?DW0Nϸ%ki蒹ױb朹`ڄc㸅5.6 <";C`W8븂"cKPh9 )9˧9s߂9DXP"c9\894e9\Y9LF9o7Z9  Y9ը]49g9hh^ 3s9tA49UaU9 Tj9&ud9Q 9;Q8^YŰ8H= 8_84]fˡ88(8'L8t_k8%p8%9#'69P".o9)iQ9Glj9D?c9 ~9uWQ9NrqXSQ9h4V9z-8풹nm|8^Q=8<> %8W7Lָ-_66Xq7d]8ZH88P8B9fPp9`4#9gha9dh9"qD9GG9๲9Y߹^A9$k9op%3/9vp@8pIY8N2e}.$wGQ1ԥ5t8H|9 +8>.9":?9n(:6.C:Zݹq:6/::DU(;eP;p9j~;W萸*;w8\;[9;ΗM:;T:V ;?: Kd⑼p9ϻrjp練ɬUuu<Dw'\Ɯĺ \oԙػZƪ93һQa:mػ:X޻];WoS6%;̵eR;?G{; ;ڠ;,;Ի>';`;yx;4a;K:&;,;X !';#;n#;`"w; ;I<" <I<z<͎.<'NA<ɻW<Cn< n>=_؞v<ן<4 <<ʻ{h\;#H;\;LJ{;:Ӑ;Ov^;KY;n&5;z˝;m;w1 ш;0G;؁Zq;] jfp;~uy{Xq;tゼ3~;k !;];jhr;b";Qɚ;̝һ; W<;5;猜"; <"<⌼E(<&8<GsKH<K[X<B9i<%C5x< <9$߻Vh鄅<4}zj{Zqo? a O¼ ۺż;wBlƼ33ļNx:hǿʧ ;ոQh;TK; U;r<79=X\qn =be =p2L=#}=-am=ߜM{=OZ =ځ=)cػĪ9{`S$ѻc;1jG#vUJ{&yY%@U"?J U9(&&g %+ݼ0%)ܽ<׻\{Zϻrֻr)Ybv*Ż r$2;P2F2;j)<۞zd8>=;(=2 <= C< =^tԼ};ټW;ZۼL%< <ڼr<}ռy*<μ A<Ƈļ/U<%0nc濼+ü/˼ʼ>=ּ+8]@=cL:4I};(;DT3/ =hDh@=`Rx=_e<`~A0<ꌼ<, \< e1`Nݻ9'8QZ /:;@M;'8ț;PS;xo *%JF+hͻKU߻پOEQV"bP{廅Nl_I:껯Cﻃ;bK2{E'œ1a)F'kUѼӧƼߘP{'c D1.;n%\M3Q2ߺ>':HX;$N>;Q]AU;E+X"< e:<?2u<y<IF *<f<*߼;#Y;! <v%Sta<=XA'='<n𻄾aݻ,eüNǕ߼t`ɹj2:] !p;0 j; <3!<ɴ. ѻ<Ȗd77;pNX;O\H;Me"<=Kx=`nio=if^t}= [|=y^>m{=@`z=oy=aky=$oy= D y=`vx=v=ӻ1s=]&o= 3i= b=`3hZ=6 H_UR=*^G=r<=惼0=e[w$={=řn =M<$dz?<ȿ<5˼4<ռ;#m廰@: `CWe7xE\dԺF"HxHκßHhGYaE-D1(DúڻdDG[yD 'E{[D BNrg?lu:Dw52n,/_2~(Њ-; 9;A@D*<f< ӎ< <.< $G-7=1=i;;,={Zڹ&=u =)=|L=} =ףS=(< ;<<̼!G;.ݺ;X;zO\: c,!޼ԈȻN'Upg7|LŦ᭻Y>tּ9;~,;bcYp=t#=&Ӽ=/=܏'=I F=ϑ= TC%=[dh,=aS5=EeC?=(I= S=F]=Vu6e=޼=m=)~̼cZt=l_y=*[!z=' z=gv=:g o=LMe=9xwX=C,I=?"K9=]D)=wM ==bjuhn7f((]A8jS{Y6VH7o*>ׁ 4͑$)IA_`SM缌żNa>ߍpM}dܲ2>rirƻZW͋ :=j;s;m1<ɾ4` Tg2/Ivs?Q3DK‚1T)>Zى9]# ^낽t]Sc=X6X}ٍPvF[ pP8|hi*b&^j\PM\c\ż9M`gieQ]nuIxq$G @3 ԻaVؗZazP;2;Q<W7L<$=,c3<R:rU[*jcIH0x"Eùﻂ. 9>k9..9@XA<2z<̼ <Ȓ== '2=1=?=O;hB=@!<;= Bah=CyT=[,=Ƕm'u;8rAq6">3̼\4>z@ ?>U B>/bd;[=>.<2>d< ">`< >{=-^C=ي=[=B=)ӽ3M=vx=󽙋=4=P j=OG=~i=~%=OI,Y=&|2 =y9d=?=kEoa=H_t=cFX==a=.Ě=p=W`<=wd1=R½+ =c= =nh=Q=:+BW=@b=$DM4T=>f{)=sP s2F̼Lw 7B4Z&.|d=='ǽ#Z`Z _](<*[31u9mV6tBN9<:و":7]CTd2w;rz*%itj>6=f=a=('MA=ގH* ; >L /C >n>r;N>~;'>׾9 >6Q+{ >϶>γS>-ټ#F>>H > k>8Wk $>WJ¼&,>FF->;+&>Ҹ<>)= >Pq=a=-=]==A=1=<=m;=uVz= =M,W=L]=߃Wr=FLw=}85>p0#q >j>X >0+ڪ>uS>ׄo>i>> :۽QT>L >- >< @>E >U X>8>I>qý>rpV>%M2>mb >܆Hf>Q@>{Lc>[>HoU!>D5?(>y掽).>U?1>֙Ǚ.>•%>.>k%>ޝ=DE='Z=>{?u?=58 =>]vn>inںK&)>C<ݚ0>~I<Ş3>=R1>G>=4)>JK='>(.>= >g$=\>nap%>`37>VI>Z>'ig>8S.)o>*sTq>cCl>(Nb>@̼rLP>6> ̷jk>;=vS<%=<{Cj#Nw$U{0DV8``R]$7I:͡>Q)"2Nw&;6&1F H@r;A\r<n< އ< =v=wQٷ3=^1нZ/ =r >=]= >k=<7 >ՠ= >ۃ=>&= >JÖ= >D=I1>[^=x>{7-=Q+>tB<#=>?:n:_>q9Gl>BOr>8r>̼gSk>ʼ*`>]ԷzQ>xڜ?>Bw+>2-0_>ɻs>@=y:=;=j;=Ĥ;=+;M=oM;,= ;n=PC=ť=@z=\i=D("=_(<0{Qi4!^᳽`.;ܞG9,ϣ<*mH!l`旻y < <Ō<Y-=I=ͽX}=ߥg=IIu=ů=/=j=2ȟ:=\.=a\[=鵽Y7=Ž=>'۽g>=l(<::<}`=B=s=z=L=R=~=`==Dw=0==-k=w=DG=#=2*=I=}= R¼?=>' =U[;=n_=oZx0=Yu^=iJ=Wh='=X==r=BOC= =JbÕ=/@=Eh7$=oys=K T=cQQ==&<(dF)=m== .=ճ=a=ڿ=yu==9=-=R=HR=o=3x=)=E==M=0.=OL<[=:Z<=wy*;; >-b> >ĭ#>α >2>TG>ڻ+=2h\tC=&=nK$4=>:TA<6=>W@U>l'c>ײ~e>u!N^>3O>CE;>ُK@%>%H>P8+= =(⼕r=xT= 8=@cV7`=>o=p>2ؚ=,>=>=d>!=>=]>=i>,====ԍ=E=m ==G=}===â=&==^=9Y=O=r9= >(=1> =ҷ>F=A>=h>(=- >%B<Ϩ=Ͽ8;i;4:ݼQΘ=q޼=vt =Nΰ=1 *=Cv=!EVQ-=?d~M~s>`<5=x];K! >I>cO>Wb#>WL+>7t&II2>~K_6>,Ojp>6>/}uT0>xh$>hst>W=L*0$=FGХ== $G_=;"H= vڽ}?:). ֽ)|ᦽʽUH4mVԼE-C=J/!k=&̼k=s =F9*=<=o>[='/>A=6 >>m΄= /G>Khf=+I>B=SE>=z:>=SK,> R<>^==$"=ӧ=VC==T3e===Ϲt=z='e==^=Y=U=1R=n.G=n=0=N=>0=&=k<<і}ý^|G8׽Q?; ZFĽE Sʽ !ֿϽm*ҽ1߽0ϽȽR!/‚S%6I⤽)7ü^|vfCJ˻wٯk (>9oV.>d+>>Խ >%.<==p=/p=#`ڤ+=zؽ(<@<ΎB <9_H<;;UOۻY ;D\d< :g=8Q=&D=Zߢ=ڵ=b7\=*Gm=܊C==q=jR}=턽y`j=e>%J<ڐ>'<$><[(><}+>K=>.>V=\f/>e= D.>=)>(=q"> >o>e>>:i#>/6=&>=!>ٸ=>s=>"E="m====Z=Y=(:z=Y=vF=y=Q)=s=v=5ɽx=޽|h>50> :>{*Ǜ=>Ᵹ:>z/>} >% >=vجĴ=X%ۦ=<.j=}KtԂ=9O_|=#2Y|=ټ&|=D4j6u=M;lf=/< S==>==+=-#=='=V=<=<*=#<=. "=5{8=A߼- V==y=*C=91v=& =X}=伒 =X=$CK=V=;=Y <(n=7<6=@X==A=<_=}UhUL,%@ۯ!J/$`(va.Ǘ4B&;)?(<?j<9OT<.|"=EO{T=N: ߂=H=ҽ==+=-?=+|=.aXZ=4&=^<\dX= >Qሽ+ >e >5>gZ=?2=%{3=g e=?k?=r @=Q=ʺߩ=^<'=; ==U='=,=Z==>==N=c=}Y==|-=B=a==i?=a=^"=-=/=L=ѷ=I=~ =ӽb=sA=޽D==n=p/=j_=~#==&=(`===s =h=K =]=@#=T=E*==hx:==S=շ=q=L==Ѩ=>==ٓ==#=`v==%>=‘=) >=.>Ty=](>ªq=0>@C=y5>=3>S W_<">j;g>2:C>4=Zq=$+/ř=`*r=䐻:=i>;h=9<,R5j=1KJ=V=㺒=ER0؎= W>=$~o=ԦO=c&=?cg,<ǽkV=2؛=୽Ф=I뿽9='ҽzP=9){=?JY=$7= 齦= ۽a<;Ƚ{ =>Kϼ$>3}f.>D5>WzWb:>u<>%|<>8>C72>3Bt+>ytD#>DG>>T>f>G>>o9 >>ꊽr=#o^=4A=y$e==?=9=:=0y;&J=?&;s<=Mi;(@<$*¼(h/:CS#E^fcyҎwue4B}i$}rӆDd!3SOu<0ȽmXѽKݼ.bսDA2ӽsP;˽<\;=aP=މ=LQx= Q=P0V=z;=;< I>Y8= >9:=>rD==@4=A=l ==՚<=ȕ[e=cɼm=qO=Nպ}=ҽl=L2f=hh=L[̸n='@t=* y=/N{=꨿B}=Hvj=.P=1~ӻ}@=<x=l!=7*i=>gY=VP=y=.===Iy=><f=23D>A;.>p<=>|= >==>F*=0~==1=@====W=^== =A=S)=c=3=Ed=е=VI==*=A9=.=h=+<=5i؄>dqA$>xO="*I=݈3=rއ=lx==:ae= mA<Ђ= <>W`<9%>c<*>e'<->h;}/>u%;V0>ܵc:52>c83>8I4>{Y:U3>/ ;l1>2;= .>S;?+>Ar <)>{s+<*>ֈKz<4=1>@i6=Q8>:=9>8z=U8>F=i2>=r'>=>O=ue>P=Q==[=Ǭ=6֢=v=e#==G=={=@=)<_=9<== <8ʹ=T;aԛ=D}:K=:F==pW [j > >y>`&>9W >Nn>u#==w=7=8L=R=5hUa=_x@=wX'=`# = 9=|=.m,!=W)==2=9{!w>=(J=ͽS=IK U=U5AH=ީ+=r/+=j-<Ga;u2(g3b 3SK'L~&aӒd,3̄5sCiW_;೼)ې<:>=<18;=m<}wȼX>8Ҽ!>d('>+ (> 1_&>_"!>0_^>4P>W>,ZνV>xܽ]~>l:p>J > ὰ >Qֽd>ǽ>l=Zh=i=~↽=bn$=vM<Ԓ=X/ʀv=>wLN=+O.=%B=* =<:/O< F.,=o[>4n=]=_-==M'=Pf=@=0==K=@==-=N=m==`=d̤=\===ݺ=$d=a=I= =t====WT=D>=Ab>=G>v=0 >=6v >C#=] >=9 >}!=+b >> >̚> >7>8>>_=>:=M===q=JՐ=zg=[_X=q=x9=;O=I<Z7=s<;=;P5)=Kpt =<>Whq]v85Ľnֽp < 꽋=ʥ<= == L=>>= >d=Rd>=l>ା= >=C>۲=U >ɻ=x>==ں==7=Ž=&=ܦ=Y=n^=fϰ=Is=攱=S=W=<=S=*== =="==1==LN=T&=r=== JW==Z-=c,=P =W=2 <˵=<=Bf<Bt>=A=88?=ϓ0@=T7&o=##ތu=1 6=M=ѽRF<=<`=&8=X=RL= ==r==~=5f=q=G>9=ٯ >=!/> = !>=U(>a=R->H=68.> 6=X*>)= ">l=+>(f= ><J=x<k=;UL=$q|=O5=b g6!w=5`=ڽG\=׭,g=7 |=W!2,='= )i=$=M7y=i4 =@=$Z>LGS>*F>08F>jT>9 >9ﻼ> m =Z${=g7o=ѽ.=@v=sq@=0ǁ=@֦< J <Piߍ<,yPX<L/1-)''2K50 TBLNνZ38LiQ\S}sgH摽ݽ5;8D'O~=`frK=D>NY=P>n= %>Q=Y(> c=O+> =k.>=)0>c=0>=|0>g%v=0>\Y=1>lO;=2>= d4>0o߉<\5>;w6>Õ4xr8>GT;>ËM>>xTXXZA>2IA>.s#>>D O<7>5T<,>l:[>Py$=s=m ml=X<#=펽 =D=j=qx:=O=DN==`&P=Y=E== 7==*==ǔ!=:=m===!=W =d.=)>@= >W=+>fn=Y&>=n5>Om=x)E>=uT>=Өc>=r>= >9=݄>U=7>9=->=ւ>=v{>C=BXm>U=]>{=BL>>9>B >d&>>KW>2>=R> =k#>H=Z'>='>=g#>n=>Z}=`>{=&=oƒ=-L=`=,=]=9z=!C=l=0=:=9=nr==fc=n=i5X=T=Q==YS=]n=Ĕ_=Bq="]o=č=y=;=Hq=z =N=9K^=R ==I<={&=jt<1~e; ս~&(Km5ټ[B>5 <"5t(8)3zQx=-oΥF#'M\ASP㑡'OæKD49^T-jBs@` 뽽K׽C1! E T>QM,4;\;ͽ ;e1ŴQ+> >;q->W(:>E>bO>#໲W><=\>=*\>!= X>2=kR>5=&L>#.=6G> =sD>ͬ =YC><>D>6< G>\b<J>5L>m3%AK>ͼp H>)B>0 <>q3>\Լn*>V >uNv>v;><>= =y=U==g=_= ==^+=~.=n=ɷ=w3=%==o==1R=K=V=k==*=3=,<m=.<9=D=0 k?=@b=H#~=|$ 6y=<*@\v=2,.+v="14y=3]=ze5/=i5=Zm4=0@<=*3=`!=YLW=qj=F/_='D2"=pɊ? >"PI>,=>t>a>30H<5_>>=|!>= >$=>M= 2>?='>%=n7>c>cG>)=xV>2l=a>= 6i>t =Suk> =g>k=]>?.=SM>l2:w>3.=:ɽ=?x=k=V; ችt񃽂ǒga8Apc,sTِܻ;i:;E</ֺ<O: TѼnl4Hb;?·}a<=LP7FPџAS[i ϼ[M}Uo D`RւÌ2&4/Z, Ơ Ht "Ƽ?Εuu6C$uD;iRFV<1`< <cƆ>Z2`>FP%>cT,+>X;Z,>WV)>I#>4'W>C> R>ǼdG >è>c6Փ>H$:Y><>Dwm<> <Q>`<>N߫<:>/< >du<|>o;>Ԃ,C =HEu= k=b"<жL/;ݠnC]=$0̞G E.RqjDI.Pżx Y|Żǫ;#9>/R>.#>1e&>Sg(>Uwo%>愽q >~>fp>b_6>I p >'/;>5>koC=Lʼk=L 6=Èp > .g^>\Ph>`Lt*>N8>SQ=D>3J/ P>$~[> ϻff>*&P n>;Or><=r>ƐAZB=b>=sU>=$E>=1>=o> >%><>P=2>֯=L>%=>EZ=6>r/=ۣ>S== <=M<3=t&=6 > =>] G*魾MX(̼% z]`Wa~2tpy1Dta#|v"BҴnvV?7< {!xE;5p\><߽8<ŵFUc=>!=,>@=9<>cd=KL>T=,]>=Ml>˽=y>71=b>>B>>>E#>>s1>4%>!=>(>8"I>> S>~W>`[>x>_a>'m>b>>nn`>C> PZ>->eQ>Վ>qG>!><>ێ>2>>D*>$>`$>>>̃>l>"y>U!>f>(>KR>a2>=>>>\[)>L>>X>p >e> >r>+D=~>CW=e>*m=Ŋ>|>u>@I>>}>:>ʥ>s>$>>U >ѓq>=YfY>u=L>>ް=!>=a>ۀ9=m_=/;=3ݽK=R A|=?&"nk=O2f4b=>(j=*'潲L==6&轝2=8F<zG 㠽%=_ӽ?@Rͽg- ͽh$/ѽ%G=׽*U۽o/,޽'8ὒD/Oe}6_It-J<YILkkϽE [,0BGI;u༐5㼉м"껸!;g=(>=qF>== c>*=~>B,=>;>ڼ{>k">ӜS<>^ݽ>pr>gp>xl\>G>)4>Tٽ%%>\/>@#(>ꏼ>u&=x,1>=H>>M׾=aH>t=O'M>=4IL>=E>X=9>gp=?&>c.="u >7=>b=Rͽ4=`n h<'^8e,=l66Un"2vA k }Pֈ[;4щjX;I.=oص=ŲG >vُ9>/ȼZ>lDl>j}Yn>^Og>쀳gZ>ýH>½5>Y!> >}=I{=\U'd=ӫY=h1ɛ=Te =J|S=˽3f=-@)=9z$p== >?==q== = =f"=>l->5>C;5U>tO^>[Nh>K4 > J>a+`>`?>-⨼A>;>/=>yn=>=>=v>=d>u=Q>W==D?>]=->=h>!#=8 >uPӽ >(-=`H2ʫ=uQ,=%iE,Ƚw$=ޗS='h=a?=}5W=SK:=:_{Ƽ%o6Ľ?߽TֽR潦ཋR׽ٽ8yR<Ma=5+>>=J>p=q`>ؿ=>l>a=wQo>bD={g>6>S>E>7>L=> >>s >)>>/>>d3>q>4>=s4>o =ж3>~u=|2>y0m=.><+>i5J:)>+:(>bD*>޽(*>j:#>mн>ݏj=T ur= _ƫ*>8L5>2~T0>oU>ν=]*~I=}Gp@<<IHƽ͐ Sx0$@νI0=5 oyӂݟ'"Pм4}D`VhK(~ZQ>tҼ(O[f ?eC[oFJ;TQNdX}ÍdVE6= =Z,>Z_< @>=p+J>tHw==T6>O=)B >={=!=Yd.=={M<& =hw;=edJ >3>6 4>-f>ԱY>']>}>>ᤏ>> >֏>֩>/[>6T>`>oV>Œ>~>?>>@>E6>-V>O> v>j>yjz>5>D>=ǯ>B(=&T>)Y!6>@Tm>m.zQ>;{<2>BP;>E=K:=n;Q=<5C=%X<G=z= I>c=h<Tm==+Z="="X<=b&>,=}@>6=D>Q=r3>lCy='>^==X==P=#h=Y >-=>Q@=,>f6=y2>j=)->I >K>D>`>6p>_=W>=>qa=PH>'=">]<.>Ҿ;=Gk>E(=>G=mn>]=}>(d=f>'[==>L=֑>nD6=~n=W=iq =v <ŵ )xI>e舼"o>z >Æl>f>u}>?3kl>'XfU>-<>D&>6nsl>QOR>>9*fB>I+$>\A,>1y+>-<# >'i= >Ņ=!?=J=j=.==y=.Kk='=x =)z= <=p<_>=>R= S>n=a<5>,=զ=-t>=>>Z=+B>=o>=>6%=> <[>Ӽ>щl>E>,ܽ7>G!J>?*>hi=шD=/p9d $IP,voVTYiǪTd31~Kt¾eeȾӺȾF!þ oL3Ν+u`pnB=x yzfʽqI_uhۃ5MDOCrÕg4PRI0S;M!=<=f޽=6mIW>mPJ><4=Nz>=>=>V=^>I=(L>V=>=H8>Ŀ=v>{=f>3=di>O}=D>l=6 >6u=Ӡ>=>=V> w=ָ>">H>U>C߼>N> >>+>->1>> >z>+>CM>>wR> >i>0W>hߐ>>}>y>4^>\>BG>Z6>^:>8>3k6>Co>[3>2>|.>=C%>/|=4>/S=>0> >t;$>Bq(>K{5>m=>`O?>ԼA8>(缄.>'>P^r">&>罇>am=*)=MB՜=}Wh^=ctQ=fE5".*|N4+cTa̼PqgTH3^ nwj*vz];Kl3Tb5_b.%f;ص< <4g=ۈ<=1?J<> !<6>#JU<# >B2 =>Ğ2<>]<[=}R=>4%=)>F=I4>=]C7>3*F->qQ">Uj> >ݽ?3=P=y9=va= E]=JLVb=*z=7E"n1$t~!mlCa#1DK><_BH@=8A=D׼= LB=[>v">-݌=*0=w(=Ҵ_y=絾D=5#o*=ɭ.+==R?=yky\=b#z=vPdF=m"$쮕=K=ս=_Dx=}@=*= Gu=m=kqu>%\[=>=H=G>/|B=Rֆ>Q=d>$j=>(1=bۄ>a=>+ = k>=Q>x=x=>T=4>0$=@&4>'[>';<>L:F>c:MR>ُ8<.q^>&8I=Dd>Bʖ=4b>=3b>\=^>,'>jm >@>՜>pV$>c >O>*>=B=&=ϼ=5==<=֛<=<{=WF=;νuG'ȽK_kH:VR\A@Od7䛚ɉ*C(>'> [H>=v+=F:=;</&2j:K>G4@3s>C:߅>2ӻ}8><A>"T7=g;>]=7>=p>GD=M>>̯!> >]=>==R==Jq=!=I=8==q<~<-QY=0󻭟=u;<)cbg.>Ľ<>4E@>:w7> $>M) >=B߽2m= O=69=A3pk=;Pc=)*v=岋=Iֽ=Kdo9ۦ=v)=w=C=l==y+>N=|Q>=m>=>4=V{>|=L>ԃ>}>>f>^@ >N>fB#>D7>1>m!>v>m>k={=:=}=%=+=pF=TxQ)=;==}=/-=k=m===?==q=Q>_=" >c=>==; ==ᣚ:=1+[9Ǭ)ٽ+)9 [e(ܽF9ٽs07˫Z |M}^6>$;;[U;12x>J >A>?>]>s=g>4f=Kc>c7=1V>=F>-E=7>4=Ӂ+>_W= >GS=WN>=]>W>e>>#>_,>Ξ;>E:>fX>gD>9u>N>>Y>>te>>Ep> >vw>'Z>|>Lۭ>0M~>r>~>+>z>H>*n>Q>!V>>&3>%>D >Yz>t6=T>i=->J<>8$a=c'=AsV =au=Nbs0=J`̠@=;U]=IU:<]<98o^ F:`vJax`u[|\l$UA||!(􂿽$05N,GI_z@l}e; GJWي苾s]So$VI/I[o~|k%p@fZbҾ9Mݾs>߾ÓM޾`޾gۑ !(Y?PoOվ}?RM33r^$򽣴c龽iW09wjp(CL?9S+v-ۻ{ [U^!.Ѽj#[_cLeꂻ1<֔?">Ţ >F>P=> &8>X>?W>p>cq>\>@m>>s>y>>{>Y>Dh>Ď>-v>'>^>}>D>g>s+>V>8>znP>>PP>r=$O>)=4J>K=VA>j>8>->s0>%>x(>f2>u>N<>>EC> >oG>c>I>m>ؖG>}>E> >rGC>h+>.C>Р0>XqC>=A>'>#?:>I>e+>6>$d>?"=b=}m=#= Rgt#ua++9J1vW<1X/3+SԽ&-P0(oCCνI諒`G~YtCȓ=;,dM uA+1*u۽^+NdȽ<tǽ/pн\CBݽ0;&K |\3L7{ nQMջvq A|vd'k;. :L.5<&<+<"=N='Y=hy==L=0f=n==Ý==ң= ==e=U= t=*UE=B~,>=I>?=$`>==1l>=i>&=T>e=->&=*>'==]I=W=5=}7;M =n#Z=P>=eyl>z=y>>2}> >Cz>Dx >3r>L=`>t=)E>y}="> <">5=-n4=L2=Ȕ^=Ľ=?3@;fEߨCE@w DHd5A;'?U;>;c:R=g=w>1=$Q{ zO gMIº Ͻcl<->2;(<=A`=8 =|lW>AB>8>d>HZ>5>Ky>ʉ> >o>ь>> >i>L> >}>>/'j>[>VS>>;>Iܖ>&>!>c>y>r>WV>{ >q>2+>V>\ >8>F>>y=[=hL=9=ჼ=ϩ/=_*!s=zg1=S<w2<=< vk:֪b)Z۽꼓iTط&Y0L8*,O=BWcI~q5QZd$agqY*?uw/3?HkEq{6J0"Z\EyZкkǻPyR4hgUdv 1Bѽ*Iɿ'Vc"/ #v^@ӽK[TĽ+9Ž[̽`]SԽ3ںpֽ;Խ5;нO;Qͽ E=[3>=(Q>;>|g>>,s>!->Kx>.>w>l'>t>N+ >qm>+ !>bd>t*> Z>`6>Q>">>7H>=>=>;_4>%u0>K$>>]>{>.=;= \=5 =6„=Y=ywK=D=M=@=Ĉ==:=S===BY>^!>G(>u1>F2>~5>9>E>h=>J>҅8>\F>&>y6>>7Z>=o=Ǥq= =xB=>=D'>>:>z0>pL>SpC>}tW> wI> V>]C>I>6>':>$>81> >t3>\>=f@>ʪ=W$P>Ed=x\>f=ra> s<_>:W>OyKJ>޼Ü7> 0>ɃkJ/>`P A=go=M=R=z̘>=j= 7c =I=;=18<=[.3=>_=0=Tq==g=0=;=S=I&=Zt=Ǻ?>=ne>>ZI>>霍>:>>v>壘>gk>>C>>Z> k>(> >=>tl>cEL>>K>?>=>,>5*>|>K>t>>^*i>=[>1ް=XL>z=>>ne/=}0>=<&> =.>>4=>U=ģ >Ё=*>b=9>=PRI> >V>a(><`>ɉ>>je>K>Ag>0R>c>U>5Z>wW>ҩI>US>3>>E>6>.>z>V>h~=4= =`?=,0=='=`K=>=~=m=<4=<|OuHǣC ncl8 r_`D~ၽ8";vH8#Ƽ9H)\U,g3*-V;@K%`Y< e`<<^Xl8.G0mۼC7!}=R  IQ7˽ϊ4BNzýqս ڽнH A?i}: {Uɼ1- EG#*QC!!G[6\ iB4ʽ5Ƚ:k9r½Y36 .D*5-M';A"xOI+A޽_u ν'z[4iHyQogu*27oz^j`Um?^w>OR"H※7'@< > F=aE><=wJj>=Ԅ>=~G>=g>>=[/>=bǚ>N=;>>`>T>>R5>n>Z"R>Y>ah>Iav>p ;>5>p@-> >UY>Э> >y>W=T^>Xξ=G.>s=5v> 95=|^>3:9>&>43>K=k+Bc#=s"J=3bPD=u花=m{kdߧ=?=pͽ|%iwGK"ܢ7 L cqy3([h(e v4[C,@CU&X[Zvh1ߜ\*D袾茾䠾ىoWeZ;5ʢ}Io8j^n&KTLN6+Y&fシ ۤʽ5ֽ٭iϽ䚽)ӽKDٽܽA۽XOmrԽ{qOP >,<3>͍=/C>_=O>> W>2> Z>fN>[>h>(a><~> o>#8>9>>h>>3>>^>U>-7>^>Xk>6>I>>n>>>x>d>2>>j>KO>>F>A>K>>@>B>->z>>&Wn>n>i>c> h>53a>Ji>:Eg>yl>Fn>~>nOm>Y>d>ؠ>5Q>E>6>Ғ>s>~|t> =R>=+>7=>_$=Q;=kZX<:=Jtsb=| ]=5#\p<1 ?9 bp>&m<&,> 3<57>&<[->ʊ!<>8>=W&r=^zl> >Z>N,>c[(>>(>"> >_>>( >=5 >=>w=)>0=9>l<=8Db=\~wA=tB= -=gy%[=]ӻ4'=QY<H]EH&V!4bӼ(toEŇ1;kMsXxn;!!.=">$=l1>k=Y;>=uC>)=I>~O=J>=E>=}C<>(~f=1>r<O&>=ۍ>+/W=_=Vs=o<+B*ˬ;:/ oV-Fϻř&3ԇㅕ: ;l;)< < ԽL<Ͻq=ҽ( (w\R6zEgM̶ z֏  JքڽmVN4/'O41m0r( R\*L̽G:h6;TD{;pp;j;oE >>T:>6*>9>s;>sW>I>{s>@Q> >ewR>{>2 K>>>)0;>{>Ю#>l> > +V>I=6>h= >SV=N===g<* 6=]J&ܽQf<5"pEF  % ڽG1!+: pS}h)u+nuTҞfMק\2JXU |&ŽEc, zDսu}ͽsMֽv} > ju󟢽l ( ٚivamҽ2bͷÉ/SpE3W$WO]<]ɼQ =v=!h=:oL= <7e===EA_=>-D=C >HI='<>*=V>=)m>/='|>'>> '(>D>7>y>]>>mg>T>>M>9>:->2> >(>=G>=B >^,==<=<=xl;{=ЁK;=w+<=3<=I==E6=>g,G=>F=Ӭ >G9=C>x"=  >=>G=Q4V$Х<5~=[tŽNl=p= IQ9=-=⺻ga >`ˉ<>s=9 > M=l.>?v=#>>є= SP>,=ec>=ku>">>D>>X[>>i>> r>=>fw>Y">kz>o>]x>t>pm>Y>Y>4?>AB>*2'>,>o>>+|=C>*=o>&=>Q=> =N)>= B>z>\> >|p>z!>y>>v><!>Dm>ux*>Jc>p3> Z>7};>L>B>Ձ7>|G> *>+gG>=S>>=B*>Y=O >?<:=d5O_=6.<K.?q4rcԽ4B/7cl(.`;5B ϽQihcߝul,냾BMnj)_|0ϝ}]s4ykeJ(Y3PҜ,IBOv=hR?|2HM]S7Y쇾oV&I;J9δ*Uǔj֏|ӽ〾kp2T;0_ [PFż E}>n 92 <'gC< =gWOc= V=xBQP%=6=h>>=X>8=}o>>.>>->Z#>>$>Rl>>>E>Y i> >L9H>=)>7=F5>>=P= /==,=8==U=-=j==u=|=;=d=s==H=+v=@a=[U=47=<==-=z=+=v====]=9=}==5"=wNj==΁=l= |=O=K{=n2=}=?=ʛ=<#=3w<\ǚ=;=C:=~9߃= 87="'<4Hz'J6 +FoW ({1EH'OO Hah̽5W8ͽ%cnҧ,1Uˈ5;ݽQUZG½q kf/!A)&ƽeἧҽ,S߽YW*| ᜽ ֥75ÜϋB&GgF_HL{P89b^Dĭkj's h5sgo2ԜͿj*넽geQ9=y[śmHLGBdw:)>* 5>|,<3> a==><0V=756*=.Bv=o =H½ī= ~#ډ=3[=!p+=p)<*<;r+=QN6S=!żU= ,f@=&[.=NSx<%v|]:iü~3/@=ksdMl>2#4׼ͼ(]$ C4=P7>71=4P>:=P_>ג=f>P=wb>^=T>`=c @>=(>U>|>G">>e >= 3>@=xL>=b\>z>b>̇>s>>Ʀ >wD>m>?2>r.>؇>=>E<=>=1>r=ps>=&k>*=;On>;=rD{>,W >Ȳ>#>>9> 8>Q7K>.>T>`N>HT>>ոJ>A>D6>8>d>>>=>滬=[>O=><u>ܽA$>Y >5:w>l3j>V_>p7pV>uQzK> нY=>ǯܽ +>$⽤=>Ὅ>)ڽܷ=ǽV=8=ֈ= Q5N;Y@#$ݼ Q0*hH{M½ ҅Jq{sa0qpA-ȽcJc-w1`㗽#5붽,^潧z`:9w%Ia3^憘OA{͘䜛+Y!vzg>~w~Mmc < ]J)w3%j= 䵾g(AڸôE y-| 2[ 14P뙾W&=(Chsؽ h_ʽXO½Ev1+E!)Il(u 77U߽o=E=DH> 6>x<d>*B=GЅ>5=k>>/>3>hi>$<>+>8>S>@/>>%>>>U\>>h>,>ҷ>t >f> >>o#>>" >b>S>X>d)&>gs>1>;h>9>^>vC>W>*KQ>R>b>rQ>Xq>U>lw>^>Lu>Zbk>qk>Xx>s^>>YM>i>8>>6t>[`>=>=Yq>\=C\>nݝ=|kB>=%>Lc=f >=U=}=?==*=Վ=q=+V=*%=G<< HЌrn ѽ|FT P- 8 ^ >([(N½ ꠛ,q*-{$i5i aZӽG_&WR+ZIr-9",7-&{**Pt&+Y"($h!I"E $`$)ὤ!׍潍i] ޽*Hy뱽CA^npVd<:X<=^==0ӥ=ʖ=7=I >=%>-=_R1>qy=62>9=k/>k=.+>=&>7=ę>w=` >`= &=V=J=#==5=5=r>R==<@=,==.b= S=/=ӓ=rZ=t3=?=y==2G>z=>=g.&>N=(>cy >%>>3>M>M>>}M>z>R=Ζ>r]=*>~==c>D<=:X>=>j0=>=p<}O>;">9T>ea=@O=Ǔ0=r½p)=̹;g; χW_)j ;NF#2ӽ&H7@a4)i%`޽Q׽H3޽ٽѽڽ`& o   D"id.!.6]9.9?5@O*,>:Х8K _~0~&-潈Q˲ٽI~ѽީ"$$˽s,Qb5ﺲ)6 -#.|$нq>=7 =)=E=iO=)|=p<"=#:=JS=8=OР=𬃽=ܖ2s=‘F2=,6qc<- O<Ժۼ&20gfgN ½*C<@7{Y+~cyf悔ԽҦf,Jʽ,׽B샽~Kན';z7Q >< ޽8:=Uؽ#=iֽ/=Z:޽=;s_=`7=+ t=F=m@=L=<$=>D=/ |t=Rhh=y=>+^ <=kk7>=^>0=|>= >QN> >9>N>>+>B!>~3>)>Y> 2>><>|I>yG>#>P>Z?>hV>㠄>tY>T4>~Z>Ot>7W>lk>ER>i>PJ>dp>nV?>kHz>3>l >)>|v>#>^>>$?;>#\>>>V`= >P=c@>+<[>D= U=[=ktd=W\<=(Ώ=BԼĆ==U<ӎ=t=y=Dy=9U=1==`=&<䇋=PJ=4㼖<ѪgQ]<]ѭ(7 7_֒v6c伳󸽍巽1&Uѽ@dpgzVMF==xE<Ѕ/;!>Gԅ3/>w;68>t<=>A<+?># l#=r5>H=+>U=P!>;=>rD<>T?=,s=yC=Mu+'=ކb<˳?yGO;0[8qƽKs}㽋7%EaJ&޽OXν?E쯽 W|c~l/_ ׽nMཔ&B߽L6Cٽx' ˽K紽6.+4~nwW dJcRtn|^m )D^HýܖhϽM摾)}wį?sK!z@?"UXzap!RM ) Y  cǽNH봽fpxM4ý{XսX۽\J9HϽt,Dž҅&P\0T;J#F;l:f;ʼk<7(=l;#]h!S; l7~_ =Oy=>!>U>_@> h>[>9||>4Yq>f>Ө>!|>FQ>e>[G>>/>>P>k>^>W~>u>Ϛq>m>]Dh>$>`>.}>i\>uk>x_>PVX>l>ڈD>>1>N>~5">_>f>ɮ>1e>y;>~>>j3>S>>Z>>8>m,>>k>O%`>R>g:>={>=>>==lo= L*=1=됗 f -Y_uR畳5oqFځY퉾piѐ쥾nr-P\?pQQLQQcT`(|e~qHtlpi:ZT]/"\RsKJ;{GeL.YV4:)ds@g‾%$""5ͷ6ǀ?kjpKF'&čz}2y\sbOSSm˼W,䑏:s}<=u\*DT=<ж=MK=Y=IP==/G==c=I>*=KS>L=2>2=E>Q=U>0=*ja>_=3g>6I="\h>4>f>>e>Ƕ'>g>e6>m>JC> u>XP>O~>U^^>3>i>>m> >i>و>_>>V>L>P!T>E>cZ>A>f>JӮ>t>;>s>>>S>Z>ti>`<>N>>ݲ>>>Au>:>'>˳>>>5>i>|>>%>[a>@~>^9>l>,>%B>m0=A>=>Xi=F=-=͵=O <3=ܒҽu&=}ֽ>=ٽ\=T佊=m02= =a=ab2=10D+\;SCS^#(ehj^TgQI6cd 5VԽZWC6, TR۽νB`ݨlm5t:F_f;V?s=ѻC=IXD=Խ6 =#$< !:FΧ/;' )nwY(lN5_ SZ,r%AX6[y}2;.Ἒ1<T;л ,Ȼʤ;<eLƽ==4_^=K^=r= ٩=#y׼㒒=tReu=ZnK=^D|T.=ݙJ(=⼞@=QYs='8=70= =WE >Yb#<">`=6>;=?JF>=;S>,>]>f>yg>I>K!q>eJ>Ky>J>}>J>Zh}>=g@w>=k>U3=g[>:VX=\F>x=,>և=j=A\p=>=W==o=7= >=>~=/>=47>p؆=i5>W='>==>~=/=n==W?=<=Vr=pi=u< <;勷[=Ψݼ}}W/UE39@o;"D:ӇhS.6],} :- d߽>Xֽս׽pP὇79\_E "#vIƻ}jeE`pb$:c7`yS=|L>S=1x>`p=؏>=q->܍=- >+=Yb>>r>>2>>>ϒ%>n7>e)>ɩ>R?+>O>)>ݍ>#>6>>ē>s >Û>>>Q=>%=>m=]>`=>=b>7̞=*ɮ>*=>V=)~>s=ԋ>#<)>%0͗d>%F>$>%5>,?=I== =qv=H9=;g =m;=VF= =ObFm=X˚3U=ѽJ<~[HRjjwmK2 CG7Q"N&TgX'Ƚ7]⽒cH& i{w/n0pMpfc lkndfn5 X(iE[ e~.b>lz`x[r½SK{! I\KM%YQW>#qB'dB-t愾#)˽vٓn~ョαǾ(3Ѿ˿ٽ^վƽԾ|֯оa:FȾbW'Hm>&;Ri'~<36J= ؝=Z̽r=DW>^j_w>YNpd*>v[`:>jG>;P>aɽ2S>ٽvQ>ڽhL>&ֽG>+ӽϐB>н>>!ǽB+:>6> 5>`'d4>8,JG3>AE0>Z+>teh%>:G> ;͆>x&<>MQ =m)> 1=c>d=##>=|->3=8>5=CC>"=|,K>L,>vK>>0SA>I >Zj->U>%>>+~>o=>=Y=iJ=j"=:< y=*,(=@ 0=Dc\=dm=k`E=I==Nнr<4RD;UxZ~9r=-ؽ„]y1UCaI $r;=_N<|?=> %>B&>>*>o>G(>T>vw >!>M>.>>eK>> >< >=,>=l:>?=G>t=#Y>;=o>-=:G>~=h'>=e>,=x#>E>>G >L>z> V>>v>=iCb>=F>=t%>ͱ=>\7==Mz=g=b =0=="=}=M==O>B{=>=4K>}=؍=?=*==/=b?=n=@==L=p;L=ϼz=.GZØ=h1=ʽzo=; '=A5<ݢSrͻ(D7 jBhݽJ9vP6SSO*Qz caHu_: (^lgiTD`aD<`Efxi*k1-@`;-2Xr}HQP4fK݁LQV&~hg'}L@OpC&)*쿞w㘾4#BY}݆rהmYlpܞ_n]6m?rG˝ 531VȽ]{j|SkøndrIJ9zI&66kͼ3#i0*.J>U<6  =ήT]=-T$^I= F;f֨=zs<^_=<=8=&|=}=#=".= =tJ=9ɸ=t=e=;o=-j==,DG====J>K="(>Pi=IA>€=LV>={d>lF=k>C=Nk>V=-"d>=mY>=hK>AԘ=Nn:>U=v&>˩=>A=B>x==)n==zj=7=vI==[:5=L=W$=[=1t=৲)>}M;=\<[=v.=J=E[==d= =@e=MsI=b=;=?=[6=E(>?=5>y=x%6>=ɷ(>Sc= >=P===Ap==n"=m=n<ҝ =U\:#P=u=Ь=A=.ս&= %=w >|G<8>W=8^>G=eĂ>">q>cJ>q5>@h>?>y>>/4>S>$>^>V>'>$>G>>>T|>v>)o>>,c>@>;\>+>[>B؍>H`>a>NEg>!8>o>+>Fy>>?*>c>Q>p>$>T>ʻ>{6>$y>>c>+=9O>(=@C>Z:=>>j=>>FE=uC>>;=X:>F=V]4>RZ\=E->q=7G&>^}=V>=3z>s=G=X=Ya=-=;;-ǗO-s剾Im`#f͟Rrz%tޒjq5 sRpORqF19srՀoi*8c&8s]8'YPCUHjbmQNzN@`]N퇾EoO*N{vjIa>Jj/.  CF kؽFL QUo=|OLu@6t:Mk=Չ =C=B; ͥ=p<һ==w=tF= >܌=g%>=\d>>.g=S>B >4oe>>Rr>8{$>w>c)>N@t> ->Bg>r0>(T>3>B>ú6>7>M:>z3>T?>4>rbI>/3>qW>0>Rh>O.>z>H1>>N;>?:>&7H>u>NT>ދ>\>>zb>SN>Ph>+{>9p>/1m>x>xq^>'i>BQ>R >bF>Ay>3=>FB>1>>">Q>%_>߅>=Z_>k=j>v"=f|N>]=0>k 9Ŵ>?;=Kp*=8<ǽ)ڽ]Ɠ%A޽ؽTս`vý7 Msn[޼ ˜h4LШP+Rؽ>1.KB8% h2sԀ>"[CH+DKKDq%~56>x~vzrjIҽ[TN8E奟*=96F7<1Z3kpX>"^+*>'MY4>.#9><>%:R@>;HD>=)F>YO=p@>R=ȯ5>W=U%>#e=$>e=B=-=׼= =ւ==#=Yp=RW<#=ϓ٬=Lp=|>-2<=vJ=)c=^{=*=] P=!=5[*=;3=ŖCsK=Bel=o8=~9'dʷ=uuh=,) > Ѫ>3\y>*>1>k;l1>X<(>g<>>c<{=4Q*<=J;w=jyq;<=4&;]{>07;> T;q>b;x%>}:G1>]{A<>$ZC>d̼WDH>~\J>5 L>gML>Y&J>XaD>(>2>|kg >qtZ<)=W< [=+t==~;=S _=xW=<b=x;Y=FsB=7ļ\$=N=Wdw<21[<_ Aꪽe96@>&Ώ;1Ƚc>bܶō#z\C;cw`Ž1wlx 9)ʯEuH ^oew]f 0RB=(#IT/摾R僾|=ҽzmY0Jt5>@hT;8NW=Y<+H4yY=9FNihqM^tHr=y;ztî/|Ƚp~kٽ^}#}sA޽4^\нs97&Nѽq=L5 )c޼,<"<'=n===K=====ж=]H=gz===0=y=.=A>5#=2 >R>J">T` >P>q >k>Q >!>HQ>d&>=A'>==>$>ǒ=>!>t=q">"="(>wM=Z{/>=5>(h>,:>$>x@>9>NJ>K>^W>mY>c>6b>k>i>%n>o>m>Qs>m>"u>{p>gfv>s>^w>4Gq>b|>i>^>:^>ʉ>PR>>H>7\>&?>u>QF4> >u&>硁>>t{n><> S>)=$3>=K>!Ο=O=J_=g}==|s >m=>4=2>=_>=^>=q>2{={)>O=L4>W=<>>V@>^ >@>>v<>b,>5>š=->=%>/=E> x=>5= >=,>+=:!>Vx= >= >V=>=r={=j=F=z=&===H=sҀ=ܜ;=B]=2<#=Bmk߻0㼡OH C.ހ]] Ľm߼1A5B|h~ چҗ_,HR"'OLŽzzQ]"þPFcľ j,þX!뿾 %= n3/za;cE#NQա J=LV-6ZmxjvƧi2$a|\ $k])N_e(n4XAv DxjRPt^Y.i|TXC_A!- #O oͪis7 ݽx3½>fM.<)>ncL=*>>V=$D>,=4E>(=E>=LA>nh=^:>{=2>G=u+>=}>'>=N]'>^=J->=5z8>i=UG>= W>4=of>=qJu>>>/O >g>n>8>Ho>>f>>([ >>]G >t>rd>N> >T>oO>>O>ّ>o>ӌ>#>=ȅ>)>sex>l1>\_>B>>\Y@>1Q>$>]c>Gu=so>Y=o>Wz;=a>!Z)JƊ">F:(=V㓽{=jOŽe;pN tǽ3c1/E@$gO:a)4[h,]a,b̲(` x[qoVU!ӇQgN 1콄yOgU;~bst[ u-/Gʎ2={C FHF`:= .,ϦH=">{]=>x=l[.>Tɴ=8>8=;>=y<>=6=>k>?>>A> ]>O?>1 >?8>>->*>$>߸:> >_yK>cI>,i\>|>Xl>Ek>Oz>`>7́>&>ق>;>P>cW>kv>[Js>]g>b>T>g>?>< >2*>:>>so>w>X>4=V<>@ =>\=9>5R==8=u=W=ɒ=c=JG====dh=q = =,%=/=m==>>5>3c >P>>T>z=4~>S=>0F==2==BS޾j D$<Ľǽ9n,?LDwgk lV;}^d<-WP!=;QS=#TRj=Z`f=ƀTM=󹗽#=G<Ľ;ӽ6!f6- VO 5|F :՟ZvMt>_dqGؽ޼hx>uL3ˉRlxx;6k[$Y+gTcMZhAO*0,s_} n=нA!ĽbFüݾcj%]u9弽.!{˽d0NݽQռ! s۽S½bWdb|,t3:S7;Ǝ={!>>v@>>|`>1> }>I>]>Zc>2>{>>d>Z4>>&>>>Β>g>Ri> >>0>> g>=8k>ʶ>TsU>\H>LA>&>ق2>os> '>>% > >V>q͢>>@>>>A>h,>Q>&ۏ>gb>t#>d>c>=u >P=)>TL=u>Ev=f>u=GRS>_=?>7=r+>7=>=G >}==&c==d6='=s@';и>7ռN>gu>#C>:x'=d#M=-xQ=JFK[9s^eTENijL>c̰ݬNVh⚾s*OF17zƅ&|Z x7xԘ|!źo@뱾剾 wӷj. ﺾ%6ug']{ۯ!sbak{K}:1[mE뽎\ v,k>Y 3;z<f=<߽=T=) \V>z;=`/>ڔ=R7>==>= B>,>FG>|.>q@O>>>KY>G>Jd>&L>tq>R>+J|>*V>9̂>veY>X>>]W>UP> Z>`>9g>:>N{>>J,>|>~>w>>7vv>pr> y>>T}>揄>j>+> >>^>t>2>%>J>>z}>>/n>?>ü[>ލ>[E>LJ>v/>>;.>X>>Ę>7=_5>=>&~=>+=_><'7>n+;$ >q䟼H=28|=QՈb]>7*> v8>=nA>+fD>8zVA?>xk02>ܰ>>>Bc?=ۚ;=6<8@=P8=\=0= =n=<ƺ= 꺲=ӻ=ڙ!=ך|7S=o =ҀX<9(; -~ R8t{>Ho.=5O26߷(Y(7Qܼ_㏿ Im׽μ̽-]ȽҍC:ƽOɽHϽfpٽƽuνPսHٽ_ؽӽQ˽q y,Lәe)7\N }0ռYKa6(e$Xż|ꇻFY:~<< n="">.=:4>ܜ=@>̴=G>6=VH>&]=SD>#=۔=>`=x6>A&=k/>=l(>ÎW=!>az7=>1&=4>!T =}> i#=>9=R>%^n=J>=k >=z>~=>7=9~>=^'>(=D>+8=>7B=GI">y=S,>=5>#=C=>z=A>2h=TB>Mm=>>ߞ=8>'4=e1>Ϩ=)>=">(=Sw>=X>s= >k=>=U=='='N=ޭ=<䃼o.ݤg_eRƺԽ5~7ؽࣽHͽ!{?৽ӴXaWpu#Ve@ h範M$KC ;\Rν^+ؽbjm>اGmqgʽ5ͽcܽK~yIf?H$)<+4=0DiS^G༛cA /bʚ,[WbSxQSI6?M9x5<*<2!&<'#3=Bt=t.=Ѹv=8=2=MgS=p=e ޴=il<=.I= `= Vp=~ >> ,>ʏ.2>?g0>+>$^&>!>l[>,)>1Ƚǫ>>MIG>M]>%Q>` >;޼,>"Ū7>AcB>,DM><T>5A;wT>G;I>;U.6>(;*>j=XZA=]WL0=$D~;߇R PըƾýX ٽDݽ4`2Hؽj޽_齽Wٽ渝ĉϽ^)XP4>R1O\ ŵo"˽b彗.]- Uz,K R)ܼx8C17@bI =)D>V >6>H>K`YT>A>Y>(;W>LEt=lK>a%=9YC>I=9> <.>'<>="><[>;:<">12;=٪r=vn=@k={:^;7=\:se=R筻ٻ)*|;Z ª޽Lbq{O0Q#!F1/>iJ(QyRN ⽜J>۽tK!ؽMbQ ڽ+[߽ocmgig sMesbabA񽇒[S*P轟@潋."-p.?? G~p/~彃ɽ=޻~;_@M+p=<.>u=?G> >&Y>,>`d>G>_j>^>Ro>zo>s>'~>=v>n>y>G>z~>ߘ>>zK>a>r.>>r>䎌>>30>ǡ>܉>2>ܣ>3>>>>>j>>>Қ>06>c>\>À>>Ό>>b >R>>t>ٔ> >U>+j>YH>>'>_>y>%>c>~>MK>'d>/>{>y>X">H =r*>=%>|~=>x=>;i>Dʼߙr>qvP>jǽ?)(>d =0y=LS$=rh񲘾-$|[ܚl~J<*Ϩf Ffut\]H^SW?9Fք-̻-"`<c#=H -SP=CjD=s=D=N㽋F= ʽ2=Ef=465=~> =~cjz;->[G<G>G{4=c>.U=܍>S=G>o=!>W%=hӞ>k >z>>~>>>;!>C>ׯ">Ah>"% >P>-7>f>z > S>Y.=Y>=>S=p>}=Gc>=\>u!=Z>=L\>g>E_>7>L+a>!'>a>5c1>m`>2>-\>z,>sU>I>>:> >E)>L>ݷ>=>$=n=R==85$=Z=<8=eX=ٿ=@'(<5[~Its5spebpVe Q5Խy|V>dRX42IX%cWp:@Mؽ/:w4ýQo<0<F9=&Dd=إmp=PL_=7^@>=#=v 1IG\C6ITD Z9i A'/NR89۽2߽_ۣ̽LYB s-%Rqlb/J]i3n]`q"q,YI < +<<_X(=h匽F=싽 T=@ʄRoN=k5=tB= _X;H<<=kB=#=j=j5=:=sXI=l=PPb==%р==#+=>Π= >ƪ=' >e= >=%t > =>=dI>=j >6=>=s>S=>=>2<7>*_U">8 >f)>> ͟ =Mdܹ=椫?ė= Iüu=<,ݼ!)H=꼈*=̕漱&=[ϼ@=ܿ9x=:=f>=4>iE=W>S= ><=#;I=Tn ؃S=q}듾ybˑ2d Q Pޚm֖цZ8F|p#yNh$ٚcE"q_pZ=uB2V .QLJxg?S/ܽ /5䧽xU ý'[]@`>nɼNQF=>%=BU.>=F>Y=]>=!r>J=r>B=kj>F=8U>l=R>=v>=?>9=>+D=y>=+>=>e=0 >=%> >a>5>x>n>n>>ll>> s>#>#>+>> 4>[>:>f>=>2><>k>5>~>"+>j>>>K;>>^=i>=_w>+=^d>m=_pP>q=:>WO=k%>Ͻ;=R>1=[>)=f=!=Y|===]=ڡ=<=}<)G=:Y;@=`g<̼߼>ἻS[Y!OļŽNE콣B> >&u;ܱ)\r;dr3#9g =ID=MGTz;Y𖽙eƘ)qbFtkz܊ʽ'ŀއν|\ɽV Yބ Rߋx|Wlss3vpn8mۼ:m,{shb<'^$=JiQhg=kF=?q=:=\^4=x)0>JY> ===a{½\6=9=Qz*=:DTժ= h%i)=6t=c.$_=w*=?0w@=;k>AOc>ky>ł(>? 5>sy]A>O>p[H_>c<1p>42=5>TP=>={ڇ>|>>>A>>cv>e>ӄc>X>-I>6=)>$ܼ='>uG=ݾ=4f=ϋk=Tz =<9@<ㅻlsIDzA>߅Uy[׽xi91bu/SյRVna}A둽"C+v$ҽ@&`0+jL>n1إp9(CG4RQ|X9d7}0t()!ز:QTYmV8\ݵ]ĽȲǙ^D΋bQnޘW3;#f`mW;=0 >0R<>/*=#0&>AJ=d0>EX=+&;>ZW=C|G>HJ=rU>V;=:a>0=g>F.=h>\4=d>?=X^>K=U>{T=I>^=5>y|o= >τ=>=C=[=DĻ==ް==t=Q>=e>R=j=,>8>"?>>@O>f~>xY>$>^>Q'>K_>63!>Y>wa> oM>5>;>"= V&>`=^>n== $==0;=Y=:^=zuf&=<~<2';:'ؼoH+hG+gm4y9Vr[O=kj4n`^#N*Jڢapv73ǽ[ ýԽ/+нYݽ使佷TN e{];'f14G@YM<νb\<ҽ9i=bHP=·=+Xr=ż7t=j@=06>&9=/>l%=x?>>ڃK>3>~R>(6%>S>U'>K^P>)&>N#J>gR>C>>y=>=DP:>.?=9>O =^<>="A>l=pG>K==V>!6>=[>uY=9-\>=X>@=T>=P>W=*O>=O>hi=P>= O>=bO>S =KgO>&=(O>w=O>O>=L>=@>/=fi7>$=$">M=>=fd >=Qu>:=nY=h=W=N=o@=۸=x=}=5=ʝ==~==E=l=E=^`==xV;==b?=F]>S=8>4<^>+<>u=zR>g=|>N`&=>j-=&@>fa%=K>Z =>4<>=1;>|t>>ȼ>$,%>V\/1>_>;>R B>:GD>@>ыƗ5>ub >`>F=)G=*B{T<ʽ#l;Zܽ[뽮7VWE`p>I2ؽ3siǽ;XR<鰽=7w1=B=4˽M!B=U$=<)r9,&q~;x%HP5/S)G#\Qtbj"4d/ cAo5_ 3[/ތV-P%3Ƶ@i䌾msFlS.,!׏"C"۵Ӡ SG {`0ꍾeսE򁾻sv7xjRb:`W#S CN`uk0T<8Df== R=å>zϽ$>0) E>-ob:c>Q C{>|>H\;><#>5xe=/>[=>>>+0>#(>W>w>y>j:>97>7>V>+>I;>D>>>>T>>ҏ>e&>>K>?>ܐw>> l>>ulc>>]>T>]>빎>~d>ؔ>Mp>ݖ>ɥ}>g>I>T>0>>ى>ʝ>᫊>HL>,>8>5>Խu>>^W>=gn>:>1Q>+`>2>8>>C=Z[=2+==v=(=p.=`=wp<,~=Z;)o=x=>0>P=:>|=<>=U8>=L=4>=f}1> =<%0>=c0>͖=h3>Ư=s:><>_hH>{.>]>J>u>nf>xg>?p>iJ>B>>F>+>>j>FQ>R>3> >>a>>~ľ>{(>N>Ƈ>>>Od>[r>e>ua>>N>>s9>N>!>N}>M>zt>p=Ok>N=`>`=C}S>}=(G>:6>Yr@v1>(@+>"=">2>8!i >,*>{:B=O=Pk'=4=)= Lj<3ԽCGqz!4>ύǽ*$Qc2A1"Q+a3w)qK:}*Ao%E DΈ!?u΢8q؅P13vɀ0Ar0_i{/:J I/~ 5g146 :>tDʽ E^W[?4ae'&+4 ߼ZtrºN4;L$A>&>^诽E->7 i0>~ gk1>Virz,1>A/>*->27)>Ƚ+$>2Uڽ- >0>Ca>> >e#N>Zs=ܽ="ӽHY=tǽBU==m NH=#ڍ$=b1e>fi>WtG>&>η=C=:;W;=-Q%<=]Ԃ<_=ǚ#JuE>rb!>IfhL.>%9>&B>t40G>V=R>Y=O`>?=$s>= y>hާ=4>*m=>{=R><=>A=;s>=|A>IM=ە>4=&>|=2>Zg=>=X >x= ?>=>:=">= {>`!= Z>=@>1׽=W.2>#= ),>= ->) >'3>@a>ڂ=>#>]K>)>Y>)>Ja>$>%b>z>X>>,G>>qV1>=P>=>l==d_W=`= =mE=<So=>]= >e?=?i>D=.>K< >tY<2=v;G=9/Pl=i-=ʠ gq<;-ջR;Y#X[<;,{K'<@>ga 8I;$pP>ûCH>3ξ9>ȉڼ@*>#&>pO>6>⚽\ >q"u>Ů!Y=xǽ=Fƽ[=?q=O=z=|yf=wQ=!=m=9Ķ=~;= <31|=7l;&=M;F<Ϊ8:'_/( 8&sQZ ,B%Ͻ D cTkqA ہ4Vڽ >A׽IG 8_ M  tPɽ|糽>ݽܞ]L봍FuIď=g㣽@!L ;ɽR=X=k=D$=G==q=O==A3==0C=G4c=F3=[A==:/=2=,-==V"A=ڌ=j=Z ==u==Ca==b=f=Xg>=>$>֥>Ƶ>4 >jS>h>v>}= >d=RU=ԯ==.\=w=Mi=Yw=6=p=<<5k׻W$<d(:/Xfޫ פ>sѽoCP3 _!q%18,jk0zҬ2d״3=/6k ;L-@³nDYI4н7gM8O⽶P1ORhRZ }OJ2nBiF;NXZ4he/8y^,ʭ+E-jnV2g8А6?+0Bɂcu@ u):rd/Sߍ! ODCn8X2DgҽZ1æ{1Ju-S#T_ 9[<33=O8ӽޏ=ƾ>9-Y7G=DK>i=o]>>=i>f>Em>x>l>Hz>h>"> )d>>`>?>^>w >M^>>H`>Q>Me> >0/n>'>{>>ۅ>Q2>";>*`L>>k>䷡>9>>/֒>H>\>>[>;Ľ>M>P>5>i>E>[>|>L>A> >q)><>>>>Y>\>Cɱ>>>>r>օ>M>6x>gy>f>Y>qzU>}T8>D>>2>=M >K`=%>=>B=PT=?=g,׽кq; >k8<>7h =!>G=>|=v >n=j>W=&>=>=Y>i=>b= >n9Z=>A&=[<>C=?='{9%r%# ?"k.ýk17>3". (pn<&=G> >ǿ>+:>->[)>MF>X4>c>0<>.>[C>y>G>%C>6F>>?>{>b5>.>D(>XD>>> >S>g=&l>*==>=>=>=4 >ؠ=P>p=ؼ>V=>;=ai>%=A>TI=i> =~ئ>=>^=9k>=w>=,O>0=>P=C>=*>z FJ<j>;{_>HRKP>j<>2| B%>͑ >@][=|=.`;%{= (V>=,kc=Ź9=Y=zn=`> >s>B`6>ML, >XD >Xx, >!>S-!>; > <>X6=\!>Q=EQ&>5=/>A=X:>>)PF>@>>LS>\>`>Йw>`Qo> >]~>s>>G>>{>ᝍ>֥>U>l>王>V>{>Wv>S>Xڜ>y>>ki>>*Y>C·>J>ae>#=>mp> 2>ka>2*>T>">J>>B>A>u9>b>q1>h>.,>r >/.>6>u6>@q=|cC>S= N>F=U>=AW>=UT>S=M>/=C>g=4>=6>W=6>_==u{=ڰ=M/=j)= <~<ʠ:@,(F}9RiUPYϏ=}@–w0s)Ƹ 7CNɳκLŽWAҽƽ޽x޽齦l# Hvb $'۽Q%L˽Q"WZ< Aս\x(m_+wENAB=-< 0)B:^@ ;߲]|=J`>.棽 :PŽ0$&9'ۼ.཯YԽ0lƽ/;U <"ݝ=qaS=P:>4=T b=1s=|C+e=$%:b=w_l< >=Q> =>=1_>}m+=>oA=>}WW=4>Va=>ruZ=V>A=1>)=%>&<%>gD4<ԃ>Mϻء=ǼR=a$x=U%N_N=dYk=sDU$=<ؼDgEF>/9!<ࣆ==NN=Qd><ͽ>8;#>ߚqo#>>k0|>m >In >&& >U4>e>#=:SV=G4h<=_<==-==H7q=nH=Y==3=?=}3=>!o >` >+N>6 >->m >H8>l>q?>=owA>A=ݗ>>_=6>!=+>E=>٬=V >M= r=K=n=H<=t<=|Oxa=Z =AqӋ=AC=> 2={=$=,=$=*=aH==ٌ =1=!<[=6P< =E<o\?>K9|+>-@>ՑԼhT>Z<"r>==Gk{>d=^>"=5>5f=og|>ֶ=oLq>{=da>"=P>c=#h?>=s->={>s=8>=k==?==p3='=\x=,a=gA=?=H=}*=jq㷽(cǚԶy=@=r=h>[׭=\ >=[> = !>>hp&>B >'>O>K0&>nX>%>>b)> >4>Q>nC>">uU>S)>f>4>v>qC>܃>GUT>,>f>k>ow>G?>>>>:>" >D>\\>[>ۦ>>Ɨ>q> >">#>>>>>ی> >>݆>>N>i>b>ϑ>2N>>S6>a>C>S:> =^>l==c^}=Ш=mZ= Fw=B_#><?Ē鍾*Sdpo!pt%xf6OՄhً|dԔZ8ͳ"4EK͵n{nڱ$߾о8G r{6h*r.5{]7zuI.fu6VT#YE;4 =1,>Ž(.K,x.s2WF@64)5ڀؼn,t4Ҵ2<*:c<^ὺc9=)kĽ= B=|Z=1: >S#>GRj8>":WI> ޏW=a>1t=i>c[=q>f= |>|=>li>~Ŋ>'>c|>a:>ė>bLH>x>PP>߃>* S>Mm>bR>ţ>R>>T>>.U>a>hfT>$>߷Q>?4>O>v>0R>5$>&Z>-V>5e>M>;r>+*>x}>o>Ѱ>FȠ>I>{>J>># >R>O9>r>>B> >w>5|s>^>eb>ֹC>Q> 1'>A>M >1>b=(!#>ߢ=>U=^>*<> >->bV=홽+=hŽз==yス= z (6=#n<C/aW;GcETVN_΄V@~_zgqnOt,z/oǀlA* 1&߁YeI銾]xٻm_/ɺާ8/vɋԩѻ~\J{rFܤcx~Ϭ,RUμsv;]XjY*'[RIy\p7u%wQBlfѽ5 TýeYR꽏*d$+(t/*9]ޮx<`؇3L= '/5o=S3m=:c=:A7=F6=֢J=/LK+=I=/>A{@=O1l=5=cC=Iνx=\Sw^=/߃@=TY=t0޼\:5?;ˁ;ae<|.\<g:= > =>E>z)>^ > 4>`Z><> >3C>a>OG>Z > M>>C(U>8==`>=5k>w:=v>=أ>u='V>E=v>=>b=R>=wF=>3)>E>/>{>>>\">C̓>+>j>4>w>nT>>>kH>~z>IS>9~r>*[>;i>a>]>d>.L>!d>5>))_>S>xT>(=D>@= ->f=0>Ç>=dl=Fa f{ωdvk`}牦caإ|ֽ+%=C<5U.$2Z@oM?F(VR<[ [.V<&ZL6w`#?dS.*N/778z)[Ƭ#Lk7Y} ;}bl"<=;\-=or="> =6>k=F*G>r=6U>=c>W$=rp>={>e =.1>s=|>u=m>0T=^=>!=>=>=Ϝ>=Ͽ>Z:=Q>h=->t=>V=I>=s><=F><=GU>=,>p=>=و>d=V~>"~=j>a=?R>:7>ž>{>}ƽ%=c=4o=!+>N=8G=x'Cر="K=;Q9E=F3Uy2=:$WS=WZx=PEU~K=Rֽ=1MN=@H›=B!=9|l=1dO=B1)U<=LU#!1= )%=2=`?C-:!eм],63b53b t3p<7"< ?A<\G\$ =O=T=\W(=ZYF"=f\,=``>=c'Y=dz=ck)=_b=@2bP=%b(=na4|=@\ >RH>`C">1-> G:>~5G>zmU>Nb>jwZn>B;y>uL>:>@y<ن>$<.>=:>#-=6s>b*=B?b>4=^M><:8>{< ">hE; > غ=k7%= {=꼳=%j=y܈=Ӽ$p=qƼ$O=9FݼI_.=W_ =|=<ǡtG RZ = >e=>ڳ=Y>ɥ=Wt(><=XO6>>ɱD>>R>/>^>K?>k>M>y>V[>Y>i>c>Dv>.>.>Ѣ>>>Ɏ>[>0Β>>!>%>>ms>M>D>Ə>L$>g(>!>>>>9˂> s>u>g>)Te>]>BU>T9U>~=J>hM>PC>E>>>&H=>9>3>0>*>'#>!>1>>~>X>N=>>%=U;=2=Ĝ=9=3==&\=-Z=eB=1Mq= < ]=suɸ:=u2Lsg)D.opi|kcw~?^Z6ݽ:XHн~vVɽ~]UGýU+W+#(YJAgZ-؄Ylg%UU^KcM[1QBՎ5' VH輀 %fѽ `/޼P1KVg]b:L%3<ڒY1B=>o=>eEr6<)=:==) )v4= D= =('=G; =x0B8>;?>CC>'yt&>l#޼K.>x05>o;:>9QqP=>`B=>s5m":>xxr5>;z->T~">s0M>Dze]>oV^8=d%=OsB=P={C =`=݇}=ۅU=;~dv=]l=d#e=bPRd= ;k=N<+~=C1==}y=nj===+=9=J=k =L==Q=#=)q=_!=J=I=8=7=Y=L==3=B^=磴= /===t==ҭD!:=.2>9k=F>^=z{W>{=rd>1,=o>~>/vx>>l>g/>5|>C>V>nV>ی>Ush>>v>>>0>l7>g>>H>#>$> > (>>X>>҈>LP>ކ>>]>>|>>w>>VTt>RR>t>">v>>>Hx>]>v>>.q>F>i>1>^>1>AR>>6C>R?>1>c+>f>܍>>ZB~> =1`>-ɨ=C>Fi=7(><F>!:Y>RM߼!=#d=4~)=4佑>@=?ɾ<|).;5B͋EXWvieUtE{Jb~KӽUyvgnc1t.!p_v]Y!0IV@²RR7qfg7~7(닾BF×gɠ*Dw;XT*:U@Đ, Kx[of]ULRHG9:)%/%㽅ƽ+':( Dz@[~ٓW^+,2Q{ HԼ5λʒwy< =e;7Q=8[=}>R=771>=G>f=A^>1>s>%><>-n7>䔊>O>A>\.d>夓>r>ˍ>|>>$>噓>ݻ>>{>&j>>+>Il>{>K>pm>>_>Q>4!R> >~D>>|u8>>3->>l">e >h9>Kx>t>T}>]>S~p>[>ma><=P>(=o.?> ?=`/>)>h$>>J>D>>@P>>1v=><+=x>=>)>=j|6>=wC>=bN>~|=&\R> D=~P>F =9mI><ӻ=>$;,>)Mh>3=cݼ[==b=L"@aoOMa6;~?|r<9r;:=DOeɬ=a+V=/yG=U<=6>G56>%B5">33><01E">)*d$>B$1`&>,5(>6)>+>J->нg->WOd->&,>-R,>g+>L(B,>|&->X\1>M!؝7>95D A>PL>gY>ayw^f>Kҁq> z>-c>݁>6dVj>B .}>.ԼOHu>i>ȕ;\>eh1ô<Ĕ:>h<8%>ٕ<[} >>GK >^2>l:>vw9'>~n4>H=B>Z1O>zX>?A]>񕃾ŝ_>84b>Πf>7yom>oau>b)>S >VBt>0x#\> ><ϽR>⬽s>&)Ȝ>Pgo>9>G(>IHؼ,|>wif>bt/3S>ZA>*ܹL2>:b">: S>G|=C=K5=Efἦx=!S=>Qvv< {f[ܺ㍽9l,傽}/@jRΦ,5C>?@Kz>TPP-v N 0Mh OPz0Sq:XWl_ljZn{rz(AJl㘽' :VƨReٵm6?tn?hQ[ZA8PC9&(1;!ǽ;`ך~;s;ȞB\;>0n;9;C0);*FG;i֔AZ<;<^5t-<~@+t<%P< G =$>FJ=t>k=>#=>=k>=>ފ=M= $=C=Q=l=o=r[=B;=GV=xj=F=Ű=^===.=Q7=P=9R=Z=k=@A=!==l>6ɋ=#==e===*==L=C==9==8<_E=;~Ӭ=8O= B߱=˻޼j=꼁=IQS=ؼ= ɼF=?=蟼=9=}=U Y| =(Ԓ'x=zfGe=ؽ8>.=B$|/=x >V>, >8 > >c > , >$n >>1T>>K=$g=@=A=='= =F=J===L===>C=>=>=#>=)>=,>3/=L/>Q=1>!F=C2>r=0>=b*>s=*">d=^>Z=>DS= >M=Z< >H=>Ֆ@==1=q=M==cLaeLʙؽAMɽhN½ QIȽ=T4+۽mYD„='> =>>=U>U=uk>=~>=>+>j>>G>>#>{>ʪ>>>>Z>2>%>&> ֱ>"> m>+>_V>.5>y>A>>O>>q]>>5g>~5>fl>>5k>=>of>>7^>|s>Q>pkh>(@>c_>R*>W>> TS>: =ZP>7=9M>=RH>=}B>9-s=:>S=1>85=7'>˛=G>< >f<=/H<+t=6=/}=ID;縉8>孽j UPѽ~J>ùF#>ej4ZBu<M󢝾V1n^w*cQа.c>o`YNYMQ2׀JfCDK;/{ /qcNJ ۽?½ix]:N\k 5UJ9PKlU>k\O~h\(y(Rq\BRfOX/RVvt@Z⼔5(Lp cj:{޽|M=ׂ>SU=-t>d=A#>`]=)>TF=.>w=_0>R=1>=2>G>3>>25> >6>>8>DP >9;>3>-}@>4=5F>)]=[M> =T>0=[><=Tc>=(l>(>NDv>o>G>%>@>8>Ș>:M>3N>;_>Z.>l>[>t>->Wy>m>R{>[> |>W>7w>S~>m>:$c>f]>&E>J>(&>/ 7>A>$>b=?>Y=x>H_=Q#==3=R<=bv 9>_[6>3 >q2>L35+==^=*DIk=gVkr=?a== iۙ=/lb=|mS~=jU=bH҆=\Tr= @є=ư* 1=_===]Žޮ=R=S"z=kT=7ة=w4>=&M>=O|_>ע=yk>[=s> = y>=~>=ʀ>+q=>je=v~>֓d=|>Nl=~>!z=ہ>HJ=@dž>޴=8$>М=>/=>=>=?ɳ>F=6>GC=>P=V>=IN>x =G>(=e>=VU>=L>:=d`>o=0>+=>=G>=h>=v> =M>;=d>69= >_!=>q`=x>9=lv>=Y><f7>/P;DO=E=h\=.;}Ǽf!S1Ͻ!Ľ)`T^bn%c])] Epv&&b .! =i#P)gf/kDw7ѥR> B;xDɩVbC` y{钾4ǽNh%q)jV;-=켌@(]{N8+ @=rѱ>3;S?0>I<H>PT=_>W=~t>=[Ճ>M>:>ԧ>>0>x>@>>M>$>jZ>>xd>h>tk>亣>[p>̡>eu>{>}>>>4*>m> >7|>>> > >tO>1>U>>'>_R>S>膣>b>w>`s> `>c>9>P>vq>:>{">A>;>* +>=>N=J>h=%=6==`@;>uS>v$>u9!,>Ƽz)1>8v 3>++;1> ;->;Dr&>;>@:(>܍fH=M<"G=5Y=)O=:E=B&H=r)="=x+=4K=؃=ؼ<~=lͱi=IׂI=({Ϛ=Co<}ܼy0%uʆQ6֫Vt=ͽs4\`mĽѽs˹6%6/d<8# v? C& *DA pAaٟ8+1Hܽe.* u{W6ʽ\̼Wa,m;"8M\P<-)Ŗ<=&T>,9=[/>FԾ=z"?>O=> L>#=AV>]7=]>=c>=h>.%=+m>5=p>*C=EBt>E>w> >*z> >.|>a >I}>3 >}>Ø>&U|>q>@Rz>>[x>i=Dv>=t>=_s>t= q>=q>=dq> =Ss>.Ō=w>fj=|>w={?>j\=o>=u>%s=>wא=Xz>Gz=(p>FH=bb>=PP>M;<ˍ;>d_R!@g#+ >$=pH=le0m=Y={Z;(vH`"覽uL&׽@ՖLh_l9h꽧70Yg཈CмwҽTP4Ľtw½g>X >YQw>#>"Zv>j >K1>0=7^=E =y =Yͅ=}3f%E=Rݼ=qݹ<BCJBuн&T꽁@_%}ig4~git aZOMG63>Dxl 46 n1 } K _Mm<ͼ):;5'&Xy.s3ۆT9zc@✽I\ǥFU항a_Skӷs61 z̝$3 tq䁾{yX.tR[d $ PRyͼl:"["{g;=9>a=y5> F=tS>'>p>B> >*>h>?> >(S>4|>sh>>h{>?>\Q>k>>^x>]>(> >P>>>%>>\>x>,_>>u>Z>|t>>j>@>C`>ui>PW>>&O>>d?G>>s>>`>4>>&>U>_>4>>>Q=i> =>s=H>׀ =Cr>/&193 ]>'UQ@>E &>j5+1>&=νRC=Ļ=* qP=VIl#adܐgWKO_݁UP6g_2/k͏&0j FbePSG9xT@|X+'Ⓗ/HlԽʼG<:sS=.{C; >@\p>q0>z3A>oQ>WQa>ㅽ:p>wT?<ه>ٙ<\>=`>C=m+>n=>C=VÝ>=q>֥=pÙ>4=L>v׫=޷>"K=:>y=t>{=>=5>s=?c>=>=>ȫ=҅>>7> >K>>y>x>sN>I >_> >s>a>o>1>Gւ>2q={M}>(=۩t>T=k>=Ya>˰=%]U>I=G>VM=6>W=$>'=>=.=Yd=ty=0=:c=le=BB="|=/y >h >M>Jf>6 &>*@.=S2c=8o=<>Ϭ='<"=d3hj=""D=%=̼=AEq̓=lO=I<{=?=|=~==`=&==S=H==< ><=>g=>v=1>b=>om=,>ۥ==>6==/wT=b=] = =x<"==(L=g0Xs=:==L=mw=|=ۭ==B>ǽ>ν; >ֽr >4޽7< >u>>4>w>Q~%>_,>]3>6:>&lA>9ٽb4H>Ӹ̽M>|O>I HM>r؆F>F<>&0>}yl">)ϝa>e>)K=`N+ܬ=-ø=uCkJ@= Rb  ǽe:i;%;Tu0=1?<ځ='<=V<>=s>A= g>#`= >8w=S(>E=j0>r= 2:>K=fC>3~=HM>t=V>i=X`>Y=j>lC=r>'='ax>=!tz>*̏<1u>J;"Rp>.Vj>2qC -c>ՠY>uG˼aCO>|޼^D>kA޼*8<>VѼy4>s>.>^&>wem>E*>N~ >U>?6>u^=>=mU=Ȼ4=D57=L5=z=M[=d0=~CV=~,/=# =)ƼT=`=< >I>Ҭ>!>:(>>шS/>DU}4>!8>Jkqm<>R;F&?>+]b <<>e=FY9>L=5>t=L0>>$=1+>Q+=%>2=IQ!>Y7=>$8=>]D8=Z>¨==<>K=ލ>7^=>p=>z=Q>g|=^>~y=>5Uu=uS>q=>h=A, >V=0>j7=+D={=1w=L<*=b<=;*=94Ţ=W8Լ3~=:(P=`b=Ï9{|mWCtViEĽ]FXPvBP>6Y3+j"Vr_e lh;:<< $}"̼ >L0Qx> U$;>l <(>v=o >$=$>@=j)>0_=[/>ʇ=v5> i=8=>=oH>o=zT>y=*u`>=h>C^>l>>k>0>-g>H >[}`>M&>>V>e)> I>+>39>t,>Z'>?->X>b,>+ >'*>k=<)>='>=J&>=#>U=} >5=e> =^->{=m >w=>a==h=~===vm==Օ=С=Wf==s==O@=Lm==?O=3<r.=_+bOm4y=9%,Ġ;F=C$ /Ď <úϑډD>S`$>ͼn4>s演YC>|鼐oP>֧Ӽ)4[>ƭ~c>Ϭj>*@!lp>xջv>,9A{> S<؉>=>;}/=Y>QSX=Yؗ>S=ܘ>Z=DO>@=>W=K>=c>+=T>=?>% =m>H=[>{=5օ>="{>2=yi>ׇ]=2W>A=FD>Gk6=η1>69=Up >F=> &]=&>y=u=Y=6====н=a=D=~"==4=A=<>=1$>Aȉ= >9h=>Sc1=>͜<6><>}1(ݬ>4y*>Nws >Mh`+ >eîMo>B˽>>0z >{ `s>yV)=cG /=wO+=6"~=Sf@R!<=K=Uf>HXf4=bD{34b*.#Il*[02нc "T+0cڽ"3xH jO|Ea )Fb5SOH M H x*\::HUR`wpXj[,T(x[%Zv$VMQU;BKa==2:a@x=5͘=%0f=&)W<=O# /=Լ=q u=zi=6= н=٬Ȩ=9m=pB=pq==NZ=O;6==\>A>>>`*>ѝ.>#6>pC>B>yW>LL>g>ES>s>U>QD~>S>c>64L>0H>@>>hh2> >O">>>|>J>s>=i>]=^>ZN=vP>=yB>!=6>=da.>=(>ok=J#>&R=7>M<=>x*=> >==R==e=M ==C=a=S<= is E#z J##MoNv5MJ~H{@LyL5vx't=smM/ ۀg]8bSaq["I̽9V伽P&}!?Hį;ϯjI,Ƕs)M*⽥˵7SճQ 0.soxfe[:<3>y<iSH<+ţ%=ɨoW=J9Ƹ=<=7=X<=Iy=7==7=G$= > X >>!>6A3>488>7F>'K>AY>Z>l>@f>mZ>\m>>>yq>>s>:>\t>[M>J/s>>}q>罣>q>[>xq>@R>ir>n>5Du>Ҥ>'lw>ƣ>x>ʣ>Dw>2*>gQu>> *q>>k>(>e>v>=s_>u>X>>Q>9c>J>A>ɾC>d><>K>M5>a#>|+>>>>_>2>l>`>3z>I=el>=Q[>v=\H>,=o3>*<>3Ha`>i+_ =jn=ӽ$5= <)G[|dB|.BMs;zKJ9㠔ژR ,:5!xɪ浩xͦUJEUmɽ ׽ΜKXΚ_6 Ǜt՟(Ɯ%=Y$.'i.+1Ѫ/A8\6A?)Iå%hS 1z ]lh^IBsUOh|>|,,!iyfF o–@jo]'{9uhFSlm`볻f(;2c<.c3}<]>ny}!>$s0>h?>Mk^JN>{S/\>ߛHfi>>~u>/$6#>i.0Z>%f>U$C>{q>q=|<>j߅>jqֽv>Žk|>Ƿ6r>5f>Z>C>C6>P9'>)~ý<>xƽ>>Ƚ^=HȽ@=Oǽ=ýT=@jJ=߬ =Fܟ#эۼz #n'*i&Ce3^0;_0xx{ؽ> ۽ >8Cܽx(>'ڽr->"ؽ/0>"׽2>A׽w3>@ٽ4>)I۽cI4>& ۽~4>׽6>sн :>½IT@>zׯTG>򗽮N>#w/V>o:cE_>`7j>wu>H4B\>p>:>;H>j;ˆ>|*E.<_;>HԗzA <_q>Xe<\/h>S =R_>(=d2X>H=P>g=7F>m=4:>=;->_=- >Q=>n={U>Së==!Q=1U==>=4=G=m=='=)=j==C+~=v=n=`=_=@I=DR=d0=E==[:=<۩-=d< EZ1;=4{8(=p4=\X42=*#>0=,6>==ijG>>yW>S>ld>co>@>;[x>M>+>V>M>+[>D>n]>:f>_>>>b>@>d>+%>l/f>>gf>ۓ|>e>v>d>p>b>xi>b>%c>O4a>/C_>"_>U[>o\>pX>Z>U>Z>kR>I[>N>f\>cJ>a]>E>[>?>4Y>9>V>/-2>Q>~)>AdK>>@>Ŕ>1>t]>H>=6 >]=PB=^=`==o֔=?5P=<%J=]<3AE ZU IpL' e0>X6qQ8=7֣94;Q1Ys-lꧾH'圧;7n;.轘ӂϽkܞŷB_@^X旾3Tސtf{zvܼ ̼|ż]lż)[9Ѽ8LG[ݼq1"9ϼ>PݽO\=z޼wʽ=$%=I;ܙ=5<=>L=V>d=>'=k>=, >C=,>=s0>=>%=&>{=>6>R> >=>m= x$>a=vC5>=G>3=#Z>j=хl>=z{>=H>=5>S=a>G>r>_ >W>B>>KJ>J>>h{>N >t>N}>&k>(>=x`>ʴ>*S>f>G>G=G<>S=2>ܰ=(>ժ= >SI=(> I=N>wz=S= _i=l=W=;=?C=o=/$=Ü=< =(L<0=_yw=MӗCM=YgQ[= TI,=>BB|c|PE'a/5bn08 ׽OA`InP] ]>6"g^TPo{r 1u<aw|qmu'=3o8fۖZ&KЁ>7 nӪ!Y 8Dv&.jӽ3K[=]nÆսozнթԽd½>UٽSJ>5*J+G׽9Q?EJ͛G~Yobbvq[F<8P%:0=?F=;=kH0 >-"V!>eP+>=^/>3>8>=>A?>>~>>-Xx=>G?> OFE>\> k>}>e%>m>vܽF>fνNh>6Ք>s>ȱIʌ>iD>>:is>a>)(J>񰏽*.>>Qoo>.Vf)=ї:=(>}>ϼr#>NgǢ4> ֊HD>CNG=s]>9=ab>>~a>vs"> V>|=>@>T>"!>-n>=1>!=Օ> CO=c>5<>Te;>tr Q> o>> 9~y>(^>Լ >M>u C>!>h;U>U?>rW>M> >"׬(>1ල>Mܸb>H=֔>_ഽ> >Qt½̨>Mнd>+Rɞ>9g?$>k3>cGy> \>tz>cg>,U>sDFrF>t^s:>|w`2>;<(->'>Mߚj> 0 >ʩf=ҁ=)ۅ=>Dz=C"0<᪾v;wKxvӽ..d<pU}[;)XAqCB90᱆7 䋾.+>C <^1ӅܑNG䖾.AFYJTj5ըW!Fu-챾]43a4-#ž8 CȾp.ɾD}Vƾ½#בDIγ1ҼϬ"7<G|5d%>y'@> -0T>4G|^>^>EaR-=A1>C6=U >nQ=>~><>ѳ<><,t>Q=>mM4=>7R=e>ҁ=o===V6=c= =V9= > <$>3>-C>jܦT>R2c>"M,m>#@gm>|b>[.LP>z>>ڮX0>d&>-!>jO>{>0>Zcq>[T>1Ǟ>B >fC>r}If>G~<<>c7>a2 >)U=#=(%̴=7.=8^=rC.#> ;1>P<4>b*<%->#=k>R<P>S`<3=n;?=01 =ҁ=щO`=jU=м=Hp=l =x廾=Qg:==M< >U<@*>0=c>>&x=^I>3=K>G=ƯF>*=i>>=7>d=E3>!M=]1>?=A./>a=(>'=>=4>۾< >,a= >L=W >D@Sr(<>R; >[<5>dN|*>Aƽ8>IܒIA>lO2RF>S AG>;D>i=>m<>4> )=O">&E=o> M=r>KR=!>e=R">=>q=>2=H >==>g=>$=<>U>=I>V<>&û4s>k!>L;#>ӽ$,> [3>#6> `$ :4>4x0>8F\1>AU7>y^eA>j]PJ>SIO>2DP>b4VN>&H>~"ҷ@>6>+>1: >Ƅ>b ,=A=3Y=ȋqߒ=ӃRD_;S>^[m>#;~>ga>&~>xXs>xDe>1mT>&M B>JF2>I$$>=>Ai{=ܶ>|=fB>w=%K>U=lz >>چ >B=WP>(e= >=^0>Չ=#2D>+wQ=9V>9;%=Ib>r="d>;3= 1]><=}N>d=<>#=T)>kf=>===w=%=[K==t=g?=rpW=8=G&=I?=nv*OzlBjp*FQ3XU#Qսs+k472"_)Q-.ۄ3|*3%%t/tR@)j]_0%@r̽%:(+>;*I $A-=_ C|q|޽ů.ý@}r1BL 3?h?/ (>p9>!(B> )E>B>:>Tɽm@,>AL>=D: ==[=xp==+=<==i=Q=c=Ƚ=2==Ų=x=E=м=c==X#=3==m>==+3=ޤ={===F=q=`q=w)=o=v<=7;}>z#>LT6>r;[J><`>bR=Qw>4=d>K=)>YyV=ő>_=0>s=>=7>5=:ؔ>T=>^x=}>=q>vp=k>_=8>=y*>U=S>)=֌>g=Y> =,>r?s>E/vh>$X>1B>O׽D&> 7>HF=y B=k3=\q<;$9-<%)*Q*,Ą($!RqD 2Ci 'ٽhfӽ<ѽ??ֽW{ཊ 9Jn3$K5KAM^ZbBn qBwzx$pbKBUHM^> 3nՁ:(J~m%v@n 8j :iild.o .oQh \%YHK4./BpnJ'彉ALצg|FJj:q)ԃ<h1=}:L}=AɽXv={p =Y[ٜ=&3=2Ļ=9#<=?=D=b^=p=J=i==f>=6 0>B=P>4=Rs> 9=t>z=>\G=>'=\>,=ۦ>5W=>c=>q=L?>=uR>L=>>J=>}x>R>v>>Ux>X3> z>|K>h{>a>_v~>)t>>>釆>>'>꼈>;̑> >4>g>Uʕ>,}>9֐>8n>*_>u^`>=iw>AS>`> H>@8O>g@>w@B> <>7>4}=>W.>?@>$>B>>IB> >=>P= &4>p=a%>=>=ޜ=2D=7-=b= E=0<Լh=T6,.=iz*x =s< s#s<BE~fϽK6>ǒ̽8T>½=l>?i{>=Yw>ׁ>\}>$Cyq>N3T(^> F>{#0*>: >PS_<=>JMѽf->۽"6>&ؽP/7>Ͻ4>KŽ@1>ŸuT,>B">>"W@=H|=\gq=3Ǚx9<9:;<$<5j(=AN\=i2\=;ߋ=אN=V͡=:x=0ֽ%]=1#>= ={\Ub8>[)>"] @9>E_B>%\'BG>UqX8F>zW@>R]6>>a)>`Y|>? >O='nj=d`=JLWm={[<;E ;2,<4: B\>D/>g<>ާ߽!oG>۽gM>*ܽ.M>jE>8>h)>e(C^>S >r(!5&=@m% =(L+=A+=H+_== 'dW=8Ƥ>=T-;=I=Iν|pa=ஞ/r=FXr=FмnX^=/";,9="xO0>̏cIC>EZ>vr>>f>yv5>_Z >Obq>ν5e>[>zP>dNE>Ԃ.s7>>b(>uK>&Vۗ>ai>ۗmz=/y^(=ǁ =]慾UZ=S2=刾'<6A$μs5OQgmO\ZP?OBM1`na ' ,ܼ^ ^@!x޽$;LhZӱS.2MӼ(  +JE!Ϙ'k%۽S;!N| 9\]Kfi ֏WgZ` _楧Q0?8(! 愪y̽9~ۼ;{<֜sB=La~=ݕ=p=!ᒾ=1叾\=؋#=<놾o==ہq@=8{s=hxM=M|y-=izsD=/wM=mD_=r]+=kGfR=-E=JO= ð=޽w=Lʽ={ֹȺ=͡B={ٌ\=2"ec=|7=c:=kl=\=(>]:l6> KnT>GX4k>D `$x>b\Fd|>e|C:]x>+n>92b>4\ET>[<=G>K{=:>%5,=.>!==|!>kk>=o>[%4=o>(#=I >m =><֓>U<>3$>yɳ)>F *>YNI4#>.{2>1\?%>;==9%Ƚ)Z=*OȽe̹m?=gП>=z?Q====ص=cgu=I~h=>䝎;(>u<9>r={H>NB=V>Ri=sa>k̉=j>=ir>=Wz>Q[=7#>/=w>=g>p="<>_=E'>=ˋ>n= >s=D>=4}>k e=xk>.=V>0ORD<&>79~>|b=ܻMB=O[=`;=LX==q[>:=>*=j= =U==5<T=<9)^<吽?r,X.89ֽɃE$۽|[ҽ2 Hʽnªh߽r$⇽iQ?7.-4.S ~Pp5 Fu`o5p7ZZ ԱU ϵŽ +9 0 q ģ\ 3-m$M׽x+Ft̋XrU5]qÃoʻtj;Ba;= =P=ߺ==sϼ==۰=w>?=U>Gc=**>=ރ5>w*iӿb& =N>?) =W@>< 0>2TW >S(>?=Vi6=cE=H =NI.=d=҄r=*Zy=~>(O>ثl>c>쁽=g6U=))U=!%=:ȼ=|0Y={(vŠ=&uZ=$< YPmah=B-ӘнDǽWV " 1/>w+8*^"=#*>oMю3 B>9cF>HXH>ڣ H>*G>A7C>zGN<>1>s $>>o#>H$>UK >: >9<Ӑ> ;v< >5k=p*>A=|;>]={N>~*c==_>I=:;k>:=m> <9g>g8<_~X>2D> ).>C$;>#i>y=5p=2*X=<'B7qRQ*J%P+˾ #シͽﵼ1 5]'n詑YսE9'ӽ y0QQG f,|Y@?dNݽfýSaǥ)X_Lf@AULg35I^((Z[o k*ڽœS3̽7L ɽR2yѽ;B-2/ &&{3%fν~' %$!x^ [g< D=y=@3=oy =xy=Ͻq=w}p=eDI z=jb(=s;Ѣ=s<\=u A==j=z >뤮=q#>>=1:>Q=`M>=ɚZ>=8a>p=Fb>B=_>|=Н[>=U>M=PO>=TH>`=HA>=8>F>W/> >%>6> >E>S>%!M>>rN>>]L>0>mJ>O2>WI>Հ>6K>؆>%N>>Q>C>$U>M >\V> > >W>C=EW>e=@mX>V=Z>h=\>05K=Z>Se

>>8`1)>->$j >Sн'=on=f lA=n=V(2=+41o?6Y> =E> hKlʕ>^͑>o~b>HY{y>6|>Jk>B!>q>PQ>;Fs>$<[>==>.z=R>qZ=>O=> d=>#=s>a=ܴ>=U>sj=>b=>S|<>>_ؼ#>>_#/>{H>f>B+>Aw>4uKe>;2P>h;6>j/N|B=_G53[=J=a = x=쇾=Jk1=;=N۠=<*v=l̥B=o =ŤՕ==e=D_5 >&&> HT@>*|X>Њg,k>3R;{>X=а>[s)ꏉ>o>] ~;>R>S >ӧћ>З>D >@j1>h*}> %c>-G>E7+>R@>AD> @"=5rm=z#= ߺ=۽s=9H=).=ӕ#=0c==i=wO==}w=+=2.<(=|U=7IP]=ۜs0=޽X; =Q@<*0#<:O< jR<u}5<<<4D<4+E")z W[8=8D=jt=5=.=*=%<=V(h= ^Tє|=L=WJ =G(=>^7=* 1=.G =Ҽ$J=K=܃=ԝ4֡=ۘټ|=d1-=r21%+!@{Xᨽ@&G? }'YH#@u1R;"<$f3=* G=xp=0Y#І=5X=ZiO<ũ=&><#^=F= >"~=є>A===y=K==T >؜i=sY>k< (&>,u3)4>>F=>_=>_۽1>V>F<>ȥ罜j=XȽ<=`=t=n-xrs=]߼P'=v}7<^c70S>KTH>E>&K} >r4_E=sz=MA 7i=HB,k.ýaձt?Iݬ*ڌ͟mVʽ:սLuݽ,:潆(4zc"*FRkʽ#i%("WDu & {`ڽ νhͭo佪%kսCĽhs)Aqh`ig=]=wa=$== =X-K=UÅ=z58}*!>)iZq.>;t5> TM bb; "> >_&‹>b=X/=Jǽz=@=T=q] =A_=&R1=n"wi=E">e=Q L&===E˽`j=i<<ҸW󀽈Kj`̽C7V4/"O"'_8 2DPKHx IEx o=3Վf)I >Ľ"Ͻwս MԽ'ܘƽ$ 誽`Ƃ#?"D۽&@o½&xg>>^<ظ>"U=6I>Q=>=R'>=l.>>/3>4,> l5>f>o3>ƪ%>T />U+>'>Bs0>g><4>{>I4>,>0.>+>$>0 >y>װ>v>a>AD >> >Q)>0>)0>>k2>EM>w0>?>,>->C)>,!>)>#>4.>(>k6>G]->@>!0>K>/>V>,>ڕ_>,'>g>M>em>.7>Qm>"l >7e>=X>j=i>H>8=8>o?=(>s=6p>i4=J >=f=`:=>=$>W=D&>l=#>a= >:Ǝ=J% >M&== <~=Ҽ׎=` z?= ƽ\<eAM"&wI>X=N?V5NeZ>/[HZ^z[l]٘'La0Cd6f9xi:*'ocl@b>;%>̽4>/A>ڭM>28X>ZºJ`>#˽f>MXܽ l>X:r>K[z> >Ҭbs>~b>o%>8)>48>:@l>B:ڐ>2zB>& I>Á>r m>,X>I!w>ӽ>tf>#5W>QȠElI>D#;>,E.>rQ >r>C>9;|=6<=i==b9O==~=%h==\==L==m=7t==y=f[ 4 >9->:n*>3 EC> {%_>Z90z>]>+|>dz:>J>Z>2e>aü9>: />GZɍ>sq>Hֽ>\a>%> A>0Wס>lvi?3x>UFuZnl>[zRa>k3w9X>5k6UR>lX[R>JA^tW>O(`&^>a>:ǫ^>⽓mU>vӽ9G>zνb|6>rҽ!>۽O>T 潐F=(=rYm >I>3h!>_+>83>(!+8>u";>, >;>2v@8>ʻ5>_< 2>. =Y.>T=<,>t=K+>y֝=*>ї=(>=S%>=">= >= >RA= ">w=@&>=@y->>5>g>v_<> >=>>"8>>5.>F>&N#>>>}> >&#>O=Z)>=d+>-V=w&>=>t =>:7=,q=ř=Ľ=;2?]=1_<<=@#=-ء<-<߀&R쀾* Yvkfl.0UV]`bUt>w(>(i3>M<^<>ߌ9=gB>6=ΚD>[g=L B>咰=<>o=7>l=I3>H=80>=->&=S+>-=)>X#=|'>< n$>:2 >_|>Ӈ>>9Ӽ>eT >~x >O > %'1=A i=+Z=evcp=`f=nGn!zVaV*'nݍ"J٦R؀SFoԆ$Y6wn>'D <#ͲlL:|kO1=pY=:=C=( != =L=:t =1ٍ8= >N= >}W= >9N= >{8= >|=La>w<">n<5>%;VJ>vm^>yr>!W>Ǎ3>CJʎ>||>25>γks>ݶŽ>{Ƚhm>|G\S>w7>܅Nں>ݼ@>7f=F<9=mK w>UO>oV>&Xj>lS(>bIR&>>i1>-;~:>D=>>^#=>Q9>:6>C6>O8>'ʽ+ :>gнS8>ӽ44>KӽJ->mҽt%>ϟϽi>{ɽn>½HS>&E>l>繽!>u;'>-v.>r8>~{C>`#}N>TX>>13<^>FP^>p Y>uO>-B>YZ3>7">fA>ĽU=Au۽=ev=CYҀ=20Y@=۽ =fL<}5>L>9i=ټo=Ҭ=͛Kfk=q!yVDK.ܞQM9vY35aI8iDsr}f惾;TS/ƈVk q98J\ن:Vlݶ<,3= l=Jl=+I=L=}=JO]=󠡾&1=<Kq2<y::A=J>WX= >Xg=/>@i=sIE>!b=!]>!W=p6u>|AL=7>B=> 1=Ռ>e?=iČ><܊>j=ϼ;M>k9m>] &z>LPz>Lq>?Qalg>bX[>hN>@>|1>">]>;>ԙ< x=g<=s(=^=J=j*=M1_=ȍ=B&i=B=!l=Ρ=qo== -v=BS=|=ذ =)}=}v~u>==ypZ>ſv=v>J=>_=F>l=x>e.=jˠ>҆=>`z;=F> <@^>>;hǥ>edR> !ʼOy>t[>޼>X,ޑ>Se8Ñ>A܏>X`7>/˅>ɣ4~>>>Nfq>f>]>:N2V>~*O>Tᐽ\ G><>Ǘg0>pX,">3>+8r== [K=kH=>=ۥ;:AclX/Gc:;QNKӽSju{L$4AKQ)`)Utiri3މF|ƐmEν4ܽ(佻ڒYdLډt t$^Qi<ͽΰQ ua!kox}WpymotqmZm$RlciY.f]O~a8D<\d:ÛV#?.R N+)MNnLͽjM=)F2Xq=!m@=:5=5+=m0;g=)=!#=#>_>T*T>va==н=ȭ=Az=.=ҙ>5=:| $>8}<>h=H>tG=O=3>i=,I>=_>]="r>c"=^>_= >=>=x>0=i>h=V>=}@>_=='>Y= >M=`=]=M=k|=5==N=]>_= ">= l$>>>K>O>>^>K,=%=nf=W=v=$=h@===;<=0;;c=v=9{ң===*蠩="չ=nd>=坛X=e2ɽU=N==< %0h<~6o?(=~oq V}o;Xf <*#iZ=ټe=aeE=Vֻ=!; >Z<><<3>nV<\R&>0<,>=<>6=F>M=R>7S=_>$F= k>:(=eeu>j =Q|>*G}[<>-;>w꺗u>`f %`>v%y>5Ƽ>$ >;5>`~>y>ӉAt>I l>Д%b>q_T>~)B>^10>m>(>{::[><#=2M<:=} =:=k&=!=z(=='GB=="0a=x=w=#=Py==8.h=r5=AH={< `"= 3OdZ>1XPP >JE >F: >ز+] >E>S.->è@> |>>z>>>>b2ýo)>q. ,>CCj$>A}@> 0:>.I$>x />K7> ;>(:>-42>-U$><$>&>h&Z=^%ރ=$=FP%Iʮ=A%7!=U8',=o)_u=H.O=4&=;!n<xA=Aɽ>b=Lɪd=G= W7.=L=r={b>w.<* ><(>A2=9$>~=)H>R=.>=f >=>X=Z|> F=E>'_=e>=> H=e>H>}=e>-=G > =<> 5=f!>`==A-=b~== =z<>"3< +>ݒ)<$=>Wn1=b>a"=Nm>!Q)=*%w>"= ?><#>o q>` .Hz>.Wp>ڽ&^c>R>1$A?>#N(*>`f>Ke( >Z\>ՔDx>&S>dk >Ͻ >D >-"cE > J>Z߼=`=戼=Qמ='|=P QO=N*= 2F=_51 =M*B6aB# ^`=jн$$y. +G0 5S;4 AlC[L[WHb毐?nE_zɉͼ4 +<ޜ-="r=琾=A|=A(== =~=b ɲ=Ə =|uj=_als=4K,E\=4G= .= ru =<Y9^<>-[7=*>"=8>-=E>b5=gQ>E="[>uwj=bc>2=g>(=2i>= i>=Ah>qs=.ug>a=e>=c>8=Q^>6=~ Y>ZX="O>=WmB>~=j0>@6=><)*>]e>{>sS'>PuS2>&#KJ=>-[H> KR>5X>Xʼ~7Z>ddU>0zJ>;o;> 6?V<><>[j=eHJ=lǼA==:=6`B=e=j=6=d"Q=ș7;=<:r=?g?=y(f==|h:Hq=l ټ"@ >== >>Y>=K~=k=8Y[=o߾>=»_=sٴ.=iէ{']=(f=I9=%>rS=v?>=tS>+=V_>>Ic> >{^>Չ >Q>>v?>P='>1=h>T==Z-b=J==Pt=!=Z=t ==Q6==i=#=m=X= =r>=]@#>5=۫4>=?B>h=L>g9=KR>Q=S> =aR>+= }O>t@=)L>_K=(I>yrH= WF>di==gD>2=C>Q2,=׷C> =&= B>=P<> =W1>*<{W">e^u<=<^=0S<,==r=R,=E =>=m<F=ջC=wA]9=Ll"+=}:=D\jP=K|<:R6><>@N<5e=j=.=H'ƽ3=b)Ͻ )=x˽ =!bI1";AT?<5<ͽ= W1=N={w. e=Cm=iU`=2bN<=jkJ= q&j3Y}jwPD F-6;?F-=@ݼ!)*̮ҽ,>;U{ս >}b>Y>p>y c>{ ^;>< e > ><=, =]`= pò>̶۽ >7>S>[KA >\>ἁ=ռb=r%=<=ꄽub;\OؽC'OŽiOֽ PN#߽*>^ǽK%VOѽY1*8Uuv,MꌽᏽG2ɏ6a<='Іҳ5=B~W=zoW{o='fq=,`d =;f=k =2j#=r^N=N=CKy=FCAc >I7O>YF.>io/??>RnNL>%HV>0]>Q`>xМ`>F^>U ]Z>ՕQ>OFB>=;r<> = >B:L=ґ= u==1E==v=h==E 2==W<6=\U<.== ^k=ySZFF=,=Tj{4JȤFo^ZVӴr.j>sjI~ス=oڽ<ď*_ꑼk'2 vÇX .aƼ1? t† l4 @6bj!Ls@rHpG [)*:͑ ߓ58Ejz:h \F<+<4=v[=AoB=+ǽ'=N=ƏjX=? 5=0>+<4><->==}0>*=#NA>dN7=xO>>=Y>B=\>1>=SX>(4=lM>ݦ*=%=>#=SW+>v=> =k> =<>Q=P}.>Z|>D>nD> V>Xb>`>Xw>2c>g>]]>+>PDO>K>؍9>e>>>fx=qr>=>jm=>&<ȃ>C<">:B>9v >ѻ; >)kc< ~>Xݱ<r><=j>,== =c>n ={d>F- =03g>¯=h><şi>fx;3p>%]P:p>PHk>߮a>X鼷R>; _?>~' +>L(>4>LN=%ս(=w:=$Tj=CD=eI< <y;C;Ns):;^{C[#>IF,fYR;d:./r2{RL#a%i~3˧|P*lxbp꽫tԮ'r"}svuk w |ow,r4v-v0=z|LJx>_߽JֽQS˽𽽱&|3g]tC,o3O;m.luv[Xn<,qgWvZ{\;t~̔<}ǭ=w`=kpb=Y7=C{>I+RY>->4G7B>+ʽ1V>klxk>X@>>r4:>͝<>6S>5 >㒬Yt>⼦ε>d ޴>г>L#ݩ>Z ̽j>A~4>#>&ƍ>w#w>\k>=~d>rb>qd>G߼Gi>֩;Sn>=Kq>[o=#po>=Pe>J=R>=5>=v>D==]=u0f=F=_6>,>2fD>0W>u/cd>&-Cm>*xBt>'Dzz>!2~>)0~>w ߐx>T {m>jug`>qMS>$BI>L@>l:>D46>+ {5>L8>o$+#>>u.ݦD>4VI>- 7J>_6|E>X3ŭ<>Q).1>&7&>(0>Ց z>>ý7=ۓ0=y7:\E=z}=4;`=V< $=W=a<= >c2=F=T=ݬ='н=P%r=|C=nuh=z!=p =!%= t W=g춐=ܽ=|b=_vϗ="h=m=Wת;="#쇰=v^LB=hW>KfQ;&>\>ld>k9l>B[OE >w3=.==s3BE=2#H;ͼ>\ҝH>' >?:O>3-<#>q=5>+7D=D>{=ݷL>"=L>y=B>L=!3>=J >u=u >.==̺==d==ş\==sN=Ǜ='c=-=a==ߨ==~=q==>T=b>D =g*>'=i3>L=J6>#=~2>=s)>=I>p=t>=N=&=ѕ=$=,==s9<aN=b9X\d޽K佢ܽԽڽ47ֽ/EKн\KcȽ{a|J:MbhE)RSnl8ӆ wK#Լ+fԧSu+iK| o܂f:<|l;}Oüj;.ۼ<:v^7=V /==ǢX= H=aE==]?=ת) =]<==7==,=ڄ==<4=#;=<>ǒ;>A (>Y:5>YA?>2F>tK>=? M>ZjL>GPj[J>qqkG>t@xB>]r9>k ,>i>p>}={O"=M=zUc=]Q=: t=h>0~=F,>F>6>>9>S>f4>!>%>of">>>|=>0=U> Ri=>t =Z>v<->҃:r> wR>V=?ST=ߧơ=K/=_)=(}=ۯ=WF>{r >U\>>c: > <$>u-=F#>mi= >=!> =N>N=>zt=;Q=h=pl==i=m=Ċ{==za=5=y{Z= [=]=$=c=OS]=/=P<{|;xgT u%lg޽ ۧB':zFW?0dNѡ޽4Vh߽gV彔aT}/Pj \Lj HMEW& F32(K~=TdHa4R?l+[vrbcqj,]jvq@9_ Hw!"T|nL~I~L}{M.T tN\)hjaMZ:aJ\85S$bK$Bf3;컽;|4:-t'NuU& | ŤA D;S;4>HLX`>4^ Q8>ĸʼ>d>4޼ـ>>-]>n>4v>R½d>dս>#ԫ>m>F:>u>$ا>&|>2#{>>P>Z`Ů>V޽ >>j;>WX_>; >Xq>) xN<'v>;?={>v= U>D=Լ1>sĜ= >C\=K===j=֮='t=,=ϝO=<9=M;D8=nI=EAj=r2=, =Ep=#U>UXnb">WN!A>I:=^> iu>>Z'>VSм5>?̼p>s;ܼp>$ɋ>D>< /X`>ƾK7>Tp>.i>10w>o̽E> ('U> >$>^;>Rm>g?>ÚyV>كKv> [>uB0>x>tČD9>v>7> 9\>&|~>q0ۄ>dHp>&VW>EdC>{3;R5>!->&l*> ;M'>>#>u>$=eӽ[`=ϋý%=g=U@=x)v"=|ᮽ=LSA<,0KJ^0['9j(|C`:Pn/c$ t?>B3(>%%y3>r}29>4D:>2hĽC6>Qߙ->T*CR!>ۼ>>;=-< G=Lgg= >=>}=>.v=>O=>==T=fB=̆==p=4=MA=R===Q'=7<4=`U$<`{=&;h==Zj`6<;M:VO;9;)j;_뻽'@R|x6h-쓼Wu%sX{!8^:}߻c 6y{jNIlR$żWl*;8<$h=)᜻)J=`3d=?ûc=t$K=L:=9<<,*,<8ͱ;,<ߍ &=7EӼ=&ȴ= *=i"'>H!<7h>a =&,>n=^E<>$ =J>=@W>3=C(`>O >5d>gx>4c>ʈ>\>##>`Q>I%> kB>cF$>p|2>">#>(!>a.>">H>#%>T >c+>4>c4>>?>դ>M>T>-\>Y >mi>_>t>$>Mz>S'>z>.>Lu>tm2>f>T45>vP>8>^3>|=>>>S@A>=xB>=U?>-&>4Wg> =2_i=:lJ="(AĽﱾ|ýo. Eq~?PWOn޴(P 8(>r?ENYc҃?22"Q2@ƽ1q8н_ ׽rQ_@޽^NGHyf?n8,E31;)!ۅͽ!v5b]XfT|J3;vOO %yJ3޽Zxp $^׀[;(< $ǽ9ҽ|ݽuRx6>$N?/>z]a>6jF7)>>q7>q0F>(|j*R>*`9Y>T[>"KٖW>9DN>?nA>g<3>7&>82@>C,>n%a>o>;h>Rd >7>~ۊ>>(>9p=4G=w=4h=O;Fרֽ;,Uɽ"mhx_hߔ8IoJ#<=8;<Ԡ!bo=^<]j=T=f=#5=e =X==%k=o=sh=j;>\1L=A>h_= +>6:&&>!=nQ*>vԼX80>8>LEtC>O>XZ>^v(<@c>A=r>F=x>T=>=#>,?=><=r>:=4>횽=PQ>q=->է=x>o=͖>=%=>n}=6ӝ>گ]=7>Ѝ6=z>= >w<[>ǒ;>ŻF>Vw[r>.t(a>#DQ>$:S9F>+C@> @G\A> ,M2G>rWSnO>`eW>t[[>A[> `X>7Q>G;=gJ>_ʃO=Į<> =l}4>=)>=(><=j>e=R=l>=&>5 O=*j>O)=rS>0> 5>hI>ؽ{Y>՛rnd>8`k>3p>OIps>ABV_v>el<>v>h<)Cp>=8a>=vJ>=R->8< >:ۉ==OZ^=O1=xb&<-WK >GQ>rY/>㢎Tb@>ỤtnO>P\> ҽKf>彀m> t>ho{>r>Ӆ͆>ȴsZ>ϽA>@J>ԥԛ>搽%8>zb>Yj>@U>U1y>:&J\>u>pe>μrY>BaFP>Jw:H>>Y=)>='>Á\g >/ i >(N,>‹> jv=L=y=ճE=^Cy=K=ڎ= =ڋ֖a=9~='j#CXڽ› /=Kp,!A&e$ð0)@0IG9C2y#2SOAP0Z:Vs{=6=eKE=*o=ҀY>2>7X">g?.> wi6>;t:>5^&;>[_E:>>*A:>:>eQ:>:.:>L8>͜5> 0>x׽7*>|L!>r>g >$>ټ=h?=` = D<+==:h>-=T$>LE=6>=4I>=D:[>=i>Ku='u> 1="|>u|=~>u=R=@|>?=Ov>wKK=(m>pp=`>>=N>R=Z:>n=6#>> >j>T=p>&=>ϏX=9Y>+<}>];*_>?!>,>W7>>>=>5)ܽ3>y#>p>z"=/q}=)9_=1?=`?}?=9=vQ= 0$a=#<-< n<O:<P=><<[<8<"l<9><<<߶.=WtjG>=ϼ΄=Y R=&&=pJEJ=փo0>"*> @>fŽT>rнNFh>x|νK&y>r>{?>z͌>}:_>M*>Wȼ#>:Ǽ>Wk{>'m>-YeZ>p/B>ޟ'>Ā+ >7н"=N=fVb=):= 8n< v _z L] y-1=ݤbcVŽŽ.߽mh'u;|f+PHwy޽+"ֽuAҽ|ElӽsֽmR۽,HO^s֟T0YA>b"K~S8a OFqoc?q99t \66< ^$V~gcXvEm4;5df<Z_+>$>Mѽ*>޽0>~kY6>!<> 뽠?>潦 B>j ݽ0kD>QϽa\H>,O>4ܣZ>bMg>rgYr>k1Kz>{>?Zw>C6m>0^a>oS>.A>FŽ*> 彿>2=d =v2r=ݾ/=q=j=f7-=VN=QXս9Qn=O8=Kу=9 |=q&e=U_:F=<&=<z>J< {>=>VL=F> => =c>=d>=ݞ>R=>O% >U+>>8>>F>>xS>t>_>>Dl>`>sy>>>~> >6C>h>Z8>\=I>wP=X>=>w=l>#7=Q>$<;>፼;͙>R<@9>e3G>ݽ>b> +>Dc>Xlo>!gY>qr>v>w.>VctE>JoN>gn9>\TUr>GNc>4=W>+>M>=wE> *>>s:>2뽧6>9S3>\۽+{->%޽*%>[B>8N>?*հ>Jy=yd=e=F| =[QٽO= Ƚr=K]H=2Z#n 3;:,R@&h齸H}*=н9En!ᖾ@],+_`Dcľhh;H̾dHcҾuhA־΄׾7}]>EraQt/:עI;S2SxԼխ Zo`OC-S7>=Wg>SӒ >f<<&>ǝ=n2>=/9>n<ݸ@><$I>Ӿ;uQ>cλޕ[>chҠe>r o>ͤOy>ӓr> N;>]Ι<>-=>j?=Fv>l=N"> 4=*ћ>=c>~>F!> S>.>#>[>_/>X>7>>z<>>Zw>jB>5d>SxB>IP>\m<>@:>/>!>>b>>=qp==JJ=$=ѹ=L.;⣺=˼=}CL=T=>Z߽E>`> >4 > >u1| >  >A >>-C>Tj$>􈜽q0/>u_Q7>M><>@>UjD>XɼH>YѼK>YW L>94UJ>2kzF>T2D>1PB>}죽A>4@>qa>>v[;>pb<8>^D7>g9>"uH>> HB>DF>`]=J>M>̇O>X:u-P>lM>SaA>08>]"Ri$=d> D=%7>~Q==Q==*L==ϝE=(W=b<=dڽ_ Rн ǽЏ"!ƽ,1ѽA>(LnHQmN= jQ @8CR9.R?%CTbYUPoVp}U^QwI2S>Bs731?p'a(L݈3냾AyM⽷Vh.Rp;nJ#輴:e t%3<Ὅ<+=нu&=Ƚ,U=6vǽv=O@ʽ = E̽re=0ǽ == =ğ2=wˎ=!j=t=!;\=ؗ=9^=@I=l3=K=;=pAH=Ռ=?=Q|=J6=N>+=, /> =H>;=y\> Lz< j>[u"<K>i<#B>I<9;>C=2:4>nM.=¦->G='>]=B!>Qi=->m0l= >1n=F=u=]= ==V=E=I3=u=Ylb=DƼ7=lvn=(RB= <=s7R,>Ɯݍ">]">La½>~>=-O=H2/g=GO=nZZ<%h"#o=;[>itqL>ma?4>ۍU.H>WZ>.펽wk>Wy}> :`>ἥ׍>G;>>uTa>i$>į5G>ȼzX>3-bb>JK>Pȍ>2нg>~sz>[y.f>o Q> j=> Q)>#) >^+=\ =xbׁ=*C=77;r߽J׽.u?ɽi,:AU{PX; {XշHjK;qdڽ,>ͽ B> ̬U>nd>?%en>r8,r>kռn>֕d>0< E>=4>r2= m#>==>P4=={==%<=s<=su~k ?<0½e^iνڄoν ƽ, ̽ޢZҽ+ѽ-˽ٜtĽR򧼽2ٯX)j L yhBF:bQJ^hg?ހ|r;͍Nb̍n$_|5DY{J*6 cW:Cݼ _X᛻&g<`ċ8Xv=ϵ >1y=>_d=>>naC=> =>=V> ?<"f>8a<>Bj` >n\>z:wx]>cGP%>L.>I26>ta9>o<\:>YF=8>#+={7>D=8>5N=<>!N=uA>4:I=B2E>A=G>vB>=fPI>C=K>9M=L>(V=gK>xZ=/pI>U=E>yD=Up>>!=5>< t,>;t!>3} >i+B>B4=ͽF~= = cb=Zd9Lr=(MUQ=[H$=bC5KcJ (֐B%RnǦtvV3 ]&))2½6bf]nwvk¤;:wlOQj ҄ļ U'#.6pW,Lzlk:nzc]?&<ۑAd钾ļܓO(e/;ʐj*<$n-=i[==dg\=?K=%0_=+S=K>#нg >٩ >I~">~C3>8.o>Eot>ʩ"Z!><(>L<*1>0p<>5;M> a[>[Mh>ds>% -~> f >ƖS>Ьq>^,H;hۚ>pJ=qӫ>wė=> _=>=˯>v=^>>W>>"e> >`>=@>?=>=->mV=@Ͳ>u=3N>>J>إ>>F>(>p>4e>! >i;>N$>x >+>L=B3>(==>Xg}|E>e&q}&K>pƽO>SvS>E/U>m"V>J)DX>,&[> . )`>1g>4> o>̹9v>SQ@%|>lGo~>Pb}>dZx>U.da>r>$Gn k>wc>7 ~i(^>zY>O>E>7V\7><ۙ*>۞">) >ݦ]#>ޓ(>;5 ->PڲR3/>/> 0>dT2>~6>dѢ9>[C;>|2:>h6>4H0>Y,2%>-G7>c=བྷ{=>eν>[=ǽsYK.ܽ;ZOν뽄]8J\ڽ #Ta̽ x=FL ^G<4A >"xIO>[3W>KΝ:%><\*>8=%>c'E=>*=M >5==!=/=]==>>=z%>l<8>4< >99M>lN>yudBjN>A&;\M>\M<_L><L>, =I>EW=`QB>߃=S5>#Ԛ= $>=@8>A=>r=r= >8)=A>w=e&>=/>e=g6>.|=<>=D>U+=N>J=X>N=_>}?= G_>h_=mX>.=wK>=:9>+ȹ=d">F<= >⓲==I== D=Ǝ==i=Bh=K=k=PG=،\=X=ȵQ=Yz=(B==)'==<=Q<=j1.=z˼_=N=렽=,ݽH=0 D3=X!T<ȉ/;Z4<1@AhDG(NX `ļ+4ν$ +;ĉy62aX]lLU9u SV C{945|u%:A|ټ5ӽ b9}콶OEsfɽӭ EٽjڽKU?нd~f۽.ĽUYb \KbDYH;Q/"۽[#>c佢L,>m +>4 >M >T=<V=N R=_ 4= r<V<`>=s2;@=z?:D=u~==Zv=p<3͒=CZʼ=>-&$>/ ->1z;s3>G<8>Hm =6>/=W.>=u-!>ph<)>C<0G=U;Z=s =sDļt=aO!PO3=ZV9=}>`A#=> %= >Z$=*>&=6H>(0=>D=(>-f==^====^i=1=J=)"=2=Jg=">-=>1}= >w"= 5>dž=>=$>t=>g=S8=~=ݩ= ==㴋=>c=>=>=rr>B=\ >3=(> -=->m=Sr3>=:>)>@>ƌ>[E>>[F>>D>>v\=>u>3>=)'>=>=R >M=>r<]P=h>F 퍾o P㮒 `02*ozQEџĕqw-'դ>񆾗)ᅾe4?S-o|okRD0Xw- >#?` 8Z8l8ڼxý':YZi~@"'xc ܂_{<9= =z[==]F½=oཟ=h0>)'>R7>C>2M>սW>%ǽPb>6)o>=>R ; >Zb>kh>#nMA>p86>2z>;{>qM>''_M>l>Bl>Vn>1r>dsA>:sr>stc>4|B>f9$&>@ >D=Ň%==,PkZ=2M6 =8T&.#v<7BHӺlS슼p\;mØ<̝4=_-=]}CdU=)=lꇽ=R=l !=7OPp=0=*>f Y >Fz >67{>8/mh>x:=Ͻ>=1M%=B$۩=CӚ=^~f=jt,>>O>N}+>K5>)F<> XB>0~VG>y@J>,v|K>xsG>KrF?>qh1>*qE >q% >`qQ=q1Z=oͱ=k_9=pd<9Y1<1KKI; ; 8(¹l9M*:սvs:n:zȷE;g1j;_\&g;Ѻ߹ zͺӻ흼HTg׋4?[Y 仱"kn:q<= Z< vE<^z܅<Ľk/<1齘'=Qh%>&m=;fE>d=g>P>-q>#>9>+>d>j!>>+<$>`»>y$>>2#>.> >>>3>>U>>->>>>M> >> >'l>>@]Q>T=8>~ = >=<^ >=f==wj=@=R=QY=\w==H==<69=q8(=[񼊖=L0=%?=dϫ=7=̽=̽=*w=oj.=> =cz.=lKh<+EyQ*8À1 ɽEMʽؽ5=V#a-1ݽ81ʽN1Ϯ!V,Xm$Z ׆nཥȄ;ٷQ{<ϖ?<\UL<@ ˦<xӘ9<_s2݇Ya:'/<"C !JD*><½-&?>w˽FP>̽Q ]>ƽe>k>#Ωn>;o>ʉ_l>xZSh>hrb>-KinF[>NVxQ>剽dD>N_4>V P >ཨ >Gv =X=H-) =2=5H=i 29E=;)=t=9 =-`=q~=A*ɽ=ڕ=aF=1ڙv=y;=sP=8oqJ<5o;A5jk|]-GGH)V49H% z˼Xa|zན$<C:G# >$ͽN. >M >;>K x=V=%mr==VC(=g?* >)H+>𽃉>wb>4*B >>< ==(A=K:`=F T>Pj/ >lnֽq>ʥw>\+U">>ʜ> s<=O>b<=>v=>=(>=ۼ=Z =A==K=s@=&=?===T=t=e={= =/B=F=/V=3.=mm6=^=+=R=5=j=L=n>߂g=>= >0= ><=0>\=d=t~==Af=z=BC=0~Xüs|GjpxD.X? N)lP l&߼i =a[ @%&@&E f`'3 qN^=t/*>ThM>n>Lj>?(> ؃ >j{ߟ>nt8>x>}>[Đ>{k½>o2>Tw>k>о=Lr> 7;z>s>lj>(`>boT>.)hE>;!3>:,=>0>ɆP =uԼr=پ^=$j=PiF7!>fl8;>NO>Y& \>,}e> 6j>ϯؽNo>ý>q>M.o>j>_ݪa>'V>梽1J>>>gnh&4>7d3*> 4U">*>ῼg->JH>E|>_T">r'K>Oӻ->ap='>|_;_6>5r<.F>M~<i>-<{>.<>ۗ<>I;.q>"лv>a>9I>,. 1>ܬO+>XmW>Gņz=ǚ=_Ð=/Aj=ֽC=IC(=&=C '=<#< ,teJ꽌dw@xA;m j<<==lr= j=E':1=|y/>(7?>=*>(A>U@s>< >!%6O>_.y>`%%->>҂!>!Hn!>R.>^>'p >ӈ="ӽZ=~2=᜽l:=oV = 2L=Ҕ=Ѻ=wD<̓=<=|j<=Vޫ<=S><|0>B-<5n>g }>IlYz>ۼ[q>חt+b>X@\xO>dW;>A[:&>Iq>FJ"X>$׼%=,T=x;=M<g+G;v2,:#Ӷ@`tEG˽VEo CA=@*9@M"k5dSg1CP.. $[*7&Nֽ athr' y O#)@Xܽ =a'>=+D>Ũ>4!d>>>:%>>P0> >]7>DJ>ģ<>>>|@>D>eB>\>C>؟>C>:"> B>F>guB>tI>(D> _>ЙH>I>H+K>Ȟ>=I>>!@>>/>q%>>'>>>õ=o>=BX>d==@>aы=&>~=! >=_=}=2E=Ĉ=p=6=.*H=(=g = 1=);<=#`< >nU<>,<>;' >{T#N=3ME=eݼ⫩=jP>вi==ݏk=_ǽO(<1rݻ"*1qѼDkAV*弰keͼsȥ/n*%p(κ`RqYq?,-nȼ|Ż+%'~5Jv~ޡxq)` ҽhVѣ.I1qP~[ -^c=Q ڳOнGٽES<̽kǼG׻l;s5T=(F =K@L=Oѡ=\Pb=HNx=xIU=TAݴ=\6 =)=G6`==,x=lد=5o`=v:G=F={G'=~=4J=r_=x[kw=<7=x=t߽ػ=ս3=ʽ[<SO'|pdQI=pW *7# i:oxϧ<#=&l$>u=)7>xȻ=hE>(=pyO>=V>=[>Z>^>>a>*>a>r3>n%`>Ջ:>?[>k?>uT>jC>|K>G>@>WK>g3>6P>#>S>>,GV>D&=X>Tt=>\>c=a>X= i>ƜjU;3y>R4Ӽ>F ><">L>q/Q>g@}>@RfS>(}Ӌ>)";ڧ>=<ס>Y< >U<:>;x.>D>I^%m>ʼW{\> )P>7zI>OH>jpFL>VԼ*S>MflZ>a>19of>Ҽg>e? BY>+J>,S#7>f:">Fg>p`N= Ns=H%={N;Ar=u$, =h°; ۼFwuԂ 7" O l] *B}d;B@5z;<;a)߼$>gu5>D 5E>F)R>.^,=d>G=fi>=l>3=m>.=l>,=h>M=+ǻf= 7X>==J>=;:><&>EH<>i^ >J-->Ο6)<>g WWH> R>ؘC[>?Pa>(sb>4L]>q轁R>߽$C>)׽ҁ1>Ͻ>cǽS >\3`=)=p= @=TR:= P=E[=.<>>L/>RQ:˫>-:$>9+> ƺhd.>LCD +> 5K!> y>qn;>/<=%<=L<==ڠ=F2=m=L=aM=od=d2=t=rL="y= = l=;m =ER==K-=J)=&N=:=<;=u½c=xL覽&ʽ~Չ d}2npui2rLY3iRUضzн!н@ػήehU4%_/*>&7CgD ߼oN0V/ٻ~\u:3`;bA<<*aNd<^{<=[X9j._w+ =DR24Ǫ3pbd$?;o:W=">B9=v4>=]D>R|6_>䊼(Ti>o꼔wp>-^t>$u>>t>r>Am>duf><3u\>cfQ=RA>fG=512>}=#>=[>"=Y >|=>==w=Hx=f>_=>O=====~=NД===b!=:ʡ=U<—=c39=K=ZDXK= tI= }=Ԉ>~O >VX >\>|>=D;J'=D<8=q[==%=4==`Q=C=M==Ħ=?=%jk?=]NBT=|p=ʽcU==c !r=n=1 =VAd,=~RN3=FgUy=kVk>S/ >M >%G>_{B4>%A>@FJ>_P >^7p>n=}N=9D=EEկ=Pz =5jR=[:=/[Y=w=`P=@sE:n=Ȭ'<= Q2_=۽2F=F%4B=pq^O=XLh=VֹE`=_[=~!>=0>4= >>p=7J>=S>=k*[>$R=0^>=$_><Z>j"ߔQ>cC>(%81>g7zŀ>Ok>6@=r̽=ZϽ.=ƽu=OR=59M=j~R=cH T4FEF_5?J#!3H!< n۽-뚼̻twߍ/l"᲼?KFƻUH- ;E9;NiDbgh)TB Q2HY;栛 =>φ=v >V=A5)>7==0>=Y4>=B8> >3=>>B>= >\(J>-> R>R:>eY>"gE>7^>N>A^>oU>SW>_Y>K>d[>:>f2[>1$>DY>c >@V> n=R>0=0M>)j=7H>;=F> 3<Z<ȸ_>'J;<`p>nI<>pit }<0> <9><->?="/>T)=ƪ>j8=!x>*>=?p>U;=i>B6=d>)2=?_>sB4= [>8=9V>x?=5S>C=4Q>yC=5tQ>M>='U>>4=\N\>J%=f>2 =2p><y><>k<;>:;W>O2t>bټ郇>g4'>7n΀>w{o>çԽmV>F6> g[p>(m=9)j=ҸG=QckTWQoZV[gj[[)T\[4i\T 8F]5]I/_&`A/c~Zf~-}jT oB'r5RsHҌq]0lVsidi]qI6YqlYyZ\s>ob붾i֝6qƾAxʾ~{Q̾fЁװʾ(*mƾu9}#,cn>"Z\BrŤS*C_1[Pܽ"Ku䕾"2 Jdx z0m{Ya@E䂽F2xp>!peOI(U& ,yn佴.ܽMp<Խ =bͽ#a=yý~=F=?C>H.>;82>V$sCJ>T0nd>->N!u>T>5Kέ>!x|<90>=h>F==>'n= >_]=>=zy>= V>=:>}Z=5>ɓ*=>B<>4Ü<>Z<<>UFB<_>ļ< >E=>LS={>=Oq>=cg>=]>7=R>F=F>S>9>n>M:*> W>> %>>)><=-*>BV=|(>3=$>;=< > m{_:*>!>_'>dwp>2>z½>@!>:],>1 7>3հB>1L>0*PGV>_6[^>J1A;wf>jK#m>Tiq>o?^q>ܐf_Im>xl8b>fo-R>o>>|lG(>Gg>R_1=UG=LJ9=<=-=oLd=S '@=VK=<۽P=Ž=6)=Ϫ==pݫ=)4=t_ =F9l=H N=Nv5=|; =;ѽ̼ؽEؽ3&|==4! =fU8='+>+>?>K">%^;o=<}=XO<=63===dg==f=:o=e=P==JSo='Μ=]=*=WJ=Ԡ|=0=A= = <</u=L=v=sE=@l<=2(=My=r='礽# _=Pɽ&=͙kO<^y<){ |>>ѽhC.q齺B:d,DG!6X׽!&$m˽Pz뱽5.ꔽ5ڼL-jt/Z>(۝μ<!Y< ;SW5I<>R<q&>:1>S n7>䅼Y8>]4Z6>'Ti1>vc+>F 3&> "><7 >>O<Я >5=Vf#>WA=v'>rb=->2=4>ȑ=$=>=E>=fL>=cOP>~=N>ܳ=G>=h 9>6=,&>:u=> =wU=g==w=_v=G=/=G=ɽB=鲍=o=Pט= C=J<ܧ=D<=A4==@l=m= =`=p=n==0=|==a=5=)c==-=Ǒ=<*q=~A<>Q<>hcG<ݯ>b=% >=P>==|(=Ժ=9==tK=E={]==|Dl=Ǣ=v=$=Ű~===1==~O=)=r= =Գ=~=Ƀ=r=M=`=8>G=|>%=&S!>T< Q0>;v.>mh:">۴ݼƼ>V*Z=q^S@=%ЄA-=PɔV; HfQֽmU vƜM&^/(ӽ]D'Ƚ #b%F̳Q,39**H5ĽĠWٽd8Kp Mz8Qc#EA1Ti>K+lWK97`C˨f/glee͕E_uW~QOZBGߞ&?H8H웾<@38k/:,Փ/*V'&\ %d6!QqMxo_X KU@6)C"lϽ-Ͷԟfo#qh߽5߽^6 nܽ]<_7нq"=ܺmh=1C~=R=l >H,43>{f\>Բ; W> T)=u>iRe=L>=&>0=E>y=5>~t=n >=6~>=lW>N=>d=>J=w>=E>=>ȩ=>-=>=>M:=;>0=N>=J>-=>=>e>=>6>3>}>+>6>k>vA>La>HCL>fU>lV>H3I>n_> G=>݉f>1>Ij>4%>j>>rd> >̇W>g> F>=F3>l=*+">=:>}=" >H=.>\=7 >m1=ۿ>7=5$>ô<9XL>EKһO`>4S4r>K->翄>ôx>fΉ>x p>P>+>$R6w>&:<5+j>@;>[>Z=^K><9>t?>sFw=R=ZaoC=r=Q====C=z)I=``='j=A/=E2d<Ɓ?<*z-rEljy&S\bnH)[>hTz`PwLGbIJF EYz?x0F6ӂ+o猽qٕ1Y頽2Bý*蹧m\Ľ3ӽ}ڄx,\v÷ w'#-.ɄY6ycTʽ;k½$<쾽L=-ה==͢ƽ=wν2>Uڽ>Ύ齨>!>u~>y>*>-A > gi> =X*=ɽ=VN-;=R|=Gu=jQ=.=x:=>Gy=/ >ۀ=}e>^=>S= >=y$>ۺ='>y=(>=V(>i=w(>h(=t(>'< )>3<ĸ*>v<,>k =c/>s=W.>B=+>b=}&>>H>\a3>9>@P>l>dah>_= z>=>2=Ƅ>7F=h>.:Av0<\>';j>>S<3>'< *=<O<5B= o<K=z<B=pJb;?}$<,ׇJ=Q/U===b=$O= ԽP~=&?5S=M $=jo<" ଵ< ;Ň<ʬJ