From 3377b6072a1462d8cf87285143b029bac0afa1b0 Mon Sep 17 00:00:00 2001 From: annali168290-ux Date: Fri, 9 Oct 2026 22:49:53 +0700 Subject: [PATCH] Import JC Web IM --- .gitignore | 10 + AGENTS.md | 3 + README.md | 58 + WEB_DEPLOYMENT.md | 284 + babel.config.js | 3 + deploy/im-web-8023.nginx.conf | 33 + dist/api/add_contact.php | 95 + dist/api/contacts.php | 71 + dist/api/conversation_actions.php | 990 + dist/api/im_web_bootstrap.php | 348 + dist/api/media_download.php | 58 + dist/api/message_action.php | 288 + dist/api/message_detail.php | 387 + dist/api/messages.php | 900 + dist/api/platform_config.php | 39 + dist/api/profile.php | 321 + dist/api/register_config.php | 18 + dist/api/send_message.php | 411 + dist/api/update_alias.php | 61 + dist/config/runtime-config.js | 12 + dist/css/app.5af3ef7e.css | 3048 +++ dist/favicon.ico | Bin 0 -> 980922 bytes dist/img/logo.png | Bin 0 -> 39451 bytes dist/index.html | 1 + dist/js/app.26bc1008.js | 3213 +++ dist/js/app.26bc1008.js.map | 1 + dist/js/chunk-vendors.cd0faf68.js | 24967 ++++++++++++++++++ dist/js/chunk-vendors.cd0faf68.js.map | 1 + legacy/imClient.legacy.js | 651 + package-lock.json | 11384 ++++++++ package.json | 29 + public/api/add_contact.php | 95 + public/api/contacts.php | 71 + public/api/conversation_actions.php | 990 + public/api/im_web_bootstrap.php | 348 + public/api/media_download.php | 58 + public/api/message_action.php | 288 + public/api/message_detail.php | 387 + public/api/messages.php | 900 + public/api/platform_config.php | 39 + public/api/profile.php | 321 + public/api/register_config.php | 18 + public/api/send_message.php | 411 + public/api/update_alias.php | 61 + public/config/runtime-config.js | 12 + public/favicon.ico | Bin 0 -> 980922 bytes public/img/logo.png | Bin 0 -> 39451 bytes public/index.html | 14 + src/App.vue | 17 + src/components/ChatShell.vue | 34 + src/components/DocumentedShell.vue | 186 + src/components/LoginView.vue | 502 + src/components/chat/ChatPanel.vue | 1067 + src/components/chat/MessageComposer.vue | 223 + src/components/chat/MessageList.vue | 757 + src/components/contacts/ContactPanel.vue | 111 + src/components/favorites/FavoriteList.vue | 79 + src/components/favorites/FavoritePanel.vue | 202 + src/components/sidebar/ContactList.vue | 103 + src/components/sidebar/ConversationList.vue | 525 + src/components/sidebar/NavigationRail.vue | 724 + src/config.js | 36 + src/main.js | 6 + src/services/appServerClient.js | 266 + src/services/documentedHttpImClient.js | 273 + src/services/httpImClient.js | 1069 + src/services/imClient.js | 23 + src/services/longConnectionImClient.js | 236 + src/stores/contacts.js | 233 + src/stores/conversations.js | 1216 + src/stores/navigation.js | 18 + src/stores/session.js | 225 + src/styles/base.css | 3022 +++ vue.config.js | 51 + 74 files changed, 62902 insertions(+) create mode 100644 .gitignore create mode 100644 AGENTS.md create mode 100644 README.md create mode 100644 WEB_DEPLOYMENT.md create mode 100644 babel.config.js create mode 100644 deploy/im-web-8023.nginx.conf create mode 100644 dist/api/add_contact.php create mode 100644 dist/api/contacts.php create mode 100644 dist/api/conversation_actions.php create mode 100644 dist/api/im_web_bootstrap.php create mode 100644 dist/api/media_download.php create mode 100644 dist/api/message_action.php create mode 100644 dist/api/message_detail.php create mode 100644 dist/api/messages.php create mode 100644 dist/api/platform_config.php create mode 100644 dist/api/profile.php create mode 100644 dist/api/register_config.php create mode 100644 dist/api/send_message.php create mode 100644 dist/api/update_alias.php create mode 100644 dist/config/runtime-config.js create mode 100644 dist/css/app.5af3ef7e.css create mode 100644 dist/favicon.ico create mode 100644 dist/img/logo.png create mode 100644 dist/index.html create mode 100644 dist/js/app.26bc1008.js create mode 100644 dist/js/app.26bc1008.js.map create mode 100644 dist/js/chunk-vendors.cd0faf68.js create mode 100644 dist/js/chunk-vendors.cd0faf68.js.map create mode 100644 legacy/imClient.legacy.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/api/add_contact.php create mode 100644 public/api/contacts.php create mode 100644 public/api/conversation_actions.php create mode 100644 public/api/im_web_bootstrap.php create mode 100644 public/api/media_download.php create mode 100644 public/api/message_action.php create mode 100644 public/api/message_detail.php create mode 100644 public/api/messages.php create mode 100644 public/api/platform_config.php create mode 100644 public/api/profile.php create mode 100644 public/api/register_config.php create mode 100644 public/api/send_message.php create mode 100644 public/api/update_alias.php create mode 100644 public/config/runtime-config.js create mode 100644 public/favicon.ico create mode 100644 public/img/logo.png create mode 100644 public/index.html create mode 100644 src/App.vue create mode 100644 src/components/ChatShell.vue create mode 100644 src/components/DocumentedShell.vue create mode 100644 src/components/LoginView.vue create mode 100644 src/components/chat/ChatPanel.vue create mode 100644 src/components/chat/MessageComposer.vue create mode 100644 src/components/chat/MessageList.vue create mode 100644 src/components/contacts/ContactPanel.vue create mode 100644 src/components/favorites/FavoriteList.vue create mode 100644 src/components/favorites/FavoritePanel.vue create mode 100644 src/components/sidebar/ContactList.vue create mode 100644 src/components/sidebar/ConversationList.vue create mode 100644 src/components/sidebar/NavigationRail.vue create mode 100644 src/config.js create mode 100644 src/main.js create mode 100644 src/services/appServerClient.js create mode 100644 src/services/documentedHttpImClient.js create mode 100644 src/services/httpImClient.js create mode 100644 src/services/imClient.js create mode 100644 src/services/longConnectionImClient.js create mode 100644 src/stores/contacts.js create mode 100644 src/stores/conversations.js create mode 100644 src/stores/navigation.js create mode 100644 src/stores/session.js create mode 100644 src/styles/base.css create mode 100644 vue.config.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..240c3a3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +node_modules/ +.deploy/ +.DS_Store +npm-debug.log* +yarn-debug.log* +yarn-error.log* +*.local +.env +.env.* +SESSION_HANDOFF.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..78eadf3 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,3 @@ +# JC Web IM 开发记录 + +- 业务操作的成功、失败、保存结果提示,不要使用几秒后自动消失的 toast / popup。优先放在当前表单、按钮附近或弹窗内部,以常驻文字显示;在用户再次编辑、切换或关闭当前界面时再清除。 diff --git a/README.md b/README.md new file mode 100644 index 0000000..07b6dee --- /dev/null +++ b/README.md @@ -0,0 +1,58 @@ +# 绿地信通 Web IM + +这是从零重写的 Web IM 前端,UI 和状态管理独立于原 `vue-chat`,底层通过授权的 WildFire Web SDK 连接既有 IM 服务。 + +## 当前工作范围 + +- 当前工作是在 `jc-web-im` 目录新写 Web 版 IM 客户端。 +- 不要默认回到仓库根目录老 `src/` 客户端里继续改,除非明确需要兼容或参考旧实现。 +- 中断恢复时优先阅读 `/var/www/im-web/SESSION_HANDOFF.md`。 + +## 服务地址 + +- App Server: `http://52.76.146.193:8888` +- IM route: `http://52.76.146.193:80/route` +- WebSocket: `ws://52.76.146.193:8083/ws` +- HTTPS/WSS 当前未启用为默认连接方式。 + +远端部署路径: + +- App Server: `/opt/app-server` +- IM Server: `/opt/im-server` + +## 运行 + +```bash +cd /var/www/im-web/jc-web-im +npm run serve +``` + +开发访问地址: + +```text +http://localhost:8023 +http://10.0.0.120:8023 +``` + +## 构建 + +```bash +npm run build +``` + +## 部署 + +生产部署请看 [WEB_DEPLOYMENT.md](./WEB_DEPLOYMENT.md)。当前 Web 版需要 Nginx 托管静态文件,并通过 PHP-FPM 运行 `dist/api/*.php` 代理接口。 + +## 连接方式 + +`src/services/imClient.js` 是唯一的 IM 适配层。上层 UI 只调用这里的方法: + +- `loginWithPassword` +- `loginWithCode` +- `connect` +- `getConversationList` +- `getMessages` +- `sendTextMessage` + +后续如果替换 SDK 或自研协议,只改这个适配层,不需要改 UI 组件。 diff --git a/WEB_DEPLOYMENT.md b/WEB_DEPLOYMENT.md new file mode 100644 index 0000000..43b9d39 --- /dev/null +++ b/WEB_DEPLOYMENT.md @@ -0,0 +1,284 @@ +# Web 版部署说明 + +本文档说明 `jc-web-im` 的生产部署方式。当前 Web 版由两部分组成: + +- Vue 构建后的静态文件,部署到 Web 根目录。 +- `dist/api/*.php` PHP 代理接口,负责安全调用本机 `im-server` / `app-server` 相关接口。 + +浏览器不能直接携带 `im-server` admin secret 访问 `18080`,所以联系人列表、备注名修改、消息发送等功能通过 PHP 代理完成。 + +## 目录 + +```text +/var/www/jc-im/jc-web-im +├── public/api/ # PHP 代理源码,构建时复制到 dist/api +├── public/config/ # 运行时配置 +├── src/ # Vue 前端源码 +├── deploy/ # Nginx 示例配置 +└── dist/ # npm run build 后的生产目录 +``` + +生产环境建议让 Nginx 的 `root` 指向: + +```text +/var/www/jc-im/jc-web-im/dist +``` + +## 依赖 + +服务器需要安装: + +- Nginx +- PHP-FPM +- PHP 扩展:`curl`、`mbstring` +- Node.js / npm,仅构建时需要 + +PHP 版本: + +- 最低建议:PHP 7.4 +- 推荐:PHP 8.1 / 8.2 / 8.3 + +当前 PHP 代理代码使用 `curl_*`、`random_int`、`Throwable`、`mb_strlen` 等能力,部署前请确认 `curl` 和 `mbstring` 扩展可用。 + +## 后端服务要求 + +Web 版依赖以下服务正常运行: + +```text +app-server: http://127.0.0.1:18888 +im-server HTTP/API: http://127.0.0.1:18000 +im-server admin: http://127.0.0.1:18080 +``` + +`im-server admin`、IM 数据库和应用数据库配置通过 PHP-FPM 环境变量提供: + +```text +public/api/im_web_bootstrap.php +``` + +需要配置: + +```text +IM_ADMIN_URL=http://127.0.0.1:18080 +IM_ADMIN_SECRET=请填写管理端密钥 +IM_DB_DSN=mysql:host=127.0.0.1;port=3306;dbname=wfchat;charset=utf8mb4 +IM_DB_USER=请填写数据库用户 +IM_DB_PASSWORD=请填写数据库密码 +IM_APP_DB_DSN=mysql:host=127.0.0.1;port=3306;dbname=appdata;charset=utf8mb4 +IM_APP_DB_USER=请填写应用数据库用户 +IM_APP_DB_PASSWORD=请填写应用数据库密码 +IM_DB_TIMEZONE=Asia/Bangkok +``` + +请在 PHP-FPM pool、容器 secret 或部署平台的环境变量中配置,禁止把真实密钥提交到仓库。 + +## 构建 + +在项目目录执行: + +```bash +cd /var/www/jc-im/jc-web-im +npm run build +``` + +构建完成后,生产文件位于: + +```text +/var/www/jc-im/jc-web-im/dist +``` + +## 运行时配置 + +运行时配置文件: + +```text +dist/config/runtime-config.js +``` + +示例: + +```js +window.JC_WEB_IM_CONFIG = { + appServer: 'http://your-domain:18888', + registerConfigApi: 'http://your-domain:8024/api/register-config', + imServerHost: 'your-domain', + imRoutePort: 18000, + useWss: false, + wsPath: '/ws', + sdkMode: 'custom-ws' +}; +``` + +常用字段说明: + +| 字段 | 说明 | +| --- | --- | +| `appServer` | Web 登录、验证码等 App Server 地址 | +| `registerConfigApi` | 注册配置接口地址 | +| `imServerHost` | IM HTTP/API 和 WebSocket 使用的主机名 | +| `imRoutePort` | IM route/API 端口,当前为 `18000` | +| `useWss` | 是否使用 WSS | +| `wsPath` | WebSocket 路径 | +| `sdkMode` | 当前使用 `custom-ws` | + +联系人相关 PHP 代理默认使用同源地址: + +```text +/api/contacts.php +/api/update_alias.php +/api/add_contact.php +/api/send_message.php +/api/messages.php +``` + +通常不需要在 `runtime-config.js` 里单独配置这些地址。 + +## Nginx 示例 + +根据实际 PHP-FPM socket 调整 `fastcgi_pass`,例如 PHP 8.3: + +```nginx +server { + listen 8023; + listen [::]:8023; + server_name your-domain _; + + root /var/www/jc-im/jc-web-im/dist; + index index.html; + client_max_body_size 100m; + + location = / { + try_files /index.html =404; + expires -1; + add_header Cache-Control "no-store"; + } + + location = /index.html { + expires -1; + add_header Cache-Control "no-store"; + } + + location = /config/runtime-config.js { + expires -1; + add_header Cache-Control "no-store"; + } + + location ~ ^/api/.+\.php$ { + include snippets/fastcgi-php.conf; + fastcgi_param PHP_ADMIN_VALUE "open_basedir=/var/www/jc-im/jc-web-im/dist/:/tmp/"; + fastcgi_pass unix:/run/php/php8.3-fpm.sock; + expires -1; + add_header Cache-Control "no-store"; + } + + location / { + etag on; + try_files $uri $uri/ /index.html; + expires 12h; + } +} +``` + +启用配置后检查并重载: + +```bash +sudo nginx -t +sudo systemctl reload nginx +``` + +## 防火墙建议 + +生产环境建议: + +- 对外开放 Web 端口,例如 `80` / `443` / `8023`。 +- `18888` 如需浏览器直接访问 app-server,需要对外开放。 +- `18000` 如 WebSocket/route 需要浏览器直连,需要对外开放。 +- `18080` admin 端口不要对公网开放,只允许本机 PHP 代理访问。 + +## 验证 + +检查 PHP 语法: + +```bash +php -l /var/www/jc-im/jc-web-im/dist/api/contacts.php +php -l /var/www/jc-im/jc-web-im/dist/api/update_alias.php +``` + +检查 Web 页面: + +```bash +curl -I http://127.0.0.1:8023/ +``` + +检查联系人接口: + +```bash +curl -s -H 'Content-Type: application/json' \ + --data '{"userId":"你的用户ID"}' \ + http://127.0.0.1:8023/api/contacts.php +``` + +成功时返回: + +```json +{ + "code": 0, + "message": "success", + "result": { + "contacts": [] + } +} +``` + +检查备注名修改接口: + +```bash +curl -s -H 'Content-Type: application/json' \ + --data '{"userId":"你的用户ID","targetId":"联系人ID","alias":"测试备注"}' \ + http://127.0.0.1:8023/api/update_alias.php +``` + +成功时返回: + +```json +{ + "code": 0, + "message": "success", + "result": { + "contact": { + "uid": "联系人ID", + "alias": "测试备注" + } + } +} +``` + +## 常见问题 + +### 页面能打开,但联系人加载失败 + +优先检查: + +- PHP-FPM 是否运行。 +- Nginx 的 PHP location 是否命中 `/api/*.php`。 +- `curl` 扩展是否启用。 +- `public/api/im_web_bootstrap.php` 中 `IM_ADMIN_URL` 和 `IM_ADMIN_SECRET` 是否匹配当前 `im-server`。 +- `im-server` 的 `18080` admin 接口是否在本机可访问。 + +### 修改备注名无效 + +检查: + +- `dist/api/update_alias.php` 是否存在。 +- Nginx 是否允许执行 `dist/api/*.php`。 +- `im-server` 是否提供 `/admin/friend/set_alias`。 +- 当前登录用户和目标联系人是否确实是好友关系。 + +### 部署后仍是旧前端 + +检查: + +- Nginx `root` 是否指向新的 `dist` 目录。 +- 是否执行过 `npm run build`。 +- 浏览器是否缓存了旧资源。`index.html` 和 `runtime-config.js` 应配置为 `no-store`。 + diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 0000000..ffa9add --- /dev/null +++ b/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: ['@vue/cli-plugin-babel/preset'] +}; diff --git a/deploy/im-web-8023.nginx.conf b/deploy/im-web-8023.nginx.conf new file mode 100644 index 0000000..0f73a5b --- /dev/null +++ b/deploy/im-web-8023.nginx.conf @@ -0,0 +1,33 @@ +server { + listen 8023; + listen [::]:8023; + server_name winchen.ezpay.asia 10.0.0.120 _; + + root /var/www/im-web; + index index.html; + client_max_body_size 100m; + + location = / { + try_files /index.html =404; + expires -1; + add_header Cache-Control "no-store"; + } + + location = /index.html { + expires -1; + add_header Cache-Control "no-store"; + } + + location ~ ^/api/.+\.php$ { + include snippets/fastcgi-php.conf; + fastcgi_param PHP_ADMIN_VALUE "open_basedir=/var/www/im-web/:/tmp/"; + fastcgi_pass unix:/run/php/php8.3-fpm.sock; + expires -1; + } + + location / { + etag on; + try_files $uri $uri/ /index.html; + expires 12h; + } +} diff --git a/dist/api/add_contact.php b/dist/api/add_contact.php new file mode 100644 index 0000000..586f066 --- /dev/null +++ b/dist/api/add_contact.php @@ -0,0 +1,95 @@ + $uid, + 'name' => (string)($user['name'] ?? $uid), + 'displayName' => (string)($user['displayName'] ?? $user['name'] ?? $uid), + 'mobile' => (string)($user['mobile'] ?? ''), + 'portrait' => (string)($user['portrait'] ?? ''), + 'alias' => '', + ]; +} + +try { + $target = tryImUserInfo(['userId' => $keyword]); + if (!$target && preg_match('/^\+?\d{5,32}$/', $keyword)) { + $target = tryImUserInfo(['mobile' => $keyword]); + } + if (!$target) { + $target = tryImUserInfo(['name' => $keyword]); + } + + if (!$target) { + respond(404, '没有找到该用户'); + } + + $contact = normalizeUserInfo($target); + if ($contact['uid'] === '') { + respond(404, '没有找到该用户'); + } + if ($contact['uid'] === $userId) { + respond(400, '不能添加自己为联系人'); + } + + $friendResult = requireImSuccess( + imAdminPost('/admin/friend/list', ['userId' => $userId]), + '好友列表检查失败' + ); + $friendIds = array_values(array_filter($friendResult['list'] ?? [], 'is_string')); + if (in_array($contact['uid'], $friendIds, true)) { + respond(409, '该用户已经是联系人', ['contact' => $contact]); + } + + requireImSuccess( + imAdminPost('/admin/friend/status', [ + 'userId' => $userId, + 'friendUid' => $contact['uid'], + 'status' => 0, + ]), + '添加联系人失败' + ); + requireImSuccess( + imAdminPost('/admin/friend/status', [ + 'userId' => $contact['uid'], + 'friendUid' => $userId, + 'status' => 0, + ]), + '添加联系人失败' + ); + + respond(0, 'success', ['contact' => $contact, 'reason' => $reason]); +} catch (Throwable $error) { + respond(500, $error->getMessage() ?: '添加联系人服务暂不可用'); +} diff --git a/dist/api/contacts.php b/dist/api/contacts.php new file mode 100644 index 0000000..7dee6d9 --- /dev/null +++ b/dist/api/contacts.php @@ -0,0 +1,71 @@ + $userId]), + '联系人加载失败' + ); + $friendIds = array_values(array_unique(array_filter(array_map(static function ($uid): string { + return trim((string)$uid); + }, $friendResult['list'] ?? [])))); + if (!$friendIds) { + respond(0, 'success', ['contacts' => []]); + } + + $usersResult = requireImSuccess( + imAdminPost('/admin/user/batch_get_infos', ['list' => $friendIds]), + '联系人资料加载失败' + ); + try { + ensureWebImAppTables(); + $remarkMap = fetchWebUserRemarkMap(imAppDb(), $userId, $friendIds); + } catch (Throwable) { + $remarkMap = []; + } + + $contactsByUid = []; + foreach (array_values(array_filter($usersResult['userInfos'] ?? [], 'is_array')) as $user) { + $uid = (string)($user['userId'] ?? ''); + if ($uid === '' || isset($contactsByUid[$uid])) { + continue; + } + $alias = ''; + try { + $aliasResult = requireImSuccess( + imAdminPost('/admin/friend/get_alias', ['operator' => $userId, 'targetId' => $uid]), + '联系人备注加载失败' + ); + $alias = trim((string)($aliasResult['alias'] ?? '')); + } catch (Throwable $error) { + $alias = ''; + } + if ($alias === '') { + $alias = $remarkMap[$uid] ?? ''; + } + $contactsByUid[$uid] = [ + 'uid' => $uid, + 'name' => (string)($user['name'] ?? $uid), + 'displayName' => (string)($user['displayName'] ?? $user['name'] ?? $uid), + 'mobile' => (string)($user['mobile'] ?? ''), + 'portrait' => (string)($user['portrait'] ?? ''), + 'address' => (string)($user['address'] ?? ''), + 'alias' => $alias, + ]; + } + + respond(0, 'success', ['contacts' => array_values($contactsByUid)]); +} catch (Throwable $error) { + respond(500, $error->getMessage() ?: '联系人服务暂不可用'); +} diff --git a/dist/api/conversation_actions.php b/dist/api/conversation_actions.php new file mode 100644 index 0000000..299cc7e --- /dev/null +++ b/dist/api/conversation_actions.php @@ -0,0 +1,990 @@ +prepare( + 'select `_uid` from `t_user` where `_uid` = ? or `_mobile` = ? or `_name` = ? limit 1' + ); + $statement->execute([$value, $value, $value]); + $uid = $statement->fetchColumn(); + if (is_string($uid) && $uid !== '') { + $resolved[] = $uid; + } + } + + return array_values(array_unique($resolved)); +} + +function webGroupConversation(array $group, string $role = 'member'): array +{ + $name = (string)($group['name'] ?? $group['_name'] ?? $group['group_id'] ?? $group['_gid'] ?? ''); + $groupId = (string)($group['group_id'] ?? $group['_gid'] ?? ''); + $category = (string)($group['category'] ?? 'group'); + $title = $name !== '' ? $name : $groupId; + $updatedAt = (int)($group['updated_at_ms'] ?? $group['_dt'] ?? webImNowMs()); + + return [ + 'id' => 'group-' . $groupId, + 'type' => $category === 'channel' ? 'channel' : 'group', + 'target' => $groupId, + 'title' => $title, + 'subtitle' => $category === 'channel' ? '公告群' : '群组', + 'unread' => 0, + 'avatarText' => mb_strtoupper(mb_substr($title, 0, 1, 'UTF-8'), 'UTF-8'), + 'updatedAt' => $updatedAt, + 'role' => $role, + 'raw' => [ + 'type' => 'group', + 'target' => $groupId, + 'line' => 0, + 'category' => $category, + 'role' => $role, + ], + ]; +} + +function fetchWebGroup(PDO $db, string $groupKey): ?array +{ + $statement = $db->prepare( + 'select * from `t_web_groups`' + . ' where `deleted` = 0 and (`group_id` = ? or `name` = ?)' + . ' order by (`group_id` = ?) desc limit 1' + ); + $statement->execute([$groupKey, $groupKey, $groupKey]); + $group = $statement->fetch(); + + return is_array($group) ? $group : null; +} + +function fetchWebGroupRole(PDO $db, string $groupId, string $userId): string +{ + $statement = $db->prepare( + 'select `role` from `t_web_group_members`' + . ' where `group_id` = ? and `user_id` = ? and `status` = 0 limit 1' + ); + $statement->execute([$groupId, $userId]); + $role = $statement->fetchColumn(); + + return is_string($role) && $role !== '' ? $role : 'member'; +} + +function fetchWebGroupMember(PDO $db, string $groupId, string $userId): array +{ + $statement = $db->prepare( + 'select * from `t_web_group_members`' + . ' where `group_id` = ? and `user_id` = ? and `status` = 0 limit 1' + ); + $statement->execute([$groupId, $userId]); + $member = $statement->fetch(); + + return is_array($member) ? $member : []; +} + +function requireWebGroupMember(PDO $db, string $groupId, string $userId): array +{ + $member = fetchWebGroupMember($db, $groupId, $userId); + if (!$member) { + respond(403, '你不在该群组中'); + } + + return $member; +} + +function requireWebGroupRole(PDO $db, string $groupId, string $userId, array $roles): array +{ + $member = requireWebGroupMember($db, $groupId, $userId); + if (!in_array((string)$member['role'], $roles, true)) { + respond(403, '没有群组管理权限'); + } + + return $member; +} + +function upsertWebGroupMember(PDO $db, string $groupId, string $userId, string $role): void +{ + $now = webImNowMs(); + $statement = $db->prepare( + 'insert into `t_web_group_members`' + . ' (`group_id`, `user_id`, `role`, `joined_at_ms`, `updated_at_ms`, `status`)' + . ' values (?, ?, ?, ?, ?, 0)' + . ' on duplicate key update' + . ' `role` = if(`role` = "owner", `role`, values(`role`)),' + . ' `updated_at_ms` = values(`updated_at_ms`),' + . ' `status` = 0' + ); + $statement->execute([$groupId, $userId, $role, $now, $now]); +} + +function createNativeGroup(string $operator, string $groupId, string $name, string $category, array $members): array +{ + $nativeMembers = []; + foreach ($members as $memberId) { + $nativeMembers[] = [ + 'member_id' => $memberId, + 'type' => $memberId === $operator ? 2 : 0, + ]; + } + + return requireImSuccess(imAdminPost('/admin/group/create', [ + 'operator' => $operator, + 'group' => [ + 'group_info' => [ + 'target_id' => $groupId, + 'name' => $name, + 'owner' => $operator, + 'type' => 0, + 'mute' => $category === 'channel' ? 1 : 0, + 'join_type' => 0, + 'searchable' => 1, + 'history_message' => 1, + 'extra' => json_encode(['webCategory' => $category], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), + ], + 'members' => $nativeMembers, + ], + 'to_lines' => [0], + ]), '原生群组创建失败'); +} + +function addNativeGroupMember(string $operator, string $groupId, string $userId): void +{ + requireImSuccess(imAdminPost('/admin/group/member/add', [ + 'operator' => $operator, + 'group_id' => $groupId, + 'members' => [ + ['member_id' => $userId, 'type' => 0], + ], + 'to_lines' => [0], + ]), '加入原生群组失败'); +} + +function removeNativeGroupMember(string $operator, string $groupId, array $userIds): void +{ + if (!$userIds) { + return; + } + + requireImSuccess(imAdminPost('/admin/group/member/del', [ + 'operator' => $operator, + 'group_id' => $groupId, + 'members' => array_values($userIds), + 'to_lines' => [0], + ]), '移除原生成员失败'); +} + +function dismissNativeGroup(string $operator, string $groupId): void +{ + requireImSuccess(imAdminPost('/admin/group/del', [ + 'operator' => $operator, + 'group_id' => $groupId, + 'to_lines' => [0], + ]), '解散原生群组失败'); +} + +function transferNativeGroup(string $operator, string $groupId, string $newOwner): void +{ + requireImSuccess(imAdminPost('/admin/group/transfer', [ + 'operator' => $operator, + 'group_id' => $groupId, + 'new_owner' => $newOwner, + 'to_lines' => [0], + ]), '转让原生群组失败'); +} + +function sendWebGroupWelcomeMessage(PDO $appDb, string $groupId, string $senderId, string $welcomeText): void +{ + $text = trim($welcomeText); + if ($text === '') { + return; + } + + $now = webImNowMs(); + $messageUid = webImMessageUid(); + $statement = $appDb->prepare( + 'insert into `t_web_group_messages`' + . ' (`message_uid`, `group_id`, `sender_uid`, `text`, `created_at_ms`, `edited_at_ms`, `recalled`)' + . ' values (?, ?, ?, ?, ?, 0, 0)' + ); + $statement->execute([$messageUid, $groupId, $senderId, $text, $now]); + $update = $appDb->prepare('update `t_web_groups` set `updated_at_ms` = ? where `group_id` = ?'); + $update->execute([$now, $groupId]); + + try { + requireImSuccess(imAdminPost('/admin/message/send', [ + 'sender' => $senderId, + 'conv' => [ + 'type' => 1, + 'target' => $groupId, + 'line' => 0, + ], + 'payload' => [ + 'type' => 1, + 'searchableContent' => $text, + 'pushContent' => $text, + 'content' => $text, + 'persistFlag' => 3, + ], + 'userMessage' => true, + ]), '欢迎词发送失败'); + } catch (Throwable) { + } +} + +function createWebGroupAction(PDO $imDb, PDO $appDb, string $userId, array $payload, string $category): array +{ + $name = trim((string)($payload['name'] ?? '')); + $announcement = trim((string)($payload['announcement'] ?? '')); + $welcomeText = trim((string)($payload['welcomeText'] ?? '')); + if ($name === '') { + respond(400, $category === 'channel' ? '请输入公告群名称' : '请输入群组名称'); + } + + $memberIds = resolveWebUserIds($imDb, webActionList($payload['memberIds'] ?? [])); + $memberIds[] = $userId; + $memberIds = array_values(array_unique(array_filter($memberIds))); + if ($category === 'group' && count($memberIds) < 2) { + respond(400, '请选择至少一位联系人'); + } + + $groupId = 'webg_' . bin2hex(random_bytes(8)); + $now = webImNowMs(); + $nativeStatus = 'pending'; + $nativeGroupId = ''; + $nativeError = ''; + + try { + $nativeResult = createNativeGroup($userId, $groupId, $name, $category, $memberIds); + $nativeGroupId = (string)($nativeResult['group_id'] ?? $nativeResult['groupId'] ?? $groupId); + $nativeStatus = 'ok'; + } catch (Throwable $error) { + $nativeStatus = 'fallback'; + $nativeError = mb_substr($error->getMessage() ?: '原生群组创建失败', 0, 255, 'UTF-8'); + } + + $statement = $appDb->prepare( + 'insert into `t_web_groups`' + . ' (`group_id`, `category`, `name`, `portrait`, `owner_uid`, `join_mode`, `announcement`,' + . ' `welcome_text`, `native_group_id`, `native_status`, `native_error`, `created_by`, `created_at_ms`, `updated_at_ms`, `deleted`)' + . ' values (?, ?, ?, "", ?, "open", ?, ?, ?, ?, ?, ?, ?, ?, 0)' + ); + $statement->execute([ + $groupId, + $category, + $name, + $userId, + $announcement, + $welcomeText, + $nativeGroupId, + $nativeStatus, + $nativeError, + $userId, + $now, + $now, + ]); + + foreach ($memberIds as $memberId) { + upsertWebGroupMember($appDb, $groupId, $memberId, $memberId === $userId ? 'owner' : 'member'); + } + sendWebGroupWelcomeMessage($appDb, $groupId, $userId, $welcomeText); + + $group = fetchWebGroup($appDb, $groupId); + return [ + 'group' => $group, + 'conversation' => webGroupConversation($group ?: [ + 'group_id' => $groupId, + 'category' => $category, + 'name' => $name, + 'updated_at_ms' => $now, + ], 'owner'), + 'nativeStatus' => $nativeStatus, + 'nativeError' => $nativeError, + ]; +} + +function fetchWebUserMap(PDO $imDb, array $userIds, string $ownerId = ''): array +{ + $userIds = webActionList($userIds); + if (!$userIds) { + return []; + } + + $statement = $imDb->prepare( + 'select `_uid`, `_name`, `_display_name`, `_mobile`, `_portrait` from `t_user`' + . ' where `_uid` in (' . appPlaceholders($userIds) . ')' + ); + $statement->execute($userIds); + + $users = []; + foreach ($statement->fetchAll() as $row) { + $uid = (string)$row['_uid']; + $displayName = trim((string)($row['_display_name'] ?? '')) + ?: trim((string)($row['_name'] ?? '')) + ?: trim((string)($row['_mobile'] ?? '')) + ?: $uid; + $users[$uid] = [ + 'uid' => $uid, + 'name' => (string)($row['_name'] ?? ''), + 'displayName' => $displayName, + 'mobile' => (string)($row['_mobile'] ?? ''), + 'portrait' => (string)($row['_portrait'] ?? ''), + 'contactAlias' => '', + 'friendAlias' => '', + 'remarkAlias' => '', + 'isContact' => false, + ]; + } + + if ($ownerId !== '') { + $aliasStatement = $imDb->prepare( + 'select `_friend_uid`, `_alias` from `t_friend` where `_uid` = ?' + . ' and `_friend_uid` in (' . appPlaceholders($userIds) . ')' + ); + $aliasStatement->execute(array_merge([$ownerId], $userIds)); + foreach ($aliasStatement->fetchAll() as $row) { + $friendUid = (string)$row['_friend_uid']; + if (!isset($users[$friendUid])) { + continue; + } + $users[$friendUid]['isContact'] = true; + $users[$friendUid]['friendAlias'] = trim((string)($row['_alias'] ?? '')); + } + + $remarkMap = fetchWebUserRemarkMap(imAppDb(), $ownerId, $userIds); + foreach ($remarkMap as $targetUid => $alias) { + if (!isset($users[$targetUid])) { + continue; + } + $users[$targetUid]['remarkAlias'] = $alias; + } + + foreach ($users as $uid => $user) { + $friendAlias = trim((string)($user['friendAlias'] ?? '')); + $remarkAlias = trim((string)($user['remarkAlias'] ?? '')); + $users[$uid]['contactAlias'] = $friendAlias !== '' ? $friendAlias : $remarkAlias; + } + } + + return $users; +} + +function currentMuteSetting(PDO $appDb, string $groupId): array +{ + $statement = $appDb->prepare('select * from `t_web_group_mute_rules` where `group_id` = ? limit 1'); + $statement->execute([$groupId]); + $row = $statement->fetch(); + if (!is_array($row)) { + return [ + 'mode' => 'off', + 'scheduleType' => 'once', + 'startsAtMs' => 0, + 'endsAtMs' => 0, + 'dailyStart' => '', + 'dailyEnd' => '', + 'enabled' => false, + ]; + } + + return [ + 'mode' => (string)$row['mode'], + 'scheduleType' => (string)$row['schedule_type'], + 'startsAtMs' => (int)$row['starts_at_ms'], + 'endsAtMs' => (int)$row['ends_at_ms'], + 'dailyStart' => (string)$row['daily_start'], + 'dailyEnd' => (string)$row['daily_end'], + 'enabled' => (bool)$row['enabled'], + ]; +} + +function groupDetailAction(PDO $imDb, PDO $appDb, string $userId, string $groupId): array +{ + $group = fetchWebGroup($appDb, $groupId); + if (!$group) { + respond(404, '没有找到该群组'); + } + $member = fetchWebGroupMember($appDb, $groupId, $userId); + if (!$member) { + respond(403, '你不在该群组中'); + } + + $ownerId = (string)$group['owner_uid']; + $users = fetchWebUserMap($imDb, [$ownerId, $userId], $userId); + $owner = $users[$ownerId] ?? ['uid' => $ownerId, 'displayName' => $ownerId, 'contactAlias' => '']; + $me = $users[$userId] ?? ['uid' => $userId, 'displayName' => $userId]; + $myAlias = (string)($member['alias'] ?? ''); + + return [ + 'group' => [ + 'groupId' => (string)$group['group_id'], + 'name' => (string)$group['name'], + 'category' => (string)$group['category'], + 'announcement' => (string)($group['announcement'] ?? ''), + 'welcomeText' => (string)($group['welcome_text'] ?? ''), + 'ownerUid' => $ownerId, + 'ownerName' => (string)($owner['contactAlias'] ?? '') !== '' ? (string)$owner['contactAlias'] : (string)$owner['displayName'], + 'myRole' => (string)$member['role'], + 'myAlias' => $myAlias, + 'myDisplayName' => $myAlias !== '' ? $myAlias : (string)$me['displayName'], + 'muteSetting' => currentMuteSetting($appDb, (string)$group['group_id']), + ], + ]; +} + +function groupMembersAction(PDO $imDb, PDO $appDb, string $userId, string $groupId): array +{ + if (!fetchWebGroupMember($appDb, $groupId, $userId)) { + respond(403, '你不在该群组中'); + } + + $statement = $appDb->prepare( + 'select `user_id`, `role`, `alias`, `joined_at_ms` from `t_web_group_members`' + . ' where `group_id` = ? and `status` = 0 order by (`role` = "owner") desc, `joined_at_ms` asc' + ); + $statement->execute([$groupId]); + $members = $statement->fetchAll(); + $users = fetchWebUserMap($imDb, array_column($members, 'user_id'), $userId); + + return [ + 'members' => array_map(static function (array $member) use ($users): array { + $uid = (string)$member['user_id']; + $user = $users[$uid] ?? [ + 'uid' => $uid, + 'displayName' => $uid, + 'mobile' => '', + 'portrait' => '', + 'contactAlias' => '', + 'friendAlias' => '', + 'remarkAlias' => '', + 'isContact' => false, + ]; + $alias = trim((string)($member['alias'] ?? '')); + $contactAlias = trim((string)($user['contactAlias'] ?? '')); + return [ + 'uid' => $uid, + 'role' => (string)$member['role'], + 'alias' => $alias, + 'contactAlias' => $contactAlias, + 'friendAlias' => trim((string)($user['friendAlias'] ?? '')), + 'remarkAlias' => trim((string)($user['remarkAlias'] ?? '')), + 'isContact' => (bool)($user['isContact'] ?? false), + 'displayName' => $contactAlias !== '' ? $contactAlias : ($alias !== '' ? $alias : (string)$user['displayName']), + 'rawDisplayName' => (string)$user['displayName'], + 'groupDisplayName' => $alias, + 'mobile' => (string)($user['mobile'] ?? ''), + 'portrait' => (string)($user['portrait'] ?? ''), + ]; + }, $members), + ]; +} + +function updateGroupAliasAction(PDO $appDb, string $userId, string $groupId, string $alias): array +{ + if (mb_strlen($alias, 'UTF-8') > 64) { + respond(400, '本群昵称过长'); + } + if (!fetchWebGroupMember($appDb, $groupId, $userId)) { + respond(403, '你不在该群组中'); + } + + $now = webImNowMs(); + $statement = $appDb->prepare( + 'update `t_web_group_members` set `alias` = ?, `updated_at_ms` = ?' + . ' where `group_id` = ? and `user_id` = ? and `status` = 0' + ); + $statement->execute([$alias, $now, $groupId, $userId]); + + return ['alias' => $alias]; +} + +function leaveGroupAction(PDO $appDb, string $userId, string $groupId): array +{ + $group = fetchWebGroup($appDb, $groupId); + if (!$group) { + respond(404, '没有找到该群组'); + } + $member = fetchWebGroupMember($appDb, $groupId, $userId); + if (!$member) { + respond(403, '你不在该群组中'); + } + + $now = webImNowMs(); + $statement = $appDb->prepare( + 'update `t_web_group_members` set `status` = 1, `updated_at_ms` = ?' + . ' where `group_id` = ? and `user_id` = ?' + ); + $statement->execute([$now, $groupId, $userId]); + $groupUpdate = $appDb->prepare('update `t_web_groups` set `updated_at_ms` = ? where `group_id` = ?'); + $groupUpdate->execute([$now, $groupId]); + + try { + requireImSuccess(imAdminPost('/admin/group/member/quit', [ + 'operator' => $userId, + 'group_id' => $groupId, + 'to_lines' => [0], + ]), '退出原生群组失败'); + } catch (Throwable) { + } + + return ['groupId' => $groupId]; +} + +function dismissGroupAction(PDO $appDb, string $userId, string $groupId): array +{ + $group = fetchWebGroup($appDb, $groupId); + if (!$group) { + respond(404, '没有找到该群组'); + } + requireWebGroupRole($appDb, $groupId, $userId, ['owner']); + + $now = webImNowMs(); + $update = $appDb->prepare('update `t_web_groups` set `deleted` = 1, `updated_at_ms` = ? where `group_id` = ?'); + $update->execute([$now, $groupId]); + $memberUpdate = $appDb->prepare('update `t_web_group_members` set `status` = 1, `updated_at_ms` = ? where `group_id` = ?'); + $memberUpdate->execute([$now, $groupId]); + + try { + dismissNativeGroup($userId, $groupId); + } catch (Throwable) { + } + + return ['groupId' => $groupId]; +} + +function transferGroupAction(PDO $appDb, string $userId, string $groupId, string $targetUserId): array +{ + if ($targetUserId === '' || $targetUserId === $userId) { + respond(400, '请选择新的群主'); + } + $group = fetchWebGroup($appDb, $groupId); + if (!$group) { + respond(404, '没有找到该群组'); + } + requireWebGroupRole($appDb, $groupId, $userId, ['owner']); + $target = requireWebGroupMember($appDb, $groupId, $targetUserId); + if ((string)$target['role'] === 'owner') { + respond(400, '该成员已经是群主'); + } + + $now = webImNowMs(); + $appDb->beginTransaction(); + try { + $groupUpdate = $appDb->prepare('update `t_web_groups` set `owner_uid` = ?, `updated_at_ms` = ? where `group_id` = ?'); + $groupUpdate->execute([$targetUserId, $now, $groupId]); + $oldOwnerUpdate = $appDb->prepare( + 'update `t_web_group_members` set `role` = "member", `updated_at_ms` = ?' + . ' where `group_id` = ? and `user_id` = ?' + ); + $oldOwnerUpdate->execute([$now, $groupId, $userId]); + $newOwnerUpdate = $appDb->prepare( + 'update `t_web_group_members` set `role` = "owner", `updated_at_ms` = ?' + . ' where `group_id` = ? and `user_id` = ?' + ); + $newOwnerUpdate->execute([$now, $groupId, $targetUserId]); + $appDb->commit(); + } catch (Throwable $error) { + $appDb->rollBack(); + throw $error; + } + + try { + transferNativeGroup($userId, $groupId, $targetUserId); + } catch (Throwable) { + } + + return ['groupId' => $groupId, 'newOwner' => $targetUserId]; +} + +function setGroupAdminsAction(PDO $appDb, string $userId, string $groupId, array $adminIds): array +{ + requireWebGroupRole($appDb, $groupId, $userId, ['owner']); + $adminIds = array_values(array_unique(array_filter(array_map('strval', $adminIds), static fn(string $uid): bool => $uid !== $userId))); + $now = webImNowMs(); + + $reset = $appDb->prepare( + 'update `t_web_group_members` set `role` = "member", `updated_at_ms` = ?' + . ' where `group_id` = ? and `role` = "admin" and `status` = 0' + ); + $reset->execute([$now, $groupId]); + + if ($adminIds) { + $update = $appDb->prepare( + 'update `t_web_group_members` set `role` = "admin", `updated_at_ms` = ?' + . ' where `group_id` = ? and `user_id` in (' . appPlaceholders($adminIds) . ')' + . ' and `role` <> "owner" and `status` = 0' + ); + $update->execute(array_merge([$now, $groupId], $adminIds)); + } + + return ['adminIds' => $adminIds]; +} + +function updateGroupProfileAction(PDO $appDb, string $userId, string $groupId, array $payload): array +{ + requireWebGroupRole($appDb, $groupId, $userId, ['owner', 'admin']); + $name = trim((string)($payload['name'] ?? '')); + $announcement = trim((string)($payload['announcement'] ?? '')); + $welcomeText = trim((string)($payload['welcomeText'] ?? '')); + if ($name === '') { + respond(400, '请输入群名称'); + } + if (mb_strlen($name, 'UTF-8') > 128) { + respond(400, '群名称过长'); + } + + $now = webImNowMs(); + $statement = $appDb->prepare( + 'update `t_web_groups` set `name` = ?, `announcement` = ?, `welcome_text` = ?, `updated_at_ms` = ?' + . ' where `group_id` = ? and `deleted` = 0' + ); + $statement->execute([$name, $announcement, $welcomeText, $now, $groupId]); + + return [ + 'groupId' => $groupId, + 'name' => $name, + 'announcement' => $announcement, + 'welcomeText' => $welcomeText, + 'updatedAt' => $now, + ]; +} + +function kickGroupMembersAction(PDO $appDb, string $userId, string $groupId, array $targetIds): array +{ + $operator = requireWebGroupRole($appDb, $groupId, $userId, ['owner', 'admin']); + $operatorRole = (string)$operator['role']; + $targetIds = array_values(array_unique(array_filter(array_map('strval', $targetIds), static fn(string $uid): bool => $uid !== ''))); + $targetIds = array_values(array_filter($targetIds, static fn(string $uid): bool => $uid !== $userId)); + if (!$targetIds) { + respond(400, '请选择要移除的群员'); + } + + $statement = $appDb->prepare( + 'select `user_id`, `role` from `t_web_group_members`' + . ' where `group_id` = ? and `user_id` in (' . appPlaceholders($targetIds) . ') and `status` = 0' + ); + $statement->execute(array_merge([$groupId], $targetIds)); + $targets = $statement->fetchAll(); + if (!$targets) { + respond(400, '没有可移除的群员'); + } + + $allowedIds = []; + foreach ($targets as $target) { + $role = (string)$target['role']; + if ($role === 'owner') { + continue; + } + if ($operatorRole === 'admin' && $role !== 'member') { + continue; + } + $allowedIds[] = (string)$target['user_id']; + } + if (!$allowedIds) { + respond(403, '没有可移除的群员'); + } + + $now = webImNowMs(); + $update = $appDb->prepare( + 'update `t_web_group_members` set `status` = 2, `updated_at_ms` = ?' + . ' where `group_id` = ? and `user_id` in (' . appPlaceholders($allowedIds) . ')' + ); + $update->execute(array_merge([$now, $groupId], $allowedIds)); + + try { + removeNativeGroupMember($userId, $groupId, $allowedIds); + } catch (Throwable) { + } + + return ['removedIds' => $allowedIds]; +} + +function updateMuteSettingAction(PDO $appDb, string $userId, string $groupId, array $payload): array +{ + requireWebGroupRole($appDb, $groupId, $userId, ['owner', 'admin']); + $mode = trim((string)($payload['mode'] ?? 'off')); + $allowedModes = ['off', 'all_include_admins', 'all_except_admins']; + if (!in_array($mode, $allowedModes, true)) { + respond(400, '禁言模式不正确'); + } + $scheduleType = trim((string)($payload['scheduleType'] ?? 'once')); + if (!in_array($scheduleType, ['manual', 'once', 'daily'], true)) { + respond(400, '禁言时段类型不正确'); + } + + $startsAtMs = max(0, (int)($payload['startsAtMs'] ?? 0)); + $endsAtMs = max(0, (int)($payload['endsAtMs'] ?? 0)); + $dailyStart = trim((string)($payload['dailyStart'] ?? '')); + $dailyEnd = trim((string)($payload['dailyEnd'] ?? '')); + $enabled = $mode !== 'off'; + if ($enabled && $scheduleType === 'once' && ($startsAtMs <= 0 || $endsAtMs <= $startsAtMs)) { + respond(400, '请设置有效的单次禁言时段'); + } + if ($enabled && $scheduleType === 'daily' && (!preg_match('/^\d{2}:\d{2}$/', $dailyStart) || !preg_match('/^\d{2}:\d{2}$/', $dailyEnd))) { + respond(400, '请设置有效的每日禁言时段'); + } + + $now = webImNowMs(); + $statement = $appDb->prepare( + 'insert into `t_web_group_mute_rules`' + . ' (`group_id`, `mode`, `schedule_type`, `starts_at_ms`, `ends_at_ms`, `daily_start`, `daily_end`, `enabled`, `created_by`, `updated_at_ms`)' + . ' values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)' + . ' on duplicate key update' + . ' `mode` = values(`mode`),' + . ' `schedule_type` = values(`schedule_type`),' + . ' `starts_at_ms` = values(`starts_at_ms`),' + . ' `ends_at_ms` = values(`ends_at_ms`),' + . ' `daily_start` = values(`daily_start`),' + . ' `daily_end` = values(`daily_end`),' + . ' `enabled` = values(`enabled`),' + . ' `created_by` = values(`created_by`),' + . ' `updated_at_ms` = values(`updated_at_ms`)' + ); + $statement->execute([$groupId, $mode, $scheduleType, $startsAtMs, $endsAtMs, $dailyStart, $dailyEnd, $enabled ? 1 : 0, $userId, $now]); + + return ['muteSetting' => currentMuteSetting($appDb, $groupId)]; +} + +function joinWebGroupAction(PDO $appDb, string $userId, string $groupKey): array +{ + if ($groupKey === '') { + respond(400, '请输入群组ID或群名称'); + } + + $group = fetchWebGroup($appDb, $groupKey); + if (!$group) { + try { + $native = requireImSuccess(imAdminPost('/admin/group/get_info', ['groupId' => $groupKey]), '群组不存在'); + $now = webImNowMs(); + $statement = $appDb->prepare( + 'insert into `t_web_groups`' + . ' (`group_id`, `category`, `name`, `portrait`, `owner_uid`, `join_mode`, `announcement`,' + . ' `native_group_id`, `native_status`, `created_by`, `created_at_ms`, `updated_at_ms`, `deleted`)' + . ' values (?, "group", ?, ?, ?, "open", "", ?, "ok", ?, ?, ?, 0)' + . ' on duplicate key update `updated_at_ms` = values(`updated_at_ms`)' + ); + $statement->execute([ + $groupKey, + (string)($native['name'] ?? $groupKey), + (string)($native['portrait'] ?? ''), + (string)($native['owner'] ?? ''), + $groupKey, + $userId, + $now, + $now, + ]); + $group = fetchWebGroup($appDb, $groupKey); + } catch (Throwable) { + respond(404, '没有找到该群组'); + } + } + + $groupId = (string)$group['group_id']; + upsertWebGroupMember($appDb, $groupId, $userId, 'member'); + try { + addNativeGroupMember((string)($group['owner_uid'] ?: $userId), $groupId, $userId); + } catch (Throwable $error) { + // Web membership is authoritative for this web build; native group sync is best-effort. + } + + $role = fetchWebGroupRole($appDb, $groupId, $userId); + return [ + 'group' => fetchWebGroup($appDb, $groupId), + 'conversation' => webGroupConversation($group, $role), + ]; +} + +function sendBroadcastAction(PDO $imDb, PDO $appDb, string $userId, array $payload): array +{ + $text = trim((string)($payload['text'] ?? '')); + if ($text === '') { + respond(400, '请输入群发内容'); + } + + $targetIds = resolveWebUserIds($imDb, webActionList($payload['targetIds'] ?? [])); + $targetIds = array_values(array_filter(array_unique($targetIds), static fn(string $uid): bool => $uid !== $userId)); + if (!$targetIds) { + respond(400, '请选择群发对象'); + } + + $results = []; + foreach ($targetIds as $targetId) { + try { + $result = requireImSuccess(imAdminPost('/admin/message/send', [ + 'sender' => $userId, + 'conv' => [ + 'type' => 0, + 'target' => $targetId, + 'line' => 0, + ], + 'payload' => [ + 'type' => 1, + 'searchableContent' => $text, + 'pushContent' => $text, + 'content' => $text, + 'persistFlag' => 3, + ], + 'userMessage' => true, + ]), '发送失败'); + $results[] = [ + 'targetId' => $targetId, + 'ok' => true, + 'messageUid' => isset($result['messageUid']) ? (string)$result['messageUid'] : '', + ]; + } catch (Throwable $error) { + $results[] = [ + 'targetId' => $targetId, + 'ok' => false, + 'error' => $error->getMessage() ?: '发送失败', + ]; + } + } + + $successCount = count(array_filter($results, static fn(array $item): bool => !empty($item['ok']))); + $failedCount = count($results) - $successCount; + $now = webImNowMs(); + $statement = $appDb->prepare( + 'insert into `t_web_broadcast_logs`' + . ' (`sender_uid`, `target_count`, `success_count`, `failed_count`, `text`, `target_json`, `result_json`, `created_at_ms`)' + . ' values (?, ?, ?, ?, ?, ?, ?, ?)' + ); + $statement->execute([ + $userId, + count($targetIds), + $successCount, + $failedCount, + $text, + json_encode($targetIds, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), + json_encode($results, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), + $now, + ]); + + return [ + 'targetCount' => count($targetIds), + 'successCount' => $successCount, + 'failedCount' => $failedCount, + 'results' => $results, + ]; +} + +$payload = readJsonPayload(); +$action = trim((string)($payload['action'] ?? '')); +$userId = trim((string)($payload['userId'] ?? '')); + +if ($userId === '') { + respond(400, '缺少当前用户ID'); +} + +try { + ensureWebImAppTables(); + $imDb = imDb(); + $appDb = imAppDb(); + + if ($action === 'create_group') { + respond(0, 'success', createWebGroupAction($imDb, $appDb, $userId, $payload, 'group')); + } + if ($action === 'create_channel') { + respond(0, 'success', createWebGroupAction($imDb, $appDb, $userId, $payload, 'channel')); + } + if ($action === 'join_group') { + respond(0, 'success', joinWebGroupAction($appDb, $userId, trim((string)($payload['groupKey'] ?? '')))); + } + if ($action === 'group_detail') { + respond(0, 'success', groupDetailAction($imDb, $appDb, $userId, trim((string)($payload['groupId'] ?? '')))); + } + if ($action === 'group_members') { + respond(0, 'success', groupMembersAction($imDb, $appDb, $userId, trim((string)($payload['groupId'] ?? '')))); + } + if ($action === 'update_group_alias') { + respond(0, 'success', updateGroupAliasAction( + $appDb, + $userId, + trim((string)($payload['groupId'] ?? '')), + trim((string)($payload['alias'] ?? '')) + )); + } + if ($action === 'leave_group') { + respond(0, 'success', leaveGroupAction($appDb, $userId, trim((string)($payload['groupId'] ?? '')))); + } + if ($action === 'dismiss_group') { + respond(0, 'success', dismissGroupAction($appDb, $userId, trim((string)($payload['groupId'] ?? '')))); + } + if ($action === 'transfer_group') { + respond(0, 'success', transferGroupAction( + $appDb, + $userId, + trim((string)($payload['groupId'] ?? '')), + trim((string)($payload['targetUserId'] ?? '')) + )); + } + if ($action === 'set_group_admins') { + respond(0, 'success', setGroupAdminsAction( + $appDb, + $userId, + trim((string)($payload['groupId'] ?? '')), + is_array($payload['adminIds'] ?? null) ? $payload['adminIds'] : [] + )); + } + if ($action === 'update_group_profile') { + respond(0, 'success', updateGroupProfileAction( + $appDb, + $userId, + trim((string)($payload['groupId'] ?? '')), + $payload + )); + } + if ($action === 'kick_group_members') { + respond(0, 'success', kickGroupMembersAction( + $appDb, + $userId, + trim((string)($payload['groupId'] ?? '')), + is_array($payload['targetIds'] ?? null) ? $payload['targetIds'] : [] + )); + } + if ($action === 'update_mute_setting') { + respond(0, 'success', updateMuteSettingAction( + $appDb, + $userId, + trim((string)($payload['groupId'] ?? '')), + $payload + )); + } + if ($action === 'broadcast') { + $result = sendBroadcastAction($imDb, $appDb, $userId, $payload); + if ((int)$result['successCount'] <= 0) { + respond(500, '群发失败', $result); + } + respond(0, 'success', $result); + } + + respond(400, '未知操作'); +} catch (Throwable $error) { + respond(500, $error->getMessage() ?: '会话操作失败'); +} diff --git a/dist/api/im_web_bootstrap.php b/dist/api/im_web_bootstrap.php new file mode 100644 index 0000000..5a82201 --- /dev/null +++ b/dist/api/im_web_bootstrap.php @@ -0,0 +1,348 @@ + $code, + 'message' => $message, + 'result' => $result, + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + exit; +} + +function readJsonPayload(): array +{ + $payload = json_decode(file_get_contents('php://input') ?: '[]', true); + return is_array($payload) ? $payload : []; +} + +function imAdminPost(string $path, array $payload): array +{ + $nonce = (string)random_int(1, 1000000); + $timestamp = (string)((int)floor(microtime(true) * 1000)); + $sign = sha1($nonce . '|' . IM_ADMIN_SECRET . '|' . $timestamp); + $body = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + + $curl = curl_init(IM_ADMIN_URL . $path); + if ($curl === false) { + throw new RuntimeException('IM admin client init failed'); + } + + curl_setopt_array($curl, [ + CURLOPT_POST => true, + CURLOPT_POSTFIELDS => $body, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_0, + CURLOPT_CONNECTTIMEOUT_MS => 1000, + CURLOPT_TIMEOUT_MS => 4000, + CURLOPT_FRESH_CONNECT => true, + CURLOPT_FORBID_REUSE => true, + CURLOPT_HTTPHEADER => [ + 'Content-Type: application/json; charset=utf-8', + 'Connection: close', + 'nonce: ' . $nonce, + 'timestamp: ' . $timestamp, + 'sign: ' . $sign, + ], + ]); + + $responseBody = curl_exec($curl); + $curlError = curl_error($curl); + curl_close($curl); + + if ($responseBody === false || $responseBody === '') { + throw new RuntimeException($curlError ?: 'IM admin request failed'); + } + + $data = json_decode($responseBody, true); + if (!is_array($data)) { + throw new RuntimeException('Invalid IM admin response'); + } + + return $data; +} + +function requireImSuccess(array $response, string $fallbackMessage): array +{ + if (($response['code'] ?? -1) !== 0) { + throw new RuntimeException((string)($response['msg'] ?? $response['message'] ?? $fallbackMessage)); + } + + return is_array($response['result'] ?? null) ? $response['result'] : []; +} + +function imDb(): PDO +{ + static $pdo = null; + if ($pdo instanceof PDO) { + return $pdo; + } + + $pdo = new PDO(IM_DB_DSN, IM_DB_USER, IM_DB_PASSWORD, [ + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + PDO::ATTR_EMULATE_PREPARES => false, + ]); + + return $pdo; +} + +function imAppDb(): PDO +{ + static $pdo = null; + if ($pdo instanceof PDO) { + return $pdo; + } + + $pdo = new PDO(IM_APP_DB_DSN, IM_APP_DB_USER, IM_APP_DB_PASSWORD, [ + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + PDO::ATTR_EMULATE_PREPARES => false, + ]); + + return $pdo; +} + +function ensureWebImAppTables(): void +{ + static $ensured = false; + if ($ensured) { + return; + } + $ensured = true; + + $db = imAppDb(); + $db->exec( + "create table if not exists `t_web_groups` ( + `id` bigint unsigned not null auto_increment, + `group_id` varchar(64) not null, + `category` varchar(20) not null default 'group', + `name` varchar(128) not null, + `portrait` varchar(1024) not null default '', + `owner_uid` varchar(64) not null, + `join_mode` varchar(20) not null default 'open', + `announcement` text null, + `native_group_id` varchar(64) not null default '', + `native_status` varchar(32) not null default 'pending', + `native_error` varchar(255) not null default '', + `created_by` varchar(64) not null, + `created_at_ms` bigint not null, + `updated_at_ms` bigint not null, + `deleted` tinyint not null default 0, + primary key (`id`), + unique key `uk_t_web_groups_group_id` (`group_id`), + key `idx_t_web_groups_owner` (`owner_uid`), + key `idx_t_web_groups_category` (`category`) + ) engine=InnoDB default charset=utf8mb4 collate=utf8mb4_unicode_ci" + ); + try { + $db->exec("alter table `t_web_groups` add column `welcome_text` text null after `announcement`"); + } catch (Throwable) { + } + $db->exec( + "create table if not exists `t_web_group_members` ( + `id` bigint unsigned not null auto_increment, + `group_id` varchar(64) not null, + `user_id` varchar(64) not null, + `role` varchar(20) not null default 'member', + `alias` varchar(128) not null default '', + `joined_at_ms` bigint not null, + `updated_at_ms` bigint not null, + `status` tinyint not null default 0, + primary key (`id`), + unique key `uk_t_web_group_members_gid_uid` (`group_id`, `user_id`), + key `idx_t_web_group_members_user` (`user_id`) + ) engine=InnoDB default charset=utf8mb4 collate=utf8mb4_unicode_ci" + ); + $db->exec( + "create table if not exists `t_web_group_messages` ( + `id` bigint unsigned not null auto_increment, + `message_uid` varchar(64) not null, + `group_id` varchar(64) not null, + `sender_uid` varchar(64) not null, + `text` text not null, + `created_at_ms` bigint not null, + `edited_at_ms` bigint not null default 0, + `recalled` tinyint not null default 0, + primary key (`id`), + unique key `uk_t_web_group_messages_uid` (`message_uid`), + key `idx_t_web_group_messages_group_time` (`group_id`, `created_at_ms`), + key `idx_t_web_group_messages_sender` (`sender_uid`) + ) engine=InnoDB default charset=utf8mb4 collate=utf8mb4_unicode_ci" + ); + $db->exec( + "create table if not exists `t_web_message_attachments` ( + `id` bigint unsigned not null auto_increment, + `message_uid` varchar(64) not null, + `conversation_type` varchar(16) not null default 'single', + `target_id` varchar(128) not null default '', + `sender_uid` varchar(64) not null default '', + `attachment_type` varchar(16) not null, + `url` varchar(1024) not null, + `name` varchar(255) not null default '', + `mime` varchar(128) not null default '', + `size_bytes` bigint not null default 0, + `created_at_ms` bigint not null, + primary key (`id`), + unique key `uk_t_web_message_attachments_uid` (`message_uid`), + key `idx_t_web_message_attachments_target` (`conversation_type`, `target_id`, `created_at_ms`) + ) engine=InnoDB default charset=utf8mb4 collate=utf8mb4_unicode_ci" + ); + $db->exec( + "create table if not exists `t_web_group_reads` ( + `id` bigint unsigned not null auto_increment, + `group_id` varchar(64) not null, + `user_id` varchar(64) not null, + `read_at_ms` bigint not null default 0, + `updated_at_ms` bigint not null, + primary key (`id`), + unique key `uk_t_web_group_reads_gid_uid` (`group_id`, `user_id`) + ) engine=InnoDB default charset=utf8mb4 collate=utf8mb4_unicode_ci" + ); + $db->exec( + "create table if not exists `t_web_group_mute_rules` ( + `id` bigint unsigned not null auto_increment, + `group_id` varchar(64) not null, + `mode` varchar(32) not null default 'off', + `schedule_type` varchar(16) not null default 'once', + `starts_at_ms` bigint not null default 0, + `ends_at_ms` bigint not null default 0, + `daily_start` varchar(8) not null default '', + `daily_end` varchar(8) not null default '', + `enabled` tinyint not null default 0, + `created_by` varchar(64) not null default '', + `updated_at_ms` bigint not null, + primary key (`id`), + unique key `uk_t_web_group_mute_rules_group` (`group_id`) + ) engine=InnoDB default charset=utf8mb4 collate=utf8mb4_unicode_ci" + ); + $db->exec( + "create table if not exists `t_web_broadcast_logs` ( + `id` bigint unsigned not null auto_increment, + `sender_uid` varchar(64) not null, + `target_count` int not null default 0, + `success_count` int not null default 0, + `failed_count` int not null default 0, + `text` text not null, + `target_json` text null, + `result_json` text null, + `created_at_ms` bigint not null, + primary key (`id`), + key `idx_t_web_broadcast_logs_sender_time` (`sender_uid`, `created_at_ms`) + ) engine=InnoDB default charset=utf8mb4 collate=utf8mb4_unicode_ci" + ); + $db->exec( + "create table if not exists `t_web_user_remarks` ( + `id` bigint unsigned not null auto_increment, + `owner_uid` varchar(64) not null, + `target_uid` varchar(64) not null, + `alias` varchar(128) not null default '', + `created_at_ms` bigint not null, + `updated_at_ms` bigint not null, + primary key (`id`), + unique key `uk_t_web_user_remarks_owner_target` (`owner_uid`, `target_uid`), + key `idx_t_web_user_remarks_target` (`target_uid`) + ) engine=InnoDB default charset=utf8mb4 collate=utf8mb4_unicode_ci" + ); +} + +function webImPlaceholders(array $values): string +{ + return implode(',', array_fill(0, count($values), '?')); +} + +function fetchWebUserRemarkMap(PDO $db, string $ownerId, array $targetIds): array +{ + $targetIds = array_values(array_unique(array_filter(array_map(static function ($targetId): string { + return trim((string)$targetId); + }, $targetIds)))); + if ($ownerId === '' || !$targetIds) { + return []; + } + + $statement = $db->prepare( + 'select `target_uid`, `alias` from `t_web_user_remarks`' + . ' where `owner_uid` = ? and `target_uid` in (' . webImPlaceholders($targetIds) . ')' + ); + $statement->execute(array_merge([$ownerId], $targetIds)); + + $remarks = []; + foreach ($statement->fetchAll() as $row) { + $remarks[(string)$row['target_uid']] = trim((string)($row['alias'] ?? '')); + } + + return $remarks; +} + +function saveWebUserRemark(PDO $db, string $ownerId, string $targetId, string $alias): void +{ + if ($ownerId === '' || $targetId === '') { + return; + } + + if ($alias === '') { + $delete = $db->prepare('delete from `t_web_user_remarks` where `owner_uid` = ? and `target_uid` = ?'); + $delete->execute([$ownerId, $targetId]); + return; + } + + $now = webImNowMs(); + $statement = $db->prepare( + 'insert into `t_web_user_remarks` (`owner_uid`, `target_uid`, `alias`, `created_at_ms`, `updated_at_ms`)' + . ' values (?, ?, ?, ?, ?)' + . ' on duplicate key update `alias` = values(`alias`), `updated_at_ms` = values(`updated_at_ms`)' + ); + $statement->execute([$ownerId, $targetId, $alias, $now, $now]); +} + +function webImNowMs(): int +{ + return (int)floor(microtime(true) * 1000); +} + +function webImMessageUid(): string +{ + $timestampPart = (webImNowMs() - 1514736000000) << 21; + return (string)($timestampPart | random_int(1, 0x1FFFFF)); +} + +function javaStringHashCode(string $value): int +{ + $hash = 0; + $length = strlen($value); + for ($i = 0; $i < $length; $i++) { + $hash = (31 * $hash + ord($value[$i])) & 0xFFFFFFFF; + if ($hash >= 0x80000000) { + $hash -= 0x100000000; + } + } + + return $hash; +} + +function imUserMessagesTable(string $userId): string +{ + return 't_user_messages_' . (abs(javaStringHashCode($userId)) % 128); +} + +function imMessageTable(string $messageId): string +{ + $timestamp = ((int)$messageId >> 21) + 1514736000000; + $date = (new DateTimeImmutable('@' . (int)floor($timestamp / 1000))) + ->setTimezone(new DateTimeZone(IM_DB_TIMEZONE)); + $year = (int)$date->format('Y'); + $month = (int)$date->format('n') - 1; + + return 't_messages_' . (($year % 3) * 12 + $month); +} diff --git a/dist/api/media_download.php b/dist/api/media_download.php new file mode 100644 index 0000000..634c71d --- /dev/null +++ b/dist/api/media_download.php @@ -0,0 +1,58 @@ +prepare( + 'select `_uid` from `t_user` where `_uid` = ? or `_mobile` = ? or `_name` = ? limit 1' + ); + $statement->execute([$value, $value, $value]); + $uid = $statement->fetchColumn(); + + return is_string($uid) && $uid !== '' ? $uid : $value; +} + +function messageTimestampMs(string $messageUid): int +{ + return (((int)$messageUid) >> 21) + 1514736000000; +} + +function nowTimestampMs(): int +{ + return (int)floor(microtime(true) * 1000); +} + +function recallLimitMinutes(): float +{ + $statement = imAppDb()->prepare( + 'select `conf_value` from `system_conf`' + . ' where `conf_name` = ? and `is_valid` = 1 limit 1' + ); + $statement->execute(['RetractMessage']); + $value = trim((string)($statement->fetchColumn() ?: '0')); + + if ($value === '' || !is_numeric($value)) { + return 0.0; + } + + return max(0.0, (float)$value); +} + +function assertRecallWithinLimit(string $messageUid): void +{ + $limitMinutes = recallLimitMinutes(); + if ($limitMinutes <= 0) { + return; + } + + $messageAgeMs = nowTimestampMs() - messageTimestampMs($messageUid); + $limitMs = (int)round($limitMinutes * 60 * 1000); + if ($messageAgeMs > $limitMs) { + throw new UserActionException('已超过可撤回时间'); + } +} + +function fetchActionMessageRow(string $messageUid): array +{ + $table = imMessageTable($messageUid); + $statement = imDb()->prepare( + 'select `_mid`, `_from`, `_content_type`, `_searchable_key` from `' . $table . '` where `_mid` = ? limit 1' + ); + $statement->execute([$messageUid]); + $row = $statement->fetch(); + + return is_array($row) ? $row : []; +} + +function ensureMessageEditsTable(): void +{ + imDb()->exec( + 'create table if not exists `t_web_message_edits` (' + . '`message_uid` varchar(32) not null,' + . '`editor_uid` varchar(64) not null,' + . '`edited_text` text null,' + . '`edited_at_ms` bigint not null,' + . '`created_at` datetime not null default current_timestamp,' + . '`updated_at` datetime null default current_timestamp on update current_timestamp,' + . 'primary key (`message_uid`),' + . 'key `idx_editor_uid` (`editor_uid`),' + . 'key `idx_edited_at_ms` (`edited_at_ms`)' + . ') engine=InnoDB default charset=utf8mb4' + ); +} + +function editTextMessage(string $operatorId, string $messageUid, string $text): array +{ + $row = fetchActionMessageRow($messageUid); + if (!$row) { + return editWebGroupMessage($operatorId, $messageUid, $text); + } + if ((string)$row['_from'] !== $operatorId) { + throw new UserActionException('只能编辑自己发送的消息'); + } + if ((int)$row['_content_type'] !== 1) { + throw new UserActionException('只能编辑文字消息'); + } + + $editedAt = nowTimestampMs(); + $table = imMessageTable($messageUid); + $update = imDb()->prepare('update `' . $table . '` set `_searchable_key` = ? where `_mid` = ?'); + $update->execute([$text, $messageUid]); + + ensureMessageEditsTable(); + $upsert = imDb()->prepare( + 'insert into `t_web_message_edits` (`message_uid`, `editor_uid`, `edited_text`, `edited_at_ms`)' + . ' values (?, ?, ?, ?)' + . ' on duplicate key update' + . ' `editor_uid` = values(`editor_uid`),' + . ' `edited_text` = values(`edited_text`),' + . ' `edited_at_ms` = values(`edited_at_ms`),' + . ' `updated_at` = current_timestamp' + ); + $upsert->execute([$messageUid, $operatorId, $text, $editedAt]); + + return [ + 'messageUid' => $messageUid, + 'text' => $text, + 'editedAt' => $editedAt, + ]; +} + +function fetchWebGroupActionMessage(string $messageUid): array +{ + ensureWebImAppTables(); + $statement = imAppDb()->prepare( + 'select m.*, g.`category` from `t_web_group_messages` m' + . ' join `t_web_groups` g on g.`group_id` = m.`group_id` and g.`deleted` = 0' + . ' where m.`message_uid` = ? limit 1' + ); + $statement->execute([$messageUid]); + $row = $statement->fetch(); + + return is_array($row) ? $row : []; +} + +function editWebGroupMessage(string $operatorId, string $messageUid, string $text): array +{ + $row = fetchWebGroupActionMessage($messageUid); + if (!$row) { + throw new UserActionException('消息不存在'); + } + if ((string)$row['sender_uid'] !== $operatorId) { + throw new UserActionException('只能编辑自己发送的消息'); + } + if ((int)($row['recalled'] ?? 0) !== 0) { + throw new UserActionException('已撤回的消息请重新编辑发送'); + } + + $editedAt = nowTimestampMs(); + $update = imAppDb()->prepare( + 'update `t_web_group_messages` set `text` = ?, `edited_at_ms` = ? where `message_uid` = ?' + ); + $update->execute([$text, $editedAt, $messageUid]); + $groupUpdate = imAppDb()->prepare('update `t_web_groups` set `updated_at_ms` = ? where `group_id` = ?'); + $groupUpdate->execute([$editedAt, (string)$row['group_id']]); + + return [ + 'messageUid' => $messageUid, + 'text' => $text, + 'editedAt' => $editedAt, + ]; +} + +function webGroupMemberRoleForAction(string $groupId, string $userId): string +{ + $statement = imAppDb()->prepare( + 'select `role` from `t_web_group_members`' + . ' where `group_id` = ? and `user_id` = ? and `status` = 0 limit 1' + ); + $statement->execute([$groupId, $userId]); + $role = $statement->fetchColumn(); + + return is_string($role) ? $role : ''; +} + +function recallWebGroupMessage(string $operatorId, string $messageUid): bool +{ + $row = fetchWebGroupActionMessage($messageUid); + if (!$row) { + return false; + } + $isSender = (string)$row['sender_uid'] === $operatorId; + if (!$isSender) { + $role = webGroupMemberRoleForAction((string)$row['group_id'], $operatorId); + if (!in_array($role, ['owner', 'admin'], true)) { + throw new UserActionException('只有群主或管理员可以撤回他人消息'); + } + } + assertRecallWithinLimit($messageUid); + + $now = nowTimestampMs(); + $update = imAppDb()->prepare( + 'update `t_web_group_messages` set `recalled` = 1 where `message_uid` = ?' + ); + $update->execute([$messageUid]); + $groupUpdate = imAppDb()->prepare('update `t_web_groups` set `updated_at_ms` = ? where `group_id` = ?'); + $groupUpdate->execute([$now, (string)$row['group_id']]); + + return true; +} + +$payload = readJsonPayload(); +$action = trim((string)($payload['action'] ?? '')); +$userId = trim((string)($payload['userId'] ?? '')); +$messageUidText = trim((string)($payload['messageUid'] ?? '')); +$messageUid = ctype_digit($messageUidText) ? (int)$messageUidText : 0; + +if ($action === '' || $messageUid <= 0) { + respond(400, '缺少操作类型或消息ID'); +} + +try { + if ($action === 'recall') { + if ($userId === '') { + respond(400, '缺少操作者ID'); + } + $userId = resolveActionUserId($userId); + $row = fetchActionMessageRow($messageUidText); + if (!$row && recallWebGroupMessage($userId, $messageUidText)) { + respond(0, 'success', [ + 'messageUid' => (string)$messageUid, + 'action' => $action, + ]); + } + if (!$row) { + throw new UserActionException('消息不存在'); + } + assertRecallWithinLimit($messageUidText); + requireImSuccess(imAdminPost('/admin/message/recall', [ + 'operator' => $userId, + 'messageUid' => $messageUid, + 'userRecall' => true, + 'isUserRecall' => true, + ]), '撤回失败'); + + respond(0, 'success', [ + 'messageUid' => (string)$messageUid, + 'action' => $action, + ]); + } + + if ($action === 'edit') { + if ($userId === '') { + respond(400, '缺少操作者ID'); + } + $text = trim((string)($payload['text'] ?? '')); + if ($text === '') { + respond(400, '编辑内容不能为空'); + } + if (mb_strlen($text, 'UTF-8') > 5000) { + respond(400, '编辑内容过长'); + } + + $userId = resolveActionUserId($userId); + respond(0, 'success', [ + 'message' => editTextMessage($userId, $messageUidText, $text), + 'action' => $action, + ]); + } + + if ($action === 'delete') { + requireImSuccess(imAdminPost('/admin/message/delete', [ + 'messageUid' => $messageUid, + ]), '删除失败'); + + respond(0, 'success', [ + 'messageUid' => (string)$messageUid, + 'action' => $action, + ]); + } + + respond(400, '不支持的消息操作'); +} catch (Throwable $error) { + respond($error instanceof UserActionException ? 400 : 500, $error->getMessage() ?: '消息操作失败'); +} diff --git a/dist/api/message_detail.php b/dist/api/message_detail.php new file mode 100644 index 0000000..06454bf --- /dev/null +++ b/dist/api/message_detail.php @@ -0,0 +1,387 @@ + 0) { + return ($id >> 21) + 1514736000000; + } + + if ($datetime !== null && $datetime !== '') { + $date = DateTimeImmutable::createFromFormat( + 'Y-m-d H:i:s', + $datetime, + new DateTimeZone(IM_DB_TIMEZONE) + ); + if ($date instanceof DateTimeImmutable) { + return $date->getTimestamp() * 1000; + } + } + + return 0; +} + +function detailResolveUserId(PDO $db, string $value): string +{ + if ($value === '') { + return ''; + } + + $statement = $db->prepare( + 'select `_uid` from `t_user` where `_uid` = ? or `_mobile` = ? or `_name` = ? limit 1' + ); + $statement->execute([$value, $value, $value]); + $uid = $statement->fetchColumn(); + + return is_string($uid) && $uid !== '' ? $uid : $value; +} + +function detailConversationType(mixed $value): string +{ + $type = strtolower(trim((string)$value)); + return in_array($type, ['1', 'group', 'channel'], true) ? 'group' : 'single'; +} + +function detailDeliveryMap(PDO $db, array $userIds): array +{ + $userIds = array_values(array_unique(array_filter(array_map('strval', $userIds)))); + if (!$userIds) { + return []; + } + + $statement = $db->prepare( + 'select `_uid`, max(`_dt`) as `_dt` from `t_delivery_report`' + . ' where `_uid` in (' . detailPlaceholders($userIds) . ') group by `_uid`' + ); + $statement->execute($userIds); + + $items = []; + foreach ($statement->fetchAll() as $row) { + $items[(string)$row['_uid']] = (int)$row['_dt']; + } + + return $items; +} + +function detailReadAt(PDO $db, string $readerId, array $targets): int +{ + $targets = array_values(array_unique(array_filter(array_map('strval', $targets)))); + if ($readerId === '' || !$targets) { + return 0; + } + + $statement = $db->prepare( + 'select max(`_dt`) from `t_read_report`' + . ' where `_uid` = ? and `_type` = 0 and `_line` = 0' + . ' and `_target` in (' . detailPlaceholders($targets) . ')' + ); + $statement->execute(array_merge([$readerId], $targets)); + $value = $statement->fetchColumn(); + + return is_numeric($value) ? (int)$value : 0; +} + +function detailSingleMessageVisible(PDO $db, string $userId, string $targetId, string $messageUid): bool +{ + $table = imUserMessagesTable($userId); + $conversationKeys = [$userId . '|' . $targetId, $targetId . '|' . $userId]; + $statement = $db->prepare( + 'select 1 from `' . $table . '`' + . ' where `_uid` = ? and `_mid` = ? and `_type` = 0 and `_line` = 0' + . ' and `_target` in (' . detailPlaceholders($conversationKeys) . ') limit 1' + ); + $statement->execute(array_merge([$userId, $messageUid], $conversationKeys)); + + return (bool)$statement->fetchColumn(); +} + +function detailUserMap(PDO $imDb, PDO $appDb, array $userIds, string $ownerId, string $groupId = ''): array +{ + $userIds = array_values(array_unique(array_filter(array_map('strval', $userIds)))); + if (!$userIds) { + return []; + } + + $statement = $imDb->prepare( + 'select `_uid`, `_name`, `_display_name`, `_mobile`, `_portrait` from `t_user`' + . ' where `_uid` in (' . detailPlaceholders($userIds) . ')' + ); + $statement->execute($userIds); + + $users = []; + foreach ($statement->fetchAll() as $row) { + $uid = (string)$row['_uid']; + $rawName = trim((string)($row['_display_name'] ?? '')) + ?: trim((string)($row['_name'] ?? '')) + ?: trim((string)($row['_mobile'] ?? '')) + ?: $uid; + $users[$uid] = [ + 'uid' => $uid, + 'rawName' => $rawName, + 'mobile' => (string)($row['_mobile'] ?? ''), + 'portrait' => (string)($row['_portrait'] ?? ''), + 'contactAlias' => '', + 'remarkAlias' => '', + 'groupAlias' => '', + 'role' => '', + 'displayName' => $rawName, + ]; + } + + if ($ownerId !== '') { + $aliasStatement = $imDb->prepare( + 'select `_friend_uid`, `_alias` from `t_friend` where `_uid` = ?' + . ' and `_friend_uid` in (' . detailPlaceholders($userIds) . ')' + ); + $aliasStatement->execute(array_merge([$ownerId], $userIds)); + foreach ($aliasStatement->fetchAll() as $row) { + $uid = (string)$row['_friend_uid']; + if (isset($users[$uid])) { + $users[$uid]['contactAlias'] = trim((string)($row['_alias'] ?? '')); + } + } + + try { + $remarkMap = fetchWebUserRemarkMap($appDb, $ownerId, $userIds); + } catch (Throwable) { + $remarkMap = []; + } + foreach ($remarkMap as $uid => $alias) { + if (isset($users[$uid])) { + $users[$uid]['remarkAlias'] = trim((string)$alias); + } + } + } + + if ($groupId !== '') { + $memberStatement = $appDb->prepare( + 'select `user_id`, `alias`, `role` from `t_web_group_members`' + . ' where `group_id` = ? and `user_id` in (' . detailPlaceholders($userIds) . ')' + ); + $memberStatement->execute(array_merge([$groupId], $userIds)); + foreach ($memberStatement->fetchAll() as $row) { + $uid = (string)$row['user_id']; + if (isset($users[$uid])) { + $users[$uid]['groupAlias'] = trim((string)($row['alias'] ?? '')); + $users[$uid]['role'] = (string)($row['role'] ?? ''); + } + } + } + + foreach ($users as $uid => $user) { + $alias = (string)$user['contactAlias'] !== '' + ? (string)$user['contactAlias'] + : ((string)$user['remarkAlias'] !== '' ? (string)$user['remarkAlias'] : (string)$user['groupAlias']); + $users[$uid]['displayName'] = $alias !== '' ? $alias : (string)$user['rawName']; + } + + foreach ($userIds as $uid) { + if (!isset($users[$uid])) { + $users[$uid] = [ + 'uid' => $uid, + 'rawName' => $uid, + 'mobile' => '', + 'portrait' => '', + 'contactAlias' => '', + 'remarkAlias' => '', + 'groupAlias' => '', + 'role' => '', + 'displayName' => $uid, + ]; + } + } + + return $users; +} + +function detailMember(array $user, int $time = 0): array +{ + return [ + 'uid' => (string)$user['uid'], + 'name' => (string)$user['displayName'], + 'rawName' => (string)$user['rawName'], + 'mobile' => (string)($user['mobile'] ?? ''), + 'portrait' => (string)($user['portrait'] ?? ''), + 'role' => (string)($user['role'] ?? ''), + 'time' => $time, + ]; +} + +function singleDetail(PDO $imDb, string $userId, string $targetId, string $messageUid): array +{ + if (!preg_match('/^\d+$/', $messageUid)) { + respond(400, '缺少可查询的消息ID'); + } + + $table = imMessageTable($messageUid); + $statement = $imDb->prepare( + 'select `_mid`, `_from`, `_target`, `_dt`, `_content_type`, `_searchable_key`, `_to`' + . ' from `' . $table . '` where `_mid` = ? limit 1' + ); + $statement->execute([$messageUid]); + $message = $statement->fetch(); + if (!is_array($message)) { + respond(404, '没有找到该消息'); + } + + $senderId = (string)$message['_from']; + if (!detailSingleMessageVisible($imDb, $userId, $targetId, $messageUid)) { + respond(403, '没有权限查看该消息'); + } + + $receiverId = $senderId === $userId ? $targetId : $userId; + if ($senderId !== $userId && $senderId !== $targetId) { + respond(403, '没有权限查看该消息'); + } + + $sentAt = detailTimestampMs((string)($message['_dt'] ?? ''), $messageUid); + $targets = [$senderId, $senderId . '|' . $receiverId, $receiverId . '|' . $senderId]; + $deliveredRaw = detailDeliveryMap($imDb, [$receiverId])[$receiverId] ?? 0; + $readRaw = detailReadAt($imDb, $receiverId, $targets); + $users = detailUserMap($imDb, imAppDb(), [$senderId, $receiverId], $userId); + + return [ + 'messageUid' => $messageUid, + 'conversationType' => 'single', + 'sentAt' => $sentAt, + 'sender' => detailMember($users[$senderId]), + 'receiver' => detailMember($users[$receiverId]), + 'deliveredAt' => $deliveredRaw >= $sentAt ? $deliveredRaw : 0, + 'readAt' => $readRaw >= $sentAt ? $readRaw : 0, + ]; +} + +function groupDetail(PDO $imDb, PDO $appDb, string $userId, string $groupId, string $messageUid): array +{ + ensureWebImAppTables(); + if (!preg_match('/^\d+$/', $messageUid)) { + respond(400, '缺少可查询的消息ID'); + } + + $myMember = $appDb->prepare( + 'select `role` from `t_web_group_members` where `group_id` = ? and `user_id` = ? and `status` = 0 limit 1' + ); + $myMember->execute([$groupId, $userId]); + if (!$myMember->fetchColumn()) { + respond(403, '你不在该群组中'); + } + + $messageStatement = $appDb->prepare( + 'select `message_uid`, `group_id`, `sender_uid`, `created_at_ms`, `edited_at_ms`, `recalled`' + . ' from `t_web_group_messages` where `group_id` = ? and `message_uid` = ? limit 1' + ); + $messageStatement->execute([$groupId, $messageUid]); + $message = $messageStatement->fetch(); + if (!is_array($message)) { + respond(404, '没有找到该群消息'); + } + + $sentAt = (int)$message['created_at_ms']; + $editedAt = (int)($message['edited_at_ms'] ?? 0); + $activityAt = max($sentAt, $editedAt); + $senderId = (string)$message['sender_uid']; + + $memberStatement = $appDb->prepare( + 'select `user_id`, `role`, `alias`, `joined_at_ms` from `t_web_group_members`' + . ' where `group_id` = ? and `status` = 0 and `joined_at_ms` <= ?' + . ' order by (`role` = "owner") desc, (`role` = "admin") desc, `joined_at_ms` asc' + ); + $memberStatement->execute([$groupId, $sentAt]); + $members = array_values(array_filter($memberStatement->fetchAll(), static function (array $member) use ($senderId): bool { + return (string)$member['user_id'] !== $senderId; + })); + + $memberIds = array_values(array_unique(array_map(static fn(array $member): string => (string)$member['user_id'], $members))); + $users = detailUserMap($imDb, $appDb, array_merge([$senderId], $memberIds), $userId, $groupId); + $deliveryMap = detailDeliveryMap($imDb, $memberIds); + + $readMap = []; + if ($memberIds) { + $readStatement = $appDb->prepare( + 'select `user_id`, `read_at_ms` from `t_web_group_reads`' + . ' where `group_id` = ? and `user_id` in (' . detailPlaceholders($memberIds) . ')' + ); + $readStatement->execute(array_merge([$groupId], $memberIds)); + foreach ($readStatement->fetchAll() as $row) { + $readMap[(string)$row['user_id']] = (int)$row['read_at_ms']; + } + } + + $read = []; + $unread = []; + $undelivered = []; + foreach ($memberIds as $uid) { + $readAt = (int)($readMap[$uid] ?? 0); + $deliveredAt = (int)($deliveryMap[$uid] ?? 0); + $member = detailMember($users[$uid], $readAt >= $activityAt ? $readAt : ($deliveredAt >= $sentAt ? $deliveredAt : 0)); + if ($readAt >= $activityAt) { + $read[] = $member; + } elseif ($deliveredAt >= $sentAt) { + $unread[] = $member; + } else { + $undelivered[] = $member; + } + } + + return [ + 'messageUid' => $messageUid, + 'conversationType' => 'group', + 'groupId' => $groupId, + 'sentAt' => $sentAt, + 'editedAt' => $editedAt, + 'recalled' => (bool)$message['recalled'], + 'sender' => detailMember($users[$senderId] ?? ['uid' => $senderId, 'displayName' => $senderId, 'rawName' => $senderId]), + 'group' => [ + 'read' => $read, + 'unread' => $unread, + 'undelivered' => $undelivered, + 'counts' => [ + 'read' => count($read), + 'unread' => count($unread), + 'undelivered' => count($undelivered), + 'total' => count($memberIds), + ], + ], + ]; +} + +$payload = readJsonPayload(); +$userId = trim((string)($payload['userId'] ?? '')); +$target = trim((string)($payload['target'] ?? '')); +$messageUid = trim((string)($payload['messageUid'] ?? $payload['messageId'] ?? '')); +$conversationType = detailConversationType($payload['conversationType'] ?? $payload['type'] ?? 'single'); + +if ($userId === '') { + respond(400, '缺少用户ID'); +} +if ($target === '') { + respond(400, '缺少会话对象'); +} +if ($messageUid === '') { + respond(400, '缺少消息ID'); +} + +try { + $imDb = imDb(); + $appDb = imAppDb(); + $userId = detailResolveUserId($imDb, $userId); + if ($conversationType === 'group') { + respond(0, 'success', ['detail' => groupDetail($imDb, $appDb, $userId, $target, $messageUid)]); + } + + $targetId = detailResolveUserId($imDb, $target); + respond(0, 'success', ['detail' => singleDetail($imDb, $userId, $targetId, $messageUid)]); +} catch (Throwable $error) { + respond(500, $error->getMessage() ?: '消息详情加载失败'); +} diff --git a/dist/api/messages.php b/dist/api/messages.php new file mode 100644 index 0000000..ac03851 --- /dev/null +++ b/dist/api/messages.php @@ -0,0 +1,900 @@ + 0) { + return ($id >> 21) + 1514736000000; + } + + if ($datetime !== null && $datetime !== '') { + $date = DateTimeImmutable::createFromFormat( + 'Y-m-d H:i:s', + $datetime, + new DateTimeZone(IM_DB_TIMEZONE) + ); + if ($date instanceof DateTimeImmutable) { + return $date->getTimestamp() * 1000; + } + } + + return (int)floor(microtime(true) * 1000); +} + +function nowMs(): int +{ + return (int)floor(microtime(true) * 1000); +} + +function markUserDelivered(PDO $db, string $userId, int $timestamp): void +{ + if ($userId === '' || $timestamp <= 0) { + return; + } + + $statement = $db->prepare( + 'insert into `t_delivery_report` (`_uid`, `_dt`) values (?, ?)' + . ' on duplicate key update `_dt` = if(`_dt` < values(`_dt`), values(`_dt`), `_dt`)' + ); + $statement->execute([$userId, $timestamp]); +} + +function markConversationRead(PDO $db, string $userId, string $targetId, int $timestamp): void +{ + if ($userId === '' || $targetId === '' || $timestamp <= 0) { + return; + } + + $statement = $db->prepare( + 'select `id`, `_dt` from `t_read_report`' + . ' where `_uid` = ? and `_type` = 0 and `_line` = 0 and `_target` = ?' + . ' order by `_dt` desc limit 1' + ); + $statement->execute([$userId, $targetId]); + $row = $statement->fetch(); + + if ($row) { + if ($timestamp > (int)$row['_dt']) { + $update = $db->prepare('update `t_read_report` set `_dt` = ? where `id` = ?'); + $update->execute([$timestamp, (int)$row['id']]); + } + return; + } + + $insert = $db->prepare( + 'insert into `t_read_report` (`_uid`, `_type`, `_line`, `_target`, `_dt`) values (?, 0, 0, ?, ?)' + ); + $insert->execute([$userId, $targetId, $timestamp]); +} + +function resolveUserId(PDO $db, string $value): string +{ + if ($value === '') { + return ''; + } + + $statement = $db->prepare( + 'select `_uid` from `t_user` where `_uid` = ? or `_mobile` = ? or `_name` = ? limit 1' + ); + $statement->execute([$value, $value, $value]); + $uid = $statement->fetchColumn(); + + return is_string($uid) && $uid !== '' ? $uid : $value; +} + +function peerFromConversationTarget(string $userId, string $target): string +{ + $parts = array_values(array_filter(explode('|', $target), static fn($part) => $part !== '')); + if (count($parts) < 2) { + return $target !== $userId ? $target : ''; + } + + return $parts[0] === $userId ? $parts[1] : $parts[0]; +} + +function fetchMessageRows(PDO $db, array $messageIds): array +{ + $messageIds = array_values(array_unique(array_filter(array_map('strval', $messageIds)))); + if (!$messageIds) { + return []; + } + + $idsByTable = []; + foreach ($messageIds as $messageId) { + $idsByTable[imMessageTable($messageId)][] = $messageId; + } + + $messages = []; + foreach ($idsByTable as $table => $ids) { + $sql = 'select `_mid`, `_from`, `_type`, `_target`, `_line`, `_searchable_key`, `_dt`, `_content_type`, `_to`' + . ' from `' . $table . '` where `_mid` in (' . placeholders($ids) . ')'; + $statement = $db->prepare($sql); + $statement->execute($ids); + foreach ($statement->fetchAll() as $row) { + $messages[(string)$row['_mid']] = $row; + } + } + + return $messages; +} + +function fetchMessageEditMap(PDO $db, array $messageIds): array +{ + $messageIds = array_values(array_unique(array_filter(array_map('strval', $messageIds)))); + if (!$messageIds) { + return []; + } + + try { + $statement = $db->prepare( + 'select `message_uid`, `edited_at_ms` from `t_web_message_edits`' + . ' where `message_uid` in (' . placeholders($messageIds) . ')' + ); + $statement->execute($messageIds); + } catch (Throwable) { + return []; + } + + $edits = []; + foreach ($statement->fetchAll() as $row) { + $edits[(string)$row['message_uid']] = [ + 'editedAt' => (int)$row['edited_at_ms'], + ]; + } + + return $edits; +} + +function normalizeAttachmentRow(array $row): array +{ + return [ + 'type' => (string)$row['attachment_type'], + 'url' => (string)$row['url'], + 'name' => (string)($row['name'] ?? ''), + 'mime' => (string)($row['mime'] ?? ''), + 'size' => (int)($row['size_bytes'] ?? 0), + ]; +} + +function fetchAttachmentMap(PDO $appDb, array $messageIds): array +{ + $messageIds = array_values(array_unique(array_filter(array_map('strval', $messageIds)))); + if (!$messageIds) { + return []; + } + + ensureWebImAppTables(); + $statement = $appDb->prepare( + 'select `message_uid`, `attachment_type`, `url`, `name`, `mime`, `size_bytes`' + . ' from `t_web_message_attachments`' + . ' where `message_uid` in (' . placeholders($messageIds) . ')' + ); + $statement->execute($messageIds); + + $attachments = []; + foreach ($statement->fetchAll() as $row) { + $attachments[(string)$row['message_uid']] = normalizeAttachmentRow($row); + } + + return $attachments; +} + +function attachmentFallbackText(?array $attachment): string +{ + if (!$attachment) { + return ''; + } + if ((string)$attachment['type'] === 'image') { + return '[图片]'; + } + + return '[文件] ' . ((string)($attachment['name'] ?? '') ?: '文件'); +} + +function attachmentDisplayText(string $text, ?array $attachment): string +{ + if (!$attachment) { + return $text; + } + + return $text === attachmentFallbackText($attachment) ? '' : $text; +} + +function messagePreviewText(?array $message): string +{ + if (!$message) { + return ''; + } + $attachment = is_array($message['attachment'] ?? null) ? $message['attachment'] : null; + if ($attachment) { + $text = trim((string)($message['text'] ?? '')); + return $text !== '' ? $text : attachmentFallbackText($attachment); + } + + return (string)($message['text'] ?? ''); +} + +function fetchUserInfoMap(PDO $db, array $userIds, string $ownerId = ''): array +{ + $userIds = array_values(array_unique(array_filter(array_map('strval', $userIds)))); + if (!$userIds) { + return []; + } + + $statement = $db->prepare( + 'select `_uid`, `_name`, `_display_name`, `_mobile`, `_portrait`, `_address` from `t_user`' + . ' where `_uid` in (' . placeholders($userIds) . ')' + ); + $statement->execute($userIds); + + $users = []; + foreach ($statement->fetchAll() as $row) { + $row['_is_friend'] = false; + $row['_alias'] = ''; + $row['_friend_alias'] = ''; + $row['_remark_alias'] = ''; + $users[(string)$row['_uid']] = $row; + } + + if ($ownerId !== '') { + $aliasStatement = $db->prepare( + 'select `_friend_uid`, `_alias` from `t_friend` where `_uid` = ?' + . ' and `_friend_uid` in (' . placeholders($userIds) . ')' + ); + $aliasStatement->execute(array_merge([$ownerId], $userIds)); + foreach ($aliasStatement->fetchAll() as $row) { + $friendUid = (string)$row['_friend_uid']; + if (!isset($users[$friendUid])) { + continue; + } + $users[$friendUid]['_is_friend'] = true; + $users[$friendUid]['_friend_alias'] = trim((string)($row['_alias'] ?? '')); + } + + try { + ensureWebImAppTables(); + $remarkMap = fetchWebUserRemarkMap(imAppDb(), $ownerId, $userIds); + } catch (Throwable) { + $remarkMap = []; + } + foreach ($remarkMap as $targetUid => $alias) { + if (!isset($users[$targetUid])) { + continue; + } + $users[$targetUid]['_remark_alias'] = $alias; + } + + foreach ($users as $uid => $user) { + $friendAlias = trim((string)($user['_friend_alias'] ?? '')); + $remarkAlias = trim((string)($user['_remark_alias'] ?? '')); + $users[$uid]['_alias'] = $friendAlias !== '' ? $friendAlias : $remarkAlias; + } + } + + return $users; +} + +function userTitle(array $users, string $userId): string +{ + $user = $users[$userId] ?? null; + if (!$user) { + return $userId; + } + + return (string)($user['_alias'] ?? '') + ?: (string)($user['_display_name'] ?? '') + ?: (string)($user['_name'] ?? '') + ?: (string)($user['_mobile'] ?? '') + ?: $userId; +} + +function loadPeerReceiptState(PDO $db, string $currentUserId, string $peerId): array +{ + $deliveryStatement = $db->prepare('select `_dt` from `t_delivery_report` where `_uid` = ? limit 1'); + $deliveryStatement->execute([$peerId]); + $deliveredAt = $deliveryStatement->fetchColumn(); + + $readTargets = array_values(array_unique([ + $currentUserId, + $currentUserId . '|' . $peerId, + $peerId . '|' . $currentUserId, + ])); + $readStatement = $db->prepare( + 'select max(`_dt`) from `t_read_report`' + . ' where `_uid` = ? and `_type` = 0 and `_line` = 0' + . ' and `_target` in (' . placeholders($readTargets) . ')' + ); + $readStatement->execute(array_merge([$peerId], $readTargets)); + $readAt = $readStatement->fetchColumn(); + + return [ + 'deliveredAt' => is_numeric($deliveredAt) ? (int)$deliveredAt : 0, + 'readAt' => is_numeric($readAt) ? (int)$readAt : 0, + ]; +} + +function loadOwnReadStateMap(PDO $db, string $userId, array $peerIds): array +{ + $peerIds = array_values(array_unique(array_filter(array_map('strval', $peerIds)))); + if (!$peerIds) { + return []; + } + + $statement = $db->prepare( + 'select `_target`, max(`_dt`) as `_read_at` from `t_read_report`' + . ' where `_uid` = ? and `_type` = 0 and `_line` = 0' + . ' and `_target` in (' . placeholders($peerIds) . ')' + . ' group by `_target`' + ); + $statement->execute(array_merge([$userId], $peerIds)); + + $readAtByPeer = []; + foreach ($statement->fetchAll() as $row) { + $readAtByPeer[(string)$row['_target']] = (int)$row['_read_at']; + } + + return $readAtByPeer; +} + +function outgoingDeliveryStatus(int $timestamp, array $receiptState): string +{ + $readAt = (int)($receiptState['readAt'] ?? 0); + if ($readAt > 0 && $timestamp <= $readAt) { + return 'read'; + } + + $deliveredAt = (int)($receiptState['deliveredAt'] ?? 0); + if ($deliveredAt > 0 && $timestamp <= $deliveredAt) { + return 'delivered'; + } + + return 'sent'; +} + +function messageActivityTimestamp(int $timestamp, array $editState = []): int +{ + return max($timestamp, (int)($editState['editedAt'] ?? 0)); +} + +function normalizeConversationType(mixed $value): string +{ + $type = strtolower(trim((string)$value)); + if (in_array($type, ['1', 'group', 'channel'], true)) { + return 'group'; + } + + return 'single'; +} + +function isWebGroupTarget(PDO $appDb, string $targetId): bool +{ + if ($targetId === '') { + return false; + } + + ensureWebImAppTables(); + $statement = $appDb->prepare('select 1 from `t_web_groups` where `group_id` = ? and `deleted` = 0 limit 1'); + $statement->execute([$targetId]); + + return (bool)$statement->fetchColumn(); +} + +function markWebGroupRead(PDO $appDb, string $userId, string $groupId, int $timestamp): void +{ + if ($userId === '' || $groupId === '' || $timestamp <= 0) { + return; + } + + $now = nowMs(); + $statement = $appDb->prepare( + 'insert into `t_web_group_reads` (`group_id`, `user_id`, `read_at_ms`, `updated_at_ms`)' + . ' values (?, ?, ?, ?)' + . ' on duplicate key update' + . ' `read_at_ms` = if(`read_at_ms` < values(`read_at_ms`), values(`read_at_ms`), `read_at_ms`),' + . ' `updated_at_ms` = values(`updated_at_ms`)' + ); + $statement->execute([$groupId, $userId, $timestamp, $now]); +} + +function webGroupRole(PDO $appDb, string $userId, string $groupId): string +{ + $statement = $appDb->prepare( + 'select `role` from `t_web_group_members`' + . ' where `group_id` = ? and `user_id` = ? and `status` = 0 limit 1' + ); + $statement->execute([$groupId, $userId]); + $role = $statement->fetchColumn(); + + return is_string($role) && $role !== '' ? $role : ''; +} + +function formatWebGroupMessage( + array $row, + string $currentUserId, + array $group, + ?array $attachment = null, + array $users = [] +): array +{ + $groupId = (string)$row['group_id']; + $from = (string)$row['sender_uid']; + $senderUser = $users[$from] ?? []; + $senderAlias = trim((string)($row['sender_alias'] ?? '')); + $senderContactAlias = trim((string)($senderUser['_alias'] ?? '')); + $senderFriendAlias = trim((string)($senderUser['_friend_alias'] ?? '')); + $senderRemarkAlias = trim((string)($senderUser['_remark_alias'] ?? '')); + $senderRawName = trim((string)($senderUser['_display_name'] ?? '')) + ?: trim((string)($senderUser['_name'] ?? '')) + ?: trim((string)($senderUser['_mobile'] ?? '')) + ?: $from; + $senderName = $senderContactAlias + ?: $senderAlias + ?: $senderRawName; + $senderRole = (string)($row['sender_role'] ?? 'member'); + if (!in_array($senderRole, ['owner', 'admin'], true)) { + $senderRole = 'member'; + } + $timestamp = (int)$row['created_at_ms']; + $editedAt = (int)($row['edited_at_ms'] ?? 0); + $activityTimestamp = max($timestamp, $editedAt); + $direction = $from === $currentUserId ? 'out' : 'in'; + + $messageType = $attachment ? (string)$attachment['type'] : 'text'; + $contentType = $messageType === 'image' ? 3 : ($messageType === 'file' ? 5 : 1); + return [ + 'id' => (string)$row['message_uid'], + 'messageUid' => (string)$row['message_uid'], + 'conversationId' => 'group-' . $groupId, + 'from' => $from, + 'senderRole' => $senderRole, + 'senderName' => $senderName, + 'senderPortrait' => (string)($senderUser['_portrait'] ?? ''), + 'senderProfile' => [ + 'uid' => $from, + 'displayName' => $senderName, + 'rawName' => $senderRawName, + 'contactAlias' => $senderContactAlias, + 'friendAlias' => $senderFriendAlias, + 'remarkAlias' => $senderRemarkAlias, + 'groupAlias' => $senderAlias, + 'isContact' => (bool)($senderUser['_is_friend'] ?? false), + 'mobile' => (string)($senderUser['_mobile'] ?? ''), + 'address' => (string)($senderUser['_address'] ?? ''), + 'portrait' => (string)($senderUser['_portrait'] ?? ''), + 'role' => $senderRole, + ], + 'to' => $groupId, + 'target' => $groupId, + 'direction' => $direction, + 'type' => $messageType, + 'contentType' => $contentType, + 'text' => attachmentDisplayText((string)$row['text'], $attachment), + 'attachment' => $attachment, + 'status' => $direction === 'out' ? 'sent' : 'sent', + 'deliveryStatus' => $direction === 'out' ? 'sent' : '', + 'recalled' => false, + 'recallStatus' => '', + 'editedAt' => $editedAt, + 'timestamp' => $timestamp, + 'activityTimestamp' => $activityTimestamp, + 'displayTimestamp' => $timestamp, + 'conversationType' => (string)($group['category'] ?? 'group'), + ]; +} + +function loadWebGroupMessages(PDO $appDb, string $userId, string $groupId, int $limit, bool $markRead): array +{ + ensureWebImAppTables(); + $role = webGroupRole($appDb, $userId, $groupId); + if ($role === '') { + return []; + } + + $groupStatement = $appDb->prepare('select * from `t_web_groups` where `group_id` = ? and `deleted` = 0 limit 1'); + $groupStatement->execute([$groupId]); + $group = $groupStatement->fetch(); + if (!$group) { + return []; + } + + $statement = $appDb->prepare( + 'select msg.*,' + . ' coalesce(sender_member.`role`, if(g.`owner_uid` = msg.`sender_uid`, "owner", "member")) as `sender_role`,' + . ' coalesce(sender_member.`alias`, "") as `sender_alias`' + . ' from `t_web_group_messages` msg' + . ' join `t_web_groups` g on g.`group_id` = msg.`group_id` and g.`deleted` = 0' + . ' left join `t_web_group_members` sender_member' + . ' on sender_member.`group_id` = msg.`group_id`' + . ' and sender_member.`user_id` = msg.`sender_uid`' + . ' and sender_member.`status` = 0' + . ' where msg.`group_id` = ? and msg.`recalled` = 0' + . ' order by msg.`created_at_ms` desc, msg.`id` desc limit ' . $limit + ); + $statement->execute([$groupId]); + $rows = array_reverse($statement->fetchAll()); + $attachmentMap = fetchAttachmentMap($appDb, array_column($rows, 'message_uid')); + $users = fetchUserInfoMap(imDb(), array_column($rows, 'sender_uid'), $userId); + + $readTimestamp = 0; + $messages = []; + foreach ($rows as $row) { + $messageId = (string)$row['message_uid']; + $message = formatWebGroupMessage($row, $userId, $group, $attachmentMap[$messageId] ?? null, $users); + $readTimestamp = max($readTimestamp, (int)$message['activityTimestamp']); + $messages[] = $message; + } + + if ($markRead) { + markWebGroupRead($appDb, $userId, $groupId, $readTimestamp); + } + + return $messages; +} + +function loadWebGroupConversations(PDO $appDb, string $userId, int $limit): array +{ + ensureWebImAppTables(); + $statement = $appDb->prepare( + 'select g.*, m.`role`' + . ' from `t_web_groups` g' + . ' join `t_web_group_members` m on m.`group_id` = g.`group_id` and m.`status` = 0' + . ' where g.`deleted` = 0 and m.`user_id` = ?' + . ' order by g.`updated_at_ms` desc limit ' . min(max($limit, 50), 100) + ); + $statement->execute([$userId]); + $groups = $statement->fetchAll(); + if (!$groups) { + return []; + } + + $lastMessageStatement = $appDb->prepare( + 'select * from `t_web_group_messages`' + . ' where `group_id` = ? and `recalled` = 0' + . ' order by greatest(`created_at_ms`, `edited_at_ms`) desc, `id` desc limit 1' + ); + $readStatement = $appDb->prepare( + 'select `read_at_ms` from `t_web_group_reads` where `group_id` = ? and `user_id` = ? limit 1' + ); + $lastAttachmentStatement = $appDb->prepare( + 'select `attachment_type`, `url`, `name`, `mime`, `size_bytes`' + . ' from `t_web_message_attachments` where `message_uid` = ? limit 1' + ); + $unreadStatement = $appDb->prepare( + 'select count(*) from `t_web_group_messages`' + . ' where `group_id` = ? and `sender_uid` <> ? and `recalled` = 0' + . ' and greatest(`created_at_ms`, `edited_at_ms`) > ?' + ); + $memberCountStatement = $appDb->prepare( + 'select count(*) from `t_web_group_members` where `group_id` = ? and `status` = 0' + ); + + $conversations = []; + foreach ($groups as $group) { + $groupId = (string)$group['group_id']; + $lastMessageStatement->execute([$groupId]); + $lastMessage = $lastMessageStatement->fetch(); + $readStatement->execute([$groupId, $userId]); + $readAt = (int)($readStatement->fetchColumn() ?: 0); + $unreadStatement->execute([$groupId, $userId, $readAt]); + $unread = (int)$unreadStatement->fetchColumn(); + $memberCountStatement->execute([$groupId]); + $memberCount = (int)$memberCountStatement->fetchColumn(); + + $title = (string)$group['name']; + $category = (string)$group['category']; + $isChannel = $category === 'channel'; + $lastAttachment = null; + if ($lastMessage) { + $lastAttachmentStatement->execute([(string)$lastMessage['message_uid']]); + $lastAttachmentRow = $lastAttachmentStatement->fetch(); + $lastAttachment = $lastAttachmentRow ? normalizeAttachmentRow($lastAttachmentRow) : null; + } + $subtitle = $lastMessage + ? (messagePreviewText([ + 'text' => attachmentDisplayText((string)$lastMessage['text'], $lastAttachment), + 'attachment' => $lastAttachment, + ]) ?: (string)$lastMessage['text']) + : ($isChannel ? '公告群' : ($memberCount > 0 ? $memberCount . ' 位成员' : '群组')); + $updatedAt = $lastMessage + ? max((int)$lastMessage['created_at_ms'], (int)($lastMessage['edited_at_ms'] ?? 0)) + : (int)$group['updated_at_ms']; + + $conversations[] = [ + 'id' => 'group-' . $groupId, + 'type' => $isChannel ? 'channel' : 'group', + 'target' => $groupId, + 'title' => $title, + 'subtitle' => $subtitle, + 'unread' => $unread, + 'avatarText' => mb_strtoupper(mb_substr($title, 0, 1, 'UTF-8'), 'UTF-8'), + 'updatedAt' => $updatedAt, + 'role' => (string)$group['role'], + 'memberCount' => $memberCount, + 'raw' => [ + 'type' => 'group', + 'target' => $groupId, + 'line' => 0, + 'category' => $category, + 'role' => (string)$group['role'], + ], + ]; + } + + return $conversations; +} + +function isRecallMessage(array $row): bool +{ + return (int)($row['_content_type'] ?? 0) === 80; +} + +function shouldDisplayMessageForUser(array $row, string $currentUserId): bool +{ + if (!isRecallMessage($row)) { + return true; + } + + return (string)$row['_from'] === $currentUserId; +} + +function formatMessage( + array $row, + string $currentUserId, + string $peerId, + array $receiptState = [], + array $editState = [], + ?array $attachment = null +): array +{ + $messageId = (string)$row['_mid']; + $from = (string)$row['_from']; + $contentType = (int)($row['_content_type'] ?? 0); + $isRecalled = $contentType === 80; + $text = (string)($row['_searchable_key'] ?? ''); + $timestamp = timestampMs((string)($row['_dt'] ?? ''), $messageId); + $direction = $from === $currentUserId ? 'out' : 'in'; + $messageType = $attachment ? (string)$attachment['type'] : (($contentType === 1 || $isRecalled) ? 'text' : 'unknown'); + $messageText = $text !== '' ? $text : ($isRecalled || $attachment ? '' : '[暂不支持的消息类型]'); + $messageText = attachmentDisplayText($messageText, $attachment); + $editedAt = (int)($editState['editedAt'] ?? 0); + $activityTimestamp = messageActivityTimestamp($timestamp, $editState); + $deliveryStatus = $direction === 'out' && !$isRecalled + ? outgoingDeliveryStatus($activityTimestamp, $receiptState) + : ''; + + return [ + 'id' => $messageId, + 'messageUid' => $messageId, + 'conversationId' => 'single-' . $peerId, + 'from' => $from, + 'to' => $from === $currentUserId ? $peerId : $currentUserId, + 'target' => $peerId, + 'direction' => $direction, + 'type' => $messageType, + 'contentType' => $attachment ? ((string)$attachment['type'] === 'image' ? 3 : 5) : $contentType, + 'text' => $messageText, + 'attachment' => $attachment, + 'status' => $isRecalled && $direction === 'out' ? 'recalled' : ($direction === 'out' ? $deliveryStatus : 'sent'), + 'deliveryStatus' => $deliveryStatus, + 'recalled' => $isRecalled, + 'recallStatus' => $isRecalled ? '已撤回' : '', + 'editedAt' => $editedAt, + 'timestamp' => $timestamp, + 'activityTimestamp' => $activityTimestamp, + 'displayTimestamp' => $timestamp, + ]; +} + +function loadConversationMessages(PDO $db, string $userId, string $targetId, int $limit, bool $markRead): array +{ + $table = imUserMessagesTable($userId); + $conversationKeys = [$userId . '|' . $targetId, $targetId . '|' . $userId]; + $scanLimit = min(max($limit * 4, $limit), 400); + $statement = $db->prepare( + 'select `_mid`, `_dt` from `' . $table . '`' + . ' where `_uid` = ? and `_type` = 0 and `_line` = 0' + . ' and `_target` in (?, ?)' + . ' order by `_mid` desc limit ' . $scanLimit + ); + $statement->execute([$userId, $conversationKeys[0], $conversationKeys[1]]); + $userRows = $statement->fetchAll(); + $messageRows = fetchMessageRows($db, array_column($userRows, '_mid')); + $editMap = fetchMessageEditMap($db, array_column($userRows, '_mid')); + $attachmentMap = fetchAttachmentMap(imAppDb(), array_column($userRows, '_mid')); + $receiptState = loadPeerReceiptState($db, $userId, $targetId); + + $messages = []; + $seenMessageIds = []; + $readTimestamp = 0; + foreach ($userRows as $userRow) { + $messageId = (string)$userRow['_mid']; + if (isset($seenMessageIds[$messageId]) || !isset($messageRows[$messageId])) { + continue; + } + $seenMessageIds[$messageId] = true; + if (!shouldDisplayMessageForUser($messageRows[$messageId], $userId)) { + continue; + } + $message = formatMessage( + $messageRows[$messageId], + $userId, + $targetId, + $receiptState, + $editMap[$messageId] ?? [], + $attachmentMap[$messageId] ?? null + ); + $messages[] = $message; + $readTimestamp = max($readTimestamp, (int)$message['activityTimestamp']); + if (count($messages) >= $limit) { + break; + } + } + $messages = array_reverse($messages); + + if ($markRead) { + markConversationRead($db, $userId, $targetId, $readTimestamp); + } + + return $messages; +} + +function loadRecentConversations(PDO $db, string $userId, int $limit): array +{ + $table = imUserMessagesTable($userId); + $scanLimit = min(max($limit * 20, 200), 1000); + $statement = $db->prepare( + 'select `_mid`, `_target`, `_dt` from `' . $table . '`' + . ' where `_uid` = ? and `_type` = 0 and `_line` = 0' + . ' order by `_mid` desc limit ' . $scanLimit + ); + $statement->execute([$userId]); + + $scanRows = $statement->fetchAll(); + $messageRows = fetchMessageRows($db, array_column($scanRows, '_mid')); + $editMap = fetchMessageEditMap($db, array_column($scanRows, '_mid')); + $attachmentMap = fetchAttachmentMap(imAppDb(), array_column($scanRows, '_mid')); + $latestByPeer = []; + foreach ($scanRows as $row) { + $messageId = (string)$row['_mid']; + $message = $messageRows[$messageId] ?? null; + $peerId = peerFromConversationTarget($userId, (string)$row['_target']); + if ($peerId === '' || !$message) { + continue; + } + if (!shouldDisplayMessageForUser($message, $userId)) { + continue; + } + $activityTimestamp = messageActivityTimestamp( + timestampMs((string)($message['_dt'] ?? ''), $messageId), + $editMap[$messageId] ?? [] + ); + if (!isset($latestByPeer[$peerId]) || $activityTimestamp > (int)($latestByPeer[$peerId]['_activity_at'] ?? 0)) { + $row['_activity_at'] = $activityTimestamp; + $latestByPeer[$peerId] = $row; + } + } + uasort($latestByPeer, static fn($a, $b) => (int)($b['_activity_at'] ?? 0) <=> (int)($a['_activity_at'] ?? 0)); + $latestByPeer = array_slice($latestByPeer, 0, $limit, true); + + $users = fetchUserInfoMap($db, array_keys($latestByPeer), $userId); + $readAtByPeer = loadOwnReadStateMap($db, $userId, array_keys($latestByPeer)); + $unreadByPeer = []; + $seenUnreadMessageIds = []; + + foreach ($scanRows as $row) { + $messageId = (string)$row['_mid']; + if (isset($seenUnreadMessageIds[$messageId])) { + continue; + } + $seenUnreadMessageIds[$messageId] = true; + $peerId = peerFromConversationTarget($userId, (string)$row['_target']); + $message = $messageRows[$messageId] ?? null; + if ($peerId === '' || !$message || !isset($latestByPeer[$peerId])) { + continue; + } + if ((string)$message['_from'] === $userId) { + continue; + } + if (isRecallMessage($message)) { + continue; + } + $timestamp = timestampMs((string)($message['_dt'] ?? ''), $messageId); + $activityTimestamp = messageActivityTimestamp($timestamp, $editMap[$messageId] ?? []); + if ($activityTimestamp > (int)($readAtByPeer[$peerId] ?? 0)) { + $unreadByPeer[$peerId] = (int)($unreadByPeer[$peerId] ?? 0) + 1; + } + } + + $conversations = []; + + foreach ($latestByPeer as $peerId => $userRow) { + $messageId = (string)$userRow['_mid']; + $message = isset($messageRows[$messageId]) + ? formatMessage($messageRows[$messageId], $userId, $peerId, [], $editMap[$messageId] ?? [], $attachmentMap[$messageId] ?? null) + : null; + $title = userTitle($users, $peerId); + $conversations[] = [ + 'id' => 'single-' . $peerId, + 'type' => 'single', + 'target' => $peerId, + 'title' => $title, + 'subtitle' => $message ? (messagePreviewText($message) !== '' ? messagePreviewText($message) : (empty($message['recalled']) ? '' : '已撤回')) : '', + 'unread' => (int)($unreadByPeer[$peerId] ?? 0), + 'portrait' => (string)($users[$peerId]['_portrait'] ?? ''), + 'avatarText' => mb_strtoupper(mb_substr($title, 0, 1, 'UTF-8'), 'UTF-8'), + 'updatedAt' => $message ? $message['activityTimestamp'] : timestampMs((string)($userRow['_dt'] ?? ''), $messageId), + 'raw' => ['type' => 'single', 'target' => $peerId, 'line' => 0], + ]; + } + + try { + $conversations = array_merge($conversations, loadWebGroupConversations(imAppDb(), $userId, $limit)); + } catch (Throwable) { + // Keep single-chat sync available if appdata group metadata is temporarily unavailable. + } + + usort($conversations, static fn($a, $b) => $b['updatedAt'] <=> $a['updatedAt']); + + return array_slice($conversations, 0, $limit); +} + +$payload = readJsonPayload(); +$userId = trim((string)($payload['userId'] ?? '')); +$target = trim((string)($payload['target'] ?? '')); +$limit = clampLimit($payload['limit'] ?? 50, 50, 100); +$markRead = payloadBool($payload['markRead'] ?? false); +$conversationType = normalizeConversationType($payload['conversationType'] ?? $payload['type'] ?? 0); + +if ($userId === '') { + respond(400, '缺少用户ID'); +} + +try { + $db = imDb(); + $userId = resolveUserId($db, $userId); + markUserDelivered($db, $userId, nowMs()); + + if ($target !== '') { + $targetId = resolveUserId($db, $target); + if ($conversationType === 'group' || isWebGroupTarget(imAppDb(), $target)) { + respond(0, 'success', [ + 'messages' => loadWebGroupMessages(imAppDb(), $userId, $target, $limit, $markRead), + ]); + } + respond(0, 'success', [ + 'messages' => loadConversationMessages($db, $userId, $targetId, $limit, $markRead), + ]); + } + + respond(0, 'success', [ + 'conversations' => loadRecentConversations($db, $userId, $limit), + ]); +} catch (Throwable $error) { + respond(500, $error->getMessage() ?: '消息同步失败'); +} diff --git a/dist/api/platform_config.php b/dist/api/platform_config.php new file mode 100644 index 0000000..af63018 --- /dev/null +++ b/dist/api/platform_config.php @@ -0,0 +1,39 @@ +prepare( + 'select `conf_name`, `conf_value`, `updated_at` from `system_conf` where `conf_name` in (?, ?)' + ); + $statement->execute(['PlatformName', 'sys_logo']); + + $config = []; + $updatedAtValues = []; + foreach ($statement->fetchAll() as $row) { + $config[(string)$row['conf_name']] = trim((string)($row['conf_value'] ?? '')); + $updatedAtValues[] = (string)($row['updated_at'] ?? ''); + } + + $platformName = $config['PlatformName'] ?? ''; + $logo = $config['sys_logo'] ?? ''; + $version = implode('|', array_values(array_filter($updatedAtValues ?? []))); + + respond(0, 'success', [ + 'platformName' => $platformName !== '' ? $platformName : $defaultName, + 'logo' => $logo !== '' ? $logo : $defaultLogo, + 'version' => $version, + ]); +} catch (Throwable $error) { + respond(500, $error->getMessage() ?: '平台配置加载失败', [ + 'platformName' => $defaultName, + 'logo' => $defaultLogo, + ]); +} diff --git a/dist/api/profile.php b/dist/api/profile.php new file mode 100644 index 0000000..cb3a75e --- /dev/null +++ b/dist/api/profile.php @@ -0,0 +1,321 @@ + $uid, + 'userId' => $uid, + 'name' => (string)($user['name'] ?? $user['_name'] ?? ''), + 'displayName' => (string)($user['displayName'] ?? $user['_display_name'] ?? $user['name'] ?? $user['_name'] ?? $uid), + 'mobile' => (string)($user['mobile'] ?? $user['_mobile'] ?? ''), + 'portrait' => (string)($user['portrait'] ?? $user['_portrait'] ?? ''), + 'address' => (string)($user['address'] ?? $user['_address'] ?? ''), + ]; +} + +function tryProfileUserInfo(array $payload): ?array +{ + try { + $result = requireImSuccess(imAdminPost('/admin/user/get_info', $payload), '用户资料加载失败'); + return $result ?: null; + } catch (Throwable) { + return null; + } +} + +function loadProfileUserFromDb(string $identity): ?array +{ + $statement = imDb()->prepare( + 'select `_uid`, `_name`, `_display_name`, `_mobile`, `_portrait`, `_address`' + . ' from `t_user` where `_uid` = ? or `_mobile` = ? or `_name` = ?' + . ' order by case when `_uid` = ? then 0 when `_mobile` = ? then 1 when `_name` = ? then 2 else 3 end' + . ' limit 1' + ); + $statement->execute([$identity, $identity, $identity, $identity, $identity, $identity]); + $row = $statement->fetch(); + return $row ? normalizeProfileUser($row) : null; +} + +function mergeProfileUser(array $primary, ?array $fallback): array +{ + if (!$fallback) { + return $primary; + } + + $fallback = normalizeProfileUser($fallback); + foreach (['name', 'displayName', 'mobile', 'portrait', 'address'] as $key) { + if ((string)($primary[$key] ?? '') === '' && (string)($fallback[$key] ?? '') !== '') { + $primary[$key] = (string)$fallback[$key]; + } + } + + return $primary; +} + +function persistProfileUserToDb(string $userId, string $displayName, string $portrait): void +{ + if ($portrait !== '') { + $statement = imDb()->prepare( + 'update `t_user` set `_display_name` = ?, `_portrait` = ?, `_dt` = ? where `_uid` = ? limit 1' + ); + $statement->execute([$displayName, $portrait, webImNowMs(), $userId]); + return; + } + + $statement = imDb()->prepare( + 'update `t_user` set `_display_name` = ?, `_dt` = ? where `_uid` = ? limit 1' + ); + $statement->execute([$displayName, webImNowMs(), $userId]); +} + +function loadProfileUser(string $identity, bool $preferMobile = true): array +{ + $identity = trim($identity); + if ($identity === '') { + respond(400, '缺少用户ID'); + } + + $dbUser = loadProfileUserFromDb($identity); + if ($dbUser) { + $fallback = null; + if ((string)($dbUser['portrait'] ?? '') === '') { + $fallback = tryProfileUserInfo(['userId' => $dbUser['userId']]); + if (!$fallback && (string)($dbUser['mobile'] ?? '') !== '') { + $fallback = tryProfileUserInfo(['mobile' => $dbUser['mobile']]); + } + if (!$fallback && (string)($dbUser['name'] ?? '') !== '') { + $fallback = tryProfileUserInfo(['name' => $dbUser['name']]); + } + } + + return mergeProfileUser($dbUser, $fallback); + } + + $user = null; + if ($preferMobile && preg_match('/^\+?\d{5,32}$/', $identity)) { + $user = tryProfileUserInfo(['mobile' => $identity]); + } + if (!$user) { + $user = tryProfileUserInfo(['userId' => $identity]); + } + if (!$user) { + $user = tryProfileUserInfo(['name' => $identity]); + } + if (!$user) { + respond(404, '用户资料不存在'); + } + + return normalizeProfileUser($user); +} + +function readProfileJavaSerializedString(string $data, int $offset): ?array +{ + if ($offset + 3 > strlen($data) || ord($data[$offset]) !== 0x74) { + return null; + } + + $length = (ord($data[$offset + 1]) << 8) | ord($data[$offset + 2]); + $start = $offset + 3; + if ($start + $length > strlen($data)) { + return null; + } + + return [substr($data, $start, $length), $start + $length]; +} + +function profileSessionUserId(string $sessionData): string +{ + $marker = "\x74\x00\x06userId"; + $offset = strpos($sessionData, $marker); + if ($offset === false) { + return ''; + } + + $decoded = readProfileJavaSerializedString($sessionData, $offset + strlen($marker)); + $userId = is_array($decoded) ? (string)$decoded[0] : ''; + if (!preg_match('/^[A-Za-z0-9_:@.+-]{1,128}$/', $userId)) { + return ''; + } + + return $userId; +} + +function requireProfileUpdateAuth(string $targetUserId): void +{ + $authToken = trim((string)($_SERVER['HTTP_AUTHTOKEN'] ?? $_SERVER['HTTP_AUTH_TOKEN'] ?? '')); + if ($authToken === '') { + respond(401, '请重新登录后再修改资料'); + } + + $statement = imAppDb()->prepare('select `session_data` from `shiro_session` where `session_id` = ? limit 1'); + $statement->execute([$authToken]); + $row = $statement->fetch(); + if (!$row) { + respond(401, '登录状态已失效,请重新登录'); + } + + $sessionUserId = profileSessionUserId((string)$row['session_data']); + if ($sessionUserId === '' || $sessionUserId !== $targetUserId) { + respond(403, '只能修改自己的资料'); + } +} + +function profileUploadedFileExtension(string $fileName, string $mime): string +{ + $extension = strtolower((string)pathinfo($fileName, PATHINFO_EXTENSION)); + $extension = preg_replace('/[^a-z0-9]/', '', $extension) ?: ''; + if ($extension === 'jpeg') { + $extension = 'jpg'; + } + + $allowedExtensions = ['jpg', 'png', 'gif', 'webp', 'bmp', 'ico']; + if (in_array($extension, $allowedExtensions, true)) { + return $extension; + } + + return match ($mime) { + 'image/jpeg' => 'jpg', + 'image/png' => 'png', + 'image/gif' => 'gif', + 'image/webp' => 'webp', + 'image/bmp', 'image/x-ms-bmp' => 'bmp', + 'image/x-icon', 'image/vnd.microsoft.icon' => 'ico', + default => 'jpg', + }; +} + +function profilePublicMediaBaseUrl(): string +{ + $isHttps = (string)($_SERVER['HTTPS'] ?? '') !== '' && strtolower((string)$_SERVER['HTTPS']) !== 'off'; + $scheme = $isHttps ? 'https' : 'http'; + $host = (string)($_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? '127.0.0.1'); + $host = trim(preg_replace('/:\d+$/', '', $host) ?: '127.0.0.1'); + + return $scheme . '://' . $host . ':' . IM_LOCAL_MEDIA_PUBLIC_PORT; +} + +function uploadProfilePortrait(array $file): string +{ + if (($file['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) { + throw new RuntimeException('头像上传失败'); + } + if (($file['size'] ?? 0) <= 0 || ($file['size'] ?? 0) > 5 * 1024 * 1024) { + throw new RuntimeException('头像不能超过5MB'); + } + + $tmpName = (string)($file['tmp_name'] ?? ''); + $mime = mime_content_type($tmpName) ?: ''; + if (!str_starts_with($mime, 'image/')) { + throw new RuntimeException('头像必须是图片文件'); + } + + if (!is_dir(IM_LOCAL_MEDIA_ROOT) || !is_writable(IM_LOCAL_MEDIA_ROOT)) { + throw new RuntimeException('头像存储目录不可写'); + } + + $datePath = 'fs/' . PROFILE_PORTRAIT_MEDIA_TYPE . '/' . date('Y/m/d/H/i/s'); + $targetDir = rtrim(IM_LOCAL_MEDIA_ROOT, '/') . '/' . $datePath; + if (!is_dir($targetDir) && !mkdir($targetDir, 0775, true)) { + throw new RuntimeException('头像存储目录创建失败'); + } + + $extension = profileUploadedFileExtension((string)($file['name'] ?? 'avatar.jpg'), $mime); + $targetName = bin2hex(random_bytes(12)) . '.' . $extension; + $targetPath = $targetDir . '/' . $targetName; + if (!move_uploaded_file($tmpName, $targetPath)) { + throw new RuntimeException('头像文件保存失败'); + } + @chmod($targetPath, 0644); + + return profilePublicMediaBaseUrl() . '/' . $datePath . '/' . $targetName; +} + +try { + $contentType = (string)($_SERVER['CONTENT_TYPE'] ?? ''); + $isMultipart = stripos($contentType, 'multipart/form-data') !== false; + $payload = $isMultipart ? [] : readJsonPayload(); + $action = $isMultipart + ? profileRequestValue('action', 'update') + : trim((string)($payload['action'] ?? 'get')); + $userId = $isMultipart + ? profileRequestValue('userId') + : trim((string)($payload['userId'] ?? $_GET['userId'] ?? '')); + + $currentProfile = loadProfileUser($userId); + + if ($action === 'get') { + respond(0, 'success', ['profile' => $currentProfile]); + } + + if ($action !== 'update') { + respond(400, '不支持的资料操作'); + } + requireProfileUpdateAuth((string)$currentProfile['userId']); + + $displayName = $isMultipart + ? profileRequestValue('displayName') + : trim((string)($payload['displayName'] ?? '')); + if ($displayName === '') { + respond(400, '昵称不能为空'); + } + if (mb_strlen($displayName, 'UTF-8') > 64) { + respond(400, '昵称不能超过64个字'); + } + + $portrait = ''; + if (!empty($_FILES['portraitFile']) && ($_FILES['portraitFile']['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_NO_FILE) { + $portrait = uploadProfilePortrait($_FILES['portraitFile']); + } + + $flag = PROFILE_DISPLAY_NAME_FLAG; + $userInfo = [ + 'userId' => $currentProfile['userId'], + 'displayName' => $displayName, + ]; + if ($portrait !== '') { + $flag |= PROFILE_PORTRAIT_FLAG; + $userInfo['portrait'] = $portrait; + } + + requireImSuccess( + imAdminPost('/admin/user/update', [ + 'flag' => $flag, + 'userInfo' => $userInfo, + ]), + '用户资料保存失败' + ); + persistProfileUserToDb($currentProfile['userId'], $displayName, $portrait); + + $updatedProfile = loadProfileUser($currentProfile['userId'], false); + if ($portrait === '' && (string)$updatedProfile['portrait'] === '' && (string)($currentProfile['portrait'] ?? '') !== '') { + $updatedProfile['portrait'] = (string)$currentProfile['portrait']; + } + if ($portrait !== '' && (string)$updatedProfile['portrait'] === '') { + $updatedProfile['portrait'] = $portrait; + } + if ((string)$updatedProfile['displayName'] === '') { + $updatedProfile['displayName'] = $displayName; + } + + respond(0, 'success', ['profile' => $updatedProfile]); +} catch (Throwable $error) { + respond(500, $error->getMessage() ?: '用户资料服务暂不可用'); +} diff --git a/dist/api/register_config.php b/dist/api/register_config.php new file mode 100644 index 0000000..887de79 --- /dev/null +++ b/dist/api/register_config.php @@ -0,0 +1,18 @@ + 0, + 'message' => 'success', + 'data' => [ + 'methods' => [ + 'phone' => true, + 'email' => false, + 'username' => false, + ], + 'mobile_real_verify' => false, + ], +], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); diff --git a/dist/api/send_message.php b/dist/api/send_message.php new file mode 100644 index 0000000..c06af18 --- /dev/null +++ b/dist/api/send_message.php @@ -0,0 +1,411 @@ +setTimezone(new DateTimeZone(IM_DB_TIMEZONE)); + $currentMinutes = ((int)$now->format('H')) * 60 + (int)$now->format('i'); + [$startHour, $startMinute] = array_map('intval', explode(':', $dailyStart)); + [$endHour, $endMinute] = array_map('intval', explode(':', $dailyEnd)); + $startMinutes = $startHour * 60 + $startMinute; + $endMinutes = $endHour * 60 + $endMinute; + if ($startMinutes === $endMinutes) { + return true; + } + if ($startMinutes < $endMinutes) { + return $currentMinutes >= $startMinutes && $currentMinutes < $endMinutes; + } + + return $currentMinutes >= $startMinutes || $currentMinutes < $endMinutes; +} + +function isGroupMutedForSender(PDO $appDb, string $groupId, string $role, int $nowMs): bool +{ + if ($role === 'owner') { + return false; + } + + $statement = $appDb->prepare('select * from `t_web_group_mute_rules` where `group_id` = ? and `enabled` = 1 limit 1'); + $statement->execute([$groupId]); + $rule = $statement->fetch(); + if (!is_array($rule)) { + return false; + } + + $mode = (string)$rule['mode']; + if ($mode === 'off') { + return false; + } + if ($mode === 'all_except_admins' && $role === 'admin') { + return false; + } + if (!in_array($mode, ['all_include_admins', 'all_except_admins'], true)) { + return false; + } + + $scheduleType = (string)$rule['schedule_type']; + if ($scheduleType === 'manual') { + return true; + } + if ($scheduleType === 'daily') { + return isDailyMuteActive((string)$rule['daily_start'], (string)$rule['daily_end'], $nowMs); + } + + $startsAtMs = (int)$rule['starts_at_ms']; + $endsAtMs = (int)$rule['ends_at_ms']; + return $startsAtMs > 0 && $endsAtMs > $startsAtMs && $nowMs >= $startsAtMs && $nowMs < $endsAtMs; +} + +function messageRequestValue(array $payload, string $key, string $default = ''): string +{ + return trim((string)($_POST[$key] ?? $payload[$key] ?? $default)); +} + +function safeUploadName(string $fileName): string +{ + $name = basename(str_replace('\\', '/', $fileName)); + $name = preg_replace('/[^\p{L}\p{N}._ -]+/u', '_', $name) ?: 'file'; + $name = trim($name, " .\t\n\r\0\x0B"); + + return $name !== '' ? mb_substr($name, 0, 180, 'UTF-8') : 'file'; +} + +function uploadExtension(string $fileName, string $mime, string $attachmentType): string +{ + $extension = strtolower((string)pathinfo($fileName, PATHINFO_EXTENSION)); + $extension = preg_replace('/[^a-z0-9]/', '', $extension) ?: ''; + if ($extension === 'jpeg') { + $extension = 'jpg'; + } + + if ($attachmentType === 'image') { + if (in_array($extension, ['jpg', 'png', 'gif', 'webp', 'bmp', 'svg', 'avif', 'heic', 'heif'], true)) { + return $extension; + } + return match ($mime) { + 'image/jpeg' => 'jpg', + 'image/png' => 'png', + 'image/gif' => 'gif', + 'image/webp' => 'webp', + 'image/bmp', 'image/x-ms-bmp' => 'bmp', + 'image/svg+xml' => 'svg', + 'image/avif' => 'avif', + 'image/heic' => 'heic', + 'image/heif' => 'heif', + default => 'jpg', + }; + } + + if ($extension !== '') { + return $extension; + } + + return 'bin'; +} + +function detectedUploadMime(string $tmpName): string +{ + $mime = mime_content_type($tmpName) ?: ''; + if ($mime !== '' && $mime !== 'application/octet-stream') { + return $mime; + } + + $imageInfo = @getimagesize($tmpName); + if (is_array($imageInfo) && !empty($imageInfo['mime'])) { + return (string)$imageInfo['mime']; + } + + return $mime !== '' ? $mime : 'application/octet-stream'; +} + +function normalizedImageUploadMime(string $tmpName, string $mime): string +{ + if (str_starts_with($mime, 'image/')) { + return $mime; + } + + $imageInfo = @getimagesize($tmpName); + $imageMime = is_array($imageInfo) ? (string)($imageInfo['mime'] ?? '') : ''; + if ($imageMime !== '' && str_starts_with($imageMime, 'image/')) { + return $imageMime; + } + + throw new RuntimeException('请选择图片文件'); +} + +function mediaPublicBaseUrl(): string +{ + $isHttps = (string)($_SERVER['HTTPS'] ?? '') !== '' && strtolower((string)$_SERVER['HTTPS']) !== 'off'; + $scheme = $isHttps ? 'https' : 'http'; + $host = trim(preg_replace('/:\d+$/', '', (string)($_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? '127.0.0.1')) ?: '127.0.0.1'); + + return $scheme . '://' . $host . ':' . WEB_MEDIA_PUBLIC_PORT; +} + +function saveMessageAttachmentFile(array $file, string $attachmentType): array +{ + if (($file['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) { + throw new RuntimeException('文件上传失败'); + } + $size = (int)($file['size'] ?? 0); + $maxSize = $attachmentType === 'image' ? WEB_IMAGE_MAX_BYTES : WEB_FILE_MAX_BYTES; + if ($size <= 0 || $size > $maxSize) { + throw new RuntimeException($attachmentType === 'image' ? '图片不能超过10MB' : '文件不能超过50MB'); + } + if (!is_dir(WEB_MEDIA_ROOT) || !is_writable(WEB_MEDIA_ROOT)) { + throw new RuntimeException('媒体存储目录不可写'); + } + + $tmpName = (string)($file['tmp_name'] ?? ''); + if ($tmpName === '' || !is_uploaded_file($tmpName)) { + throw new RuntimeException('文件上传失败'); + } + $mime = detectedUploadMime($tmpName); + if ($attachmentType === 'image') { + $mime = normalizedImageUploadMime($tmpName, $mime); + } + + $mediaType = $attachmentType === 'image' ? WEB_MEDIA_TYPE_IMAGE : WEB_MEDIA_TYPE_FILE; + $datePath = 'fs/' . $mediaType . '/' . date('Y/m/d/H/i/s'); + $targetDir = rtrim(WEB_MEDIA_ROOT, '/') . '/' . $datePath; + if (!is_dir($targetDir) && !mkdir($targetDir, 0775, true)) { + throw new RuntimeException('媒体存储目录创建失败'); + } + + $originalName = safeUploadName((string)($file['name'] ?? ($attachmentType === 'image' ? 'image.jpg' : 'file'))); + $extension = uploadExtension($originalName, $mime, $attachmentType); + $targetName = bin2hex(random_bytes(12)) . '.' . $extension; + $targetPath = $targetDir . '/' . $targetName; + if (!move_uploaded_file($tmpName, $targetPath)) { + throw new RuntimeException('文件保存失败'); + } + @chmod($targetPath, 0644); + + return [ + 'type' => $attachmentType, + 'url' => mediaPublicBaseUrl() . '/' . $datePath . '/' . $targetName, + 'name' => $originalName, + 'mime' => $mime, + 'size' => $size, + 'mediaType' => $mediaType, + ]; +} + +function storeMessageAttachment( + PDO $appDb, + string $messageUid, + string $conversationType, + string $target, + string $sender, + array $attachment, + int $timestamp +): void { + if ($messageUid === '' || empty($attachment['url'])) { + return; + } + + $statement = $appDb->prepare( + 'insert into `t_web_message_attachments`' + . ' (`message_uid`, `conversation_type`, `target_id`, `sender_uid`, `attachment_type`, `url`, `name`, `mime`, `size_bytes`, `created_at_ms`)' + . ' values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)' + . ' on duplicate key update' + . ' `attachment_type` = values(`attachment_type`),' + . ' `url` = values(`url`),' + . ' `name` = values(`name`),' + . ' `mime` = values(`mime`),' + . ' `size_bytes` = values(`size_bytes`)' + ); + $statement->execute([ + $messageUid, + $conversationType, + $target, + $sender, + (string)$attachment['type'], + (string)$attachment['url'], + (string)$attachment['name'], + (string)$attachment['mime'], + (int)$attachment['size'], + $timestamp, + ]); +} + +function attachmentFromRequest(string $messageType): ?array +{ + if (!in_array($messageType, ['image', 'file'], true)) { + return null; + } + + $attachmentFile = $_FILES['attachment'] ?? $_FILES['file'] ?? null; + if (!is_array($attachmentFile)) { + respond(400, '缺少上传文件'); + } + + return saveMessageAttachmentFile($attachmentFile, $messageType); +} + +$contentTypeHeader = (string)($_SERVER['CONTENT_TYPE'] ?? ''); +$isMultipart = stripos($contentTypeHeader, 'multipart/form-data') !== false; +$payload = $isMultipart ? [] : readJsonPayload(); +$sender = messageRequestValue($payload, 'sender'); +$target = messageRequestValue($payload, 'target'); +$text = messageRequestValue($payload, 'text'); +$messageType = messageRequestValue($payload, 'messageType', 'text'); +$conversationType = $_POST['conversationType'] ?? $_POST['type'] ?? $payload['conversationType'] ?? $payload['type'] ?? 0; +$isGroupConversation = in_array((string)$conversationType, ['1', 'group', 'channel'], true); +$attachment = null; + +if ($sender === '' || $target === '' || ($text === '' && !in_array($messageType, ['image', 'file'], true))) { + respond(400, '缺少发送者、接收者或消息内容'); +} + +try { + if ($isGroupConversation) { + ensureWebImAppTables(); + $appDb = imAppDb(); + $memberStatement = $appDb->prepare( + 'select g.`group_id`, g.`category`, g.`owner_uid`, m.`role`' + . ' from `t_web_groups` g' + . ' join `t_web_group_members` m on m.`group_id` = g.`group_id` and m.`status` = 0' + . ' where g.`deleted` = 0 and g.`group_id` = ? and m.`user_id` = ?' + . ' limit 1' + ); + $memberStatement->execute([$target, $sender]); + $group = $memberStatement->fetch(); + if (!$group) { + respond(403, '你不在该群组中'); + } + $category = (string)($group['category'] ?? 'group'); + $role = (string)($group['role'] ?? 'member'); + if ($category === 'channel' && !in_array($role, ['owner', 'admin'], true)) { + respond(403, '公告群仅管理员可发言'); + } + + $now = webImNowMs(); + if ($category !== 'channel' && isGroupMutedForSender($appDb, $target, $role, $now)) { + respond(403, '当前群组处于禁言时段'); + } + $attachment = attachmentFromRequest($messageType); + $messageUid = webImMessageUid(); + $insert = $appDb->prepare( + 'insert into `t_web_group_messages`' + . ' (`message_uid`, `group_id`, `sender_uid`, `text`, `created_at_ms`, `edited_at_ms`, `recalled`)' + . ' values (?, ?, ?, ?, ?, 0, 0)' + ); + $insert->execute([$messageUid, $target, $sender, $text, $now]); + if ($attachment) { + storeMessageAttachment($appDb, $messageUid, 'group', $target, $sender, $attachment, $now); + } + $updateGroup = $appDb->prepare('update `t_web_groups` set `updated_at_ms` = ? where `group_id` = ?'); + $updateGroup->execute([$now, $target]); + + $nativeError = ''; + try { + $pushContent = $text !== '' + ? $text + : ($attachment + ? ((string)$attachment['type'] === 'image' ? '[图片]' : '[文件] ' . (string)$attachment['name']) + : $text); + $payloadBody = [ + 'type' => $attachment ? ((string)$attachment['type'] === 'image' ? 3 : 5) : 1, + 'searchableContent' => $pushContent, + 'pushContent' => $pushContent, + 'content' => $text, + 'persistFlag' => 3, + ]; + if ($attachment) { + $payloadBody['mediaType'] = (int)$attachment['mediaType']; + $payloadBody['remoteMediaUrl'] = (string)$attachment['url']; + $payloadBody['extra'] = json_encode([ + 'name' => (string)$attachment['name'], + 'mime' => (string)$attachment['mime'], + 'size' => (int)$attachment['size'], + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + } + requireImSuccess(imAdminPost('/admin/message/send', [ + 'sender' => $sender, + 'conv' => [ + 'type' => 1, + 'target' => $target, + 'line' => 0, + ], + 'payload' => $payloadBody, + 'userMessage' => true, + ]), '原生群消息发送失败'); + } catch (Throwable $error) { + $nativeError = $error->getMessage() ?: '原生群消息发送失败'; + } + + respond(0, 'success', [ + 'messageUid' => $messageUid, + 'timestamp' => $now, + 'senderRole' => $role, + 'attachment' => $attachment, + 'nativeError' => $nativeError, + ]); + } + + $attachment = attachmentFromRequest($messageType); + $pushContent = $text !== '' + ? $text + : ($attachment + ? ((string)$attachment['type'] === 'image' ? '[图片]' : '[文件] ' . (string)$attachment['name']) + : $text); + $payloadBody = [ + 'type' => $attachment ? ((string)$attachment['type'] === 'image' ? 3 : 5) : 1, + 'searchableContent' => $pushContent, + 'pushContent' => $pushContent, + 'content' => $text, + 'persistFlag' => 3, + ]; + if ($attachment) { + $payloadBody['mediaType'] = (int)$attachment['mediaType']; + $payloadBody['remoteMediaUrl'] = (string)$attachment['url']; + $payloadBody['extra'] = json_encode([ + 'name' => (string)$attachment['name'], + 'mime' => (string)$attachment['mime'], + 'size' => (int)$attachment['size'], + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + } + + $result = requireImSuccess(imAdminPost('/admin/message/send', [ + 'sender' => $sender, + 'conv' => [ + 'type' => 0, + 'target' => $target, + 'line' => 0, + ], + 'payload' => $payloadBody, + 'userMessage' => true, + ]), '发送失败'); + + $messageUid = isset($result['messageUid']) ? (string)$result['messageUid'] : ''; + $timestamp = (int)($result['timestamp'] ?? webImNowMs()); + if ($attachment && $messageUid !== '') { + ensureWebImAppTables(); + storeMessageAttachment(imAppDb(), $messageUid, 'single', $target, $sender, $attachment, $timestamp); + } + + respond(0, 'success', [ + 'messageUid' => $messageUid !== '' ? $messageUid : null, + 'timestamp' => $timestamp, + 'attachment' => $attachment, + ]); +} catch (Throwable $error) { + respond(500, $error->getMessage() ?: '发送失败'); +} diff --git a/dist/api/update_alias.php b/dist/api/update_alias.php new file mode 100644 index 0000000..7f3be6c --- /dev/null +++ b/dist/api/update_alias.php @@ -0,0 +1,61 @@ + 32) { + respond(400, '备注名不能超过32个字'); +} + +try { + ensureWebImAppTables(); + $imDb = imDb(); + $exists = $imDb->prepare('select 1 from `t_user` where `_uid` = ? limit 1'); + $exists->execute([$targetId]); + if (!$exists->fetchColumn()) { + respond(404, '没有找到该用户'); + } + + $friend = $imDb->prepare('select 1 from `t_friend` where `_uid` = ? and `_friend_uid` = ? limit 1'); + $friend->execute([$userId, $targetId]); + $isContact = (bool)$friend->fetchColumn(); + + if ($isContact) { + requireImSuccess( + imAdminPost('/admin/friend/set_alias', [ + 'operator' => $userId, + 'targetId' => $targetId, + 'alias' => $alias, + ]), + '备注名修改失败' + ); + } + saveWebUserRemark(imAppDb(), $userId, $targetId, $alias); + + respond(0, 'success', [ + 'contact' => [ + 'uid' => $targetId, + 'alias' => $alias, + 'isContact' => $isContact, + ], + ]); +} catch (Throwable $error) { + respond(500, $error->getMessage() ?: '备注名服务暂不可用'); +} diff --git a/dist/config/runtime-config.js b/dist/config/runtime-config.js new file mode 100644 index 0000000..2728254 --- /dev/null +++ b/dist/config/runtime-config.js @@ -0,0 +1,12 @@ +window.JC_WEB_IM_CONFIG = { + adminServer: 'http://winchen.ezpay.asia:8024', + appServer: 'http://winchen.ezpay.asia:8888', + qrAppServer: 'http://winchen.ezpay.asia:18888', + platformConfigApi: '/api/platform_config.php', + registerConfigApi: 'http://winchen.ezpay.asia:8024/api/register-config', + imServerHost: 'winchen.ezpay.asia', + imRoutePort: 18000, + useWss: false, + wsPath: '/ws', + sdkMode: 'http' +}; diff --git a/dist/css/app.5af3ef7e.css b/dist/css/app.5af3ef7e.css new file mode 100644 index 0000000..753c543 --- /dev/null +++ b/dist/css/app.5af3ef7e.css @@ -0,0 +1,3048 @@ +:root { + color-scheme: light; + --bg: #f4f6f8; + --panel: #ffffff; + --panel-soft: #f8fafc; + --line: #d9e0e7; + --text: #18212f; + --muted: #6a7584; + --primary: #177d72; + --primary-strong: #0f625a; + --accent: #d84e3f; + --bubble-in: #ffffff; + --bubble-out: #dff4ef; + --rail: #202a33; +} + +* { + box-sizing: border-box; +} + +html, +body, +#app { + width: 100%; + height: 100%; + overflow: hidden; +} + +body { + margin: 0; + min-width: 320px; + background: var(--bg); + color: var(--text); + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; +} + +button, +input, +textarea { + font: inherit; +} + +button { + cursor: pointer; +} + +.login-page { + min-height: 100vh; + display: grid; + place-items: center; + padding: 24px; + background: linear-gradient(135deg, #eef6f3 0%, #f7f3ee 55%, #eef2f7 100%); +} + +.login-panel { + width: min(420px, 100%); + padding: 32px; + background: var(--panel); + border: 1px solid var(--line); + border-radius: 8px; + box-shadow: 0 18px 48px rgba(30, 40, 50, 0.12); +} + +.brand-lockup { + display: flex; + align-items: center; + gap: 14px; + margin-bottom: 28px; +} + +.brand-mark, +.rail-avatar, +.conversation-avatar { + display: grid; + place-items: center; + flex: 0 0 auto; +} + +.image-avatar { + -o-object-fit: cover; + object-fit: cover; +} + +.brand-mark { + width: 48px; + height: 48px; + border-radius: 8px; + -o-object-fit: contain; + object-fit: contain; + background: #fff; +} + +.brand-lockup h1, +.list-header h2, +.chat-header h2 { + margin: 0; + font-size: 20px; +} + +.brand-lockup p, +.list-header p, +.chat-header p { + margin: 4px 0 0; + color: var(--muted); + font-size: 13px; +} + +.login-form { + display: grid; + gap: 16px; +} + +.login-tabs, +.code-row, +.phone-row, +.captcha-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 8px; +} + +.login-tabs button, +.code-action { + height: 38px; + border: 1px solid var(--line); + border-radius: 6px; + background: #fff; + color: var(--text); +} + +.login-tabs button.active { + border-color: var(--primary); + background: #e8f4f2; + color: var(--primary-strong); + font-weight: 700; +} + +.login-tabs { + grid-template-columns: repeat(3, minmax(0, 1fr)); +} + +.login-tabs button { + min-width: 0; + padding: 0 6px; + overflow-wrap: anywhere; +} + +.code-row { + grid-template-columns: minmax(0, 1fr) 112px; +} + +.captcha-row { + grid-template-columns: minmax(0, 1fr) 112px; +} + +.phone-row { + grid-template-columns: 86px minmax(0, 1fr); +} + +.country-code-field { + height: 42px; + display: grid; + grid-template-columns: 24px minmax(0, 1fr); + align-items: center; + border: 1px solid var(--line); + border-radius: 6px; + background: #fff; + color: var(--text); + overflow: hidden; +} + +.country-code-field:focus-within { + border-color: var(--primary); + box-shadow: 0 0 0 3px rgba(23, 125, 114, 0.12); +} + +.country-code-field span { + display: grid; + place-items: center; + color: var(--muted); + font-weight: 700; +} + +.code-action:disabled { + cursor: not-allowed; + opacity: 0.55; +} + +.login-form label { + display: grid; + gap: 8px; + color: var(--muted); + font-size: 13px; +} + +.label-row { + min-height: 18px; + display: grid; + grid-template-columns: 86px minmax(0, 1fr); + align-items: center; + gap: 8px; +} + +.field-error-badge { + min-height: 28px; + display: grid; + place-items: center; + padding: 4px 10px; + border-radius: 2px; + background: var(--accent); + color: #fff; + font-weight: 700; + line-height: 1.2; + text-align: center; +} + +.login-form input, +.login-form select, +.modal-panel input, +.modal-panel textarea, +.search-box input, +.message-composer textarea { + width: 100%; + border: 1px solid var(--line); + border-radius: 6px; + outline: none; + background: #fff; + color: var(--text); +} + +.login-form input, +.login-form select, +.modal-panel input, +.search-box input { + height: 42px; + padding: 0 12px; +} + +.modal-panel textarea { + min-height: 92px; + resize: vertical; + padding: 10px 12px; + line-height: 1.5; +} + +.login-form .country-code-field input { + height: 40px; + padding: 0 10px 0 0; + border: 0; + border-radius: 0; +} + +.login-form .country-code-field input:focus { + border-color: transparent; + box-shadow: none; +} + +.login-form input:focus, +.login-form select:focus, +.modal-panel input:focus, +.modal-panel textarea:focus, +.search-box input:focus, +.message-composer textarea:focus { + border-color: var(--primary); + box-shadow: 0 0 0 3px rgba(23, 125, 114, 0.12); +} + +.login-form input.captcha-input-valid { + border-color: var(--primary); + background: var(--primary); + color: #fff; + font-weight: 700; +} + +.login-form input.captcha-input-valid::-moz-placeholder { + color: rgba(255, 255, 255, 0.75); +} + +.login-form input.captcha-input-valid::placeholder { + color: rgba(255, 255, 255, 0.75); +} + +.login-form input.captcha-input-invalid { + border-color: var(--accent); + color: var(--accent); + box-shadow: 0 0 0 3px rgba(216, 78, 63, 0.12); +} + +.login-form input.field-input-error { + border-color: var(--accent); + color: var(--accent); + box-shadow: 0 0 0 3px rgba(216, 78, 63, 0.12); +} + +.login-form input.field-input-error::-moz-placeholder { + color: rgba(216, 78, 63, 0.78); +} + +.login-form input.field-input-error::placeholder { + color: rgba(216, 78, 63, 0.78); +} + +.captcha-button { + width: 112px; + height: 42px; + padding: 0; + border: 1px solid var(--line); + border-radius: 6px; + background: #f7fbfa; + overflow: hidden; +} + +.captcha-button img { + display: block; + width: 100%; + height: 100%; + -o-object-fit: contain; + object-fit: contain; +} + +.qr-login-card { + position: relative; + width: min(248px, 100%); + aspect-ratio: 1; + display: grid; + place-items: center; + justify-self: center; + border: 1px solid var(--line); + border-radius: 8px; + background: #fff; + overflow: hidden; +} + +.qr-code-button { + width: 100%; + height: 100%; + display: grid; + place-items: center; + padding: 18px; + border: 0; + background: #fff; + color: var(--muted); + font-weight: 700; +} + +.qr-code-button:disabled { + cursor: default; +} + +.qr-code-button img { + width: 100%; + height: 100%; + -o-object-fit: contain; + object-fit: contain; + image-rendering: pixelated; +} + +.qr-login-card.scanned .qr-code-button, +.qr-login-card.expired .qr-code-button, +.qr-login-card.error .qr-code-button { + opacity: 0.22; +} + +.qr-scan-user { + position: absolute; + inset: 0; + display: grid; + place-items: center; + background: rgba(255, 255, 255, 0.76); +} + +.qr-scan-user img, +.qr-scan-user span { + width: 70px; + height: 70px; + display: grid; + place-items: center; + border-radius: 8px; + background: var(--primary); + color: #fff; + font-size: 28px; + font-weight: 800; + -o-object-fit: cover; + object-fit: cover; +} + +.qr-login-status { + min-height: 48px; + display: grid; + gap: 4px; + text-align: center; +} + +.qr-login-status strong { + color: var(--text); + font-size: 15px; +} + +.qr-login-status span { + color: var(--muted); + font-size: 13px; +} + +.primary-action, +.primary-inline-action, +.send-button { + border: 0; + border-radius: 6px; + background: var(--primary); + color: #fff; + font-weight: 700; +} + +.primary-action { + height: 44px; +} + +.primary-action:hover, +.primary-inline-action:hover, +.send-button:hover { + background: var(--primary-strong); +} + +.primary-action:disabled, +.primary-inline-action:disabled, +.send-button:disabled { + cursor: not-allowed; + opacity: 0.55; +} + +.ghost-action { + width: 100%; + height: 40px; + margin-top: 12px; + border: 1px solid var(--line); + border-radius: 6px; + background: #fff; + color: var(--text); +} + +.ghost-inline-action, +.primary-inline-action, +.danger-inline-action { + height: 38px; + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0 16px; + border-radius: 6px; + font-weight: 700; + line-height: 1; +} + +.ghost-inline-action { + border: 1px solid var(--line); + background: #fff; + color: var(--text); +} + +.ghost-inline-action:hover { + background: #edf2f5; +} + +.danger-inline-action { + border: 1px solid #ef4444; + background: #fff; + color: #b91c1c; +} + +.danger-inline-action:hover { + background: #fee2e2; +} + +.form-error { + margin: 0; + color: var(--accent); + font-size: 13px; +} + +.form-info { + margin: 0; + color: var(--muted); + font-size: 13px; +} + +.app-shell { + height: 100dvh; + min-height: 0; + display: grid; + grid-template-columns: 64px minmax(260px, 340px) minmax(0, 1fr); + overflow: hidden; + background: var(--panel); +} + +.documented-shell { + min-height: 100dvh; + display: grid; + grid-template-columns: 260px minmax(0, 1fr); + background: + radial-gradient(circle at top left, rgba(23, 125, 114, 0.08), transparent 28%), + linear-gradient(180deg, #f4f8f7 0%, #eef3f7 100%); +} + +.documented-rail { + min-height: 0; + display: grid; + align-content: start; + gap: 14px; + padding: 24px 20px; + border-right: 1px solid var(--line); + background: rgba(255, 255, 255, 0.82); + backdrop-filter: blur(12px); +} + +.documented-avatar { + width: 64px; + height: 64px; + display: grid; + place-items: center; + overflow: hidden; + border-radius: 16px; + background: #dff4ef; + color: var(--primary-strong); + font-size: 28px; + font-weight: 800; +} + +.documented-avatar img { + width: 100%; + height: 100%; + -o-object-fit: cover; + object-fit: cover; +} + +.documented-rail-copy { + display: grid; + gap: 4px; +} + +.documented-rail-copy strong { + font-size: 16px; +} + +.documented-rail-copy small { + color: var(--muted); + overflow-wrap: anywhere; +} + +.documented-rail-button { + min-height: 40px; + padding: 0 14px; + border: 0; + border-radius: 10px; + background: var(--primary); + color: #fff; + font-weight: 700; + text-align: left; +} + +.documented-rail-button.ghost { + border: 1px solid var(--line); + background: #fff; + color: var(--text); +} + +.documented-main { + min-width: 0; + min-height: 0; + overflow: auto; + padding: 28px; + display: grid; + align-content: start; + gap: 18px; +} + +.documented-header { + display: flex; + align-items: end; + justify-content: space-between; + gap: 18px; +} + +.documented-header h1 { + margin: 0; + font-size: 28px; +} + +.documented-header p { + margin: 6px 0 0; + color: var(--muted); +} + +.documented-status { + min-width: 180px; + display: grid; + gap: 4px; + padding: 14px 16px; + border: 1px solid var(--line); + border-radius: 14px; + background: rgba(255, 255, 255, 0.88); +} + +.documented-status span { + color: var(--muted); + font-size: 12px; +} + +.documented-status strong { + font-size: 15px; +} + +.documented-card { + display: grid; + gap: 12px; + padding: 20px; + border: 1px solid var(--line); + border-radius: 16px; + background: rgba(255, 255, 255, 0.88); + box-shadow: 0 16px 36px rgba(24, 33, 47, 0.06); +} + +.documented-card h2 { + margin: 0; + font-size: 18px; +} + +.documented-text { + margin: 0; + color: var(--muted); + line-height: 1.6; +} + +.documented-list { + margin: 0; + padding-left: 18px; + display: grid; + gap: 8px; + line-height: 1.55; +} + +.documented-list.muted { + color: var(--muted); +} + +.documented-meta { + margin: 0; + display: grid; + gap: 10px; +} + +.documented-meta div { + display: grid; + grid-template-columns: 110px minmax(0, 1fr); + gap: 12px; + padding-top: 10px; + border-top: 1px solid var(--line); +} + +.documented-meta dt { + color: var(--muted); +} + +.documented-meta dd { + margin: 0; + overflow-wrap: anywhere; +} + +.documented-password-panel { + width: min(100%, 360px); +} + +.navigation-rail { + min-height: 0; + display: flex; + flex-direction: column; + align-items: center; + gap: 14px; + padding: 16px 10px; + background: var(--rail); +} + +.rail-avatar { + width: 40px; + height: 40px; + border-radius: 8px; + background: #e9f7f4; + color: var(--primary-strong); + font-weight: 800; + overflow: hidden; +} + +.rail-avatar-button { + position: relative; + border: 0; + padding: 0; + cursor: pointer; +} + +.rail-avatar-button::after { + content: "+"; + position: absolute; + right: -2px; + bottom: -2px; + width: 15px; + height: 15px; + display: grid; + place-items: center; + border: 1px solid var(--rail); + border-radius: 50%; + background: var(--primary); + color: #fff; + font-size: 11px; + font-weight: 800; + line-height: 1; +} + +.rail-avatar-button:hover, +.rail-avatar-button:focus-visible { + box-shadow: 0 0 0 3px rgba(47, 196, 178, 0.28); +} + +.rail-avatar img { + width: 100%; + height: 100%; + -o-object-fit: cover; + object-fit: cover; +} + +.rail-button, +.icon-button { + display: grid; + place-items: center; + border: 0; + border-radius: 6px; + background: transparent; +} + +.rail-button { + width: 40px; + height: 40px; + color: #dbe5ea; + font-size: 18px; +} + +.rail-button svg { + width: 22px; + height: 22px; + fill: none; + stroke: currentColor; + stroke-width: 1.8; + stroke-linecap: round; + stroke-linejoin: round; +} + +.rail-button.active, +.rail-button:hover { + background: rgba(255, 255, 255, 0.12); +} + +.rail-logout-button:hover { + background: rgba(239, 68, 68, 0.2); + color: #fecaca; +} + +.rail-spacer { + flex: 1; +} + +.conversation-list { + position: relative; + min-height: 0; + display: grid; + grid-template-rows: 72px auto minmax(0, 1fr); + border-right: 1px solid var(--line); + background: var(--panel-soft); + overflow: hidden; +} + +.modal-backdrop { + position: absolute; + inset: 0; + z-index: 5; + display: grid; + place-items: start center; + padding: 88px 16px 16px; + background: rgba(24, 33, 47, 0.28); +} + +.modal-panel { + width: min(100%, 308px); + display: grid; + gap: 14px; + padding: 16px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--panel); + box-shadow: 0 18px 40px rgba(24, 33, 47, 0.18); +} + +.modal-panel header, +.modal-actions { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; +} + +.modal-panel header strong { + font-size: 16px; +} + +.modal-panel label { + display: grid; + gap: 8px; + color: var(--muted); + font-size: 13px; +} + +.settings-backdrop { + z-index: 24; + place-items: center; + padding: 24px 16px; +} + +.settings-panel { + width: min(620px, calc(100vw - 32px)); + max-height: calc(100dvh - 48px); + display: grid; + gap: 14px; + overflow: auto; + padding: 16px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--panel); + box-shadow: 0 18px 40px rgba(24, 33, 47, 0.18); +} + +.settings-panel header, +.settings-password-form footer { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; +} + +.settings-panel header strong { + font-size: 16px; +} + +.settings-layout { + display: grid; + grid-template-columns: 170px minmax(0, 1fr); + gap: 14px; +} + +.settings-menu { + display: grid; + align-content: start; + gap: 8px; +} + +.settings-menu button { + min-height: 46px; + display: grid; + gap: 2px; + justify-items: start; + padding: 8px 10px; + border: 1px solid var(--line); + border-radius: 6px; + background: #fff; + color: var(--text); + text-align: left; +} + +.settings-menu button.active, +.settings-menu button:hover { + border-color: var(--primary); + background: #e8f4f2; + color: var(--primary-strong); +} + +.settings-menu button span { + font-weight: 700; +} + +.settings-menu button small { + color: var(--muted); + font-size: 11px; +} + +.settings-password-form, +.settings-placeholder { + min-height: 250px; + display: grid; + align-content: start; + gap: 12px; +} + +.settings-password-form h3, +.settings-placeholder h3 { + margin: 0; + font-size: 16px; +} + +.settings-password-form label { + display: grid; + gap: 8px; + color: var(--muted); + font-size: 13px; +} + +.settings-password-form input { + width: 100%; + height: 42px; + padding: 0 12px; + border: 1px solid var(--line); + border-radius: 6px; + outline: none; + background: #fff; + color: var(--text); +} + +.settings-password-form input:focus { + border-color: var(--primary); + box-shadow: 0 0 0 3px rgba(23, 125, 114, 0.12); +} + +.settings-password-form footer { + margin-top: 4px; + justify-content: flex-end; + flex-wrap: wrap; +} + +.settings-password-form footer .inline-save-status { + margin-right: auto; +} + +.settings-placeholder { + place-items: center; + border: 1px dashed var(--line); + border-radius: 8px; + color: var(--muted); + text-align: center; +} + +.settings-placeholder p { + margin: 0; +} + +.profile-edit-panel { + width: min(100%, 360px); +} + +.profile-avatar-field { + display: grid; + justify-items: center; + gap: 10px; +} + +.profile-avatar-field input[type="file"] { + position: absolute; + inline-size: 1px; + block-size: 1px; + opacity: 0; + pointer-events: none; +} + +.profile-avatar-preview { + width: 88px; + height: 88px; + display: grid; + place-items: center; + overflow: hidden; + padding: 0; + border: 0; + border-radius: 8px; + background: #dce8f2; + color: #24435c; + cursor: default; + font-size: 30px; + font-weight: 800; +} + +.profile-avatar-preview.clickable { + cursor: zoom-in; +} + +.profile-avatar-preview.clickable:hover { + box-shadow: 0 0 0 3px rgba(23, 125, 114, 0.16); +} + +.profile-avatar-preview img { + width: 100%; + height: 100%; + -o-object-fit: cover; + object-fit: cover; +} + +.profile-avatar-change-button { + min-width: 96px; +} + +.avatar-preview-backdrop { + z-index: 32; + place-items: center; + padding: 24px 16px; +} + +.avatar-preview-dialog { + width: min(520px, calc(100vw - 32px)); + max-height: calc(100dvh - 48px); + display: grid; + gap: 12px; + padding: 14px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--panel); + box-shadow: 0 18px 40px rgba(24, 33, 47, 0.18); +} + +.avatar-preview-dialog header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; +} + +.avatar-preview-actions { + display: flex; + align-items: center; + gap: 6px; +} + +.avatar-preview-actions button { + min-width: 34px; + height: 34px; + display: inline-flex; + align-items: center; + justify-content: center; + border: 1px solid var(--line); + border-radius: 6px; + background: #fff; + color: var(--text); + font-weight: 700; +} + +.avatar-preview-actions .icon-button { + border: 0; + color: var(--muted); +} + +.avatar-preview-stage { + height: min(430px, calc(100dvh - 160px)); + min-height: 260px; + display: grid; + place-items: center; + overflow: hidden; + border-radius: 8px; + background: #101820; + cursor: zoom-in; + touch-action: none; +} + +.avatar-preview-stage.dragging { + cursor: grabbing; +} + +.avatar-preview-stage img { + max-width: min(100%, 430px); + max-height: 100%; + border-radius: 8px; + -o-object-fit: contain; + object-fit: contain; + transform-origin: center center; + transition: transform 0.08s ease-out; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + pointer-events: none; +} + +.avatar-preview-stage.dragging img { + transition: none; +} + +.avatar-cropper-backdrop { + z-index: 30; + place-items: center; + padding: 24px 16px; +} + +.avatar-cropper-panel { + width: min(720px, calc(100vw - 32px)); + max-height: calc(100dvh - 48px); + overflow: auto; +} + +.avatar-cropper-header-actions { + display: flex; + align-items: center; + gap: 8px; +} + +.avatar-cropper-layout { + display: grid; + grid-template-columns: minmax(0, 1fr) 190px; + gap: 14px; +} + +.avatar-cropper-stage { + position: relative; + height: 360px; + min-height: 360px; + overflow: hidden; + border: 1px dashed #b8ccd7; + border-radius: 8px; + background: #0f1b24; + touch-action: none; + cursor: grab; +} + +.avatar-cropper-stage.dragging { + cursor: grabbing; +} + +.avatar-cropper-stage canvas { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + display: block; +} + +.avatar-cropper-box { + position: absolute; + left: 50%; + top: 50%; + width: 74%; + aspect-ratio: 1; + max-width: calc(100% - 44px); + max-height: calc(100% - 44px); + transform: translate(-50%, -50%); + border: 2px dashed var(--primary); + border-radius: 8px; + box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.72); + pointer-events: none; +} + +.avatar-cropper-mask { + position: absolute; + inset: 0; + pointer-events: none; +} + +.avatar-cropper-placeholder { + position: absolute; + inset: 0; + display: grid; + place-items: center; + color: #d9e8ee; + font-size: 13px; + pointer-events: none; +} + +.avatar-cropper-controls { + min-width: 0; + display: grid; + align-content: start; + gap: 12px; +} + +.avatar-cropper-tools { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 8px; +} + +.avatar-cropper-tools button { + min-height: 34px; + padding: 0 10px; + border: 1px solid var(--line); + border-radius: 6px; + background: #fff; + color: var(--text); + font-weight: 700; +} + +.avatar-cropper-tools button:hover { + border-color: var(--primary); + color: var(--primary-strong); +} + +.avatar-cropper-preview { + width: 108px; + height: 108px; + justify-self: center; + overflow: hidden; + border: 1px solid var(--line); + border-radius: 8px; + background: #eef4f7; +} + +.avatar-cropper-preview canvas { + width: 100%; + height: 100%; + display: block; +} + +.avatar-cropper-controls footer { + display: flex; + align-items: center; + justify-content: flex-end; + flex-wrap: wrap; + gap: 8px; +} + +.avatar-cropper-controls footer .inline-save-status { + flex: 1 1 100%; +} + +.modal-actions { + justify-content: flex-end; +} + +.list-header, +.chat-header { + display: flex; + align-items: center; + justify-content: space-between; + min-height: 72px; + padding: 16px 18px; + border-bottom: 1px solid var(--line); +} + +.icon-button { + width: 34px; + height: 34px; + color: var(--muted); + font-size: 20px; +} + +.icon-button:hover { + background: #edf2f5; + color: var(--text); +} + +.search-box { + padding: 12px 14px; +} + +.sidebar-scroll { + min-height: 0; + overflow: auto; + overscroll-behavior: contain; +} + +.conversation-item { + width: 100%; + display: grid; + grid-template-columns: 42px minmax(0, 1fr) auto; + align-items: center; + gap: 10px; + padding: 12px 14px; + border: 0; + border-top: 1px solid rgba(217, 224, 231, 0.7); + background: transparent; + color: inherit; + text-align: left; +} + +.conversation-item.active, +.conversation-item:hover { + background: #eaf3f1; +} + +.favorite-item { + width: 100%; + display: grid; + grid-template-columns: 32px minmax(0, 1fr) auto; + align-items: center; + gap: 10px; + padding: 12px 14px; + border: 0; + border-top: 1px solid rgba(217, 224, 231, 0.7); + background: transparent; + color: inherit; + text-align: left; +} + +.favorite-item.active, +.favorite-item:hover { + background: #eaf3f1; +} + +.favorite-item-icon { + width: 32px; + height: 32px; + display: grid; + place-items: center; + border-radius: 6px; + background: #fff7df; + color: #c79520; + font-size: 16px; +} + +.favorite-item-main { + min-width: 0; + display: grid; + gap: 4px; +} + +.favorite-item-main strong, +.favorite-item-main small { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.favorite-item-main strong { + font-size: 14px; +} + +.favorite-item-main small, +.favorite-item time { + color: var(--muted); + font-size: 12px; +} + +.favorite-panel { + min-width: 0; + min-height: 0; + display: grid; + grid-template-rows: auto minmax(0, 1fr); + background: #eef3f6; +} + +.favorite-detail { + min-height: 0; + display: grid; + align-content: start; + gap: 16px; + padding: 28px; + overflow: auto; +} + +.favorite-detail-message { + width: min(680px, 100%); + display: grid; + grid-template-columns: auto minmax(0, 1fr); + gap: 10px 12px; + padding: 18px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--panel); + box-shadow: 0 8px 24px rgba(24, 33, 47, 0.08); +} + +.favorite-detail-message.recalled { + border-color: #f1c7c1; + background: #fff7f6; +} + +.favorite-detail-star { + color: #c79520; + font-size: 18px; + line-height: 1.4; +} + +.favorite-detail-body { + min-width: 0; + display: grid; + gap: 10px; +} + +.favorite-detail-message p { + margin: 0; + white-space: pre-wrap; + overflow-wrap: anywhere; + line-height: 1.55; +} + +.favorite-detail-message time { + grid-column: 2; + color: var(--muted); + font-size: 12px; +} + +.favorite-detail-image { + width: min(420px, 100%); + display: block; + overflow: hidden; + border: 1px solid #b9ded8; + border-radius: 8px; + background: #fff; +} + +.favorite-detail-image img { + display: block; + width: 100%; + max-height: 360px; + -o-object-fit: contain; + object-fit: contain; + background: #f8fbfc; +} + +.favorite-detail-file { + width: min(360px, 100%); +} + +.favorite-detail-actions { + width: min(680px, 100%); + display: flex; + align-items: center; + justify-content: flex-end; + gap: 8px; +} + +.favorite-detail-actions .inline-save-status { + margin-right: auto; +} + +.empty-list, +.empty-chat { + display: grid; + place-items: center; + align-content: center; + gap: 8px; + color: var(--muted); + text-align: center; +} + +.empty-list { + min-height: 180px; + padding: 24px; +} + +.empty-chat { + min-height: 0; + padding: 24px; +} + +.empty-list strong, +.empty-chat strong { + color: var(--text); +} + +.conversation-avatar { + width: 42px; + height: 42px; + border-radius: 8px; + background: #dce8f2; + color: #24435c; + font-weight: 700; +} + +.conversation-copy { + min-width: 0; + display: grid; + gap: 4px; +} + +.conversation-copy strong, +.conversation-copy small { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.conversation-copy small { + color: var(--muted); +} + +.unread-badge { + justify-self: end; + min-width: 20px; + height: 20px; + padding: 0 6px; + border-radius: 999px; + background: #ef4444; + color: #fff; + font-size: 12px; + font-weight: 800; + line-height: 20px; + text-align: center; + box-shadow: 0 0 0 2px #f7fafc; +} + +.chat-panel { + position: relative; + min-width: 0; + min-height: 0; + height: 100%; + display: grid; + grid-template-rows: 72px minmax(0, 1fr) auto auto; + overflow: hidden; + background: #eef2f5; +} + +.contact-panel { + min-width: 0; + min-height: 0; + height: 100%; + display: grid; + grid-template-rows: 72px minmax(0, 1fr); + overflow: auto; + background: #eef2f5; +} + +.contact-profile { + align-self: start; + width: min(520px, calc(100% - 48px)); + margin: 48px auto; + display: grid; + justify-items: center; + gap: 18px; + padding: 32px; + background: var(--panel); + border: 1px solid var(--line); + border-radius: 8px; +} + +.profile-avatar { + width: 76px; + height: 76px; + display: grid; + place-items: center; + border-radius: 8px; + background: #dce8f2; + color: #24435c; + font-size: 28px; + font-weight: 800; +} + +.profile-main { + text-align: center; +} + +.remark-row { + min-width: 0; + display: flex; + align-items: center; + justify-content: center; + gap: 8px; +} + +.profile-main h3 { + margin: 0; + font-size: 22px; + overflow-wrap: anywhere; +} + +.remark-edit-button { + width: 32px; + height: 32px; + flex: 0 0 auto; + font-size: 16px; +} + +.profile-main p { + margin: 6px 0 0; + color: var(--muted); +} + +.profile-fields { + width: 100%; + display: grid; + gap: 12px; + margin: 0; +} + +.profile-fields div { + display: grid; + grid-template-columns: 80px minmax(0, 1fr); + gap: 12px; + padding: 10px 0; + border-top: 1px solid var(--line); +} + +.profile-fields dt { + color: var(--muted); +} + +.profile-fields dd { + margin: 0; + overflow-wrap: anywhere; +} + +.profile-action { + width: 160px; +} + +.contact-panel .contact-modal-backdrop { + position: fixed; +} + +.header-actions { + display: flex; + gap: 8px; +} + +.chat-header-actions { + position: relative; +} + +.chat-title-button { + display: grid; + grid-template-columns: 38px minmax(0, 1fr); + align-items: center; + gap: 10px; + max-width: min(460px, 52vw); + padding: 0; + border: 0; + background: transparent; + color: var(--text); + text-align: left; +} + +.chat-title-avatar { + width: 38px; + height: 38px; + display: grid; + place-items: center; + border-radius: 8px; + background: #dce8f2; + color: #24435c; + font-size: 16px; + font-weight: 800; +} + +.chat-title-copy { + min-width: 0; +} + +.chat-title-button h2 { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.chat-title-button:hover h2 { + color: var(--primary-strong); +} + +.chat-more-menu { + top: 38px; + width: 150px; +} + +.action-menu-anchor { + position: relative; +} + +.quick-action-menu { + position: absolute; + top: 40px; + right: 0; + z-index: 7; + width: 168px; + display: grid; + padding: 6px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--panel); + box-shadow: 0 14px 34px rgba(24, 33, 47, 0.16); +} + +.quick-action-menu button { + height: 34px; + padding: 0 10px; + border: 0; + border-radius: 6px; + background: transparent; + color: var(--text); + text-align: left; +} + +.quick-action-menu button:hover { + background: #edf2f5; +} + +.quick-action-menu.chat-more-menu { + top: 38px; + width: 150px; +} + +.conversation-action-panel { + width: min(100%, 340px); + max-height: calc(100dvh - 116px); + overflow: auto; +} + +.contact-picker { + display: grid; + gap: 10px; +} + +.contact-picker > input { + width: 100%; + height: 38px; + padding: 0 10px; + border: 1px solid var(--line); + border-radius: 6px; + outline: none; +} + +.contact-picker-list { + max-height: 220px; + overflow: auto; + display: grid; + gap: 6px; + padding-right: 2px; +} + +.contact-picker-row { + width: 100%; + min-height: 48px; + display: grid; + grid-template-columns: 22px 36px minmax(0, 1fr); + align-items: center; + gap: 8px; + padding: 6px; + border: 1px solid var(--line); + border-radius: 6px; + background: #fff; + color: var(--text); + text-align: left; +} + +.contact-picker-row:hover, +.contact-picker-row.selected { + border-color: #9fd4cc; + background: #edf8f5; +} + +.contact-picker-row .conversation-avatar { + width: 36px; + height: 36px; + border-radius: 6px; + font-size: 13px; +} + +.contact-check { + width: 20px; + height: 20px; + display: grid; + place-items: center; + border: 1px solid var(--line); + border-radius: 4px; + color: var(--primary-strong); + font-size: 13px; + font-weight: 800; +} + +.contact-picker-copy { + min-width: 0; + display: grid; + gap: 2px; +} + +.contact-picker-copy strong, +.contact-picker-copy small { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.contact-picker-copy small { + color: var(--muted); + font-size: 12px; +} + +.contact-picker-empty { + min-height: 64px; + display: grid; + place-items: center; + color: var(--muted); + border: 1px dashed var(--line); + border-radius: 6px; +} + +.group-dialog { + width: min(420px, calc(100% - 32px)); + max-height: calc(100dvh - 116px); + display: grid; + gap: 16px; + padding: 18px; + overflow: auto; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--panel); + box-shadow: 0 18px 40px rgba(24, 33, 47, 0.18); +} + +.group-dialog header, +.group-dialog footer { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; +} + +.group-dialog h3 { + margin: 0; + font-size: 18px; +} + +.single-profile-dialog { + width: min(420px, calc(100% - 32px)); +} + +.single-profile-summary { + display: grid; + justify-items: center; + gap: 10px; +} + +.single-profile-summary strong { + max-width: 100%; + overflow-wrap: anywhere; + font-size: 18px; +} + +.single-profile-footer { + align-items: center; + justify-content: flex-end; +} + +.single-profile-footer .inline-save-status { + margin-right: auto; +} + +.message-detail-dialog { + width: min(560px, calc(100% - 32px)); +} + +.message-detail-meta div { + grid-template-columns: 88px minmax(0, 1fr); +} + +.message-detail-muted { + color: var(--muted); +} + +.message-detail-summary { + display: flex; + flex-wrap: wrap; + gap: 8px; +} + +.message-detail-summary span { + min-height: 30px; + display: inline-flex; + align-items: center; + gap: 4px; + padding: 0 10px; + border: 1px solid var(--line); + border-radius: 6px; + background: #f8fbfb; + color: var(--muted); + font-size: 13px; +} + +.message-detail-summary strong { + color: var(--text); +} + +.message-detail-groups { + display: grid; + gap: 14px; +} + +.message-detail-section { + display: grid; + gap: 8px; +} + +.message-detail-section header { + min-height: 28px; + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + border-bottom: 1px solid var(--line); +} + +.message-detail-section header strong { + font-size: 14px; +} + +.message-detail-section header span { + color: var(--muted); + font-size: 12px; +} + +.message-detail-member-list { + display: grid; + overflow: hidden; + border: 1px solid var(--line); + border-radius: 6px; + background: #fff; +} + +.message-detail-member-row { + display: grid; + grid-template-columns: 34px minmax(0, 1fr) auto auto; + align-items: center; + gap: 8px; + min-height: 48px; + padding: 7px 8px; + border-top: 1px solid var(--line); +} + +.message-detail-member-row:first-child { + border-top: 0; +} + +.message-detail-member-row .conversation-avatar { + width: 34px; + height: 34px; + border-radius: 6px; + font-size: 13px; +} + +.message-detail-member-main { + min-width: 0; + display: grid; + gap: 2px; +} + +.message-detail-member-main strong, +.message-detail-member-main small { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.message-detail-member-main strong { + font-size: 13px; +} + +.message-detail-member-main small, +.message-detail-member-time { + color: var(--muted); + font-size: 12px; +} + +.message-detail-member-time { + white-space: nowrap; +} + +.message-detail-role { + min-height: 22px; + display: inline-flex; + align-items: center; + padding: 0 7px; + border: 1px solid #c7d9e5; + border-radius: 6px; + color: #416272; + font-size: 12px; + white-space: nowrap; +} + +.group-dialog label { + display: grid; + gap: 8px; + color: var(--muted); + font-size: 13px; +} + +.group-dialog input { + width: 100%; + height: 42px; + padding: 0 12px; + border: 1px solid var(--line); + border-radius: 6px; + outline: none; +} + +.group-dialog textarea, +.group-dialog select { + width: 100%; + border: 1px solid var(--line); + border-radius: 6px; + outline: none; + background: #fff; + color: var(--text); +} + +.group-dialog textarea { + min-height: 86px; + resize: vertical; + padding: 10px 12px; + line-height: 1.5; +} + +.group-dialog select { + height: 42px; + padding: 0 10px; +} + +.group-dialog input:focus { + border-color: var(--primary); + box-shadow: 0 0 0 3px rgba(23, 125, 114, 0.12); +} + +.group-dialog textarea:focus, +.group-dialog select:focus { + border-color: var(--primary); + box-shadow: 0 0 0 3px rgba(23, 125, 114, 0.12); +} + +.group-profile { + display: grid; + gap: 10px; + margin: 0; +} + +.group-profile div { + display: grid; + grid-template-columns: 78px minmax(0, 1fr); + gap: 12px; + padding: 10px 0; + border-top: 1px solid var(--line); +} + +.group-profile dt { + color: var(--muted); +} + +.group-profile dd { + margin: 0; + overflow-wrap: anywhere; +} + +.group-loading { + min-height: 96px; + display: grid; + place-items: center; + color: var(--muted); +} + +.group-member-list { + display: grid; + gap: 8px; +} + +.group-member-row { + display: grid; + grid-template-columns: 42px minmax(0, 1fr); + align-items: center; + gap: 10px; + min-height: 54px; + padding: 8px; + border: 1px solid var(--line); + border-radius: 6px; + background: #fff; +} + +.group-member-row.selectable { + cursor: pointer; +} + +.group-member-row.with-check { + grid-template-columns: 24px 42px minmax(0, 1fr); +} + +.group-member-row.selectable:hover, +.group-member-row.selectable.selected { + border-color: #9fd4cc; + background: #edf8f5; +} + +.group-member-row input[type="checkbox"] { + justify-self: center; + width: 16px; + height: 16px; +} + +.group-member-row span:last-child { + min-width: 0; + display: grid; + gap: 3px; +} + +.group-member-row strong, +.group-member-row small { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.group-member-row small { + color: var(--muted); + font-size: 12px; +} + +.group-management-dialog { + width: min(520px, calc(100% - 32px)); +} + +.group-management-tabs { + display: flex; + flex-wrap: wrap; + gap: 8px; +} + +.group-management-tabs button { + height: 34px; + padding: 0 10px; + border: 1px solid var(--line); + border-radius: 6px; + background: #fff; + color: var(--text); +} + +.group-management-tabs button.active, +.group-management-tabs button:hover { + border-color: var(--primary); + background: #e8f4f2; + color: var(--primary-strong); + font-weight: 700; +} + +.group-manage-section { + display: grid; + gap: 14px; +} + +.group-manage-section footer { + justify-content: flex-end; +} + +.mute-save-footer { + align-items: center; + gap: 10px; +} + +.inline-save-status { + color: var(--primary-strong); + font-size: 13px; +} + +.inline-save-status.error { + color: var(--accent); +} + +.mute-time-grid { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); + gap: 10px; +} + +.message-list { + min-height: 0; + overflow: auto; + overscroll-behavior: contain; + padding: 24px; +} + +.message-row { + display: flex; + align-items: flex-end; + gap: 8px; + margin-bottom: 14px; +} + +.message-row.out { + justify-content: flex-end; +} + +.message-sender-avatar { + width: 34px; + height: 34px; + flex: 0 0 auto; + display: grid; + place-items: center; + overflow: hidden; + padding: 0; + border: 0; + border-radius: 8px; + background: #dce8f2; + color: #24435c; + font-size: 14px; + font-weight: 800; +} + +.message-sender-avatar img { + width: 100%; + height: 100%; + -o-object-fit: cover; + object-fit: cover; +} + +.message-stack { + max-width: min(68%, 720px); + display: grid; + justify-items: start; + gap: 4px; +} + +.message-row.out .message-stack { + justify-items: end; +} + +.message-sender-name { + min-height: 18px; + max-width: 100%; + padding: 0; + border: 0; + background: transparent; + color: var(--muted); + font-size: 12px; + font-weight: 700; + text-align: left; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.message-sender-name:hover { + color: var(--primary-strong); +} + +.message-sender-role { + margin-left: 4px; + color: var(--primary-strong); + font-size: 11px; +} + +.message-row.selected .message-bubble { + box-shadow: 0 0 0 2px rgba(24, 138, 121, 0.26); +} + +.message-row.attention .message-bubble { + animation: message-attention 1.4s ease-in-out 2; + box-shadow: 0 0 0 3px rgba(24, 138, 121, 0.3); +} + +@keyframes message-attention { + 0%, + 100% { + box-shadow: 0 0 0 2px rgba(24, 138, 121, 0.16); + } + + 45% { + box-shadow: 0 0 0 5px rgba(24, 138, 121, 0.36); + } +} + +.message-select { + width: 24px; + height: 24px; + display: grid; + place-items: center; +} + +.message-select input { + width: 16px; + height: 16px; +} + +.message-bubble { + position: relative; + max-width: min(68%, 720px); + padding: 10px 12px 8px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--bubble-in); + box-shadow: 0 2px 8px rgba(30, 40, 50, 0.05); +} + +.message-stack .message-bubble { + max-width: 100%; +} + +.message-row.out .message-bubble { + background: var(--bubble-out); + border-color: #bfe4dc; +} + +.message-bubble:hover { + border-color: #9fd4cc; +} + +.message-bubble.role-bubble-owner, +.message-bubble.role-bubble-admin { + overflow: hidden; +} + +.message-bubble.role-bubble-owner::after, +.message-bubble.role-bubble-admin::after { + content: ""; + position: absolute; + top: 0; + right: 0; + width: 0; + height: 0; + border-top: 16px solid #d79d22; + border-left: 16px solid transparent; +} + +.message-bubble.role-bubble-admin::after { + border-top-color: #178a79; +} + +.message-bubble p { + margin: 0; + line-height: 1.5; + white-space: pre-wrap; + overflow-wrap: anywhere; +} + +.message-image { + padding: 0; + border: 0; + display: block; + max-width: min(280px, 62vw); + overflow: hidden; + border-radius: 6px; + background: #edf2f5; + cursor: zoom-in; +} + +.message-image + p, +.message-file + p { + margin-top: 8px; +} + +.message-image img { + display: block; + max-width: 100%; + max-height: 320px; + -o-object-fit: contain; + object-fit: contain; +} + +.image-viewer-backdrop { + position: fixed; + inset: 0; + z-index: 80; + display: grid; + place-items: center; + padding: 24px; + background: rgba(12, 18, 26, 0.58); +} + +.image-viewer-dialog { + width: min(880px, calc(100vw - 48px)); + height: min(640px, calc(100vh - 48px)); + min-width: 360px; + min-height: 280px; + max-width: calc(100vw - 48px); + max-height: calc(100vh - 48px); + display: grid; + grid-template-rows: 52px minmax(0, 1fr); + overflow: hidden; + resize: both; + border: 1px solid rgba(255, 255, 255, 0.18); + border-radius: 8px; + background: #101820; + box-shadow: 0 24px 70px rgba(0, 0, 0, 0.36); +} + +.image-viewer-toolbar { + min-width: 0; + display: flex; + align-items: center; + justify-content: flex-end; + gap: 8px; + padding: 8px 10px; + border-bottom: 1px solid rgba(255, 255, 255, 0.12); + background: rgba(24, 33, 47, 0.94); +} + +.image-viewer-title { + min-width: 0; + flex: 1; + overflow: hidden; + color: #f8fafc; + font-size: 13px; + font-weight: 700; + text-overflow: ellipsis; + white-space: nowrap; +} + +.image-viewer-toolbar button { + width: 36px; + height: 36px; + display: grid; + place-items: center; + border: 0; + border-radius: 6px; + background: transparent; + color: #f8fafc; + font-size: 17px; + font-weight: 700; + line-height: 1; +} + +.image-viewer-toolbar button:hover { + background: rgba(255, 255, 255, 0.14); +} + +.image-viewer-stage { + min-width: 0; + min-height: 0; + display: grid; + place-items: center; + overflow: hidden; + background: #0c121a; + cursor: default; + touch-action: none; +} + +.image-viewer-stage.zoomed { + cursor: grab; +} + +.image-viewer-stage.dragging { + cursor: grabbing; +} + +.image-viewer-img { + max-width: calc(100% - 32px); + max-height: calc(100% - 32px); + -o-object-fit: contain; + object-fit: contain; + transform-origin: center center; + transition: transform 0.08s ease-out; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + pointer-events: none; +} + +.image-viewer-stage.dragging .image-viewer-img { + transition: none; +} + +.sender-profile-backdrop { + position: fixed; + inset: 0; + z-index: 84; + display: grid; + place-items: center; + padding: 24px; + background: rgba(24, 33, 47, 0.32); +} + +.sender-profile-dialog { + width: min(380px, calc(100vw - 32px)); + display: grid; + gap: 16px; + padding: 18px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--panel); + box-shadow: 0 18px 40px rgba(24, 33, 47, 0.18); +} + +.sender-profile-dialog header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; +} + +.sender-profile-main { + display: grid; + justify-items: center; + gap: 8px; + text-align: center; +} + +.sender-profile-main strong { + max-width: 100%; + overflow-wrap: anywhere; + font-size: 18px; +} + +.sender-profile-main span { + color: var(--primary-strong); + font-size: 12px; + font-weight: 700; +} + +.sender-profile-fields { + display: grid; + gap: 8px; + margin: 0; +} + +.sender-profile-fields div { + display: grid; + grid-template-columns: 72px minmax(0, 1fr); + gap: 10px; + padding-top: 8px; + border-top: 1px solid var(--line); +} + +.sender-profile-fields dt { + color: var(--muted); +} + +.sender-profile-fields dd { + margin: 0; + overflow-wrap: anywhere; +} + +.sender-profile-alias { + display: grid; + gap: 8px; + color: var(--muted); + font-size: 13px; +} + +.sender-profile-alias input { + width: 100%; + height: 40px; + padding: 0 12px; + border: 1px solid var(--line); + border-radius: 6px; + outline: none; + background: #fff; + color: var(--text); +} + +.sender-profile-alias input:focus { + border-color: var(--primary); + box-shadow: 0 0 0 3px rgba(23, 125, 114, 0.12); +} + +.sender-profile-actions { + display: flex; + align-items: center; + justify-content: flex-end; + gap: 8px; +} + +.sender-profile-actions .inline-save-status { + margin-right: auto; +} + +@media (max-width: 480px) { + .image-viewer-backdrop { + padding: 12px; + } + + .image-viewer-dialog { + width: calc(100vw - 24px); + height: min(560px, calc(100vh - 24px)); + min-width: 280px; + min-height: 240px; + max-width: calc(100vw - 24px); + max-height: calc(100vh - 24px); + } + + .image-viewer-toolbar { + gap: 4px; + padding: 6px; + } + + .image-viewer-toolbar button { + width: 32px; + height: 32px; + font-size: 15px; + } + + .message-detail-member-row { + grid-template-columns: 34px minmax(0, 1fr); + } + + .message-detail-member-time, + .message-detail-role { + grid-column: 2; + justify-self: start; + } + + .avatar-cropper-panel { + width: calc(100vw - 24px); + max-height: calc(100dvh - 24px); + } + + .avatar-cropper-layout { + grid-template-columns: minmax(0, 1fr); + } + + .avatar-cropper-stage { + height: 300px; + min-height: 300px; + } + + .avatar-cropper-controls { + grid-template-columns: minmax(0, 1fr) auto; + align-items: center; + } + + .avatar-cropper-tools { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .avatar-cropper-preview { + width: 82px; + height: 82px; + } + + .avatar-cropper-controls footer { + grid-column: 1 / -1; + } + + .settings-panel { + width: calc(100vw - 24px); + max-height: calc(100dvh - 24px); + } + + .settings-layout { + grid-template-columns: minmax(0, 1fr); + } + + .settings-menu { + grid-auto-flow: column; + grid-auto-columns: minmax(120px, 1fr); + overflow-x: auto; + padding-bottom: 2px; + } + + .settings-password-form footer .inline-save-status { + flex: 1 1 100%; + } +} + +.message-file { + width: min(280px, 62vw); + display: grid; + grid-template-columns: 38px minmax(0, 1fr); + align-items: center; + gap: 10px; + padding: 10px; + border: 1px solid #d6e2e7; + border-radius: 6px; + background: #f8fbfc; + color: var(--text); + text-decoration: none; +} + +.message-file:hover { + border-color: #9fd4cc; + background: #edf8f5; +} + +.message-file-icon { + width: 38px; + height: 38px; + display: grid; + place-items: center; + border-radius: 6px; + background: #e3eff2; + color: var(--primary-strong); + font-size: 18px; + font-weight: 800; +} + +.message-file-main { + min-width: 0; + display: grid; + gap: 3px; +} + +.message-file-main strong, +.message-file-main small { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.message-file-main strong { + font-size: 13px; +} + +.message-file-main small { + color: var(--muted); + font-size: 11px; +} + +.message-bubble time { + display: flex; + align-items: center; + justify-content: flex-end; + flex-wrap: wrap; + gap: 4px; + margin-top: 4px; + color: var(--muted); + font-size: 11px; + text-align: right; +} + +.recall-mark { + margin-right: auto; + color: #d93025; + font-size: 11px; + font-weight: 700; + line-height: 1; +} + +.edit-mark { + color: #7a8792; + font-size: 11px; + font-weight: 600; + line-height: 1; +} + +.delivery-mark { + display: inline-flex; + align-items: center; + justify-content: flex-end; + min-width: 14px; + color: #8f9aa3; + font-size: 14px; + font-weight: 800; + letter-spacing: 0; + line-height: 1; +} + +.delivery-mark-delivered, +.delivery-mark-read { + min-width: 19px; +} + +.delivery-mark-read { + color: #1aa66a; +} + +.favorite-mark { + color: #c79520; + font-size: 12px; + line-height: 1; +} + +.delivery-check { + display: inline-block; +} + +.delivery-check-second { + margin-left: -5px; +} + +.delivery-error { + color: #c0392b; +} + +.message-context-menu { + position: fixed; + z-index: 30; + width: 136px; + padding: 6px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--panel); + box-shadow: 0 16px 40px rgba(24, 33, 47, 0.18); +} + +.message-context-menu button { + width: 100%; + min-height: 32px; + padding: 0 10px; + border: 0; + border-radius: 6px; + background: transparent; + color: var(--text); + text-align: left; +} + +.message-context-menu button:hover { + background: #eaf3f1; +} + +.selection-toolbar { + min-height: 42px; + display: flex; + align-items: center; + gap: 8px; + padding: 8px 16px; + border-top: 1px solid var(--line); + background: #f7fafc; +} + +.selection-toolbar span { + flex: 1; + color: var(--muted); + font-size: 13px; +} + +.selection-toolbar button { + min-height: 30px; + padding: 0 10px; + border-radius: 6px; +} + +.forward-dialog, +.edit-dialog { + width: min(100%, 340px); + max-height: min(520px, calc(100vh - 130px)); + display: grid; + gap: 4px; + padding: 14px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--panel); + box-shadow: 0 18px 40px rgba(24, 33, 47, 0.18); + overflow: auto; +} + +.forward-dialog header, +.edit-dialog header, +.forward-target { + display: flex; + align-items: center; + gap: 10px; +} + +.forward-dialog header, +.edit-dialog header { + justify-content: space-between; + margin-bottom: 6px; +} + +.forward-dialog h3, +.edit-dialog h3 { + margin: 0; + font-size: 16px; +} + +.edit-dialog { + width: min(100%, 420px); + gap: 12px; +} + +.edit-dialog textarea { + width: 100%; + min-height: 132px; + resize: vertical; + border-radius: 8px; + border: 1px solid var(--line); + padding: 10px; + background: #f9fbfc; + color: var(--text); + line-height: 1.5; +} + +.edit-dialog textarea:focus { + border-color: var(--accent); + outline: 0; + box-shadow: 0 0 0 3px rgba(24, 138, 121, 0.14); +} + +.edit-dialog footer { + display: flex; + justify-content: flex-end; + gap: 8px; +} + +.edit-dialog footer button { + min-height: 34px; + padding: 0 14px; + border-radius: 8px; +} + +.forward-target { + min-height: 52px; + padding: 6px; + border: 0; + border-radius: 8px; + background: transparent; + color: var(--text); + text-align: left; +} + +.forward-target:hover { + background: #eaf3f1; +} + +.chat-toast { + position: absolute; + left: 50%; + bottom: 132px; + z-index: 20; + transform: translateX(-50%); + padding: 8px 12px; + border-radius: 8px; + background: rgba(35, 45, 58, 0.92); + color: #fff; + font-size: 13px; + pointer-events: none; +} + +.chat-toast.error { + background: rgba(192, 57, 43, 0.94); +} + +.message-composer { + position: relative; + min-height: 0; + border-top: 1px solid var(--line); + background: var(--panel); +} + +.message-composer::after { + content: ""; + position: absolute; + inset: 6px; + z-index: 4; + border: 2px dashed transparent; + border-radius: 8px; + pointer-events: none; + transition: border-color 0.12s ease, background-color 0.12s ease; +} + +.message-composer.drop-active::after { + border-color: var(--primary); + background: rgba(23, 125, 114, 0.08); +} + +.quote-preview { + display: flex; + align-items: center; + gap: 8px; + padding: 8px 16px 0; + color: var(--muted); + font-size: 13px; +} + +.quote-preview span { + min-width: 0; + flex: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + border-left: 3px solid var(--accent); + padding-left: 8px; +} + +.quote-preview strong { + margin-right: 6px; + color: var(--text); +} + +.quote-preview button { + width: 26px; + height: 26px; + border: 0; + border-radius: 6px; + background: transparent; + color: var(--muted); + font-size: 18px; +} + +.quote-preview button:hover { + background: #edf2f5; +} + +.composer-tools { + position: relative; + display: flex; + gap: 4px; + padding: 8px 16px 0; +} + +.composer-tools input[type="file"] { + display: none; +} + +.composer-tools button { + width: 32px; + height: 32px; + border: 0; + border-radius: 6px; + background: transparent; + color: var(--muted); + font-size: 18px; +} + +.composer-tools button:hover { + background: #edf2f5; +} + +.emoji-picker { + position: absolute; + left: 16px; + bottom: 38px; + z-index: 12; + width: 256px; + display: grid; + grid-template-columns: repeat(8, 1fr); + gap: 2px; + padding: 8px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--panel); + box-shadow: 0 14px 34px rgba(24, 33, 47, 0.16); +} + +.emoji-picker button { + width: 28px; + height: 28px; + border-radius: 6px; + font-size: 17px; +} + +.message-composer textarea { + display: block; + min-height: 86px; + max-height: 180px; + padding: 12px 16px; + border: 0; + border-radius: 0; + resize: none; + box-shadow: none; +} + +.composer-footer { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + padding: 0 16px 14px; + color: var(--muted); + font-size: 12px; +} + +.send-button { + min-width: 72px; + height: 34px; +} + +@media (max-width: 760px) { + .app-shell { + grid-template-columns: 56px minmax(0, 1fr); + } + + .conversation-list { + display: none; + } + + .message-bubble { + max-width: 86%; + } +} + diff --git a/dist/favicon.ico b/dist/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..a758e4187258f184c086a6df7de0531ca8a8f925 GIT binary patch literal 980922 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

4H%`;NW5V3u% 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­Zk|^dv;p_b&9S}N4!>_HwtJ*fk#vW8 zsZ=D-lixW+oeohy0d{8mK!pFL*EDvBjS8gcn|03Xbn!bi*-?Xxzilp?cv?0`; zt?lRQsk`QiGtahH{6mAdrJN^TGKpjLsmBmAE^&QMTeJ?wtYr^A}9;0~Z z$>4x7m1nURHur|h>qq1*+0RW`upMWvqRzteBF^AHekbx)?LanAfPc3JK>QBJ4~N(T z+tnGr&uAaXJGD>cLFn9y?JHf-O@k=@gZl@07aA;Vr#wMlPWVy1hJAz|t8Hht(iVRG zh;{s$`A6&r-l*+}G9Y1auS4k_{`KRuHTicIQeS+|oa@ZD4faD`;CNqpIA{mAS>ibM zMcxzmy9cHBTuy`kQvr`1?^PRs|JnbnLR+Xnhe{lsES(U7yOw^yUg~_|X3Om)jshxF zoG(z8(eRPv^kQE{9)7Z6isJj4`bS53xMCfA4 z)~DYgeH(B_*M<&jf9@TWT{3@J2urE6=Dq>pxe{m2FSMyaqmC2jTcRt7w;cg{^@|qi zfdbso{-u4Ci8e5XzOJJ|D>@1MYyUrgh8DgZl<{4(zYCpQ$~wD1YimBONZ{BZ=&^Kc z>tw!{a80~K{BG*AjB5|NA3}TyYd{jG0sb@CMy(fZa=Izd9Q~qk*bg;!B|V%yn6|Fx z@1`LfE5#KXF z*c7ERlaF@T;ggrbTbfg@IX(U0A39XxvWf4ogKxVFTXzWkonaQ<*~Bz1>Cv`H>~HAy zcx(snZ2IzK(EhwF);1gYMPj0*#w3p=4P1Rdl=4@5 zKKR=wSX22f@VSh(8t}b%zp)QI*MSV`#=qv_7U&PR{ekgskCbC|Mt%!#i2{2BpSl+s zpnv0C&>;ZPz=PKdI#*hVgH;=W9%o@l@zcx==p047@ZaA9NQTdZQl6LST%q;`= z+H1TvX1RlU%Svp_mDC4_t>}i34sOmHHc!XL*Mxm+$~??I{&4CTwB10{q#n;$#|g4Y zr32`DLIZcL-{=Rm4G+S76&lpX$X-2w?A&QxuiR{{Qx3t0(gzxMtfI%@N_0&_Mh~Zu z?i-a6UQx`oTXRTy2cImKSt&9HOQ+|Z#(W!G1d$S<-EtaC}&;fa*_7Ln{ zj*f;te&2TUz6(c-eY}Hyh6Z`sL;Gvs%b)CH{w({rIO!bmSq`znlFNlk$x?T>S?9Ml z+2I#Hh|C7(#7hdw@dvRX@3%5EaC3Y#&&SR6>86F~;^uqO7G(Fg9?yO##D}TQt{*de z78zn~dVgJQL7Xa^vV8*kKcfqbc2H@NT|_&G(+1QIfIufuc6341cVy7P0WztMO(h>{ zk@2+jo3>l(yu+5diSgkli3MZsgGRWdFC<4C4uppg6t7W8lr6iS@wCbKufO)Bb)E7s zV=nj8KYb8bOW7VJ|8?kA<}EO%sv2MG&fWM&7BRmzfPfD5G4cT|w$A4)V*H`qAwu;Y zxqNg;EV3B$CujqLz*iCQzt_uwuOjFpsNd{uB*`Y(Ns>#V zh4w5@Gq#)}#-i&bk6Y?5nQQ%#{g(dxUQ2yxuO-jjW696%vh3MAEcuovtm`Dky@-WL z#n#d10M9;tUNQ9UTJiMjxMp5M3-d=j#P8=`!2fQpZTw#7axdk$mo!#d=L?ov*IM|) zW2S*Ib(Q;8pnV zNdt%b7Gx1n8w38)6IpDZL!V~7XU5~i?vCZ%pRkfo$5U87=Obq2p!W0HkOl3~0l%!% z2LTv$-*U_@6P)BWNHxM4*a{^5EKlixF1)5dMiD)|r_3 zszB|a(FTZ76yA|VnolL%C$Nv&FW8D)RsT59aUR`KKJ)j6dmhcSqGbq&PSKWmYn$6; z9j|Of|H1#zp^RNr8iW5@{e?L8s=Kde%z1Ny$HvhkxSjU58K3; z9mMA$lN2M_vX!&uEC`?h@xm3w4aX&mh}-5|3FlN9^l)>0Xcq-^blYD&Y{`e2k3fZF z!K!b5wD1(g*{EOB7JPHf5zBk%-w(5%iTps~`!qO^UJ(8R8mLXwp@BIXc%6V>b&T*I zwg<*K4O_LlEfALhEi~q)xJboEx){kZ+qk!l_lS9Ocqi@wI=FakWK#vmk6DkuLHd|= z6VS(r7p^64MSFtD)2l-j2;}O~z`xQw8tFFEQMy?+s(MzbC(sLDfDYKHRq!s|U?Ki1 zP9FztLT$kLE*vdnA9dSEvW*Pe$i=@f-mJK=Do`UvwYyD#d+BLt5X@Z&PfbaWwFxe)+NRdqHM5|5a^Shx)at^=WJW`TAe~o3i}b*H-WryMLnv2{9KfyLEFI;Tsvas zSYM#)LdKikc>q1Fx$YWIqYcn50=*FEW#?yAzpc@C3uqAFAKW|q2e_{xiz=c8Gzj8i zhzoWx+U)&^J=%8mla`!(kT?acs^qz1FeM(ncZ74VS44-W;_x+Bk5>J+)JDd2euuB% zgZqeABen;6l<;qh4jOMWH^zxvabvEE_Lpw4j!$p5 zj;l#`XUg@}6-S{%cz7!KPq_E8N9U)E2I2$tX@m>+H;8vBbTH3nWtVl0g&yBIXq_M0 zZ`sq3S1*HapSQ=d&jOAk9vR4RoqqmqOTA*3W&Y1@OMYyxb^KtjbzX~~`+-Cw_AQ!+ zWMBjL5|GF6P`*)o3;(^%%Q}Wda&|^{egQu87Yzll&K~WfP%E+?GjpO2G(Aeyef9!dIt?B9C4M9=a>KUG(;*a`e-ItDAFy}a{h=?$+tl!m`Q*z}%xZ+IB+`bS?2 z=lU%=jP{|lqlc%j^7A%#^!YQ_PYnhrRF|t}c^Yu_MFjT!Qz7dRu4jF1$ zpLzf2U_i9=&|eOo?te<{J{UXguC?2Pfw+X`bFiLFFh1tnK=j<5!XM|AXgUyGeSJr( zhK`>|Y~-^vQt&_cRJC?E5)wVV(=W_5! zH$MgZCBBe6(XT(Aqc1uSq#K4>!_lUHBRzPk8Rw#Xax3eLT>pga`a(2ti}+wGf)Yi8~lc}i~R2sj{+2d-?#kne*M4DGMi0m7-SN0au#i))Ld zJ)Hd!n`?r~wK97*ms#&mZP3f>Bzu^&FWY5%{(ZUadIx(lkGX<5vX?_|(Q`a-4RCD; z6FGaB5Ih^hbD-W5LY%XJ@9MFugLmBd3a-Zz`+Es-zv77ttmF9?*}e~4XNP~o9KLmj z*uyr^C91ciL?9P>YM=)HHdpW|`0Z&fUEpCj#c=!so%zop&R5L?`s-HEF7#~phj8lk zv{uG!UwhE@{b;2fK5Y_l^`iMTwAV?{M=*spJOz49W?q5^=+6Gx4QPQU1o24@8ua&k z(0oQV)B){#sBqYm)8%!-JL%_XN@WDp`|(#t5+RbfUkg zp*HXBL6vPdM^GoV%7E6QmFTZSccmSh54|Jk?@)1kk(5F87XM^*rfy)9K z$EGpg>U!qg1#6>f9aZg5An2yQ=L3I^@PhVLZ>D$C?^^t7(i`t+FZx%Zzk|4VVqC}@ zmm+t5XPwW!)Y?8f*V^x54gE+3#RpaFMaeSB#LrPUDH$LbF71_RmG3pjB7F$m zd-E1+pUWE2``GK0X9Dqp=LaqwH)zjL)xWtth|c1RfbNnc>`{;}SnJq_to4+c&|G+z zJf8|o1NR|7|5`j)L-%OWUpye%3uG%edja}a0gI0d0NqmuDzWpCNx!q!_pny?t-;=b zk_TnY4uJtsWsUlC`zbw|X)u(+NVx32$v%sTF7 zt;}r2t-GRkCC3BV2(26Q!FU4E%ly{bEIOp?Td!DWhhM>7;|-e60Plk74n%7Q(BJP( zsI&H3=@-xo(LJ>rdZD2sCJiVPBr`;NL9Jz+gT`<11UynhH{_%n-g&LHFJOMO>IFzH z%AV0$eS)X*7)kqAT~h2re(1$B;Q2Y|;9IbrZ{hl8>OKR0m`pohzwVdQ*ZTb3c5pm% z)Yda!y%6Y&XuUme2uFt(ZnOPwVV`4gsC8)Tq*ZT$?ru*wu339LfTKbGs7*kdZ_)+P z-=e#xd2i>Mc!N4*=}RPHzqWnn%wirIeM#!*+LshXN{%n z;dj#GcYSEqu;s>pBu6;Y$vnV#x4!?f3wSIfGwco^gC)+X&J)yax zt)F8p67+ikTh7sa%yin;3dORt;DjjGPsK4D`QL;7^O&FK*hctzmsEPxQd(@xPAQS@a*yp|8~b3y1QoOC)-;HwpCD z-ZAF(Ez#a3A$UHBBM$^lF3jO95I<;7gQ=Wn05>rY9lEp6mEU{J?E@NTpD6J_FA&|M z*j+n&P&Q!*&Gtac6!Q$7W_-% z2V_JAe?n{Q_w*T;U=@aTul&h0F5kZVc{ubr7T<_>#RIMED^h``YWuy?-}6C8|2lN{ zAbtq;+tOZ-0o0xSF#DL%zb;;A_zI*80{YjnI|cr?dRFK z0sW;D>MdhQ|9tCu?nTzNDDWGphg3rlJl*Lp`JXFPE%}N?)L|}ozMXT=eT4k}P5yj@ zT?h|2UU2rn9B2`?e}8VsflwaM{-gGww+jQ`0MDSg`i-J#E;a$)q#ydc$<}%54BPwO zTWsIwZnxHNuz%RUEVInNF1O4NS6bq{rPlt{J8aiyX4|fJ-AH||v(A=D*r->K*2VCS z{Jk1em;jGYps%B`1I7^|P+{yqP=yZ!-cG1N;|k~jf!--GCY3-I z9Gdo+^N~ouR_bM^3}hD!$5!vJ?T*GXd4S}T@A#6|lT`cdNqg~vr@KG*M*qMr3~a)I z=wF5Yfj?k6@&mwb3}7n!cMX06{4KA#)ed}aiFI7E-a6QyJG-aL%0;bp5%`}noCPYo z2jN>;XG)_8jYY@ip+nCFF4_{3=<2ZWtpF9|W`ycmRKK zl>WYd82X9o(B45vduI#4A32_vG`0i}w2gbj@j#aH5W?c@!lxzu-I^e***|d)ZB24} zKCl4%X#bvo7d+kl`3U+)`v=H?f#_czgTF~Ofcgs1Ui;Z~(k>63&N%*$@hdE6{q0=; zmXrD~&A_cb551da4Y9U)?ECZ8JMHj`C0E9hH@-jdf!h3W&>iq{Adm$|_7}>s|7q{# zmMeJoN~eRoPq~hbV91;f^g-){b&dyIp`NDgzlxt$xXC=;Ze7|Z*U>!KyJ=YTM;G)@ z|5>z=S@7CS{6v%N;PKbkfv+yKuEngaSJqljf$gj^jrJjqlD;benZqSJH1P@B_5ZPV z9sqV-XPuunBUv`7KpF%#l_aoP5_&>gvZ0qOEQEz6)TJzBAp{770NFJ6BKNLtOLCPh zTed7)mb+}rwruq}(rEg;dGp@1H?M#D`=4{qn>%lcW;8`3Yp(Roxv$-O?)mz6zVn?= zt^rq4U0mpgDwk=mVOmfMd-SaV+t%)%c(|D$+4bMZg$5aU1$Kzn%ABL^Y~bP(Dg2SPi_Ux@4g zA0HU@6)W|M9oz}uEwdBnEVrh=*=oIw)KiN+m*&|tFA+^5#XgyVQ^sGhQqAiI=^}m7 zwe6@K|CP1Yg^f@^|0vHuv`|DQdGPjS5x&n62OL6fq``aZc~{#}=%@8>w_5A(u)l9Y zbZ{LI#f#7dJ&6mf>#?Jb?%ach8_&Sw%)})$9)$=4na`^Z_&wOk!?+g>1iXhf;61dp z_*XnY^9f-OXzhhAouL?m_IU01U)XL3yQ|%g^TurRhn_cptJh2~L<6!Lx*ut@V?Vi? zoP>+$@3r*zX83`4F!n+g{!W4St`DuYj{p6zwXJ4P^~N42OBDZ++-kjPr}ZY3m*nF| zxq8vdWtM!)CDwN!+EaTT;@{5#vQNNW$FPqizaPN=LIwng$$}sgTpR7}YUm6Hk&hVg zuU7FS#RoK()cNr{t!EpxKpCs}5$vMS#y^|s^Kg$5ZR{qZgVq~gv=eW=5<0lTQskhu z|M$DC{rc_JyNf+qFf!xvD*ROM>9<|vv?wm*X+XBcb-+c|`4M~=>{scZcs=y+`_t8m z7c>?+2AX@V^UV?d>mNJ?{BOXX*ZcvoAV7O=YQOO$dcNb|pR+9YlI|UA{9FfS=}&mR zaQP9qkDgthh3^SRJ^R@^_Msz|O%GWguO%b&{zS(R`D~rtN5$#3pEY6F7Zf1Oyon^ufrM{hr}@$@?7h zK+W%3YwcT(xp@-dJ?NU#@vM`*XOM^bexOygit7d%8S7ff?d+?OxCnXY=Ls}d5atim z_A!Utdh>R7O_wL(f&#L3JdAbC*?uqJU+XI*zk0s-8uYu7xu8?QzkEmOf_u2eYHR-l z`|Y;M8<&10R|1-!X#8gTSton_s(hf&)$>X4Yxl+E52EjL;5y732mF^bcYrQPo_7It zwj-Mtd8oj^X~jSHFQL@3V5#?5za`)OF#LZ%c>q(#zq1*jok8Y?TYrnVTokX-6Z%}r z$ztHl`<`r?)UV!+oWBbEUkCjYBTy{B%^BT*EWMuhln-;co%qyp#}gWpB6}d6PW&sM zk*qfQQ?btfu>;>mIRFnj{1>Mv|7AB067y~QU(dqtWoQatTQP9Xhdr({54R`lv5PzQ z^L&N|A{uK)-GUu#VQX!%B3pZj{p3i!gmwo;Sez#l4$OxU51N`gGU7Ojn z2;Q~2hq3*)pu+>Or!KNU`+94ibq6)}fU^(yt#SujfB!jW;|zlJA~|yNeg0!QV=kW2 zzSXj6yEh$&_L(1GUMe0x9DS~s!VQ+hzv%DOD9NtCDw>3TnND9P`mOlC<)e=yyRi2X z?6oOiKQ)2qpi;lt(S;=*8XN!cy?p)V&peI|LF}EI<%N6n+v^$sn&a~T|9tr=Wanj! zS$rPBpS$^{D3(~D%@afHLk2YeIr}6F|4`8Bz`sb&*?iX=B^LXDLJnxJdk_A+2;H1`=Y7`SmWGz0F*OGfu0s{UWO+<1)c7Wy$T7Dg!%MoxtC-|q|`X{@k>ym@$ zE%ESU@crX}aQ_(KaX)4&+n`SHkhP=p+qbeWrF#f^KgHpntlZQ0BvYhwozCQbeTR~k zT6xrx>)8(z`itLsve#9&Px-*M74N53?PJdRQt<5gUO10Kz<+3iO`tW3vKjiedl?XD z;FS9_i63fQv^T28ssQhI{HMpfu8(l<@jn6XMHdeLo9X)oYyX#5oDLJ$qr|4H$0my> z*Khi)e)l%_S;yxdwLx-B`-w3PGJl*t?{@3_*BzG4Nu$oyQE|3k$LHybbieQ}{+}fN zWe3V1?E0U`RJvSb42y~h%;KSO9B?%?uvu5h=9gXX`Cho64F2UG6tETBe&AsnWDTNl zQY=gQ>wIecpDg}0Bm>2qb$;~~%Pdx&@k-zhcusk1>w!D)yH{KHyY8^m^5M06zBi)x zsrBn*D9|%|O~+pE+u5&uiE;^UVK2>F;g8Ajzmo&#jN~~>ZQyXXrvdOE#w4^S>&sL= zSG=!}J2{`_lP@ran;AQg_sQbl?X^s*MBm_MWLIkHE>5sg3hk&*qD1DbPK>+sO=qZ=&qbgLUve;N8k|7P-# z?3WFw3N_7NdJ>!da>jER_-EcQMgu|ahc?K6wLZt~66^lTg+k*?=QmK2JtAe9_Ah4IyIMnS}@ z!h8Dpc1!-`Ch)FYQ1SX5;QcnskU!M^FWcEeoc;3Hf4A%BA98x2Oiq!$qcw&@&`R=m zi9;Uib9Acf&9ofQ6^H2Wz`&4ozel+t$bV>{6y+fMy!4y#lg5F%n;H9SE%||)Z7Azz=W9DRm=t|Ig!^`ydGVXcnIBM)(h_oSMnojkHEvV?~nJ|;XnE?eLwp!e&1cl@#Wl0a$Gd9#(Lj~ zO?T;T<`YIs?>zf|=d-eAyc|%gzV+iHbp8HgTU^lDWfn%5;0H{w1$`1>D>Uo;=mN9uM!hb{q6XO3dbkruxZ0hv=iuoz0(x>=u`dTxrs}_$cSM+w5BbfZ; zBk*Xu^HcnI_+N1^=!~t@||~KKS~?Sz=15(dLPkg`#-Qg+~ojG9{(lmz<%;ZI=`^RJ+rP8$J=y! zsB38)vj_X|mmX#8p0iSe;92w(av;b6wN*NJf^+->-m73MbbatK8!F_`{X}?Y5dS?Z z4>{XiGJ25pSvZru+a3m;Fvjc(Snvza{58@LDfcQh(G1!6YASm!zXfc76FhCojO z?&JNRZU;qE>D!ta>n+%G&pO=4@m~bbrFsBcU>M{dJmdVn&VSs?+8X=^d_JeQ$I$;% z?W6jX{pwESX4LfHJ!LFaEj zVgq|p{v!O<^+ZQ~#E29>D1wuL3-(q&pZ1AER+)84)V}$+*1^iQi*P>){8zA5dY4>h z*`waK3N$d?erb(|a3;Ok`GsBZi1>QDl@~pS-3K5G9Dskxfs$*7MPHqlN8@s0iB+tzELC>w0?Pr z9HE|j4?6yrB{&oF=dMm1SCntn^|LR-YtJ!`FS5QPf;woy(Ezqx9e`}`AbNNjdU?!x z-hr<`9VkcQ(;TRPf8kg7@BT@xJ5gPrl{Wa#JFED}vxcvaS`v!!Y7N0?ejkbZ+Rr@= ztg+;K$jgd)uKp+gC;qOJ6Kk#I)7*QS&lCT7@QHe!XhR0w;$+NJ@L#|N==wM0Ef+1( z=b6C2^365YxePfICybL)u(Ur6R@)B}EaiY5{ z{Q+`Tt9P9KNmx^o?af){JJ)cJTNv+=b*@I}1fDtA0^)z=jko>Q{qU+{TGSbX5W-lU zO7HYrXRGn!{ylxnognYVz`y8WO#H+DeUkkbHde>)RQfUMH^ewK?t?A;R#>E1-FoNm zbv}B$`qi!no85bpk^AH0|4ww*8q4hNtX?;B>k;rT+z=x=mzot_ir~)75pX41>-rRV z)ZkP#4B~aJ#>2npKy?dJA6;j?#FFI46o_w!Yo1CE-TFS}=44T(9_V5`$v>~#K~C38 z@YE|FIF~Fi-nV+>1H3ONb1uD*VU8%drESW$SHCCfyT-hGdkgrH?Z=wX`t{b2?W3_1 z^j>+u#cN8`4>+0Lp9ueM?a`*jYX3VQJAtpIduq;*IKXS|Glu_g6FplmIbk_`3^!Mq zkPJ}WyGRzOjqHLrJxB&*zGH>;cF5932NbaaqWEaI_EcK=qy-6CuGVvX3;o&7bH7SI z(6giP|B}PMY(vq3$NzR4Sn{N0k9(VRviBC=RhPI>K#GmyC+PW7>koqC74&JH4SYK_ z2nP$1?n7Sv-HYhY)%YaHhcV>8j~ATW2FNnj16K^|m42S3zd>BS00&J*%l2_ z&zb{_H*-NepX%342LGym+)oZchB|{Yf`2DxWl1uB{?!xo(mR6j4)rPXt(TE8vhA6p`N54YpGx1?ueyHu z5&FBDzSP)$&bD8V9jp2Q>-fF5_s5h0@OV*n{$FG7=)xSuJZl}^aUb`T4Y1M%F5Bg7 zKtik^cGmMZVrGGGGFKz`(!!hTbi$4rfkxPlx{_{OhUGe@$Ga?v?TJ zpMd{`e@7$Wr5-&2{+oYfJ3g%+m#N_YWaB8Ql=@@h&G4b{-}alEsw_}*7nGod68fU$zd!HnQHE$z{IBm#=Fs|(wx1@47+h+M`oHi3 zJ@vZ3lqp*A4fk_@{J;8jfOLT7^;MUad4YS6JBpOA-S%fs@LV_Z8FIj_J(N5c23@1) z`>AgkbxOa{+>mHa*K7Y}@(bK&GmHOx-=JmQA=!qlQ7=07P+RXTP7kV$J;Yp4@3s5f zSh$$-IQlbsoC%wNf6;f(FCD}l-8lmHjt=Tyh1anOf;|wm!hZq$cm3(BRk=JF{-3Zz zu@8&nj0}FSvegh2e<`Dc$ZZZ~l) zS9!*@Y1lkpacJ7p(X5d*PkQ%m2xC zb*Q7yhR%`fmmR*!lB}W8UG%tJ8yj6bK)S*4K6KCvZ=~)y7L(N;|GJ-hzCU=3-`v9W z;`kRGC|7KqrC;+lm7}kl4)dOTfZHs$G`nearq?hzXJYS z!FN|d$Jblt8~9=Te!BSAGX(s1eMlcOMG_155Wi+f4SIWI!>o+Im(Wig54o-isYS&@b-yhsL|}4HVBVNIGS3CUoeC@di|KLxA zFpVSNzx%%(0RMX#n*+f92=gy8}(ESE-l%w-)>}XSm^*`)nrvsGq6t*LwIB*d^RcIsjUZ>w?;IJ+tUH^DW|Z z{NBMd380GqPwlVbzmhn>*fP%`I*8eVBhRr5&;gmhIKsS{qLKWYCN0LtH+%jr@T6Ss z+bsQI=H#P8wpiycY22U4%M=~o${VKwf;5rLFF3AhmGSOyCY@~ z#LtC)?U&Jav6ufE@9FYfz<=sj4lv%bdwACRVURsA67SwOaDDluUZowKewei z$0HPGvso)HlD{DRp;!-g{;xh5+4V{ zQ-2`pY3k)R*4fIw_j59^ju zNyn)F9`}>Me?Pu#YB_qEUd$B!b*;X?ZDvgID-%Hd{wkE}4=~Qy1_|^7P)=}f2gn8F zf9nsuG-dpc7yI-62;)yotN(jdFGl@E!PpDXmPIye@ zdyeDhui!KCwkLys=s@`aImHRVrRbo*Z{s-wvI8{F)XQFv;mF)_h_P1Q0X0dNQ1_&p zbxh&I8EBJRR1;#ECpn?A&VUr`sIPw7zD#_}5IUvi8!qCb4yd|3=_w6=Vl` zkWDyD3r-dwFZ$|tSkE5K|3FETGyo^!f6-!!Js=0&*bDz_EzRq23|vl*zQezd`&Icq z&_dw*nzqbq#R#3gkALQ3L3e^{^8KJK-CsusbIrZ-&AGqg4?VATR6q0InBL#?wR^dz zasZ{Huwjt_CHfcmKD2@VosB?0GUqY}bg;+C{+Y=CsN(;L9`KLd7jU0|4iZNr+=~Xh zUpOoa4$}Ai)V+M!Qg>_qJdE7Q$HmF{acD(6mb&Ap<45Vn{5i?|X>9st^^2?41+8vXOo;PZIdO zww(;lYri8Lz~}vc;o~a0S7C@b@wdx9m(Eya{a5UrQT%s&;$i1oDi&2v0L(=R0{zM^ zC_sNjS}z;ca*i(i>ljDWzMHl?AQByF?LIOU{nIEgPwhsci*?o$7L0-8JuZ(#?Gfq&6K895;EbRb`0 zKV$bAbFQ6UK8~Z;C(#x66~)Ce?@_He$vf=bi-|Y6PyFA(RKIoKupfMEvD6#1j$3-d z%L=#F!^zNLIT{~N_qoHnj}I1z?e@O$cI)~K`%*4Dh+Z9@FA#tA{hMN(YuxpF-cQ}z zY2;dX+?O3KC;wV&tJFuye$|HZGC*y-zdHB$R~%wJxpphavu~R0P)_N48r{B4DR>LL zU)O?cW&K+{`Ie*LSXCZ~9x4gh1^X=Zdxwyj1!xIt0>9)`4#`&Kb?1oh_<3LS?n>Df z{s=aPUJE}1Y1VTI1RKX00V)4cTqf za8AY7eMdK=o(8nP z4s%kH0qTDQC7vT6<-qp5h4a+R`k~=@Bm=S??2Gee_V`8zloQlqABB6-!?6)i!9Fx} zLHe!xEt4GJ35h3Egq>46WQ%rxz}sDt0lgn(KPUE~9calo`CEHsy%tu6m>){5!5{gA zuQ4n75s&#e@NM{!*zg~@&obBVv%z%M%?pW2YxTKaX9u#De6E>mZQ|J^E66|l5c9yJ zzRi~>b$I-XZhKi*sv5Z3Q#X$PKnHHGBxoSCvJ3JJn&Y_5+J1Is*CW(+-Pr)2KE_xf z|LdEN6ec zm3}MyOV7*Z=-Jg}sf*Z8>Zh46dZX%-DdKISf9-3wjA4=@X7 z8vEp)4Doe%zOJ3|CeB#b>UDwiL0lG8<-jp$;~3v z8lZMV^XH$n%sZLe2k*+!Q0&&rV?Xa-0bhgQtLI}6ThFcg-5j5n>BC$a&ZL)guDrsY z`;Woro6&R2xaJD_E?oO~vtkQF$Y;su^xM}_&*TXk$P0V$@f7So*?V#SO!sd2hZnfE z>Wzr^NAIPl_W~UZx1yE1E&0JsmUTSkx-u(&TKy%#Xo%$#5^dO-U>y7_;{r#^O*g$_DDc#qq6 zUcb{3aIbUmd+PCK>-@w9=+xVZzCN6IUGpl-ZQxD({?{M3^d-Bk=XvUvQ7_Oxi7pnu znyxtUQH%fH_I_*U`W~<1{mJ3Kgq#?FW?KLGMc0>!?>fCt)n`3#*X8Zde+%Q>MSmp+ zfcjy2rr~@G!3_-88<1qOijvjBl(|aOg-Pi7Mxjh+h?(GEG zQ<4dqA75d~-+0glx`$)NgV^33f6iJJ7tfar5f93)VC~1Ztz|9v7VEkb|F75oX7YU; z|C`~t#Z&5c>)*ZvjcE>w{ga&RKMDTj7t|{U^=RnH3mq?EjUpfi?t8$?pyARO%gzir$HzkVs&eR}|a~;vEC^q@KZ(66}H;PF*^?diNOVk;;w(#4T~gSrXy$yh6?y2ygCZ<1tz zmj}eW64(Vmk^1SSgtrm3mZcNhCeY_h(&$*vr*(P4fBMN3KF4AD+`-rhYUse>zoiEM z(8D6;3WWbR?Pt#zzvuZ>?545$bh7s(4+NPO@;*QP5I9%;SLuTQsu71?_<3|`OW(;Z zHzS{W8yI_<_*Jj-<*1*Zcz8nmyM1*d{A-`h3U*)1JMXr1I`5uuw#QKq?$#86e?{`T zf1(8$fDMpHqKi79$r>7fCTjWL`wMO0;D~kpJZp;RxjZM;tqgclJCjG8C&X`EUw-E`eA5QN_enNkHuO+`-^+d$;n;AdRz(Wq){s?Z51Rn?Rdn$Wb zpuLi`x7rZA-~N@CoGqm~EyB%Q9;y41_=2tQQ5X3slf^%Ff|C{O(~SJ+{6-5tg|xuz z;lDa25Q3z-Y|mcy1W&CwO1&ufuc_C`Pd9pTVyXUc22Uc~4{^t)|4I!_Y`1cQrC?4SV)s!E&!8-9520Hp@uya$pl)Rs=pJ+yQg46mGGBt@j5FK=qA3&^6Herok zaQ>oVM-8Hzc5GK-0vmY^{VTd(xTswtO8uqmN5=f9WM+qRb~J z9wB~9+_s8;uLqU?ZvqVaHcqbaXrOqcr*F?cS0^e>H;347jJpQ=-e` zADK{$`v*02P^oW4X0$>x#9H3C*D|m4FgD7>2lI^6Y~g?MPd2mP^wQ1S=pENV^VoZN zc)FN)lsL*`jKibA7KihIduIm6{NoK5?AqEXN@Q9;$3 ze@ngqyq`!R%gBSn9td<`i4N%2gJgluN5};1!~*few(n&xk;Vb8SLBLF0epg)$X}YM z|8wz~i*rKHdHK2AuqQ1I(_hsEBkw#9UnzzWk7MW@)|7uETJFA!TEY#Rk$qd?i>=5? z50U{ReMtTdG6!3m+-f${#-;y<$U6)$hT z?x1y1|GEhN0^UPAS^O7}`?43CsdJ%gY6eaD{n4%-TPI3oZ{{9&B z?&s&VU#e^l#mz_Ge}*3L6ffiY1J6rd2{rwlX>0n_v)K9A^mW_F)qebx@L!RwfZRwC z@9kz?qT&~tGnsb>&n_vQ0b9w>w1Gd(4J6U;X`rVHWo*JSK0s)P?Lyg##0~HZOUR32 zgJOvt*aXegwPuge7t`+9rA<|r(Am{)tVf=ou5nQ>gm=XdJ8nNg9e>qH-@+JdgAayb zxIX%m`1Vga+7NwIA(9E+C)mpGw-Teg$GVmta&q6r-{&p;D{l(9NA05a?{C7Umko$d zNNgz3L0P&X2DSKixF?QWs>gZ(BRKHlzoBbl7ppJwm+7l>&+0zS7x&(HDp+K>QH?SA59D2+;=>z_1B4cYNZ# z2dv}9cJlj_NvPaB?MX%yLhBTmn{s_{J($@)f!3to#e;eFLBjiSnrWbA&^rEpkF}qx zeNN!(I@W?LdIrA+{3m=}^w1iw<51;$$qDvSEW`iO71~oNi_LiaCpKGwnuGp`#&~8Q zZAPvZ@IO5M>=p7z$~uM1x;|t;L<9JQ75RmM4r=hPn6R5u#s-jY=;s!R6D&H)`yGrg z`?fNF*zu9Qmb|vjhSDAfq6Jw-KFTs9kK`^Ao=bYi(||X?QgS`>pHEPvHBq z??K&*(E1DLF6u#m`^n(HRtISRB0Ub zzKS_{R=lVgy>Qgp-u;?&Vk7oFleS!$ z+7A&01brNI#i@>1_`NiXxG>w7v%U=-*81DKt^GXZ>%r@FFQKQXbCICtT>}415b$63 z9M2Ym8hJ1*7oJ8gP%9OgpTl2hde=twD8_E$p7Yh`nP^O<8^w#V2a?OX$omovkUs?t zl&}c|vJIw&|41f8vOzh>iW?S~L+V2&q<@h3;g^~$y_vZLY7V&kqKP_rlFu~uf`Jo# z?5jX7@L%q-&i86hiD$w4bNJ&gK+iiJ6zi#T0sf2ik^#do0{5bW@$iqGVD-`g#CYDx z+LPTr{&6PaUc)N6sru7dC_r^px>i$niTIw?^%5UK_t(oekS?GFWGi}mQU1X&RQW%| z2_pSa^%tQ9bM}F31mpuY!XUW?{ck&FT|alw(*M|Gy~~o8d&cAH5t{-Qgu(xan=P!cum$?TuFsXrEQXN!U zR|lE*RR2=-PRh_g94d+JydUTPr}GWORlaK4Av zd!Vb=km=x@dS?}&U--_^W~@b7BlBMU+suZizz0h}X00{*T3ImX}_?(>u--?x>V zC}`hf{>(u1NqXt%H|Cb5p6)@uDQ~Ek=Vlh8Aw!#CJg@=AgeYDBeaJ>oj35qG`4H)Z z3id%|k#bXIJBrpMa}<+20UQGw0ojti9j;|_nC}ayZ$#Xw;%XWk^yjK+Q@?v8Km($M zKnI}?atS(!LtGZF_u_pAvAG1zD-8RK#2dkT)h+=4CLrh7L2NyOU$cCS?~jI&^$VzT71gyF zu6erO(SVl`qJx+WkWQ%K|DXp-=mdd$!=ke#p0(6Dk6G*0*elMr#LkZ-zsBeFd?LM#AC-g*Bpa` zm|fsvM!`o6^NN8E#+3)y2%?dgK5(@x>JNc8$pLHu2jD$c=d7w9qPmAA$pgSffa*lZ zXL!Yubx&LC7kAqbwE{F(;Jjqz?jrY3$8kFFUwux<-DeL-^0B7(rX=$w)ZT;!Nu7ThkuJ`z|}mR0ROp$ zU6xyfZK%4qvKgJt@ESb-qILclzQr@pGXvn`Q{K)CI)AQlG1vF2;(d%0Ndm>!(%ot6 z_(H4ofSH8CUUg(zMq+zW!g7+xDTgYwXgxg*!gHW2=6;|2JJiW5}rf=C{ObqW>L zwTs&Yk_XhYaXy3U-GX}$s&6%1_f&N-Rr7GDf&DJ<6AQ8r@gK9`z3aPy>#66+6H4AI z-hgl)H41Z$58Y4krTK7_$n7YRH$fD}r1!Nx_ULK0o;NnZOZfiI zUqCN_W7!2&JJIKn;tRLnrNuJ&2`_w2BiuO75M)@I136IGX^^*PGd9Siq*-nl-6|1j=zeecQL z&&x<@hW=w2OMSh=xS!Q~w)cZB$|^A8iA22K_Ks&iLr zXao*fY0+V9686CX|K)mUfjE-lM2Zonh!1xC)IRH2-fWqk0Vn5cCA`LZz8sSKA;QwG3RImjE zZ!Ihh<`k1#n&j6i@C(#&>;mkF_G>(>s~JaD7x9N8X%d*!;nFE!_pa zcQO}Rm@jrfZ9nze@l7<88e7ftYi=()n6orF2HpSIVjZ72Moofd=HyzD!CH4FdoT^o zRHH(A1KZH~irywDBSQowzOOk%#f#0giWMtn+{Am}o;YzHe5>~Ppz;phw$GY>i8^8z zov_r)-NZ4pc2RjK6$e7OmSoK5@zj_G-q(4c0XNQiW1b$qpR%1icS$bj&|lHSVAG(b zHzlp>YpvG(*;ecNktS^KCL37X#9UB2_Jj6?YX(k$)7C2FI3MD@A@Ds23^0G#_lBdE z`cJG;{^`Tk@n_T!yz+!)wowDSX1{02B=?U_$cI;-)X(`mmM({|#_ktA1be^@>KXS( z^48OWq_1*@a}`#UcJ*7|Ue=R5K`oFCN$Xz5JoM6b>$xaEhdWO$#kN?UWG!m94Lrjd zq$B(myM2iHOI2%l0ll+lf8cQ~vN%$X|zlLRj_|fqpW8v{7dEwuQ z%MAS@K&`eOe&2Do|6at`l0Rej;Ut4U4?Z3X_n}*X1}6GW`0nX!Co}e*0-~4#aRt?! z73T_@;~kD}q+0}mPika&xOZsByViVsUwuB=AsW!W>u36LCgNu{$6RxoyRp6}888`|IoY)qK0m!9ARG!Ni~G>qKr`XD;r)g7%ozdUF!*#+ z#eaB8{VvdgTD@L4=JyDQX9M1++tYyaAV0Wo?_p>ts!cUOdGtH|(76e+D>FdwV zh@2f)jpJN+2{6-7FZzl@xX*a)OyB=(zh02P8t*vHg%LPgMj+@%J?}((HJ`>~ zqJ9Sc58nyAuJ>i*oC)%6K8^K4UtZrM5a*XTZ^X~%+Xw{SuI-oJ7X-Ur`d+W&{(bFl z7G5umz`_WO9)Z9&K@O}v6P zkOAWVp!Y*NThG35-Gvc2+ebh=CjJZaX<%4=FU7DixU1Ww-wNdJbofb4>qJ|tJhk}Y~q_g**_MqptCPTvTK2W1BY z5MR!u9H`~}AZt$F6EEC(VFVUNpmqerry(XMnIIWZ%e%F|napclBk1|~`DA{(@STMb zSQvr18-c*@YJ)78&fSA;5p@30(9n#?lbnca=^X*_ec)Bu0H=Bgmy!YV6{kTy ziQ?jLs?R&0e;07!@S%Fw0GM(A3Y^D5?+e_XTiSQ4Oug5sK!trT;^3~K>x>Pq{&v(S zf3BL`^o{+V*cxesEfH`QZ|C#4pUHib91#Bp+L_9;I67P4|EUbwtbRA(FwXx~euVc* zaj4-_x2J)src{on74MZSKu-(cVP3(@{!kmvqqip6_+JLQ z0?VS>2WN+bd&?T({)Hm7Zsa#C@c$&oclN#}{*@gdei2OO2;b9h z?4uXK{=gSDdEqTlC8MOZAQ`WPs**Z2JwBsxGSmU*?+R^i0v_oHh%J%%zBg62eM{MuEY_)y= z@^}@Fe|4LkxZpYKxMsJdRvfY9<|CHb-e!Zl`YqRpUhhVqWYH_SFA`vgR{fRFV7#hW zKc5XanNZ+M754w8^L(b?@I5+=xZsiag|i)o>5VTf95Xxu;uGm{wL!O^>=yGmuQ%|0 zXixSmXWHiy(c)>Xq*V0Q@ptrk09G1I7p-r9+R~4mu;i-UcKoZ)+TlOhXh(i&jUE57 zTdm`RtE}z2Z?cxRUTG(mTxi|(U$dUXH>{`b0`{^Ne5(e|=k@vSbA6|u&--}Y+i}6+WrsUXieXKm31~;ZoPGvTBhz| z`1exIuVk;|YuU&AdiJ=!fxWJ8puLg(uy0~d5MRCfh%IoG%p*??R?PGsu734Fu4&b`1o-@VjM{NT0L^oy%(*B7_g(d*bh{ZaN* zZ^Swn@DCp|8r73pA4P)t1kSV><9#(d7|%Y+@~{VIMKCd>a)Q2 zp`EGg&eU}@&T;VmuHM7?)r1(ID+aGwx>{*m!H&=D?6SsHyKLXzK59FEa+Mu@_tkdf z+>5Ne?h^R!a(M1C_A*}zKVAdBUJqOch}UldZn0A0W-9}g1bpt=>o~s#p1umW+RF9U zIjA%sBLs;XJ=EW16`)XmqZN3s2&m2Tx2=Kq#1FlvBk+=5>wG>P!gw5t&_EnccVE@FlH?{nx*(6gn=dlf_*?~`T<|g2 zLOBP`51|g_9a9sY-zh#;Jdv~G8xPxS_}~XVeY>^1?P}|Se+HahzY3iV|DlJalf9m% zO$fx_Ks`DfJ|7P%3E2R$2Rzs!_|^e3V-cU#^L`AB^Ej0GouCv!rCz_e0U6@K>aXSA z5g-pF7b?i6JTht!dDV|xNMk3oo%?lb|IpR8?~m@b!+SweE2i%9xWFzztS4h_VJNChs?daRTW^F%nlf8D~p7>eID_Zav-w6*vTd>`7{&(G%9;(779sG)w%i&4R>*0MMSC1bK%ozXI*b1l2_mLgod0+hRLHr+wT>aHHxadmDorBM^ z_%fam8G+9-NL)d_Oc(Ot*qgp$2R?PZ9lhXLOK(qFIpuA>d_XQTAYUG`!7|np@-^_j z+S;R*eri8I+h2#dfM5%pPTlY15js-&q5*H36ONz9dA$Vk;;%m zN9+Ed?R)1^+xM9}?fA{FTJ|8GL4;&U)PDZui(20z835e?wMU?x(AIvw@EUrJ^uESO zJg8Rhshz7M;HQ8S98C|?7jFYPh9ZBYKxYQwB)uWxi_@)w-dDr>tKs=o*!Q== zZcA}zwd>VHUInbcHl>EvJ;Cg z!oIx{9>3X2=`{hAMuD|3%L_P6zLYzG!Z&R8X#1l6X%ycoa`DWz74e zn2kQ@^ANV*5I#dLk^z1_%UECbKbJodr-2}MLOc2wk`f~kB=y?VDO};&C4gZ(01LENIzUTcjiT{Hg5cK|dZ7u&- z=MI>c)LcSo5ix>>rOpn}T!L~J3|Y{RZ_s+)H|)UAF1OZeUb8|{n%^H4e6JijWRMs^ zz9QdCF<4{(#1!Oypn<94eQatt^WTk+gU;vr(A-Xr`N$-ABMZbTeMLL6>9Fnlr)TZR z=Qdj7pKP*2UwP3w9ws*2C120uQvLLiU~r5q&|I7N(m4sTVe}|K)WECIK}-gO=MJr| z7e6!<4tP`7a6Hd-{hBuN)v)rVd&q3DLpzSz{y)0Mj=%MK;#ka=Gyg7|zEHOYo|f)j z3GJ={R#%~x{{z2Ug6{y~b!g+Z|9sZ})8_xkMkpt)CVqIevkAOiK-{n%n*h0LKn|Or ztL|&I|0k}pBiFoO*)DH^Wuc0`azA+Kh5NI9{sjRM=86~iAA*e?!S5fB4`N@Pu~YGr zc+oLdp=^WjKhr)o^kUxje&!)N{KhMo|5}c$UxDqs0^4te4Sd_}*74E1Y|rQT{OX;S z+LN>jX(T$thkf8({(@rdgREO8O&-@!eu8X>GPVTQ=azX|&C%((;}D)dv;}Bpkni`q zYocTDPs+^cYhGH>d>yIn89VZOTdm{VThaA5Ih}6kdTY219*%=}e@xn48Jcw0>8w?`;{x;=l`eLT7%{qi4)Y!4^$fP`(sf1xswIV zA(W%p(d+1|f++KwzcU_-~VP7vq`qzU9dD2pWT;t75pPW3UI{3m`8=lxn4=w*QH zN`bDVh~toxGrX|ufh_ZPPut()~D zCEN2e(8t=tQV8ylw8kTFcrPfH9OY*%@V_4)(fVA+{B>vX795Ly<_`&=ZU18vIU&kl z-E7%K8>}D5*55}w{66fy4e-`_KDz_B57>xZu!ea0t;C3#Pr_D6zT-}7`qaaA5>jvme5bEV7Q(OB19(yII#Id+fmb zZ=$c)aBuWJvHDVCZI$mA_0|TtWOzUR9b$&$K<2?o3OUeL_f>oGf81{A z&EycE43tSYq&3O#eo?Vw>^SkiTYISZfc(a@^a%7W88DZJR)Q(-Tekb*ZToG{TQ9}F zmA>C*1B>sm;yLTAaL#%gTC&at&bb2}`w+I?{Z?Ldr&Si;W`pOfvK(!>ejUGC2kuum zSO5LI`}ACD$}l z^4VwVWcyu*?U|py(e^i7f?tm=RQ#@C1$|sbA8$oQ4eNf%fY-17_x8Kb6`mZgk7+At zuFuJUI3G{_Tsek?`fIFt$u-tbPJuDMS|;DPojBon&ntrw`SBa&}$3jRUJ8whPYm%zPO z6ECQ>8+ms{KQyRDS*zM)oK2)~+JlKpu$v%hqncwct# zY#xF4eJk5b(OEEo|KIVyw!y0_;al-CIv)Nn)ZaS-^6Q~-+CPT0o@ z;4C_q3{W2MY#z1zUxxqtQNW7HH~-<2@R)Mn#s3?}>+Ha1HrTPR@359Ft#;zMHf#Lt`|RMkm*8`(pkH^P z(-hZNjBh>HykZ4uMnMI?YXrpjcuf0$lAl*)K#acwpHI~0$Q{Tv zT;*hfY=I$S##z=M9)8b7c4X(93+*ch+xFME#`#}nw~M+_imGJlY`oDy&ABVvAHCT+tOwR18`j}ZU^8Iv7s<<4e6K`X7AQZT&*EUr0gM32 zi79~A0Za(Q2g(zH=J+Op`epQe0;riE92pC^m1mnc9#H#vwVnv;e%$$V8VN_&+~I{&%v$*$=WIBrhaOBH%nO3&iW5--l&H z(eXLF4j-3vjvR21@a-_KGuNm2z6JiDP$ryy{`YH)s&N5$zKom@6p0HADVK@4!h?(c z#`gT}y*5bR&;T^qufzc@?&ALf|IePJQOHI7FIlRi=`Wrjw`T=7xgS}+(F*W?o*3X{ z_5Wzw09%0hfB4JWyDy zoPjHu8@kY5eD9Uky#4@m>DZoBG3AMRJ0Q;MW1UZ$@E5)~Vgy_c9`6k9?X&K07msa% z_wfOMlJq}NoP_^BTK`A!g2*R`>-@3K^YHdC!1tQtBi>)chnN4aIN=DW;eYQF1mB=0 z7NFR`Nn!yL`u;99;OhZY*A3Og0*bsI0oYQ-7@U;<`F%VGA=m-qwMFW6#G%&zuYK*~ zgQ_jcJmD$i2TbJqkL~}D)c=OAk3+eE*Fc5$-FjpE0?iNXdMot_|Kk;7`Jl5+`-ltX z6%#}dC}$~Iy2UvyAAiQxz$(|12S^Tp{k$oxPLc|)y#^r#KC zkqZVT4=IBfIk3S0lV?`V|CKZ7Y=Cj}e<`v9`lvO~D_~7wFZH#g|DAm= zAHNFz{W5E-r2EZ5l#3X?Uo$UIwFj90FJa?*AT~gK6G6xU7_I*`N2s{~_e$VrHk$ei(71TNf)fn{qdMu+A`1yM8!^@8s-y$CzERVi> z3vB@Z8^1>gzeOe#$^R?Xv(ErfMh-aMc5`dGmfoX{a)eZ$T)$Dgz|{{|e(pH&z>xnt z>hl@q|4IXW00RH3)<{wD!Fu*bP%bgDAc+jv`-8*?cXm4sm1obzJasB02Wn-&sZsyJ zuatXGfd4i3lJ6X{u6J!g{=)zD4}cr32VyM%P@X1)ynu1rXs#gG31N;fv{k)d8wUul zN7(}-*&7)<><4Ox@-DR(x=YwbotA zoVn`wUk!e4puGuL%lR5#tLwZ=thj`Ihp1oHPu0^(8#z*;wTBog4?3Q18 zniv3idx-}}@W0jtDK}Vc9Kw4ilMmzaeH0%Ie!#rt|HbHY)*U%HLB68&cqQWX4E&Ws z$9K{8d>b{j-+hy{etelV{=yx$^A8`g9sfk#;cK?p{*}+$k-J{AmWK~n_fto$_l0H~ z*wF^Gvv;4M%`#6nS;v-x)^g8YYh1U}b}f6xp1Nq0z4TX)+TP#1&ssjQ+PdF&gY}%d z99!*j>m;{+5I!j&6N(O~?+_V7`}jNj_rH*H|^N{jc6&qj<5jT%4T&d zL@72C&lOnU|FL;}taqJ!BnB|VXp(Yajpy$~XQ5ME3}Dy>P+q`9FjM>=KGAMXYj@eve|^r5{@OFv{^7f+ z-+zs@)L%;fE~KB@gHZebuy%*FIAyID!Zs+v+p+~th5rk>R%8d%^1rVsq&fh8U$d$l zh~&XA-$(qv2;PoE)gD0q^L`I?hBDX$MfO&#P>ZmQXKH;bdl;=c=*CCuiTjxsAX5+v zpuE8UqbO!_Z#e#^9>ZX1kg+sNKhbHK^Hl2tewPnW?|p!Ycwe8*cm5y0J^*Wo6UaLU z==D%Hj5$YNGfaB}V6PJwO;R7Y{r&e?^DjJOd#Q8MarbfSKiJ0_O4*{}&^f%%OMxQT zqEO{pXrJyrKJ5Ye__PllCg|rp!)F=ZPXlUIF(uSYgu1zcYH1C+GiJqQ@j98|P%e5Yt0W{ zY`fq74NI=x@Nv74OXGzwojpJ5r61B`31{naiUV~>EVy`{Mo_H*dvE5*)=9r(d5 z=nm|C<^UA~%q2F#-^>Y&u>D8c1JmaJ;0J^@M_!KeQA0|0O;fShR-q zL-09%yyJD{186-letWiodIC{yq3Vb!ZkK`Qd!^&wbfq2o_-Z@wS5I2Y>Vxbl&`Yi4 zkz*<9693~txql-+^{;$=Waw11>VRL3qDx&VfPNRw;dsTo0M%<1@Yl%{$rV>K!QZC( zcc`o1nw~sn$1i!w8h>e>wZG#M?1J-ouFK#fcntqV@yfvl!E(--OMvg?hnsTs7NP6e zAH=uUjq(SAe^AoCq?1^8TtGGykf8;9`~rOMTb)P1`Xa3x7N3VYvk|%|Mw{b(fBNrBE_k1zK*tB3$yoE(U$SFAb%z~& z^HMurcM;EgIk5rag^Q5|>~U0KZv@R7Xl|i|{~d?G@3rkz`M;!?KlXi<@5kZ)FxMzq z;N*Z}mM)fYJu>WK+xK1Hw3O-$x@SZJ5)WM9e>WUc`r~T+TnkA z-gf@L4R)Aycxh~cUTT4rsl{OADyY_qlL0PPAiF?$242sHwpI>|jt7j45ythu_+K$f zf#g6DsO~$0{Pi_OJ>NV2$A2h9>jsr8toO8k+jHM_k#*j8!r?-DK`38%LH|#UDy5e+ z|JSdA-A-c+TIQ*C>wfc{#FeS#gY93a9~txae!%?af7$&`_tR$U?|}EIKZD-S3h)~` zp{YaYlID-xVvS$jYQ5XLt)!qFha{o+MqYcKLgz!GF9qh@ypy7J^IHN`n9~t%weNYE zA}>REMGv%3QWU8G-9v{9)_CnMd*$bs+2JJ@kau@JyhUyh{9j@Yv4}lT!X8k5K@t8J zjK}}Ac?02f*u%VtKVO7z9k1i#EC06~=Krzpi$K}=CD{6W*VPW9Za@XOr2WW>k_#>t zcq#icu^&4zg1)*7?A7;QjBUdLRu1I_2yqMczZ;H8{Sl35{x1hPQ<>4xd$wo54*vLq z!~j@}kNzL3-{fL}W#qtkP-_p=zMg)3z{df?d_Zj*<_$wzq()((f!rZ#4JdzUkh&wO zMRz;Drk8yFedv!@KEA>ZU$MiAEzv0SXREsq+-p9OJ&_v7b7J10K>m>8 zpjvaF9K#~Aa|96ci`xVxeqSKom?Msm1#-$gaCyh#ZRz+Mkil0|GyFni@VD&18!oiA zH(hESi>Vn}_itSLLU5=15}$POK;oBtU;CLWXQ*$<`Ln2gYOMFkYf!{4|e_`?8k#2T4zVE-eHwy>2a+) z_oO18330aCRgwU#nOw|KIw-~*vo&g+77+(V#bU3 z0P~$W(Sg<%!t;*zIUm9Mk_9#VU*L5fIWdIX$P#NT0a+RrwJZY^Pk6Grqv~@n*WV^q@eCl_9i~Exk49;|I9|u%y(AN>jEWQH!;R;?ag-*X= zdw!CjC_UzZh#-K8Dso1*7@j> zJ2T$Vvxxr#o@-luUe@PGfPTh8IR;DzS?V6-z^^Q`Jxjg;&l0bb&c+Wncv^OV{Bh~{ zsvL0q?`sh%&$u63zYlx95B}_f-;>k>JN7+G?bV-NX8Zr{aXYbokLC9Ex^;eXt0alL zfj&S-`hgbP^#SEOUO`-v*d*5rAX$)YAP;g8K7`8=Qhw#v?J#?j=DQ;q9oPLjUpU4b z0Z$Lu|KMI_S1Q^EnDgxZjHSMpH2~BD$in~Q+5O@DT76&p`sDh5eBPH#2Mx9V3$WwqV;QzBoD6Tv!&FL z6W?B9ZEwEZj{MLHYx|RJcJvnP$?fgrMdc$L_y~$@&OH8z>Hw?mdmhZBiLLZ=|IQos zG8c0J*O%N;93UPOyn#6G^_B$s6er+*+Joo_`;==c&>e9*AbM+|894$$A5`f+ifdKC z{l4Es_mlUZOKfJ|Ofo>VK^|~WrX2w%u@AJCAP%+iK>0=^pvDdebwFy{GV=qfPnbiex+@8K5UkWzu%^n_FzpyDvr0UII-Jzhge7kN7|udC>1{@C&T-+rD8(KX!@j z|KnA5`1+?Uwe7f-+Yzwwp&o1KYCc!)ljJ}pQ?{c&s`}x`9px^;{{bWmWCxV6OH@Cg z>|z90TB`mcOI~rr;ak!~$r`fnR6k(h7(D{x@xQ)#mu^+|%(tDA>?z;cD9eMK#bgAckNt?O4AH-<5wL-$3J8NS1B?r7zj8|8t+EZ+Xp1yE2x=SnuI8`R_hgLf=(HNxwjH zAa|!S^rAn<{{$nNe{~Hxf0sJnq5%I(1_VDK-WqX$Vgqu3dBq%a0(*Y+a?3Vq=TYTt zor(nFhiAbNa2)8z^N6fJ=8O;b+0p-UH+irdh_yb1jkW1C@IUeYG5B9RUjk(N%lA(b zb83FaE!MsCHTIhHwtkL4)(})Ugpd1r=6#WAz~4-fY#1-`t!hLR$^&qb-!H-$^yql0 zdGVK4J81o=Xa*;qT!{*Mw`0R|uDu=IWZYB)0N2zEWv+G54*uthT@0{5>@f%LD@V9i z2FMRkE|Fxw5H>)Oc?Rt}w&zdSuND!cn5O1%HP_|FN&Q?n+z5=t{~9B$2vlCsfzLk0 z_^aOTX6A1d2Y8UUD=~n2d;N7y!tL92@9_VW-_ty1fM|9kA#5xy$9o@gw*IG^2mx3F^bN* zf39hrYa(dE2j}cHZ9iH5mn<;oVu&2Co$vaRrC1lKBZnK{ zJremO!@RHavz`Cl0O=3-EHNJJ$m#e${dAY5zXQ9!4*g&M@M+Wk+FQ`u`ickKOPuEx zJMcE_yi0bue0*8_c@kJM^g0{yym;T`?9nb9(;I=n+mmglcQ<}bOyR)KuO_B*8M^*@ z_#eMM()%aV|MCw?%26VBIal`;+xJuC6gQz35Gw3ADx<~GIe)5h;B4oA`9`t@e4S-x z$I+o0rp_I$mVPI`|7qrbqH8cg!jcw-IpJ;=BWOEaWU(FPXqr;4oC(l z4%kf`V$V-MVA)qP4v$*1*pEk7Qk*&Bd!O64!2fQ5&ZIwb$+fr|%G1$G9$%XEh&gJl z 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�lhZ_DDZs&WZG(&aAhJT2-p3xi@7Y&yG z9@7^tGIgAt)h=7hJ-V0pZ`C2&&b4lGohSA&_(Hzv(eNid>J|D_e3wU2Ru{xUw#DT0>qa6hc(@P+Q&4+-PfMwvLU6g1)z3M z=vxzmzQ|9e;2)V=)G}E+Zm~B$j;;j$h4(q|pRM5U^x0`Z5%xt3%IWwJ9RDjGh5sM0 z*cDr>dt=K*zWVd~In7nHmi(K@D&w!(2Id3)g?-V0QS{};U)%0;S&VxjgZ2>-Ifq&w2q`%1+&Q=HJO-?Rp5*QpIai;D5@IZKN) zXA$;w)IArs(s~`*-Dh1dc^v+P?GK;-ocJ%K4LqMt2WG;5h#?UEA^*3(<`GMr z4pkf@-E)zqW!9e!>q!wZ*z@_+c+;?rUoLz99pIjryS!aZ`Ld@!|EQm50{_f$uxpxC zewo?;@F3;hy1!61wXy}4`-{#WEg!yzprS`k0NBXq8is9M-N`-JT&P4vaMnFXKgh+5aK?9OeJ0#q#D#dYkKb^ z_*IAzAp|*ZHNxYp|{hypf zhXtQYj(}C+`^aQ3#J-+CL;On~NJ9fu-+K_-a_!217ndU!a1l+&J9*jXe19s$CI$Xq z`Oo{|C952_j$QEUu`%Fzlzpj1#saOt<^$aqMpEp<7kjPf#0J*h9mM%9KK{qRcI6-J zDw+z7H{k!|w+?ZgtGP~cfyg}!_}5-L>#XwnC;d7l*@RgsI!%eZ6u;B>QXT!)^9JSU z5XTJO1OC?*;J?TocmepA?Qo3s(f#UGHuzMJ$02D}bHpWP2nJkK{4*D-4KW4()GJSq zWvt;>k8*E`U0njcmmHni&jbHC_`AXD3wy->gFb-FkDst-*=Fn6RqN}hFgA9+myWQn zc&BLZ5FI1g{G5IZKr4S^VD{U8Sr zQ(r%3BUdV)PkH;Q`@4AfSMH!>0OcXO_B?jPDzeeF-GK#KO zdy}5};(q^%DsMU~6VWTt=JXdn7yAX}X$t4Ja=)m*s@g#Cf7L&pPyR3b$HD)=mDgF% z_9pkQ_&O*B{?9!U{wL*s?4+#HWPi$9-+Rn$e^z#k`8ZD3G2iDA|5=Y4IADD*pq5}w zKd6#rZQ!8 zT_>_lg#QHBUiX_pZ}44%7V_pr1G|8u=&|Q(e`+6m`4;RM>q3xGDb?l1j6>aqhA z^vGW5egbR^aqXMj#Uo8BL2OE|aU zc9LZeBDX4LP|u0S;TYuc{AVU;LqsEHKZ=K^h*y?Bua{ba<8{hJ^rgVKc?N%w6(Bv9 zur6xbe`_B8YWe2;FVq1fyL*EKLf7vB*;BI(3{gu7QE~}Zl)!3lm{m5+T zvi0}`)}X&B_fmDxLNE3Q7Qa4Qe1K{W$iCA5wbQOmi5tkSqFUu_UA=hvKQrO7a325M zI=}bvssS5#CD@1GXB_|Jhs;3(&We99ZUwy%|2b%cYJGM7963TFJ~Y|bqc$J-*E!T9 z{1+di-#XW07$=n_Vx!h})mpAiJ~Y+F68@BLzs4H=c(2c;>j`d--_B;% zW*+~Vko=lZoub$~wnD4X0rF!F`p#|E{YvT*AvfrIifxN06q+N+fu)Fl-6J7y_^D3oeF0-d?$1=50Q={O|FXRO zA8ZF1K(8lzA^!FE0pk9vK5+!OEZAqF{1YEf0WHw$XVNYd@5R5V5?Ufv!w1@|pZb2n z&LsZtK~G*~m0u@ril#d~@%#P`zVuHX21je4t<(sV><_*pOci2OJYD{|6!N*#7H}5_ zqoeq)2bZtrch*8XsmlZArAJ7PFZ}-5p1aJzITOnizaaeIiVc?gRM?~+=3iI+&Lh}5 zR1ftnqco0Py>=+u{HC z0SfS+D(I#82^3X|M=&Qv4=CZhdf@QE18eEnZRG34@c*I zrbqejWGQLB?FhVH_@~~N%K*Z|J?!{Ob+T*PiztMvh(w--d@1gOXFd zfILr~g4sO&!(O1+3D6h1U-FQ}{*$>nL~iEIr>y?RAA}yLwjFc;{JX3mdEp$oXXWsPrYAkfXDtW(5(n3lK-QcWT*drH=kL_HA3$u@Q)a&D#v*pP76ZoH$|K}V3m7m%q!?Cvv_Wx`N;9vNX4LoYP?|nCSSZ~E4>{=(0 z4Q2B?!TcPbwWq1$u<@yRZ7tDv1P0j*Rfr<-3iIu`j@r8pXz~Q%R`Tt$KrT=w`9VuqKT|F{LBRg`}_aT(Q1 z9RJZi^R<7x3;xggnS%e@ZQ%L0TY^{*HPJ7>zd&EO$~3V{HM)8hjAxeL<+`_O^F-L! zQMEQ@7tm3(K)D5Vue!_nj|UlB)G_pc%TZ`b^Do_x9&jU{C4NQrMEH8B*)O}qbj%mN zr&_|Q?Ik;P|NFKv-oU09x#M5s*6(#aTyMk3D?t~Dw~qH=KkX0Nzw>_CR-vzwPZz7{w<908MxoyIAI-$C9cFG$BOA*9 zKR5r+f`9cKy24EOFO~-)-mhbZ-|1QQsKxHBcRe#9;kqD*v=sS&@ZUfue|`t|6(5qz z{=!(^_y0Qf&mfo1XOkPuZFa5L=aw2YN!ie`{bhy!W#kRafPcq6_!ob2zMsebC>~_l z*fd36hlukFpFJq)Eg!ubS?W8`;@hb~5_F1Sn>Y*p;pM9JubLj|m+-wo)&%Et+ok(1 zctML-lCyldbe%}Q(DxMUc$2mM#$I1LTHU(tNcY#V6k7)0YzKY|e;f zzXks(=t1}U*u%s{XHbN*K>orYPn(^(`4Bcc#S4I)W#CA$KSlW0YvF1f?039u6MR3& z{Mv;*OA&GH=cl~!G=|6|&$S1SsK9tUYjwY<{eV_N19V>D6J33RKI!$;E*(Ms!yL62 zynYFEBV9l0_;-CpHWLvrTC$%ydRINnIfVaw3;@SCEoi~`IwVM_QDS@asBoLw;_Ue#7_hTG_^ezRY_S3VZUXRoBVD!r6OS;yTN!^L{?P%5AsRh1n7{7Q#=kri znzEK(+<6i3ulh~_|Lt#}=1{|c|8}Y1U+YCaK-mGptOWiq{7>+I$3HQ^=fVH8Gvy8B z<$#Fy>zKj*KXT>cHg>d!6)jn|wE4f*jj-6b;V5=*$?=kd;r)63FJD~c?N5Yz%;(&` z!u$%s!cY5qH*?LB39;)H;oo>I`(5LUZ?VB6A$MpDNkZq4A3^I@GI@v}3;u*rpEZ7H zq6K0wik-RPgZSpX-Zef3`~q2cwrZ2ig!}Mbu;ril;w~S*eoyWy*#acjtDX3Q_J3XH z=MewT;=j-wj4|$xEp`4GaahUyQTI1X=0WoqNM`Ft*jpaIi81!sZ2x+HHoJfHezCnj zhrB<@|0De0Xt8V75ntKwGg<2RpDO>Knicyq@_%9l&kz3xZS?6&1OJj6g^A<;whJ9; z9cu^v8rj?7pX1mAnh#g;iNLRgg%mVR`oHr2dR{F#Ty->%8;bFdT%AOJ=v*K6jAL^R z;%bFGeic41U!Q(k?Zmg3vnP684ba~;E;XSvp7)=OjpVHUgZSrJ<7s?|N#X-k!)q@5 zE62a;)6_HKJgQfz-;=5l^m^lUv!-2@@OtGuNPa9ORR^d~Z0oleGn zc|YU6p7Dzw%Z{7x<>)u%@^f;1T<2V}!CZfne4yHblJ{gIZGSWM9vgd|B8o&ueX(s^ z)A0X~#rUswoaf4*1qD5eePBNDKfLUyjT}_&A4|T(@vjA~mEHQ09o$pu;eda|&SZ$+ zGxXxIm!sFSziuJd(`pkY`W~%;cPd^m()XtxwGJ~Yh#%@5vtB+w&H`~$ADeP$FC?9_ z_HXu5C-p|op*=WPS<~z9u))(|4IwYH?sX@Swk@aMIDK(WJX`QH89L)q`A zci~vE2KBF6Yso=zfAN3L$GO}W$m^lXZsHb%4PiyK3j_W~nTwX++U@d!|7r>2U)B?~ z*hf^;=Bf&UBVg}5(#E_q-k9zW-M`FH`386d}K za4B)L2lDcNZfr_E)MC>{UnoTns*lk7CdKe*{R{h&sqaG0zQKBba$C`-B`*Zt-MmsY zG!#EO759<-U+<5B(fY52SUSlK`fe|eTCuS&>>=hq_zpAj(^VjQKu@Z!p}tI2uoY?_ zVc}K$S2Q4E#C%AOS$O<+zkRKxVtM;N z@?6RC|04N+F8sS5aGvsi6fYFvzrXyjbw1MKbTM%W;6K?uZi6pU+|PaZN71Rv~YFOuVFiWzDAgPqpqx+*b2 z9y4?=baylI#8zb3TdeJMYptVFyEcgXf>tL1T4Sts^h}*;tUG7zZ&jR+WRU6nU-Url zkHFhocAe2rJKd4pA!sl>feiG%{UQHNk1N1m8DA>=-%ZXKd5QV@0i}$8zX+zO`Td*o z_?L{oaQK%VAla+y9qXv2JnZ*E`IM!Hf5yZ;Z~tl&cH<|Z@s;qHYSu)x^M5Pn`3ybs z3uKfpOrMkY7to3v&y{1;TXxuDch|GDh^ZkkBO4NIef^ap{~tKmZGFon`%~iwERK@L zlV<(*z)Md4^*$eW;e)JyYOSAm3j5$qTywDfOLkVDN&|?$LmpKQ@yM&T*!bHIS? zR2zG>Rjzr=N9`kzWC_0t>}DU|=i`w-K{P9k?{8c_fXmrm_lzps2YaDDuJu$(E!1yi zd|X(^yY6S)>zE74QS#$r%On;ci!M;u=hE@d{x@t1+|LBMTK)UhSh6G7YhitqBhRFlsf*KHmY|2joerH z@9zWuiix?G*xNN$`JF?49fc3Vfaq8&dwVPIPqFP06zzZ}K$ zvL^EQkFebG=lC96kHAg{|IhII3C28%-7L1X$!!2(C6y-rb#GE5DeHKfYBdEL&IJCk z`xRne&(DtWx&4PZXv#SFZ~S@qMPJB}DBJ@unpcf$FB+if~Epxu>fB1>#@!|BpK87B@3XCeg z4jxj0ERHVFi#*V^wQkBUg?JsVi_Oe>UJCC9)AIYxhJXES6rDN_u9W|$*E8YNWpyyG zyy5Y(2W<#UhZqFx0Y7}BwH=Fm5ZqDWp9fj=hMw;AdSjw5Go4qoM?S#zPwv;(_#To! zv?K7%uu|K;cLdwxTCV>g_(Q-fg!hhdA-S9N>d6(3J|I_D)|LO6; zRzdAB`b@Zw-V^@2*!$ziKL@_4$dOXTf3&90{PAO~b;)(q?gWDgYydfO0DD*9|E~>p zxafAO*0b*SX!EEgE|<-adb6yv+3+v^FWf6GSf4pN{;@x>hxa%*RE+N!v53R`M(pbA zt@U`P|8`jMVMK@j^g-nNbxylx#6R*x3jM!ZvI`PnVrxUg>4%5A4}~xJB7bYd4i!ExrH63yFI{ELUwx9;%3d3MAjW=Vo7u2QeoSUYNIa$&v<@rm1zsaD#V|AU>FrZps6 zm&a`}n8mhn72;p_ZRq3x_HD)e)G`(|Eoi%TtEG}*ed#`{ zMVP52roIQen&;R;Gv>m7p*`?i@Go0nA(m51C67=S6d7fN_?EGyl0Vlw4;m+Dq42YX z&kONCu;Nx5uO9ZR)-^;lK-ZM+Nn8Ib*gFfpXBIG4?Gk6D<`w&AGSH|QB0-q@Bi=v zEH?i2`_cWCbTry9Vm+^`X6?Y!%b)?W|H%h1OOJ3~i2W(gk@2(YksP3$p?uGkonT!) zW_{OEKcGwVq7eiR8jZ0aVQL)bBX| z*L%bisGhNG09{+K`{?@hkGWG<6OHS6*TeXqh=EIrUv|eD83(g2>KOpy%7ALx=qmGru-hDS|g5qg1eN%z4-VK_g1t~0w*w zis-`ZIzTc0LmWY<*(iHY7CO`Uyp`7TU=!R`G48Vcm5%*y691z%k|feQ4*ow~jZ7;W zVB@T~k7&Xq?#~zhq6PYmGuFah!4lKj+4BPcb*jxmTb9=s+L0yTnF0UI13Go}7x(JY`JU#DIY5Rgr8abk{Xbt!-V{2V z_C6B*o{oRs2mgA%Sl%ywJsba*9H3b1QS`pp+sO?(quL*V?`uXP8nD=N<6~isCvxDQ z`cabiI#yASZ%GZ;-^iMUFPAmU+Mg-@v-lJe*aXKajv+rkZ5s1TG4#SsmhK9Bm`3<_6@a^=TA&@v<=cYqyRBUOpW0>88-8cIUwU4OD>?kP zZK$&$_Fo*tPLg2n1Jy*Cj(=>X7l{8r6ImPNg~fiB`e>bDT?_Z6hJTGGkxE%S9sJil z+d8fLO4R@p?pxUNu?{+jF93RwF01#Rt$;SD^M1x@h3Lf$9lJngj-IB*c!s@(2Htwa z5*?C1G={w92<8^ONmpYKsbtpr-uNJET)r>G@(BC#d)>@FfZND@%lpfV23)!3337LS zz-R9zS7zb$|MTYm1u}xyA1hOhf_rRGKEV8b1JdQy^r*Q=3@6zSFzo*w>mlSih4!`XkmRNxghx-`#ynGpSV!G6|mskqDo zty7)lB(cwKHxO;-y)^oScVr8vDI8UYE%v+j8_;4H!MY{d7}3;dT#I$o)TnC@$AmT{ zVr(PFhOGN)Vs!BN*^;^OZx!`((||d!FW;hQLyF(&d^tAq1D!q%VfFaaMSoDFhOha) zxD8#k!To6|>}di2+5?+7n-A~van7Xgp7`?a3H+zP|9RQ|=CIda2+n8wuJE69{|5UQ zmaVg%hwA;h0{R2~eZ6p@Z9ldd8{lfkz0Rk2=q$9c=T+n=j!KGTT|qm~SKjh3&gVlk zc%75wExU$tHO8sEoLnC6<4pL^$`^`1qKxdRijz?}H6fqpiE zDfY8kN^OhpLvLu2pVnV2@b$sN+|D_ksrSBL2t$;rluf_R&E&l-cCq_V6?q|$3|9Ql(E8_opAzG+b{c-kf z21jlK%#Tqzz%aIssD6O7hsDId?uGblWWR~mjav7c6|Zrt4O|BP$z6`*{|PxD&;KJi zpm>foH#86epN`rh?xHR$Dx+xdUs z@iWQ)5&m=Kb*$^qC$KMlU{3tQ`^#&Pshg3>4qL-#(FIswJ_POO0T&7X z@*4=t$+Cx`QFlStR@u?d@A8TFTakY@?$RRrpZ$em8rJ)FE9EpDX4;^ZHu(0+MI& zO$rYgyS*Lc@VgHQQ`oszRos0V* z+M_*FR7Y7FN$g*bz-v^qn4HZksL@aThRFUO@&D);?vZkX=9+)`2+{jp|If?+OK-up zpm?aep@rmQ{s^}JT5$$in7WHQ31|5=+5N_oNw@#$xoDJH>zY>UXa7&}{~R{JbOpKH z=YfCGgg^skunFerK$>G(ImSz?z{g4JfBrG++8gs}@>(`wC}+8Xh5fT^`f8{C>`{2) zYF|6f`>_>?-;FF?XCsdjyiCieU|%8rd9U@KpG5!vmfH!(SbK4FrQn$oOilk zP`*L+A{)V+>u;{Ld9Hs`470lO;T6N9dX?nzm#?;t+iU!~#1olDoxu*!`WorgcaZbA zigT^y`>MqyIzkscp-1>Pa_fSgz;B_G&drC;73;|8(p{h_L66lnurCGI)d%iX!=UHY zTkXtew_4XD#C~$=?$ONiel235Ni<;SRFCyt#u&MtXl$Z~L!7VW=abEFJ ze|Mc;wkm&L_C4WM^oHMH>|@9?eHAxZ z=a1fJ)x^Yi?I!LkZ@br+kqo&G@ROf=4qQ{x_31=^+Ip{|1`y|oVh(kF(a7$1Y|HOm zz~?VA{$1t=`_lW9Y)Y8oKIlF+tv^BCwpCpFcKTNI9p(JOo1F$+0R9y>DE_ab{D1HS z;XjF7q#UExRY5nzs^;~WG?tQXkN~Hcu(FmZPIBJnD_d`UY|hny?FCl z_eBnn_tN$Dhppz%sVRJ*)%{}mQE~4JW0l!WNDXgIc%0q8-;3&^`Z-s4m2d_au0#GB+;Sxa>1JHFkB zE+`vb4>@JRe2l&j_!kYRW$tQO|4&%QKQ}r~MyOhs1^dcP6b%4a7j^dhclpiCaN36d zn|yzY>72yB@;e6J8TQL@t0nl?niJYx4q)vIPwGOIy6`Vt6kds*k5&%YnQuR7P4C-= zO<^@yy$=4o#&N40z7+Y!M(uzI_tCKs|Kj`dFNg-Dl$XmIR-EfF=ZTl0&%f(IJN}Q4 zkZXlK7fdi*Z<<-rCMJ98!18~ea^M1lDYed@r%n*If{5Pe7>6eI{>THCV2^EG*TuH~ zr;tw)s`J9!r&!7IK_pI&*{L_O|Bln|2>ao9HvF6BkvPvJtXQV zz2#xc^#%PyYhcPv_Zcj$2hn#$u~Ipbf9yN4x7!An*D`OdmReqqzXLzUS@54LYlK%d z7RUs8K6}qqU>9)yU&HtGTU8c&KlXruoDGnZ;5-LD9C&{rY8HO(w00e<#QwFvllZ+Q z>sadn{{d@vTL1Eu*0z?sKyI%-D=Z1)LWq355$+>8AQ@UJg0BUhYjsc^jL%2cmbLz4 z9n=!uW9_deuYmZ`F))>dXJyMCzy`y5RBQ@*foMR4f7JribJgQbf!?`8Sixff@0ScvjQ`@-kzFP_7SjRQ z2{X{&3A?~7Q5+;HT`6;B}=c=?`N07bG+`Tbb91`)|_J1^tUuLO7%&bUw^N) z{`D~%YfA9jq3M~Va$S+OC60qlQTzaY&9p{3b4!yO5^HL;lN+D5_RsCM*z<0o<}WsM zw^Pb?sdcZI;OnjCv%CBx;v*Lu|0xXp5&k91W=E*?|A}p`t7T>P%gg<<$^U1=zsm#K z^FC50_I{5y8bywc6MGa_Ey0Qnj6-$% ziM>TC%ALh~vaBn{yi$RHuJ?~1f~U9Y;Djw21D*8HC* zt^T+7TJLMgeL(KezQ+ll2kaqWKf|7fhE07OzAAmA6CJztp-Ml8uEyz|zgqYQ&DsDL zmd587tPjL(9_X{?mnu$4c}>Vr#rVe;s5&mQ^u#T&`zU@ee1&QwZnWx`+-QS` z2bt|lyT#VFu+|#6{yyt_o@DhlXx}6am=*UCO*m)#V_(3(7+-c8THRpvZ#io5`nZiC zttKf-kQ)ap^q@sY_=r~P0?x4u>zp5EUim)h0PtRTU7FZ0t*HrHJJ01;RvjF@FQ1y^ z0_~^M^^&`-<~Md&<2vdpQ(sA=FYFQoa_rqV4lpMz1wnHtTtLdtsQKC{t9tQ`%+V^= zGh;#i7VT-i;ufp=!s9mBDY;%vD^EzDY?`e>dZ@7~?N|~);7-z4GJLh2JoOX*?|{|+ z^d{>jMrIfvfqF)AkNoB?gXHCX@qGFivd1Xc8eu%AKY%QfU-a@DTul96*Eh!f8fTsc zeTK37f8iqLaeprs|7STl9<^(e z@Y+qBPsbJOSVwDuZC&;MSpPY&p;#VM?3`@CP8;wG@}6{Y*^*T=Te)EUFTTaQ|H@z7atztsj03E2_< z=EKkw$@r1)&i|PIyUroXAXy}d(;~*c1*iUi{mHIT4RO(}Rp9w%#*R+Q_*2-ovdgi3 zk`oxk`nvstYfmA2Xb%MA`r0pFZ#|E84g`m#k#Av)}K6XqkY6BGmGL@x$MQ}|6mavnGjN~ zCcla8x7J!y#rIiLTJyoL<~Bhvo(2E$a&kS<1#_w`=h)eV-4wr}cqKeiwmjv{bRiq` zzUXeN{@v}?!M-^nZ&7m^kT(>{?l}%pi>K&VEEcPHd6#SD--gyl= zg!Bu<3HO@>-9GpsL_gHTk-GM`TJ0Ae!uNj%W6^kS#+FaafnO6c46^Jvv`l*o2>*&n zF!Y`%zCdwAZVN&FP)>9^e6M#SdZ3>li>BsGa*d1}7qfx?G5%>fYu6v5=J|D8)5A7U z!9Hr-8_5AvX}~1*MFY+k|EdKs*|jF_wAL%Hv(7E;zG5y_{AUz9#oCiJS@)gO=$-KT zCB3ZccCHs1pk9VOa7jBIzkuw5GxTZt!8CoKk+nA2v&jCLvO0dNfpt}BT^qX40l+>0 zNrL|%PfhYjhPR+i{A+Rz2L!cjYPQ2~RBk8x^nn}I+EyH#$9;g2k>%9FSf z7aaETKyJoX6mTP%fjl&1Yt_fNb#C- zdLh|CI=<)tpApSUAUI6u`@0zG8)vZqFhH z0l7X+o@^RDKV8A!9Y4a5Vi6=8tiz}NU8}qnp0}6vL36GF&D6Xt1n-aJnds<0TJVtN zx7}ug|LDZ~?uXt&yP&&iaIYTm`ExxM(}USw=Ug|^@7-lhKL$J#$C=k1+3Dxaak}<6pm1@AyyR3vB$A)5Ma=A2CM#UhHTB00elPgThFQS(2Ll^(v;Sjs?a_#Y;nlkIbglK`{K=8p+4_Ch7$(o*m09*;z z9O3VS88)%UTI)NBS7vOIL5y+Ab|?G2>XIq8P`2+Ba*gyB(F6f171K&<; z!Uk))YMsS?db8Dh>yTx;!v12OXD7L30b7Lo=s5MKME`=VwQX&+RaUHF?D+WdJ+lz_ zXaBWqzDu?kWL}&8_tQS_^07|xj;SLp^;f!$(z*M=U3@reEx%NS{#t`>-eMVi0cm1^ zQjY!k<^Pc^AU}ZUK+|Q^YQMLab*)%BJc91Cg14}~6`Oido0c|M5)P%g>(?b`rhCZq z+ulfQ&35a5&;2&^JjL%^?{a<|+$cWO_n5|3AMhXYe0=X7w>^tD-Ou$xGr*T>47a^# zgVq1_UhC=TpS;8ZXhrM4_$ZHsG+=!c5^gQ)E3NJ)R)gCgpudIOw-ma35?$VP5@eGQ z7mREIU-x}II7&v5T%x_s`k`wbFTBmV-m}9_erbob-h0v#F>$xhWJd^@?Gy}L;5Pkw z3x6>9{L@TX%?GxzUZr;hpP#V55cp3KlcAo52566ky5-RDhg*cThS&#}aCTe(XuhVBV56 zD+$w?9V=Y_E^d>=!98UNh(=Ba^!pl-x|;Ofq3RK9y8eV!eqxJ_T=5|IxdooPit7>I zRlE%Pfcx$O-!(9pLC+q+zvlJy(LGvSZvCpzJRq0;~Js%4>*IC6-BT$ZUEn}w=R(thH)^QuLfZf=Jy1;)Y zJR@%lh>qo|7ckk+j{o2vklwGJF6_h+W}pL|D;~GLjiH8uPbiZr{dSDw#hzc`ZL)=5 z*JIQR|EkX=yW>`~;kecP`c~_Cnd;6`3mTif$IUB#h;^Ei51rUCkM9MaIXy@37Ojx% zFiH$y(=Xj)J?!7BCfP$i5!VY`Pm^C?=wtn3qHX!h$E~MgE%!&dh-44h9Yk{!Ka9;D zIwQNip6fTH%PUu{Yw1na_zu?aKjQBv2GNBZ|Hbg2^G}=af;S4D7JO@dpH9O+1TW1* zr1G+0qAO$7?|q0lmQCYf=lK!#=Y{`!%umP_$f4g!W|G`5|7R=mRrNnT=FC9Sp`?+E z&!gsVzJ>o3J~vUb90E<_Z&riE$EPg2r{^IDhC78-(A-h}Ri(nLxI5 z)dylN@xFK8uLr#5?eU5|Y<~gqJvSVk7?|RD`4$ zH=G9Gqf#v*`Sa7r1*%`t{noqjSM9RSCt^0v`Gj*tKIXl6I(5mkLj1eELrNI7QO$xL zJO87`YL*cbg*={HK>Yi@huB0F^DEg(`Mw>`XaA+WoznWrLBIy8z|Q==;mIY}gemR! zmLdL5*U`R#7{Fz9teq~d8J)a5*Z`-<0N4iQ7l``V@E`I0=s1P{mlF@Pocv&DPQ&u2 ztm8Y-9@-#uX_zr(Jbo_t!Xo_ZSV~RuxbP`D5UmBt=RGI;t?nCCuioH(!_%MMVez3rRV0t-Sqnazrsw?tezcBzgB=0eeH{PY6ni5! zzF}nIIKIa=_P?zD&=#wI2;Cwc=!YJ~wKP_zTdq{_W(lIVv3q>;ADuw*%UeZsf-q@tlEy^r0hjzeQJvX{2AszwUWAV_fh+>W@TBPSALw7y#zxcDcxSaWeQb*j zRjfvj46&->DXKxALRU}Wo6|nSN$g80c`M4vhb!$W}_15xRk6Q1+u8C0y>#pNrKhWM(2-G43ekir|TZn(z z*0U(6U5uWPU#t7t6V^mdf-Tts{*~*qR{0rY$;Cx!^QU%nFKnBhIuOY0;i zr0WN@j(4}15rC0!`%HAFFU_McC10R8f?DSnW7wstx&Cf=e39&5g#9UULG(A*3nt@- zXR;XwgJ`5ch}lGGw-r6$?X);{=X)_QVCTEr=(N*e#?HrtV%NNc8R2fmi~ z-2PGVm)pb-0dUWk1?KRf>A-zR=(2K?v1 zzG6B%(c7B;;t;$@@|^@HWT-s;&+YD)?x#EsNc9xdxiOOq}85F%-aX{Drt*nc6 zd5*Hc`Qo3Ppv*Gj4#+=FFRO>vHd^c>m6oRdlyZZ{u>lJIA+J`-$|cqqyYpa%E$m16 z#`3$I`ox;9bjE?{^!p4=HweE7v}M_;=Y~G5|fof3_TY;2pmrdnKr* zYt>80@!Hqna)|1U1^zGT?$U2l@DHyQ@92NH+ge|E3?3xxchV#5pWPl%m^+~7#j^gi z*TO$JLFvoS5Gz+pe0?jm9FAJc*H1GNdE>Ev<@tXp%dNAn1dW{@ta&UQmXCbL9>dC) zx*zMdx@+%ro1HK|jvX*T4>kQ1k1yR`dcSHBh!&v#V^3^&2lZzTa$o$1S&707*twK> zzb?i1W93?8?bo%89O<*uZ%{rozP^g>V0Fuc?0=#BKgttO{NN=1g?n@a#T6izH4rP& z{68M|+|4-HPobD(rJTrj?sI=>KTO~s>}T+4s9H>FFlVt}sKa;F4)%MoF;O3=0y?l{ zfH~=+cd|Y^yq`@jn1=V_7$VpGm1hv+9(35)WsR)$lh*Mf_6^-SjIC8(Dy$O#Xxyc* z;0G6{o2i%b-Oze2#;2?<8T?4qpWTFhwQUZ&~x|z z3cGarDIK|9dO(Er;$x&ANC)tad?8wp!44=|TTdO7*zNU!eiNUrdX+9KBQJ}tU+QgQ z{%B{@sUBNAFX^h5Z1>e0vGrd^Z1MHzLaNoj3V+N>Voz?e*lQlN z&W+W6iIR(yDR`;3iS;KeNq)h3nuN}4B{p1t3O}ZF{)ef(^9UGzbiwhTCZ-^_WV8R~ z2)3CTa<6Sf_HiPz@S9}d`%bH{qw4ryttsYS(pRPmOM#ACPBF&fP~a>;)^xKCL<(jL=_0fz>tHLq!~9`**$$rlL!&n`zF zSjO`L8Zh7ZS8QRHZsoPyhhA$ftFpFR8>tmKjzl;F4S*JNJ9I~8>OSyG=wTcl;<@z9 zJg%Ja)rC?4Y>_tAEKV5gf9YFT=Dwqos}HefY=r#R zD&+rOVonCB5lSroQfdU0_o0vV@P0SF(|ZOVfx3K#h5fAbAI zXD3^DZ}Rn}@hsex=Pgv@(Jh1W!ND>gIP*mG= z?CZT~gr4 z0kF|UeKy=j@1IQ{h~xqtr3<9cA+*QAi4Ws{mCZ>juEb-e=KUu5HH*JMlPP?E^k+|a zj*gWNA|KJq0{@o`5b^!!m{#0SK|dS*r~MsTBfp`^2C%fvlGp-e6X;lS*xEmYPSC6x z7zx%)A93M>Uc+Q28t@$c7h+Xh_&K$zfoBLTWKBJniv(-O1%GB zh=1v2x^CUA-iJG^?Q;C_ONhm)=tn;fyg%T-dkPH*I)U_p(5K=1Y;i;p{{2Y48oEI0 zvO419*gK4xp=bW$2=zE}UNcP9gXOu$x~{D>v+^YyQIh#Yj{a+d6b9!&NOe=qE_<37X(yS(6b!yq%H!FXX; zJdy7gsMtY#jGfs0Pkm;uj1iEe5is!V#J{jFY{|!@dv)SZ*|P&5y)B_yANIeorNjX& zku1;)J&<2e`9f1^fn*9!0$IMIc>2o-~%H+Kx0cXM)}Y( zGSHx-X7q*N$9sC-y$Y_w7aw z-|0Q4BiNt2Kf>SV=w&-N*JMwYZ^f1{+0*=O99g0tJtIM^Zw>pv4ICNpI_kr$dtu;G zt?_mKcWd$+$_Gd%@p-U$h4k!^$40F3m8Y0%;sA&PN}~g)XO|J&ytm7Zh5m-lK+$m)X3`}u-IwZ)x*Lj3D_b`0#3j~w?}ulPO>kJ?l3xR1Cd+4^_GCw5Nsg~opZTjE%SWQ<2y ze|xbx-fvA`e9R|I;ZdTu0AE}M z{C)*CQqcfpf~@QU=ZOD^4on=2Xh0MX;4#FGe{2CuTiiF0gZ@-6KW=^BApU?tK_d_X z(E!N-ipdiHe-8hpv0@|qOBz#5|0uaL+P!0#$DyhLJ54@+%ysaC(0F(~dcJT!*}-Pn zqjSgrbMSu21qHlc&kK2f3j8asAjSLI_vQ2(sUuz+YKv!y_0c}VlfIeKn9qwf3XcUQ z)=@b)2_>sQ58^Fj*8JW|{3A7v|1@@hjCj8~dxxkmEdJ30mO%sX3yx7otaimwtNsSB z^KyXhmsq}BHJ(TE9RI&q%VpNz5&ngJk1O+BE(!h#>pVGVCx84wd^HxhsVK4tA7Q+TH+?oXuMI}f{Wt}vk{lCkvaZU@ z?d!X&>&1_|te;&1tt=bBUc>(3OFOXDD_oNLd{v~u}{E85s&!*=4@o!Hv;z(>G7{60lbgZ1J*DF+0ZV7e{fEd0O7Hju!d zFxiz;u$8?$H&V+LyCQpeYrKS*5$6y7_3By5LzIKzI)HElwp1q=O2CGTIqUvZy|t@$ z55B-D_$NMK0{07sf6;)@Q`9FDy=Yi^%v!!wV@dMFd!PbcL<IvzH``)zHO7W!E=+#_Y=#rYZ~SYX~06_KZ!q4y#EY! zMG`yEXWtSJzMe5bvyngv(b~H1ME}dyH!1&wNr0@+Iq`skoWPym-kbX z2L3M{Ai{lgoP+mECYZ+Wi~WPs`2QsS$Djkl%UZo=KvTtW8~AyWCsoX+FkYY_1K*=YOIJ&pYT;-BK3ffi;!Rnm2&!Ed!% z^%YNoJ$wPg1SgjgtLyxKq2>Qc{ErhOlv13~vIcTQsUdp#L971caZ5j~G0O%3?x9=K z0RsNzZJuh&eKy8+%!=7_`NLW8@4hk_U}QT}E{TW$xN2T=!k&7q_7~r2>C5oBUA~oC z50Aq8FFyZ|E3Ocm{~-4M%8!y8+>=FOL{=O{=Es%<#|xcBq|1FaHsOCJ+6N_o1|TU7 zrmgCK9Y>C>`F_CpH}6f9@XH|DxlC=>Ivz z5iQ$nBbTer>Q1Y>>LKghPn)6_TP?T+s6^gn8^KH1fv?@yG>zzIW&*pccd5VtmkE?#9bj1ukorxpwi$h@LuVoL#PwulbE7*4& z|9W!iE-(-7!Mw14G4Y?n4wy#YA0wtv@qW$JR*3z3rQb^F{8aS_qRO-E=0^9i_&Dn{ z03lh_b(dw$9az(AXV}l%6cd0CKTAx&6dFM8uwsU$_5Ax6%>RXda4+m9@e9N+uR}hF zAqQ03@vEM&x_{wyZ@3!em*mhxC6>xpIF4Ua>sCFI0d#z>%{~Lg>%`;4@^dI%D+1BT zwtjo!9h;F4w-aBt4;gSj>tfFY?w>jSL;UZg9PkKhYxb@@0kjNx zo1g*Eh3p*t!tt-YNQ8gwS&D4{yW=?f7si)2GNu@HbE@pj$Dg#ZTIdsZ+-*Fv0cfc* zc*Qt+oD)u;NEVps+Mjzb%s{k0RNq_)ds)TvVC0j%jCatl($;$8Q9JqCyO6^kMb2hV z2juUe2)qlmmsdlO7!V504pKv5Xj9G)69*bMm@9ndOD{pta zr79l7CbWmXi+iEIds?@0a&6}5Ir0JK?D_bh>2yJu-wEdTvMzRUB(DhjL-keEUEhS? ziSdqO4@wFD)bo@cEXu(|A*Wc#EzG%Z)@SjEA&}Wq68>_g}V*g4#Ij%vuW8(X&=PT?_;Qu-O zZ_XuMh<`2rBymzbPyjfnb>Guxb+4$0-!?GcV3GX53>Xv+Bi^4QR-mwF`P|I%uPzb_swpo#9Mcvd}#Zn~t*{U1Fz2+u!Y)mJ`5{@yO``w1|6f_Xm(U*Cm1 zCK@oE??>;=KmLP#K(>DM^ipaDLzCLE_qBie5Hd>+doWaA_I_+Zsy7(fezdlqYje*) zA^v^7gc9Yd|uf{DBZSJqqht=!5*(UJpXKhWQ?S>ry>NHjfGZ$8{_BL$aNG`4gQv(Lc?T zW+YxYW;OqE)T(~?0rKXQxBD3NA$R}(>|F;y6WP;GLO@VNP%KzzD#ZqNPEkNX#Dcvb zB6h`!pn{?lE7-7O15r_I*uVx-6a=IfrT5-D1W4I$CSfsh>UsZb-hEjd-)56+c4yyj z-pst2c?7c)jM>7V(+h=gkKueDiS@6we>(mlo&d*t7S;*@BIsc2!`caj6Cl<<4d#46 z$k&1ehz0#x;CW(v7=NGsw?4$>@QMed^>fOz4~2?9^Ew-ykoU~@N8b75SrA)299 zKr_S#vcMMjHU7WvAN*F{0C^nse#AV=02ZuO#9My^Ylrdbhv7QKJR1Oi9|nBPAq0DY zpyYyoFque`jwUkAJ`%MtV57i&;H_YM0L~9ILCs+X_y}6T$AvYin{Xx(>;#-UBnk2J z@7j3sjMQ@w_vrs@X#qSS!M!y%LPhdsthETS6YzdB+&kJy_|4XWR-)j1Hjy$qkej#H z0`dDC$_Mc8e*k$K26KENL@PZQ=J?-piA@awS^RAx;JxqBxAcED=o(0fbv95dPz&f8 zt#~~!$5<~4c!#mS26Fo2mG2UaAg~2t!+Rh%u7ro@_wRd#2ZJwUGN&A~CG4&y1r2Q#^~ z!an-}2=L7jV5?)x^%HiC75I(upTs@cejESj7XYH?fDD510M;AExM4ONtA#m)TA>_> z56J=jF&+ANJdrLNMP!(z5!L=6uRw)Coq(J(z&UPieUY}gZ^Y0S+fUTT5Z9!P!smrH z8kfMI!Ic5r94W|?;Qn#FdfZ!S$YK!bm(z%h2_J|YsF70#cxtAGLypG>Sf3>d^z9gs z;gRj*{$Dlz{|NqZejoM!R+w*S=<*Wg`TV$Rs+R5l$h{Yg?`r~kAMHB9_SbTNlnLN1 zcUpY7eEIY%*8*%;?NQEU~@xFVf4vyppF1i$GJilcOC)8>9+P)`a*~K z!;b#K&*Og^{vl4_vy6Z`0+>q-YmOncfM1{$hy{8=3*-{iK%JA!?(d0$1xZBd^&+AP zbQ&;+arA^9#j}dhM}YZ}Z0K8DpBc&mymcT5lLCzKAi3raFO8i z0{w;S%jD@TC=KB1;SVmk3Vh>!6-0(b3XwPD1LWx;j>3Q+@qn*bz&+Gnr2+Pls8Jv< zBY{uhu#fY7ZPaG>x9k5Dm~FI9`Iiawtp(cgDBn^ z4tK=M3*csP(R$icWEz(03g0gM&Gxj?>H0o*5X zPqu$H{;{^`x2cd@+o%s= zqnVNoIc*<_N(rb%JSLIITAxg0I%g4;A3!63+r?Tk5E{{8<4FT#2GDkVC-NatV46g((Fe#!q~EZ;ZObPn zYYgCeq&!)Gc}6g20P}?e)*Rr<0i0jV0a=g%_mc|tO)AkSl|$63L#*-g9HQt%I#KEi zHOtdrwQg8L8X{{tupRTLuu37%mf(%n_&Lm_;StX>$J5^Ne^fK@ETr5ZM|gaV$1#ni z5!Mi{h_4{BZ)OnrmT92Z#}d^;Lx?)@Hz0e%fj$7{qX9SI8%Lrh0N>+azCIRYa6H%E zXG6;YB4BP5i9-PyfYc@j*xc{KIS}LDqwm@N_#Wg0eL+-+Bl?0q`v-7Nj{$WASfVc= z#?u#ayaFM%3({GY@>>M-kOs6NpN=WTIqz2H-H8h_Q$iAORq#yi5 zq_2x3N+zWdB?I$_QmHJW1pM@+5CdBSF)_`c+oS!$gqSBL*!8VIEmVkw0PM4=@m#{V zUHl9`{ZagLsA2H@!oIBs{L23SHvYNs0`wrFNjQk8>GTH13vVI|V*4^Tg+t5|YFr=} z(b*x`{xJ^l;~#YZ9QzUfNVv~i>5)U!y{#oajf{l69H`$%1s@F!6a`_PEx`2$;5wt2 zJJd!ToFf4HfW$r7{tWo%$^h^eqA#&XDvGF(j0Ac139dDdsG{Y9ZJi9VAO>VYB+R2l z!T1{o$DvM%SUOSGBLn0^7Ez&^MU<&$5_y`bM4=AUSDlhY6zOCU#oDm1l|d9tN+uus5m2Wd7l^rF zfG>c7b7WXB1YToBE|k($5wNDvh*XdPs856Jh8O{k5UjdH#k@hlKew(B_y=L`5ZC-b zB5_Z)|2Y03mVgC$1}umxV8MO^_zD|@q5c@WZh`CO);@zc=vHbL_{B5fUeJC3n*wy7 zR>+fL0fv=AMb^?dRbDIqyo!1$0T{F`nlO zY}NE8B5_VU#F9hqJ_U|KEM5!7^e;OaP*#h5^2P`Vg1$;p;F91G)Z_#&s1K>9xpGN?+ zT?vVQvc*Yhj5x0m=ZtG>rLd@DH-VhsYxs>$#W*Jb$wV?4u0$2C-r6{vNSlT>pXq^DHi< z!S@jVARG7z><;$#=x@e90ds@|xG4Dl zfCxIQF#xsz8)ZTp&Pksj`TCn}2fXu-{kZ?NF`xg~Z;t;k4}kLmJQ;wskAP?}R|sP~ z8}$Bf@G$@DmVhD?#Ip(7^Z?KWP}k?_`y|f4)n@-O{I~f5&=h;~Y?H#ArtF7q#`J zpRVHzF6f6i!1V>R`2%=90S-|WR7)g7?qDqiYJGrDfC=l2HH(6t4K)M^h!AO3*B%$Z)k)y@LD&C+K-VYd0=X?s?}ws;zh0pQc6z+FO&5aPcDbb$tXHLU#wJ^}O-0{!p! zhxpx&K0?0NsQ>fJ0A4&0jPs-%=!k#N{RyxExP<%s*vI{U2>+xU_*P5GfR6a*fNzjP z!v|Oj0!1fRBmnQLl({?^4hYp~f`m`&fqok&n11 z>EGP<1=s$W11JMv@`hl8JpjlC34m262%_v_3Gq=O8RoYk<`1yX0vmt{`2(#`M+9GU zYkb1~H)X(Y*#B&-6Z}2mlLaUzaIT-9z8L#E$^v}dE+^V#!QYJkc3ijX0X*HGlmq1Z zWZMz{q#uB6+i_3IgFlFW0%DEXm`@CCGc5+}z7WXac|v3uy(8*iZV2NYaSay+#ExLC zVG{Rb%k3nB|Ni|P0Q|Fn%D@-U47IqSSOZ7^2&9LtF0_uwn4SUkIf`I@9DD#2kPXyY z82ih?=MMHf*aN5sd{qbdE&Tt+`@FhhSX+!oY#Pibz&^L$C>3;rUtu0%89+v~(|-*A zJbi#KPVhJJ4|9C&F+$Ppx<8u+xCguw&|-Tzbsg!diPxpb4PIr!}*MNI0BH#1BY? zIp8vwBZAoa|7*jhBTN5{ub7H*AQr9*n^=%Jia8`OF5tQ|82{XEEB@Tw_)oh!jA{7)xN*$^kOQr3 zjO>K*mH-_ewwmX4M8b5)$rsLsz665=_y-B_4|0Udp$j`H!{Z zo|FL{@J~Q~5&`x@yA1e$hJPl^7ckL3fLI11IugbvQWHVu#DX4x`GavFXE6rpBl!0) zCOQ=CyVpd^X|DTL$`p@5Jha2QR zXL#Od0AiiyCa&&>IdO0dT<{h4r9`sACn5*p?HFhaKzslP>kENT@XPVP;)~bc!awE~ zAn{`#_kR=r9pwSk9Oc#>ZIc7v9RI(i2mGdg;K#;)GG>4y1o1I6JJ;P;OItq@DhPdKKNHUc-UkUO7%F^Gxa-;X8g#2}szVw4#m1Bw9qISaw&52^?G zj&u5$FNQ0$VMGXTZjaRCN!)jAJ9L}>)XV=*a<1cpBcC&L32xtD0PeX+KS1K1Z2uzt z|L?*-1MrX31a*QKK&S(7^?Gj08|Pc#c&iZRDBxUWJoxs*iPRy%M44+5ckN(&_K5jr zF#6e$D*^*Nm-zFg$^Ou>?bvVrORupWvtav@1DNB5>u{hRfMZ5E)Tyt!Uq&ST0=0%| z8K6_b+JoSuYsGblA!e9Kg?d*IN5mmxh&$9DC&zuVCG(2NmOM_jztRUVMu1uZeH-im zv=MNhs{?@VA8HEn&mD62JIaH$d>}F}=vVWF9pnQWUVlND6F}w>bchZ3B7P9!hzTTa z9zh0I2O!6O{+84W$d(Cl0W%VIW!^ z==S&;bo@Vxe=5WyBa!}qU*RA9gBYiPb^yqL4)FuOvIqWl{Aa;6ea1frYXD$O5VSlS zfaf1%gO1LE;~nh*@-<=~sRgjkCD8AiA6eOz5-Fw; zM152py7#zqdd=Y9V?c-}19JD8VI9_Hs1bv>{*mqf1OB=F9Av^T0DuSq%3VZ86C4}3B9qb~4U z<3H#`+;RUK<3DNle{MhHpDP18<`=cSW`e(fiFpK&Psoiih8zUUMd(`~P(g z;A^r9%|osX06l;Swg9*0Qxn7tz-z2*%kv#UT0v|Jk!_wua*-|Gx$Q;PZpL zV4nWpar{TWA364ao(n|me-;0r6Cm!HkXO_S-@|%G1lRt+^MgzPIe_Z|<#qOhdL>Yk z*4_74#uok4=F8 zFQowK4<=j8`$T;J`xKjN8}MR7NiDKIzK%%Wo=Id30-ZoO3+ie>JwCuCM;LI=jT=Op z0Os$g5K9DlK?}6aK%eIezmr=4x&Y=RaOfBph;pMXh5+LUK_+nX2hbnDM;&90f0bVd z@`C?ZyI-J9KfqdJSXY3TXN-A~ z{QznQafCtd=h|6N+W^M=Ch+SOK;7^($p9i{#(N^~F2rp^{ay6rZ4W;#dv&q+lPg0l%$6C1AT^oDi-X&WjiNYD^*Eo;=Qi zb;Y@{fq;1y_yBqF$Z%e$Wk`Tr;Kx4h|K0fKP_hA^*>I15dn6j*9*K(M_IC(t6~X)M zd4-_cGl6P_z=toC4Cg{!A99^RPpE_(-L(F}MBb7lBG(Ikix;W^78&SgY|zQD7ChG9 zN1qMsI4IcTiAh4Fn5Qw;t>oIk|)0TTaMgA}n&)*B#ggLeF*y@2Dr5X1!|-r@6T3vfV| zaD>|C2L8eEpTn&+g!P61t5A=CTQ30T|8WgOAQqKJY`{7jFwX(mz$1_wFrUDN_mOzD zhcaQD&jy(Q>!gBhpDhfrJ40iLJo6l)>NUh)L+KWb&}{{-Bj<4`r0;El{`__BAnuWn zKP2|?lLCHyonK!&O7e|^oe+G49I!PZa{zj06F0A*wU$BDzo;UL%!-Ko;aQMNoC|## z)&S%B18QNcgSY`4=h3dG!+-{{1O#{PfagQx;veIMz=y!bn&tFjAk@uaA9Vq+F)&Z) zpC132^h}6}%4nxnSjPm3DGcK|P>T@M0fzCs8Ho<{14ZC{5vVWNMg)xaIB(AZyS^D> zc5+}2uRtn{D46w;D7=_Q)aQV_3<8$pZ_59^qFPzHoL0LlT>^D+JaWx<#A$M|yxaG&4S@0e@M z^BrOg!Dr&x{a9nHjef)aXX3i1P?wO4cfdBe{wdF2kPYj30^WgGASYOG-_0N^T2U{c zrNcO%3ip%*I#MK&DE*d5*NG%D4kkej9?+L6fpM_mN=J<_|Jne9KLhK#x9Rj4pMigZ z?e}qj9JlaWG%km(S2Yah)!h8HDi)Hkh2M`_w?>UCAMG zm!%QuN^wLr#PQaGENFyry_M@P!1cm02N~iCxPCvZON9Odtn~|o*hgD{>mxw<@cZ!3 zF9Ue80cs5Z)=6r|{g2`wKF5SQ1Wd34P!^DDow49J3v7aBln+>^0Pc|h`NaaCULDNW z7l2Kl+c|>B`Xw4_Y(s7GXT?NIIYwdPa>%&OA<9qCtzeN;4kqY>egy-+z^4DP?)c45 zA?8WK5An+Y+$VK{Z=OK###cE&%GLH3dop%rm~(0YKQ*oo&4AGiEHB>oLDgzZX(9?P z7I15m77R@x%DR0b3h9a9@5%xl0PzAg0#FMQ%pG7&0?bL~tzClk%fPn?wgHDv2K?6e z&$AoQcHj{c@e4TRwS41#2mJHaG{<$#c|^_!Fom*t*oSklV6Kr3Yn`(p_88*`aD9Si zh>s|T9Gy%`1d%2jPUI@UTBkE2h}1(M1AGgJ2EaVIp+4UPT&m+R2nGgYqtL{l3uIYa z%inj&?+Mx;=K%IkQvb(qk^L3otN0Ogp+X{0~tq^;{Yz0jK>;eYx zAFO|_9}Bz&(6vE8pbH_nnJDuvB=YQYiTpX4M2TW1Q7D=Ya|rn`UV%5kn_xmgdP-jPC?v=|U6amO9avl%ADcF852T1IHE#8Ohuh1#vmWo#TmosI8nZJcLLwj3M%O z!`g(G^NEr$$dxF@psLS2!aL>7o&t_hO@gtfz5kK=DfB}wU$8}LJ5GM?^VtM@Kf(dj z>v7!wEo_tgMSkPHVEbbnAo=;Vv!EOxd5oOq;R5TDalHlHub^CLZHAhK*-b=MbPZAb ztdz(*olE3x$s+O$(}+9`m}69hSY+umkPT^&_gcV>L23ZpHh{g|1h4TJgDWG7Ku$m{ zlkX795&V1ujOTS=t2YAH8$i}nLtIX!@F${N64o7r^#%*nJ`%awpNQmjP(#rH)&X_T zB`Uyg*OUSIwJ?=|>N_9g0n6lT-koxRk9Q1xjGwqSjsJb)IQiN3&k1&Zhy#dylmTRa z`_`BE|X1KS;Sc?`OT4X>Gpa?GDZy#@*M z?c3t?;1ymyKk<+2+>;3Y`%5^0d`3KfZ$sHY$_P>p2=M0ZC0TTDv{?^!!SHiVP(JpPHANkH-dk6oGvm+n* z>Dzb38{^6MdE-B+1)y&RJMLQ5vlxV zNb;LW`)co|L=OsVa@j6L8@LO%i&y(j7wErvz{wV&*t0(0)$^az6 z_Rn&Fd>&-W#UCJEun9PT9Kin240VqFtg#x;gR&p7kMV(mO~3&G2Yy}-kmCYk7G=R7 z+3*~AKJFOPW>1j&f8@M^?+Q2|;J}~H0TQct=0A#k@*Mo2yly;3%7vfxJ_Oe#;J}~B0qpanZcLsRF+ke* zA-Q_Z{zFWn?+NT4ktv%`z{< zsmDEum{Vu!-_O21-+#W1R%T+UPkpjCLryx`uD^4BVB;#^m+6(w#wuB}hn$!k@-H$(k|pPQh%yZpo9XigOi~sfRn=8B`mXH>B(B!NrOF z8rZfhCAO{Bo)gC`75h*Y#f^W~H%e%cmDEzAs^4&l)7F>V&UKX)-PwOx?l0Q%@R#%9 zfW30XyUgI4=V9y}6LJIV&*{j8CDKPyEOzug`|vfPR2rCVbv@ZOUvB4{3LRzZ^QB_V z(d!eXtf>j6Lk@O&7-*xFeK*V0YFGbknN!bL3Xdrcyg&V;_F?HCY)0uhR~J4mUUgzh z-9#;g{_p970)H{A4qHJxO@C1>x=F(%ud1xk_xPQ$iiacb^$3}GxL#a~N+bVFL@O#P zUMUYBUOr>OoH=JX%>8y5V@gs+QD|?Jn`kd6_pG$8_71x~>9Cn%V-y-~t5${2xwgBjlf~UEXA@eEgHq7@4W+fq zhMs!2(?IIh!Xb@W!a>%rTsoI9!@6cz4|r!uo~QPZ{l*XKdlg$3cr6|<;H-jT^^y3| za-2aK%-j2C-L5^fzmNI*KFvn{uZB>Kb+h`h;u&>`gNysET)Nl!-W7#(^5HF@P~&Ci zB)=JyW8l@a#)TrPPP=3p$q32Fe%{o514YxEZIbJjc-GXMd{9)HzA!c3b@kJdl1teZ zBb@9r&KaJQ^`mPa(vlb?Wh=F>#mS~_^nQP)QGjyuF;9)!YUlg$Qzw7^x-9MH)SF9g zF1WebVu#qS`F(2!#d#@Dq2*9Z-Ya#_57TSep}j{*JKMTQLAENfGlRTPio-3q<1-~^ z2hpA{^Lp81_Rg70t}SkHs+f0C?Q-%OxKwR=f2wY^Z^JN3sF>}W8k)s5YE5;mMqB^q zVn9V9N6haM#i+Y<*Tf3b?wjTA)LExlonJSzs4--VP(zTEyKa>5n3nfqek|4nY0p7J zdu5RwhDMj|MA!9X=_VzPzA$ydX1CB%liIwhyO$3PjHlLIII+Yq#KbU2YKg~Ci9T|7 z%&QyrYj&-ctNMK3b2`&CUF#Ym1H;TNZFFPwUgQ3%*2&BB>aDVZK)Ie97B0Q+d+OL& zol8S<)vllDeemwP&WV2Km03*NAz!i~pF)+gu9TLH?h)Uc+S|XrN8YVF`;P|D-H(Ne z1w4LId}8gVIi2lRWXKh7%!>`Xv16*t=UX_U6V$^xGv8-!l>NpVO7B*8*Q~6sJ$k!1 zziSt{VmpuSl##Ui9%?>AiuGhyi-ypfJ2N%%he*Ere1cO#blvQoP5}lVGAF80>0(0iY$8CCvzte@4Sq03jTroCC4qds&%n@B^kW_?YvCd&SL^D(6| zBbS$Uw=`~Lc=RZodVzA+{Qij~&4z~&C65m7TdQg?>j0xmh~2``N1u?-{~Vnjyt{feZD;Qul8%8#7ryGm726=Vdx<)x%$Ys= zm&4leQ{weooTTC`_9Qr6+#8xJ-{;WOHI#+Z=VYvt)R`d>5LCx7ywI32CnNjlQ4*`# z_CW@R?MtpJh1|Ssar4}23hPJcqb`Kt#XDU zM`wrZ?YP{lNs3-JqHF5h}K3yVZKD z*>|oM3v}++$DTdLz_CZ0gfd^IAV1-rk$=hki!_m6<}`FVJn2OCz;cT9%}0J#oYd?^ zXLMpG+qN?bN4bh4_8UDN-}IsW;?(NjZ`>K#qUykYJM9VvQ?6eUebd>~%XWU#IY7cqKMUDhZ`oUG|DZ|}AAuniqF^nthP1y!+(w5d#WxWG*;&+w3_oUzW2!)^*3T$ic@R zKOGY>vUi`JnmbZ7td)Y#Rp)nBe`KqlxgtNJA7BUN#^!Y+<0hW;KG>%pb3G+b$T%dk zx^~Iiyn`vDX>PyN2upyNOB8j8FX&g9HB#Hj+0S9#s(@~ZCnL39&o=8nzi)5bOS{C( zI*In*Alm%&)=1?ES3Ufl=fB)Pk}`$HsXLUpp{mQxs7a$7N7J3>->sRAV+7q{9(}1t zU}kFcl>QAV{aoDiX9W14t~&(uV;FFTdj80wm49A)X&umgyL zDyL%yW(d&@h3IGLJGAHwgM*QS))^*g8NFPa_M!O$qkxe+Njt|wM?ST9($pH2#*E%V z?&4>K;PHbO2157-w5-`|BPXj|d3Sb#=)t_#d0kbm=B=N<|3hBT_8!^Kdo)rR z!oB6q?<=?)yt_3jZ;cG4t3_;S`J?@gb?GT7Pb^+nT%^)!wLY<{b(dtFD_^zqj{d$* zQ*=zjE;PhlFbK7jnSNBM^YobJi900TCAKV89I!v7)HB`gSVBLOfVHcdYO{tB9=}_Fj{inCN%0 zlwr&`bCIG~vhLFyU9Ff^8ZmN@rW%H1n=+%vfcm5{LNcY)&{S{zm?b?Y8Ct0ck4^k^ zcZk%0BiBX_t>O%EFFmwHF;a1LNrK9SaSX#NBj2xiFf*aSe^s6L0`G+)#(nRFA6S{b zzQ5CgEVK22s(GF=drzswH4nRSDAIJ9s@3^%hZXlHDy$AEKb^EK%B zGLIX&NkzX`7T$BD#c??!Ci-^V>^rWDOdQ|Z_^i6oPp6tyS&*DjtR1YQ@8r3tTc*>M z^0`vCZ;vt8mfvgcR(DEbrqeM8wp4HZMb3GJzO}w`m9O>0LuIRTq~y)F$jd8f8}3}{ zW8|~U#Vu@hOxO%cp0ULFr4~nS*09&^+~O|Nxv#wBL2bj3^LA1LrEKSoe6@a(`R!rG zCnbU`bmxr;Gd=d!vd6MJC5pRSH#_Y(@@o8R-B(vrkJR`6Fyp21#c0R#L!|;7E)~Cg z>iw1xqi?k7A+yVRcayXovvmE$^5fi33>UFIwilG@Ahfa%cFV;x9I%=Iv zvEj0A#W!pwbSYhEG_yr^gR~CauIJ)Qhi#6%i!_bh>ekOyN$=go*ZFg!?v#(FoeEZ{ zvQh1K{ArwWt6Qt?2wy)RzsbI1Eo(bBMUU{SHn|m|cr=XS&_k4}ns{1-;MRw|r&{HEmaJW6FB&nf_R!R_Aj#*Wn+xr`DoXfwF`PX# zWQNPe&QlUhrYT-w>gRF}-c1dS+R?p6)H-UaT81-dEZ6s6KRG94@M{<1mFu20)AZ@I z)Yjxt_QmSw&x}ek=}w8I_wQtXc$A2!ra1ld$BCYoJ*QjSMgMYT&kPT>Wu^V|-<}jM zmTGyiVD2g>ntYV1lTcsDX&#*``-bd)u&uJIW2<42zMsr|w&rqr*-CEebD&qX;k{FDuDx=tTU)N^u6TIfp3swv zPMTFWEZn-}G-d8)$Gt<;-p$^x`$pm8mBJ;Kiz0hjT)ZA(lUdHBu>(b?#v}$&mF!1PyOn32=(p*n zZ@5c}y67f(|6R95e9q>b?h+V~RJFrYtG2cL;EtNKB{vo3+XpG=XzOM%j2aiIiJe}! zQft4}Lwb<%BfnAgNu2Yq0wwNkQ%I#a?AHlm#Itu=Uw0=$1G_O_OruBZ73!Mj_4jrZ zx3nyNtX^{N`Q>{X2E909X};%Sjmo=#BP}tz^3=}7EQ=_Moc-XT4r@v6hCA6AdHJqB zW0$NF87FzVIw&<*J!;E^0X=8FzTGK4!cq8)guSTA*qe@3M(gIzGcgifaPL-%rsmCa z0S?VBy<}e8TRB>|-obOtmYT@qV}};3U|o?3VMbNyy)lj|8eBJLcJLv2nebUc=gb`I zhp7)4H+)IVGP4&eqmTC-sx~XVVT#kMkK3IRg6T^yPn>`7BTbl5t~Nxx<=iN#foHSJ zY6i>;aW^=7y8BA$tgYULOY|wuZ%2gIh#xy$(ffn#IoA5+thLs4%o zHd1JWeQKphl&;^(#LaqrIwfoyIAQxpn{5U0Lsw4ATrYAmfyPuzhx~#-ceVrjG7X z8}t03+bQV*&xe^aFFQX}KUX}(#5wc*``b6y6^|O{KW5!%%XL>Ln7*jX^C{f$ENOL% z{OIVjBJ&SP&lFEMbST!{eEFNQqNJW7>UV2=55O3+PO?U0R>B^&dkl>cV#gf1QwHZ~ z)i~{`4J=mLXFcjI@X!2`r?nLiFZ|wlROrcv%RGAs26BT@_I}A-Y*%`I?!~plirefH=Yf# zn%1RQLscYVYyCahu|i4yK5TlB}L z-0^uAKU;fvzKldmX=beYO{=H0`IJGrJ>`cRbn)1by58)D+XLgSMeZgWz0aSXnk~O( zbMdyN)FUg4mZu)u&}E#>x=@RmLABzFF{27!O}QNIal7G_$3gi=;Ul;E&fKIPa&HLR zMEsG4zi;!LeOgXg4hJ3tGT+X8o>sY0@fw3s%iKZBst8up9H2=*B)4me`O~Ept|OZ(vV=r~v$$nEV zrs@!(>}jf%&tPn2>E`WwIv_XS#L)KriubO`Q;CJ6 z$Id8LQ4N{D?$(&6V}=@yk#x$PStKfdSaP1r8VC8kbKe$dkH3H2W}wB5gWIICwCO3j z^AGIxUDarqS>|;tbGX-1<=FKRMrpfckE}lPEb67#&O005AAU1-h4G8qGdEOZ-0rgY z+EAlACk#cz9i$~xM?^Us+_q4+@Nu3>{kEseug5>IDGu9pV4Hh=wN`y!;c}{{WcIk2 zskZZ`a6UCY$m-JV14pJ?7eI9I*;Nv^;+Bfa5?47c9ereUU#Ax*elJe2&3ciZ!?pyRj z25s8jy<3F$v5Phrx8J$!uwhBRi$v+oSr&DZ#;44_HS1LQ{ThOM5z3)?`o5KCg##K5Vgi zNXSPO-B{J=nU3j_3Rb6&tsK-kY{k3i45wE+ibh8ckF#}|IgY*jZIP*(QI+ai6&Hh( z1CErw-?n1esMAxGp9w8+Ke253x=||fFTy>KD6R9)^qKDvpkpi3XXYZW%(Z6@zA~$P z8e%v#Z04|ZvqmV2<AQ*Rdfeq@NKicHv2D%pGBOe+(` zy0pnT*}Gi2WRyF+oHyNkifBQ!Egg z_=b%UMWcp)47p@-N5N-H-~+q)FDqm3zX+X0WO+s|ww|~q`ht?8?fUYedROnoEIZ>* zct`6w(kGM+>lSYC%N()e8n1WsxDZ}g$o`<`uzY@WkJpx(jyAm)xKB{IaLYVmrXfS8 zrPaK*S&(x#=i_lby~Yo0lIotV-KdFqx({dVFZI zUi#vyhv}7!A&UvlsdX{8TCK)yp1C9@B`hSySGH!Y$_YT+HalN_4tlzGFnhPF&&^>mk)!wQ?LEMU6eKbr=fl50nL`^m=^;YCq zTq#giu2Fp@^w6nl+QhxRyVu_oilxvcn#}tS@kl#rU%h$%_4qmWX6UN)&)pTVA<9gr zLgHYL^M*Yy-E#=_Gs%#WS3x0Cu<$xC@ zi?$jaD_(rp<>AL6Mh-Ho90D~_qu*7s^`&_R$K4eEmR$}_WaasBZpji65kSeNGD_P4g<|uu^;xncs?zAtDEfd z)p8#mzEw%q(Vu$7{z8+)Rh1WB^G?gYeNpN2B6Xemy4e@$chqL3vS4i5b7SN2>({4D z&^Eqy*kJ9%)gpJ~57MVcxwoF!EGK2tb7p1mGrCu2>7~9onIn~l8S9pJp}(DV!XiyU z%H`3igRysgrYyA&3Z4?=JibxKfc8c@h%q&cqB1XbaLDL5{mIn*>MDksw$>7om!xR{ zftBN3rI|S%%Z^Z7p6^OJmU{isYoGIlx)$YNC9d`fa*ByTa`8#Vs#(g<70cO=2$?)^(QAitZy-&WJajzA*YpaCB`S!!1FU zW9)k0D^?q~SUoH^+YDhOLj$dytFy1yZwv_8I!h&XnVQjC@fz! zX`iBdSGB;!8g%ByBH2=-5|bBQLY6;_e%3|EGWu$1&j-<4jV*UX*3I#(On6XS!Lr=2 zwe0z|Xt%3V?@8V~h9&P0})L`usy8^KbO+eEidx?y@I(?^1sowPI$Z?T3oG z$letd4@O^n9kOJ4r?lhyj zi8d(YI0aTe%$Hp6eRAxi(+|ai*7{sHWn^6%%p2w-~MOHk097 z-%oJZk$ju3Nb7uWWRDBynwQ4hF1)@+YoCaGME1JLIUBZc)?AcST1R;!X4*5letx`# zglv#%v4luj?+nKA@J@x39AA%VNla+5S1I1uJ5|JdA1!G@sle)%x78*z?iru6gubcJZ ztb%G&bN5Mco%RJ*mZ%SWU){RLu2{yFMwgJG^;L7D&Rx8hu|KZSfaWS;-|e)g+pZAz zDB_g&;CuIpo@5_ashMqjUvcC%iGB>D2ks$*SD#kAE*fq*&tV~Ck@M|jqf^AefEh7W9lX@c3t-JWZo!0(P!i8D^9rD?D$X=5UMHXCuCM3 zv2(pakAb=}gM>^1Vy+0c_OnZ9Sdyw((03%ItjC0_I^K2+=cD=oPlp@=|G?D4_805& zd$ct7nelW)T>Px;$KCE8EED=g@8i)MiL#rRheAFj`_7ddwQIn~kyQD`J{2aHg3Ax- z=p3HwnlONo(Th$S7QkK^oHW_UyOA+&Ym5Ga7woK4x0iS~RWuGA=Q^!R#+}qKXIYBw z&ETjknd=UnlXLp(YSztlJt1lRvU=izmmb+>mi^U)!`(-!oXvKqiG1@=^ku~0u63`D zcN@|2a@VF6;}0meuBNf-s~+d8wiKU>r8wqVX@Uyoi!t6%jwOj63Ye|FCJR4bdB$N;{m&StlYS<^6=Hg0i!m% z1U8>{-OqkA`)THrpzb;nU82{nnmBrFfZnLMLwgR1nKz$xzw5lI-=^eK2P33mHb7#@ zp{mCblFRLbR%r)~rt}@?cG0G9^+gH`+{C_2ou0-0C2pB3L?;SUvy=CEEm&r}&fi~b z_j==TAxo`$R&F`{G<>tGu+hcB8@2t9t?7Am>CB0aHA|MJ>xW!tjtpTtIDe7JzS~9Hr5ZT_WXd6?tJqhjPnBLOQ+*m;O=!wF4cE2m5en7jZv);)Nmbg7 zT-9_x z(UnJ^jxMY-ydkb~MCYo69_xZr#F8-;a#{!KMKyDZ^(k4Zt-9=`Yo@XFUhJQ7`|O(e zjgJiMl6o))&5~Bw`DoC>cTAnB?gMF2;nN1U|5*KH!kG0Ad-^|=-X1Ulu;eKg@=Dc0Q>o$uN z4VCYI;`qLhnrYRoJq_w=_tJ06y(#~2wA|9=5TV{{XkEhgVds`Mo7pzZR5a*gt$u2K zw-O~A?KJkYay2D$=@hH|vgL9TYKoPr$&uT-K0oZ`5V|Qd%k=fC=W<@@QIUER8J({j zFf~hm?-FBNYL+Cd(QuaH0vpPVsPBXOM4Eec@*{RbXKm#IT%d?`5du3aXx!9I}cbevCy;BQpQy& z_~C=YN_N6Z_Mc3yJ_@?M_>9=T&S@;sz?Z32j2o$G6Z^fWE4^}i_uQgwJs)OVdT!Ba z;H3F<-O!CEe~Pmrrt? zeDr0Abd7wmq^sQWvgNBOZ{qE3N5Rm!5@h`2_pS@eJ>FhFoH6rI*{o+eaqF`65;8+w z?{D?@TXR)w{mCZJ*$?~|d9yliZs|jbPzV@q6>~$>QO0!E>mAGe({DZQKWLAY)kTSt z;^k6zW*1eZ*VWmQMdb9wXQf}Z@3G#LUxmPvd{asdgU$UC0(CX z>=aW?syDmJT%Fo0Kz;j$$uC!?S{gl=9jyIo=acc5dkVSxzLJpHHTUJ!L8&GA+57Dp zHEdYD6++Dp+nZmiIjhSlQwylpXpQNTJC9Bc*HV_sH4|QOmtie>H#WQ_V02j*eR-$q z0E*0nshg+Ic^yc4U(49JNAq@wed>HW@9?npnO}woP@n7RhXVt?AcXccq8i)Xgk-JkxA%{o;A& z=T#jVO>q*N?6G6K>bAYRm?KV{t$b-Ewo+Q1ab(ZHNj6gprfNm696Mvb?uMS;mb$ll z3@ugLrDmYI`%>wWJIP*_vgxX^9_nL!*3MKrzqMsa)iN`Q9tkrouT{{8x|${(uvisG=?TM1?wAj1NUOWzW$UvpaYOy$mX*G+-Dh4~#h$#3Q$1!&{?UF(EXjcjyTwgSElFtzUDSGK{EGvZE@<8MaJpe}$}lnb z;HVjwhDtqfe4-{i)O7ETTwfbv#UiEil#NFZoOQ7bnK8esi(P@Tqjm8hipgI1FQlI` zO{;VQN_)XcyEfb0HhTTz^IOYO`$q~b*q!TAGFBAI$?3j zF}~@Srs`^siqLM4)9YStTb3IpWBg{K^HVpY7nQS(hAc6kF?9B+Or>Fv4@D_I;lYEZM! z9_6=EcD*&v&D1bxb}X5oG@7$&R06&F7YWXeP}a@$cOJ)Qs}CL4#cuVf1!he*k2yJ< zsaPpLBYk%1;Wrj5rTxuwo32%wKPzx`PO4~SzO3-Fy0W{}B{r>`C>T7{^)>$j`Uu%5C^ zRY^By%l$n2K3&GjdZ-`P>18&>bG&@CRoorh-u=quwBOq)Z)RlM*c)V;U0ol!=+4{u z(u$w@M%Z)>c_gg+K!WP~(O`z?#S>{8*P1zNSPqfta`-yL}`QBjXF zVtu*>9*LAZ`|0qxKxYG=-VcTQ{WAF0Q0g{u^~T)6DX(9R?6db>pTiaG%*?$J1F1FE zYbx1qJk<*io^2c&7dGi_uZPA9wa=;yAE3MI?Gs5?_ZgFWo)<~?Ub^Da<5brBnrM@wHbq@uYXfto*P_9bCoOxCZm{Q=L{3!KnG+&kNhT!Kol6I)Xg6x3oB?ZWX|)06{8o9^(Qd3Y zm#6kVIE^lsG0-ESG0`$$h_I?=bF#rE)u{XHmvs%f)kh~++wD2cv*L!HYjAw zKZzk;F0x@7CvRb=-I>IQ9~=oToy&`lH7n*1U%y1LVeqVZYs#)4y0Gt!{D_IldL@P& zKlerb6}6@*x1RMF8KB{2|2}&WC%3x?*PEg{ z%%OOwMXBQc>;6jgUL$8be}3xuTd#|me*UYC<+d*MOnc%I_~EjU>HFqSiw23Vc8|B1 z7Z|?j_>icn=eLDy^jN8}Gj36us?v;NVZGEU`I`N6&Z-ypexPqHE-6V5333uU?GgC0 zi?*yAwNG-cP@g$6^ttovEVYk1eso%WX+pHPUZ?zpPfHeW$n0?=AU)aiUBk9VCy&(k zm3#PfF|qB!B-U&{rm~e+qeQRP#T$k%h)$UnuRcA zRlW%Uy>?f2Z<@qD_s)8D)vGb~-L6gCBxXNj$c>|CkJ|!11 z__DLL@uY=Q{KEqpZDjpq4Sne=m#o`k5MzHkq$F+mXxmA<`UQ>N{p9(h=)t9uLXPg@ z{)l3lFzzJl|?NA;=H_`Rt@D!q=M zl5$_7XV~@fmgRE2syuts49+~4&pmV1EpcN_`I~+NE}lCg9BvV|%(rleW8HH~V1(0_ z{{x9YcE3N~v}=F(k!}B7-RAF}L9vemd0J>qGu%6}t~`SAjRmZ^k0rPCs-#v=Fe@lo$;qo|$b zFIAQ_M^qQnXXxLUXQjXI+^O5mLi9^zV|L=(kCqA510^s4}lTE^RoDP6yG^3n9tHHdw%G$S{%uwh_wT#p5mpppi!$ThCe^K*&14T86Rm+Lm4Z zjX68_)oCmIG6saPD%dJYk47g6XnBBh37QzgY9hu(N=DKVvrJ!g3;-GEu96jCAaq>v zLAhl8g9PB9AbYgwc&mV8u{2+Q?@)a{Du5H>!1>dRyDT=VL|3G)Kh42SP#gGL;pZ*LgqqNZWWb# zgj^pdRK^k5ab=6wz#(N}e_Y%@@(I6>0)dAmKs{ZOUS?_uUEPN1`S16k%YbwVuHG~> zG)8o<>oh24?Z^n64S{Ier*!16I z?en)^wdcNm&Y2ia&q46Z$kUG*B%F!^Rv1` z(E$Lvswf`E>N)PlNdWu|K1uvt^++^+T3|d~|Lni_@5%eP(K|U2=n}YO#@+YFEddx( ztiE>=K#2y7j(zS&f7quw#MmX-?I41;Z(ElZFMXy%8v0TYq~}XMuU>`C04)imwB3*a z)`c1nAS43@tdT6P&4IxlW~A zA^hErmMpIe3_qtH0_qo9K691;Lnk>s{UM3)-0Vb%DN-GBcM*1NH_|0Dy*dT0j)k*2 zYRP$c#sX`WofX8I?CJ0PWy&`HZiAWs4V(V7Xp4>WDD=&s*O#&_I+zam(Uv~vxb@Z} zJtZU{_PDnpI2&M;i}MSL*Pm@gUqy4H;VDEc&G7Iz@g5#)cu3Pzh;9@Sfw=1mSmIv0 zp2sl?$@=g5n3qY*pG+_LK2AcBjGugW)*JCm_RD^}-2mJZF9FcK;iDxOt#JVE7i8d* zMDe4Y=2&X<;k{fTk~3-hUKY`;c7`}f0lreL)z?@Eu&w;6b)K)-xqn=;i@!NV-@!{K9cQ;<>AlfCcRa!?+Bxj|13A-B1_%l_O4EW2k^mdj527fDKSH8Mr z3tz?1))^97PqniikQY=YC`E}nD5|wVWp|?0e85$`B zJaG{4<0z}`06Ga!+`vI9i#%~PKBWcn4L!8_Zt8)Eky$=lk|F;RqHC2Bjbji-uE7ih zgFUuUu=bm6TlvnaEq`y#s@FI{a&yj}+CBr*h*61F0plj19T1o#{*or7U??@~aI%DP zlxk=JPg+11-MX88#!&c^R{axKpWO_~-s+8RUxn(D4uP1p7ULvh0=k5`t1Res2FjhH z6`9p%TSe>KY}rS@`<^{`XU(3zea@9cjIjIovG(pT;YIAe5Qz~JJ4F#;Q1aMNDe0RN~4gi7y>9DJqi{o{f z{nuGIY@nrI&P`iccKew~q(5O<07SF=y%pR1n=PyVtZj44OE$Gt#4&{@ zkQkQ`OcvV!8I=2~^s9$)zH|C-wC8!0o0PAZR0kkAVQLGL$6QheAQluo`l;WZfWg5J zTi+*50w5d{cVntg9~F5V?sh|aK)gei05s9qkGnlHVrl%3aFPJXsh#wwBZ5_@Ub~@V z;Eo_>8Gyrx6%~T6T>?n#P_WHlT5zkdX01QV2h%dTL6K7^_GB1aDc*H}k;ys zao5JaCbJ7k4s@z%OI!B9FVb`tGLt0XV4R4+SX6&7Sv_Pb4@;0AGWihwNrymhjo%kk zeN|5VRfEC5JI~!e1W95hr`RqkKl1V;#~qI4!rK_u6i1HcKb(0q)==Wp>>l&Lt>vt( z{iJI59=v5&Z(Xogf9(aEdYV~2XA5L<$n&zK2v5+!@}}E~0JHB75t3(crxpS|OMoH< zo)I{;&^Un=cUy!&FOGalEKeOB(ZWOa!ewutQz6)X#Nj;<{L}`nsDT6>PqChAm1QBgxF6#>A!p!Eb|H+~FhYKcvS*0~`hEM?GA5wf%mieZtl= zC_Z{d7;J=-+2Bdsq!NG#nEetsIQL)2pI1MMK#)!{_+c52-b^x9rh|NZ*j)f8P67~( ztR6_C_VK+yBVe!uz>Pyfef#KLPIrc>b5R@#>2>joG(%fu)#n^@&0XVLYx~l?*-2H{ zPI%v1SF1Mj`GP(7ix=(eH#uYD47+vaurZ)z0Sr$_&nJUqLVp}PI79*vjbB%ws5nuX z5)y$}P-nP%$>$beUVVB_VpZVe?JOBDwOV43$7=~Pi zhB}g5xQx3=CvFkbp)#o?!JSkH^dtZ$wSuRuUi}%gMz_R^IS7i z&0gHrA~6(P;x3|PB+y45>U z+wc9b!P^*T$Y4xCWh6K5lJM^L=P1^=@OWC?FZO!HeCmF>9rKGnCi6?S|D^5XtX{@5 z-1F>-e?K4&u}BiY_;j8y^APw(OSTCliZi=^Zp|)!Y1&@<7qe!cZ&>DYF#08|3ZS4% zY|A0Vb2d4_0UE#Bbkj^XSk~KS+&2u?pKvksgL{&c2_MEK;TM*j9|n2{A9pnNI{5rT zibo8Ag0z4T^L1G0*AcrZ4hPXtmM!vhs%ZHthl*fNy#7wzKKlLZw)NdjD}PeP64{(J zwEf7f^b4JIr3XSZF)?6oa0h%bW@bR&OfO_zg)|*u(KeC*} zjRHo)FA5RUqJxLz*<8)qM?YG&PnJKim;d>ByP99H{7VHZlq%@|REQ_S&v#l&04GSN zQR;@NwA6b=9yIQKZoCF}q970?04J(BHI{b|))XQ^r!|bozKZBxw!t$xQyf-bqI-Lv z<4E7B*!AE0*w((gYKv=2Hs4rs*8CdvCdNmkd(3trkcuP$+BG1P!0xDC5Qg&evm}2P zNRynt{06y1aR)^?R6kic9Oc>+P!JtP1T>49#O>mnNGJ)9NoSb5d&49p9sKP{mjEQk zQxXc3w$GzT0ODncPSn81bx`RFz^aQYcVd1-{xJFVPTiIb-GED*_Vllo?bUyA)~3IX zZp}0bfzz_nfe|4w3=$d8A!V)8S?nauHugbAxrdbij7lqn9X$ks1mNglezZBFrPax# zG3DE^dP=5zQSy@kP!x(g>m6JB-A()W&pxyi+xtFOeU?89#_+qF+WvM>Kv&)6%!`HZE?IfgUmakvu(m4>zlis_f~?PSbt zw_xG+1VbP&08en^?5AksW+>7YYGt)&7|mZ2bjOEobZqmzEqn8i-m~f7o3_~p^LB1$ z!De>mU6w2gxFtmNjoiLuY56+~fgR@m_=)ywmLcTB@jknXx!;-pu8$^oNzR}jHYq7J zj&dD;j=``p9xoj3@D);)1ey1PP+9K;_*twMw2dE1O~Z1%7I`LezLhu5w4LCc={WRW9# zi&o%NGC83T6o=i+T9QPm2ua-U&Io{3YDLg36iUkmG&``=o({0B3(P+PKdo6|00l|f%eBe*GI z&n2Zl$^46w3gX)C$leCNq=&eWQzY<(0cc`;+##C*h0up%+@v$$Mo$DfCZi$2DOo`p z;l^3=8;E~n>5bDd5R)~^jS*0c`qYIzTC0prwijVi9f0H-_`}ZNdj%Q#FqpLW#)l(x zLq8rHFlqZF>%TX{(H*2A`Thtu#Xdvn?$r5h(Am-~>#4_Q5#LFA@Y&4Y+stcu`^taw zn&rRNwyD>OR?F3_3eG6yr`;}rh{+$ENzefp4432L8zcb7rKN_IGd}*oY98Hb&?-n~ zM05OYU)!*2zx#=;{K>jqxcRI-Q+dibXv{egi3Zz;HgaqYgym0z9P;b{(BUIO9y0Lf zQsyoNKqm!|pQB#xK@oxr5SSPOqlnFZ67QO?85`AgX=3^N*bkoA2p$2%7}?mmQzMmy z@MET%ZNCkq0V$U8X4w2&vN^Cq!LnPg+sfOw?JxfA5A4jRCHrde3s!gviJ%w@@%Z`U z51}Wv>7Ias1qr}oZiGjk@pPv!DURlKaypjc+Zg7NsZZ>FN|guXma^v ztNg`|&D>+n-{vjFp&>QwjJMeq=#oP5ufyJ8t@md^AZ!G3e>-Rd4|kIj|8X;DkKTrr zVf+kg*q4#NwERc8aWi<9Or29Iem3awZ`{x4vA4ZP!PkE^{64z$!@u((zRdppVejfQ zque-4fi3!%s{`#I*d*8FBj$5d4x__#h~+4^w>@^p_HDV_xBoUN{GFt&pWH(~34Wto z212enwpa$#ltAFn$aZo7N%{&X`=T7YnOU>#*=2k2pPjeo{*yB{`!$q%=dlM+tb-HS z2gG(keT6=;YcFSD3@Kn5J%PAOwqHCfJU@952oiuNuTAz>B9D0(e>(N6m20?lJ8jd` z%w7BZn`^8A{-|XivfjV`S8H~8{k$!=HQ>Ym06+jqL_t)r54g#(eU(PlIweQ?8N{Fj zkb(On-R{$fa(Jv7eLo`N*dSkxu@R3+1WzzdTD^vWe;k80?7QH9L=X^z%cU_MnZ1t2 zuIr}?tBI%=Y$`Kn?e(U8@Ta$IYir$JS-osaKVP=|^Oy0HT%-4{|I3)!xKYC!T4?nY4e)^2f|0{HdF0w6f7CcdG zp-aH&gkTBD7<)DdVwLLeK!`kprN0<(p1{Yz06c+>@-Ri(aff?Ikf;rLoD*J4S>x@F z-Tbq4d;c#!v#W1kuuGNmHqE)<<@Pk9JSq8!&_~2wB7c3`eRFyP%HIhKBhQB^&O^ub z=;)z8d_q3hMfe?Dqk?(=qzGG+uDJ8@;(o{J*-JbQtIWq8K8FRD{if^1{sWnL*54$` zm(@Tm3FKSTwv^6u)c2It|E^*mU0=7U=}mj?n^$b+=P((bXUQO4;|sPHYJc%zH~xMr z8R9)M1Ofx_$e=rz50h(V}D4e(KhOUD~|B zAw4qg8SUtm$hL+?f15S`d@gTU7WHI2#2wSlfKF+nKSaujc15hlEz&0o^pNl45PXt= zK4kJo65ZoLPuo=|@5lCuU1gY*r(&h1=UmFWlkbJ?_aQlB+wXTiUay|sBXJ+sed7H+ zITn=Exbzd*?R}jPK6?{(I-V9Fq)l45(0d>PJzJV|JhTv@DDjS4E#~Syl@liqD&zikr!bXu@40Q zcy+4406gaQat3xh_0Z7U&9DzI9q|-(ieo@U{2zSlo~{1znx+4)WtUbKZJ|B~N00R{ z2tMdpX%8>J!Gw4MIyAK&Y=*{o>;b-rapEs#OAh_aq0R;E zx4pZmBoXZXJIv5xOcdbjIV_R5AsJuQK1d=Tz5B3aI^)t$#y@rMBDzDMr_nxc#$D*1 z_9+vU$oL!Fed(do|D5lM*vA;sw)9-41i08 zghDab1f;J+w{G?HJIsAL1|W&*=bwM0Af6mw1-SHn_nM z5S&IkHCA*9QODsrnCNw5IN5oG+6Tppr!y>nF_Tfwdt>-CeR#JwsYiAHhJPDREh>kI z&?py$ikRz)V$08OON)QoFHuy2cvyH&LLh>ye)nE3j7}gXz+cJl^Vs{&v)5H;{%Gre z)Gs3AK^>L@)Af?2ccwTU^sFtvQL%sjKYrV8{P-S+iLva6jR7_rp%I`dhFX@db<^c; zQR$+$@cSe}0K5<85AM()kOXh?JuOpqjJ!4{^~nUMoc7&HGZ(p>Bh)&VqYcsCENr68 zH^oq|TNZoXwR@YE`JYSn@&9+j3d^%Lw|U0q+bHMYG$0%7^KYh$5ccSMOi$^)7946+lX+(huj&6(MIBpy92S z$J18mF=pkqt2gDP4&mJlrqJ6q|{33Z2RG^;n>*W;mPr~C#G~>VlElq zw~ddoCw$yl5&pv=_ZDz;7?>a5XCkSNhro~z1>Np9D%0L^&3B3tZ%mg|H{E__abK5? zzR|Fd(XZ{o7CQtmBi`f~G5j|3_pEv4rv2)F_o~hQgOXK$5!EAGr|fkO9GbOq6P}z!cNLU?8iKruV@6NWEU68CBJ@%iEoc^~B*h4Dmw8zoFdI=2{9z1KVwqfy zmP1fS)wg8Wg5gcEmMrIvnC82-j)ibmtRdVU7xO<$kQT0!N)A$4muCA^z#@0#D z=8Nut?S8rYE22cPc6;~U6qo?4OUHdj0BIL7^ptJEw85FV=*@Y1aC_6f^*_C3zp?!V zn|UE`b7yB@a4Xj6RIx{b?tq9r|LSv51_Ltc6(T%5P6z}B;4wfy8nhaD63+|afwbd@ zkAWj3m`2$KxxM4O3*2Wh){$8T;a>09r~lV|`{XYl*wyXl+}{6EN~8qKT_9vx$CFL} zCRYByzTJ__P{hw8jK@&z6PYCzlm|KyPf1~J&TTqE##|j@r@huWD>6f>a(4tVzv7yx z34vro2jrX~>Do|t>^h*8EqdtZsp>TmgD8^GLdPSTp@XAw5PYNuI>TKjId+)-*NR*8 zGR2LMvc7jN>VEWxs82-wf_Scv@U0^(VgSkzZ{i?INs(wVuS27R+7TP`l&Ncm7m*+J zSt0+3m{S`1^y*ZVG}whA27pVtCryARiHQ3BRE<8$cPeX}GbTD|-2nt)6wR7#6kN$6 z>crf-&XE*;IP2;}xrZH}5#)!1pvxZ&jiC09yWRQ203e~v!F0lwx;`YPZ@&GM-Mu{n z6L8P2tZ&=re*0Nl{H1B6L7TRd-m+Y_=-Rx%34|I2!9BSU2n@gxw@rV5MU+EG&>>9j zLYQE_2;G7FB^B621gDvQCNmFd$XfGm)86|1Yqs{MRgC*ww6o1C5E2Gwi!=NXt!h24 z2{X_{8X)nvGgTWK<58}$N+&!Lud#^XaS#MVoCi7i3%AzUSKXm4rI0BGAY$lH&ZLbb z0M`aht)R+|V_k$Bv#d^f1I-i4ZFgq)6@dhiYLQk;1I)J55YaTt0jVi0vLPkP6d}X~ zc7#l`B!H2pOpbTVJ-5qKScYbgx8Aej3U-r>Xxk@#-Fmd)BxF3M*`!oR5vtqtxffT>PZSiwTt!B*6~V*scx z(k#`j30zv3l9e<-OshM3nJ_m3+~HHya|Hc}b?ZS*aIE~)S9}{hOu>hAzlTX;NL-~% zq1uwbNJ5FUhC-&fvb1rTt%94&O}qW?m+b#0F3z2I;SR#cKBHZzYTp+HY5Lx4*n@(@z;l(b&$ zFAgx8h9H5EXLJy_SC(Xt+11}5)4AQQ-oQ_FsskN(z3Kg{cH47XPFYoK@KysX)y!L zI6LSENHU-?AZ98_=u|ZkOir!u7ki(&`eDiV$>EU<*D}Q<&Yy*#WR!L? z{c&lJ%YR()l5kDt*G6wcX{0*zO>mSHilw%s2}T3pbnL$EEIhEw|GaFk|JN6-{N)0s z1Zpq|IT$|lk8Oil_vArf^yqo=%6sBUA zGJ!GCPg`)3KiO(P*FL*y3_i!Y{a zYKa}z3u$}l>x-71#lmA5<*F%+ug;PlXE;Dh-GNSyXwq*SlIGXX*0dZTKP^3YH<*=E ztiFrC=~MJqfi6W$+LP5&#d0L%RC`?vqbS0Hp9O0h=TMS_){jgk3@C3^?rs$X?G|^@F-S z_vx2ksk;}zSuy=Aj+U9i>`OC?;XZ5W-(jAg3RZu^;Lk+V(mSDKpg zyMlDdN>nKN@1XicWfQE%Nw6Nb1fbzys|r4vL$ET^4bxHaAC1d?8~gu?qjpz2h^(jK z{f4TKvowe>-K*{>w9V=^vc26ik4#bHaDSBmg~0WVb+GLfL%{ zw?l@&pwV;4S%&0yL4d7(!fjIc)0)3itzz~s1|S1PZ`^9wTi<@unm^%E zQe;<^K~6{tY|AKbF=GOFc`#(=^~B==4H^b$mqktmCJO zFmWRCxoGR4Xedjmy?oV*DuZZWj@h?sY}e{qHAgx?ppzttKohKZ+883I?*=>dn!PTn zvC@cU{yv8E4g?M%c72&aLe-Hj0#@PVqd(Xi2*0ErNHdU7sciWoYr<#CHvjUXb=J&Y zxKAQ$$R|Ff-y?x3S225zo7 zW9gOicI}UUY%4RjEOY+zc9ynIBjwVr5&ijzM?d`l{XQ%n&r^^995UR8N&pboyFJs} zV5x#s_b}yK*s$5!f~63Vrf;%N`YAK{f19z}KfQ0ARm8%~j;30yqk?%A-|ZaG;1s6o zI^`GT84WtO2h0Z!xF^e(j3Q;NQO*&_5fQYwG0Kh0U#1Wa(|J1tu9p0`>;P~?8ko7_ zqnULMhAb<>ifiJ5^qNVoG};kwXLgtgty*(&#~Nq1tiG^mg$riW=ZZG}<+7c9?!3)D zJ#THc^rxp`&G_CCYzNz}h`xsl^$_LLZ9(_yd|OLE)?}0u z6Cq{8PKBPvZr6=F8@76D%|83&rmfytwdw0i)>v&JHK<$T4$5ac=d4^=WcR>4%L7Qk zFm9C>KLDKHiCS0W$KJ6Bf18qfZ+->MiVVeeoMR1astZlOk zz|OAOOY91G;n$bU{!8k|(pM8vN2&mmio_sFLF_FoBBz(eU9$fs-{Wz^^W+c+5`f8J z_-HA(0mNV^KxFbe3fZgjKeBux&fZZGs0$jSwSdX*6YgNuY>w;2CE)BM*)paoiYM^Xahu~++ zDLZpv#>&qvq6v-K8pOYF0SV4LZFvQ0%?wCx4rR8i&QWu_Zy0D+5NZP7{bN zkwwf%I-_m3@&o$7waCo%FkP2!4$op(+YbNYXhVinz!$p%oKwKrv3_EbvD>iqV9T!k z^#j+t=U-{rnb*%-wxq4e7$&3iV#2a5c7Lb~FouGAd=Ll>z~h5GIWue+U}*+}_J@~Q zN9}xy--jJr{+(5;e4l;&tDL|E@y{U}j;yVL-}uro0AMh;?mVClZa@z34_><=kVX4m zQVz}LTg(QVTnz}4tk%ipi)@8MXT6rGSS7n{wGwx(+yaJ|nBm*kw^+NMwF}RpmH#{n zatnMUwF@k#I3m;1zIj@j)74szdxO~Vo>sf7y`yYgoc;Wqn5CO8-q(!Mu?k%{uq)7Q zY0S(6r4GdWc_xq$_6u7DJG;zM!Hv4D-rTgCAKbR(8>{FLEZX*cX8kNDOmqIlOluCJ zKJ6HSG>Pp9*rN1^t2^k~w2=z5kP_%FCaj2MOn1$+J`R7bONW_nZY(RS<+kYY`_rI*iR3OaK3E|FU{JeXU^E%)hR1p zVEDX-G1@Zv>a5{QanC8;x+lg??5tiP@hI`TZlzg@6+;5hg>odQ8k z76)ZlfF|Z}I?J9hTbj<>(ld*8_2FR_(#HHQW9ey@5|QQ6|)KjW!T6 z%a?K@T!y4(%FC%v@GdEjBl--Wi1_<~X985v=?xtP)e|IdizGhSTvQ7U2x&sJY>TD@&rx+}Zxj_FNSRdO@ z&;dAP&?nanle+*?HOPU)Z1*7UA2jU7|9Z#Pez@xP`IlQWh@_)6I1M~-mU9ky@rfIB zLU1^*O`BXZi%6P_GVmu^zGNiLjz_t12=4H805pwwG$))^$)QExorcz0*rzY$tkGh| zUq^eNJ=vT2B`Z^E@a^}nxQrJw%NPC`>r+r7UHrFrz|9;EmmyA)vU$Q3n3FB z%5Ir8Qw{FXARthR#Oz>rr^Qyj?fSaa^V^o62GXSlYx;Bc%*&VTnV+9wYhK=pmqBc7 z+skTQpIJ-?3rsES*jKacV@JseO#$XUQs|RlSt4bTEaFGxo@bG+NK`8O`mROA)wytP zUFZ9Te?Rf}0U|8HE@C`8tSO@z*n_5HvqW(`w5$WeCgVqo#Ti?Add})!K*!=9hb&#M z+sgGVyU$wm+Km;K{U{29Clcq(Rkbo|NW1#B=JA- zZAS&w(=h-5!Pl-2!HUb_C2db_S-F1JI`>m{`#-XNV-M^b=jJW_B5P#1P2`>%NDN>I z+(_XT+>t{dFaSpk@)R>fAv8Bmpzm$ALv^mT?ase@V9oEP?di{+WB)hH$e7@)p)}SI z^_LUjXSUcweVz-5LWlm2&9AXwWGGQf`MZpL7gz z$naJ5H80d}bSc9=P~0{x;3*=lEpu|(sooT0#cO`HVRILz?73gMZ28wfMqkAHa?0xS zHSE||Ibo4G4n(4kaitXY^wBTJoUQDkNARyB&eRN2b{w?s>9UAPW@L@g@hI`)3FGyP z=*o0ze-d!ea+vcHyl_&!)T4a0cp|$5y2~kUj>D4hLdOE-J|r?3m@wHP$Y4crirp94 z^Vl5t>Lq*j>*vgFn0@-~ZCigA8ya`(wsC*c&NII95U&gpH??7-DV+`ee7UetxL?=n zYy17+1jG}wrn4yx+W?W|E9%;g=>=z%%T3$ftlMmxGcDHA_THbZTH%>ldvOUvK~FK3 z*ae_%paS<^>B|WK&=X#TpaU?bfhHB}$q0ni$U=v1K^Rg`7ib{RK3qJky|$+%gHUuzv!O_gmDr{i8nxt6rA zM!0difEqF+!uNi%91;6&f&@$nzK9^}?8R@S5k-P@GVBkx2J4Fu;yTJ>EU3tgx#cjh zvz1-3<>C#io!zk9Q=GQ<>m_^sD_8Bz%c$?8rOct`c2}ZpZP#qDrj0p5b`xOCh9#Rc zCW+H56Qmfoh=fR8hjo!8b|6N%$d2Cd7#%O+7#?Lz$msDm=Hs4ns*g9$GN_N|@4Iyn zXd4*o6bdfB9k;P+nQlw!!WXSsLtVqR&#l-u|4rGR{%063`voRD93kx%&1fPux0niD zE)AIK;0_N0K>~1iu#HltLrYn&$)M0yvod>@%P7AzKiIaP{pn9^;X6-Tu{LGp?5x|@ zoPxk;w^-MnnudYQ#Fmh=lfDTC5a>B)SGcFjllUA%%` zN4hbM+{rL=BmNZPdhI#ig4^26tXgAf+h)E{w9kF>IV*9NdGO{(65;Q+QB*1)7VeWnK(LLNC>jN)U-`HP-9`Ug5Uj8mFvQBtYPw$B zWglCF8$Ayx8RpREI8$Po=hA|G?HgaUtyeSl=J&4K-D|fk^8h7JmIt(ra0)xkO1i?i z4Uz_QM2IBe!PoUD{3bPnt>T{?7qyQR0_D_3nw)gNcajD`{q<%g#>@74#{TU8e8YYt z_oAJDY0e5WNDqV`rAt6NN$t}a7GhTv99eLO2!R0JLjP#I}nhak3r6OJhwo1llZ3uoi@5Np>C*1&Ed9v^@$wf`;zy7l{cA zHC!#mDm!902K!8^Y&)Bm?63a!5A4e?UAE`GaSEyS#?!UI~=4PJ0sw9a0f8=TAsqq+3^xgOLO-t+R_>144Hk=~i}! zB^NY}uWZ@n*O%<+UpZ%)&w+}bq07$^(cx_vGo{JwL-HBPA0^Hg%-s%)u2`AaLtMn5 z4G9e1M*x8&qWT+`7{T%VxxNRs4q10XP3waVs@647s(Fn-gorS0{(i}u==FWCL> z@7QPG*|L>)xbAOR3GshEU8b+W07N`F45%al>NA{F7hc^z60E~y01w#v1!34mB zrC2U2!2smy*l1`j+1g6S{`7zNzWt}we`HVp`Xc%pGWHNj3dFSabZ0d9gF6%m1P0(x zz}io=jbf4re5S_iVbg5oPuA_D-?@nevy45{e9dp&72M$xmg{MyPI2%4$^`0*I4M^DQwzSdBZyA znrz+6*~QYB&cJ?xtQ zUU}na07ykb%L3BJiSU`$`wPIaXp45ms-NAk@BA-s*l*4MqLsg%N0F0o_yEV^1K#5f z-zU9m1P0)cTSz)XnFcfYyKL$IY2DWUWZ7D8vlhmICT)rRH8AMqn(2z@$QqrThLzLy zA3eTY+>`pFs*6m!*#mT6^k2`C&Nq42JZ!#MvPuU#@wRU3rFFLQHEr>wl3o4z7p(XK z3SGYneA%<#=Fk{0z2!1kDPszls*?!sRm}Pd*xi)|9-{QyI`#}tzvE&QjK!0vY{4Bp z1a=YoZuXA&i%H~<4gNf{gV#a(RDEd{#XpIs)d!$Z+J9>~bVFV_cgbG( zhZk-2`HsE&gHP^Omm_b;2{zNwd3(bo4bp9y#Wm%?lVZX8yu$ky0lt zIJyBEzq1c6*m~u@{pA0?VPDK%vBj^mJyT4zw%)4!T*DlXx*o?;1_t1eS`D&A_mz;a zjb=agN$_QUuv67ol#l&M!@6oye#5DR794oYHhkT`&Ne5jHhzA=9bxLIC%*FRx21 z{2UkrqN9KN$weci|L&he^u74s`{^F3XfU6o?c1y?rx|D+iPvavF>UP}$K5){TUz~G zoG+Y)P!*O~mV+-iUoKeTYfsyqzrSy{|8~VT-o0+AJJaw9OKcxx*MRmQ(qGh9;?BLQ zlP3J*aZcoOqRx4CGO?J+Sk1Fb2Y_-?V>^vvB~sB8b_1sBOMob6pM2+*p&@PGSa{x2 z&!7Z&hJ+ZJ;|Nr;&67GMClba7SgCRFJ;1C^S5jIb)ZiD9YTc{Z&f9Bt`@6U7(!E9O z%FMCfm_5!Yy_CU1(p+yjB&5+J!Y|pEKG)pk__}!6qZ&o{Fz&BsT}eDC;w-0GLNsL~ zmi~cP6H%`Ir0|z#k?}c>+gRI!uB+XISUuIW`SX|*e)gih@cE1O>0hkaoxjCK#HVc2U1yta zg(U&$>hR}guB0g^DOJS5!yLr8gKn^kb0U8P)Yxc2?U`{TVlM_821|@LN|bJVGahF- zBU|S^Y;SJcr$1P>^5v4f^4k|}>I@9KxVDjQT=>Y3Lm&_cb^yk7gQ19}`<*&AJ>1PM z)g7g{+Mt8i*+(qWKKreCt9-9v_y6dgW#7!&d;_IFSlg=N<=K{08{LV=5toh=v5l$3 zh~S2Z;|MnnVPzo3s(}!mK%qCi>sj{<<;#J15t=%2zT_P>kn#?QpuyxxvoRgmA~<$& zHGUkAoW@83a@P4OGcAsHg^W9*yo~Msk7wVvJC|=*>*%Wc74o?V|0?9v3Czm?-k)w)fgyKXW99Xj8F2HmBxxqzm&Gu{^g8a{Vy2t z&#;?^ExIkF2x;JyLU+LJ#^7_E?8p>~<-8L9V(9oMy(GRKhd*6GPVrBW08HBWnkv%y zWKUjVVQ6g%>-(SC4u_MRwexiI2$_iNW>8>qA5Tz*XedpPz=WUr zQ|?6Yy>pKg%-tE3LUG#M6HUUSxxIseV_tMDD=}dbybgqHCN!m-hj&IC6|MqoYq=&y zeC}BrasLb7c+Q^s#Y;B#bEp)ZVgElS#hc9Rqk~D5o*=`W|6R_#4~LqpGg8#ZDVbd# z$6vbX$GyVyV}pQ4^dk6iCx7|%MZ?_|^*8kg*H?U3i2@uUrYq!h456avhsW~evdzuR z*&;UWpMK?v-I{LNy|>Xnxm9Dy0BewSwwDk&kB&(O1)!`SATEvWQdYNLw&~zXSC=b> z`{CsTIbk?CSJNJnki-NB++|i91Yz}h1GCK2wsvd9e)ioBD?NA4E=-{y%^IBAqQP<6 z8E1zH5)Md$%CHatVJ9Zu3 z7>{=+Vq-k9G4@P^Cnh##!aKX3nV4g}>m83hl5N?NB}y7u2PN?m$>vQqufDs{2O5nV zsPn7Z-~WB}0R=P~=qA|RD4-rtRp0%+moHytzRY}?{xBC@FJ=CEMWZYZfrbFEIDD2q z3lpng*DC5G7RP_4NVb^ah+SY!aqfrHR(Lmy<4_s_A?gCx2yY#ypwAHg# zT&W6Ie!GI!&FVQqqMs}eREe<^I_@>u&|3p`=v#vX@!Ckr?U=<=X(kXd*vX@cI1cy@ zC_TEuY%9`e@YLBpUU5)Zu@!0v0L$(g>{$f3C>d&NhH@s{?Ci?LHw$(EjzDq0_OAwP z-Sg`#J=w%t(rBIIj=>3Io!X1RQ8Ph!Pc;dU|2^IOKHQ`Uy0q+S(+nYFTXKOu^44dp z5|l@(QQ22Rga!3~anr+tpLpOb{gG%C1ByzoD(y)D6}~hE`S_Sk$HpzR*|RP8LU14K zwq!p9U_Eccmr^qXXR}u}G6=P13BIJkdDZJGOGAZtl>l4qmkWoSpbDO$BeT zBP3SQuZNaH6DFPi-pMcCKVDq1L2|=5GL1VxE zAs~F^Pq-j)Q!`Pwk^uE}p?A_^y>aX4OIqjtjdtXF19t9-5j*qpSqqIsZTVp^KC#Ogsp_C0K;=Orm04RvC`lVG;+8?JC%9 zAKhx{?F0~NN*Y!cC-BR)LjFa7k|F}bCbUOIzZ%D)sew<(d!?`LfvfndAppGB&aE<+ zN{D4dFf64PO_ETgLJHF9Z)dIWblG|bH(1HbxU7Gg0hE~z%Ob9#+qLY-4G)ktKw5XQ zj=q9qKEW{8z*F0#&R0vdErzTmRSwype7aWW8SAv$XWR-8A}`?r30Sg`3CrQ^7itSz z|4(hS^+afEzJv9_oth#r@FP{nA6}40y7E1|AtdZOr_7nk@S;X(Kwvo#&=j4IuvP-Q z1OW*FzU!WriMAlj;?dFqcK4fYe{_Rw?(MT9J?HGmb0=-!-FI<-OFC!v=B~cCrMse=nRBSV!JXXrh`8owZmUN zW*biTT2Hpu&fw)90m@P7`#hGNagT@z5$9oe!~tMgT7a~Hw0b2~3XoqjiDeaW=w%el zqOJt>2)u%|_{R-R>L)*+7y^JMp3z$CZiJcfF>7SQtm7fza1Q!wSMrlA`84xJT z+Z;4f8e*r=2T%RH6T&UVGSaQ=`o+k&l_3G~y(vqqi`wqJ8!d51$WDA^lte>=HZfYT zuILt41>nif(1>6R2=nan8V@BbO{m7LLjNmaQ_00@@P#c>q*?y$Haqmylh(Fjo23sh z((%ElICw*SB?MH5xSM!L2oM2Ke=VcW*V3&G0pLCKwvTgS|567s`w!vyTO`=U$+Erq z-w#{tY{Gg%JuH7i#f{clNJ=DeRNP{Qx*LRNy9~0b1BAR+!~9iczYf~Eu|)$|b#dCb z>Zo)3?l@)<$fmRe3b!NSM=OA}{6|87mP=&_l`Nxy0&8zJ|22zbkflEi;*CRGvh=h84R^)r&OV=X znErC#*=eWSm(+_=DiXz%hl)$t?56n3w6?fB9y?n$T3>vfz46459eZ-z#)${g6hc$T z^IR+<@H5aPXcYOBp*o1JzN&S5hg$6PhKyZl3tc<~ppgVto%!`P^y*=I@^22>hj-m& z3Ct}yv?og5Rc7*_2}Ce~5^Yew2$F)OK8>5J%Q_Y%j@X-o@EGmE;>VgtJ04X#kihq#CDH4Ba8?Yfe(tXtO z_vUQdFKo4*`#Y_DbH;M~#Soa3*)0O_6-mH(6b8JV4l0uIueLZMAeiXCrtS?JU@epy z+gA#K`Se92Imk~SKNg*r@E$N5O$v04`$P83m8NZaz_X*@zhG~EWxxur#BAL-(JDPM z;N^4`QwU}Vd8F4I#2}0_T!dM0Oqwl(+5!&7iOlQpCOpAwffg>yw~j}o%Fgg$^-t6~Po z5mwHudfZAW*Q+Wn`(G8FwQbibBhlIXMA(i#Gi0&vk6ZuGZ?Zn?xuR`KacBBE*8PK0QF3Dk8m0TiP-n~F@?s5fNiwx6>5 zK7X%uf1!iG>j0vS4_H}Y5No8a5s#68!Gg012{ zY&2~F2-Gr{0LQ@7nHe(2go|PDUM8>1#;7%|YqAa7_Sn<^;jkU~&M~VL$8Fu{E=Mbr zf;x`2uq@l4CLO~4%L%y)ROgx*uWNNZLB4GQ<*(k#Lp*GA11&O38Kk;>P>sPcMCDv4<~x_cgmhAQOw8BH~XB zW}b%m%XzngJwKb6vdPr2#cmGSE&t#qYq^D`lN)GA3fmqDk_6)r0v2nnoL%2l5_rnt zs*J=h?SQkMaw(z(r*)5C#P|c|uiqJh99+=&Z9w1}L0~?viK&Sh6=6=8vt6p&_~y9X z|GPV^b92<5_{(Q4k?TZAAQlEH|2PhTQT$spZd`yHq4fll((;SGk}^?=iI-%x(!{GWrmt2R^z77E3O4n8&Th(e6O^vQ#*q<}0$BCB z630II5iP5%a3q(Hg1mbRiph>Wb23IowbnsvzdLO=e_^|YKaU+BkLY}5f;`~9dOr*i zbiNUi>{V)DaCa1JcAvO)mIR@{n|H$VZgKwkG)y(1{K z&kv4W%in9w@Pp^qwo&a-i#5JuaS>c72_-$Mo{ov z!W+rDjHK%41~>Kkz8+c|sW8ijF61IP2h@z$Y;6~N?bz3bEcX=jfR({vRs@9MpHn{(lbXJ3cE&(O692L;YeQRb~9wpTOYZG?t2gj}RWSd2!%{HDUm~FmD9)K9R z!U<5rfX_3KUC7zcOS^Bzbbwwbl&pux@;-~~A24n`+rsomW51_<$ zgsuDGE^GZL%cSll=uaG`564%+l_-uol16ox$97S|0DlRo^LV5@eB~_V?0fvW!fVP3 zGSDau2;3kD)H3E;0YKFemX=r=sO6~&ZX>}}%&EkRnDOX{mC_aK{$!8cyW=K1);DA) zU~0vaQ;Yyz2SalMqB@(^12wGlwI+(%32pGmp@ND(ADw~*Bw04h(&=IsSs91z&A%M6 zo}Crz+uLc8G`?D*3-|1Bap8@cE@39X?k6jC7JSqgUd=`At0hTd+ag(Rwhrf341jndVwrw2 zsNIK)VdD&5-RC8dS4Nd-KDWk*@}97&dKqPb{i zE2B2ubkchFcUtEsH(TNX!uV}LI#=dCIR+L9?MZSK&Ga?@*BWTeki_iqnQ}!AKrA_VTpPC{mvnP3#nOE@vv!UY0sL6;I}6cj>xIW%B7 z_p1KavZ!vNrYS-pB#WJnG!Y;i?I85G+-aFy#s=0ucg$ZBqLUJ5`#m_XBMt#! zHVWAr&f;%A8MfTvf}MQfgoOvmQdJ>ewazh!!>9_x%;hQI2KwwHSLK$*l3+L$o^lR; z^1^Wu|CqIu5CUZPk0F(>zki)=yML3l-O*}Z8=+5?2N>rj$RNU#h?k&6sSZwm$KRcI zC^*&lZ9t%IAQ0g2te`J5mhhWDPKp5MNrM++Tr~IK9C+VmYtOdZ@$z}QaPWdPPpyMQ zp$Wi=mheD0yfI$1ssOu!mcP#;n7_8U}-+k9w?$~WD z_!NcFHp)!sL5!jSchhY_N6g)1Z{A6ctfdlwXf3swK?5pPKW+qp92$@_$AE@rlA4W9 zgK6n7N#{qH{h#q{@JZr&AG&D0#SMg}%{Zjg`gEa@kDjx*7VNK1;A%uwEQ`~U)?~E+I|r&%4Vdf9MG;Jlth$i-P;{nBSN!{`_Xj(x6I@r^sx>D71WaDPGlk7s1k>^0yfRglm9}mO zJO59x&mEkwuE`eb3U|5XDef`O(|6`+Yh=TRUj%ig%a6`%q{Q-wu_y$q4^RJ(theq5 zaR9unh=)JnfD;5&#_q3~kemZW7nL7i4bZMNf)9;mUI_#w@6IVm1WYwBe<2B==FjEF zEZx>(ZTBQ>U(Yr>mY=rc&ktJmJmY2>ADVJA*Fv9okV2BNxh9J=hteRn7P`$F14cg{ zu>SSr5ZT0J4UHS(6a-8@=WP05`LDp(A|&h|vdj z0z7LFlK$9?y$Zuw43#@e5ai(X>fY9a=v#i8;)o(>k;XjUxL1vf4s5Z zfIvM$0J5-nQAR5?jh=^J30F50PT9t7vb2`;6s|WvwT+ndPqp z4uZ~LM0370B2J@$(fX@SrZPy zg~T^AbY1%rqI}pPOjKhoEZ$kG@9dfr0IsA9edh0riE)MXJBbD0g_2Fb+Atkv002M$ zNklz@oSZY28vWV2Bk5Li?CawfE(wXe=|%MBA+}F=>M@PFm|T zqt>yGOsw5F6w6OSftSSm1s(t;O@JJgMl@HdVjQd)*>4w zZ0FByw(ei(B-jr^K@=Mt;kyzz1-dyu>zXUds))8g@%xq2ThP-vm&L0JGdHMLG5i`$ zYe1kD0u@4E!=j)c8Yhrrx0KBn2pBF_>hdhn6|vi58OfX+Swg|*_4EbU`;rtbg(@seML zXjnk`*9z@k2q83uUDG8{o%z2$DCDRkVZhF?3g83nk=0f#L9mW#A&Sv&}y;Z6NwXmtyCaBOPDm{O?KhPxE=Zl z;gzA+;erIKDonUR3EJ4@vzA%@T%25U8UUBOyE zYc(6SkH3^aTz)X9=A|g}5>$-^Jdd;%A!7BxPD2oE&wtr< z-B*nkAN)&Jhes&JL7cFB5w@FnToIutOa`uVkwL<6W~}FkA=Gk(Mb{nf|$+@ zCj|y@kXdFumaJ&wf(8Uu2LxsW1`Qbv;ZP0-<0O&rB5svUyeDKgfBqJ$OrEo6|LcIA zekWvYi8iaS956z(L9NIU)Aa4!JY>1-)*U_ zFnEHLsl;)tWaXrTiCDh00|N0{E^Ar-u<)C7JohyFnvK2i~;BwVVkNprYA`;NqUbp+;#ypaFp^fPn1(x{NQa5I_KM zHfthcx};dmurB;=ZvNHvR_v(Q(SOde+ldKljuIIUL4gQ3P5>`Jd6YUEvHS|&S-+QP zb&;5P1WjYO6tR{_0-ee_%N{yvM;^Oq{kJq*dP~{`TB?whu|jm9kfO7q8F9G-W+;07 z!eBWy7wpz_i4sy%xuc~TcNzZ*47w2*_nT!K{1#y)M_R0v031n=1%XxZ-1qy3;raiL z#RaM?F-lE*$pbW_=DslirXtHI?ry$Pg^D!+67lyasAF{YLCBF1fU~gzk;RL|2FPcueUyxW z-x;?vuR@nbh*cutNJaX8B@_^xs^$?#>)gq;_qDpk!v*?N>pf-Xk}rTO^nM8E5aeaX z9GEm6wc@dg4Sx5mrQbHHIXy?))nA==$F=c3miaci z@VvMKWjVSmQf3IuBG>4Y>aO+{m~BjqiORt%ZDNlVImeF z5dh=B)|V(ne)J~oRpG3MHcA5m4G1g>fxt({(GGDoG?XD`w@Jo%lzAGy0Pfsp;;R-!LY*7n)G!XT_ zTp|@*tjr3Da<0R27b14(+o!Fkx5rwW5CX{9T9FMP$Px%(^yg?DbkoHOn6bgE&<4NH z)mn1`Kmb42+3I>s_!>-d#)-3>gsdBO{E2f`d~w41vJ9pwlb6g`fyvDbP^SFK?j>h7 zA&?lqX8$VgM+d9>?%*~0T5NDH=as6u#G9s~XAyFkkA?;;v@L5}KDEs{9%!=g2H=)b zDiX1Jm0(MbM~F=LMqH_|;cjnyH6YM{z@-piMSzNCt1%c|RF1Xmmr*m8AUbh`@LPU) zJ?1vg4*uCYRvIi@PiPaiZa6=_JJ*UnxJs>nFF72CwZs^D9B4m)j-x@5VvC)As%S&E zdDgm<>r&7t%mC5=2$F7s0x$(npN6e~23_YW_!GA4{L&lwI!U~Nq!&U&E)vm4K{u3m zGf|A$_!}4PttZ~G%v8#{$n+Ngs0{P>2mn;#TG^7Esvn_&)ZR|zFSWmf02Mjl$o^g9 zGw7eV2H$Fr2D$&KR$v+L3EH4hAqK9$^WKmRZJM^eU)yQTKi6TQ+gW~0BmYlZ3O7};b z$c|ve2*Jl9Q_yL$jD`T-$rkbi9JRtR3?f;Gby>_GvjIXtSdQOoyafDh&4IyRXUjOk z^Iy`l7#RLGcJ$e!79Pg4mgrJZqD-l13@NdM2iI40DVYHLVT9g*lVWrd2xc?@oRm+1 z1cB>QTn*ocSE+r~$Dj(6aFH*JStwJqeUIK`ZFdrVte;F<85D2j9Kw&%B@>WDt0vrX zKdIP&nFy4s)EHmyL!UGru@)f^kd7?FDIYDs@3X`S=EDk{fPc%}r~Dg*NZ!)hqIS_{>-U3IHc~{Ns%Fcc*%Tij1FsmO_ z#>q7<+A>89gyuW~j_hQmoIQEqC${}VTWsUUaRj`T*+^!JnZLY?V`L*^*3X~|%w|By zZ;FH@w)By&g2Ikzt}i`vWkXeg;F7AB`9B&+IK%fDEB_SXJ?Nc0WT}rM+ zmqeeG9$2c#md$b7|B;=x<(_VvY8fI|2O)wO1SZ2x_Rfo#cAve7It6%YZc|}-Wpy%lLmIw9URonQt&kdB zr)p^6h=F-A*0GcD=fXEn+1Qg8tT(sO@=0uKWB^QHFDljyy49dEQoCK@$E6fS0E*!( z6l1v&*?O5=ge(`%TA?j(ox3`%>miu`E(C)%V-X-e5KaJKM$dKOU;t^PRUbRQ`(|hU zGMilHqWL#9_8SmrK)^v@mOamI)q=(s$Ne?`vPVWc61MK1i0#SskfC$f3TGLy(=a=< zbs@3{N{vt^Y@Q;RYVz*pG_?<$x9x`bykqb0?xjM_+~+Uc?zz`oW>4fMOvq$bMI^HQ z_VV|JtmT22ZF#W6IX0J_IY8?M)^1q}`l}Z*V78E7Y{@%8D9xv)tm{;pwT3#dsc{TJ zIaH~Jjamj2mXcbR@#yz-t0w<59|=H?C&SFCs5Xn(6vtB|mft#MnFr$5a&z1&oiKmA z9rGd_?y6w+5LCfEB-pv^?`jaBF59@qi3S9200gAARze&F{VB!?W|ksIc~8Z9?@!qF zkGEQCJ0Wm0IdTff*;yPPH90;z8nI4~$A+VWm-}_s>Dq-q%Wd-Ip8I|r_m_4vg~Qy@ z8M?`a-$>XCj~zA}DqAL$c0Npk-&!tfP6H6E|JSO1IfP`77H#x<7cF!sY8#3hi76em zTm?rGB;=AJajDesH`%j&r19C=eEbP~4E!7Y!4+&T_`6K}yBt$>v+a5H7UK`V2gm71&L*2iEOk@ZHvep&W$weHpZMbiW)>b1{zBvh@X(5=jS3AcWnwVHU$AYB zgAE8YAaHFVAkSmQqO_TEf+Mu4#S%m=-4e0A>CJZGXvhY?K{7K;oUP$*Z2max@~7A* zo=bS9Q9N6&H$#*uVzJ`8TQ7FSQs;;cfYu{M9)OPWdVBZrckTF{!?yM3yDW)Gvkd%1 z2SqPuY5P*oTs`O4oCZM79qQj~x!%$dfD`Ii0W!DJ4^2L##|7O;!fv;c|Ye z&3f(d>fl;nj0H#^haiL?1o`;1jid%`a>Jqi?<#-0}^P*BfL#jXD{Z7dJGXcOU! z2nuA$!!b9G0FdJP1?}%nn9vjn1}WiUkEVbj|@4#ZoUR=79VEL zyF=9{)jV*mctg*?q0TlmgA@BF$UVPWucY8Vn$L0!>K;2_wy(9z#s^Dw^eba{zhx{6 z ze{RCIHWOuWgJ?T%aW9ey6o*l8udBR9W zQmFl<+Lm+-*XOztCW7E@{nly&g5xV0cr&aa(EFB}f@L1d(irBm$H=k$)q?dN z*=W&81=GMurW7M@G=r(I&MgmYVgOYLrctaCPi?yyl*5lIlFVDDTElA{3N1CmFD|x( z?h24FI)|{&-VjK&B}^VsN8E|)&k$gVzeD;omu5IlE<}6XPTBB*bGGvjZnNUug4iUU zv-r-ISq_Qn%$ZEMPV)+l5rz5nJpismSY87%<}BE+`&K19rCy=XC(Hr~4hx3+aVkX8 z(s`+{=mT(9bS;cO2h%{VqhFl>AQDi$SK1&>3#G*jG($we;EJ3@wW*K9XT3qepCiV) z>PER{5YVVwtgwd14Z_+{<|aA1PmxZE);W?Oso5jl_F%fp9{WdsZ{gz`Sn;#Nrr?fI zV<XAUfd@YoNkP0nscm%Sb3opfB~Wo?b*x3inC#bV$+*W8F z{Z!la=X4;nNr97D=xw3=R?FhY6st^#Q65O-qy>`{?*5b{oX;f`PWE%@ch}N%rB|=9)6Z7vDZ19DPmLJVp9KtC^ zTJZ>!;SeaGb|6m`!yRG;JGC!Z;oI^H@{2F=YrJTHi>!DshU4LLHr+R65B~fC>)O%^ z!zZJdmOm0pyhtWMG5^495II_jqjU(chaeyn6o;0&7YPWoHHv+-1O@R}h;+PW*DC9o!A@KXzrxA!A ztQPPog?rkHZ0Gz+iQW4}zY+xe{gC1xAlW*DCiH*$T)|Gimb3ghA_giWtORES2FEV= z0d#D-5i$Q2t7?ChYXIn0;$_pntbQSsuhjbth7hK(p=U;{@ES9jY2;qK+eJK!Zn}ez z01?%6Nh&mzfcfjU-ioh*5Jndv-g)AKCvfV4Akef?^ds+XJ83t4rr$a~grpBoAiN(l zKdDNZStTK+A|;vzgbxe1)A(9B5FiJ-D|ECnoe{j5U1fpyjWh}Cg1M7Mb{Mt)h(}Cx z9K_BO>jA=-8;25dN2&uh(FX7cJ6IfJbicEc7LqjqU$o~O2}vmFVJLA znC`N`Uh#YC^TJgw0ML=rUDBf!7@)c}oJG<*1|fX0Xr1SKP=n(cilZBHpp$@Q9o4^R zo>ZXq%>0FtuzuPOQHKbGS>Bjn^+SPnP2lJ_o|v@gr=r&TS)%-~+)qM6D3605Q^f+p zPyy_Svl2psK_F?A6$k-!4xQ{N2D(z6qMrA?G&HpN5aep~Xx?7@?s0qN`(%qdg+Iqw z+7h`m3?R)Fj0IvpOhm_RJUL=*H#gZWkL<9!KizNXcDz174W90v>j#~IkP;?Ze;Ol= zva%r%!mJr(B~Ou%--S%VVm%SNVHS6%2;#aRvIYU#UCK+9jaLObhjlTf@M!^-~SUa zWhn4R&x1EkAOJ$a47lF30N}Eltl{?H2DUO`+6~3~Di}F=5zf-R|435d`8B8x;@NDwrq`msj%-((Fv=t}A zmYLpfQEZ$E7Jz9iNJ}t^8o0tNKZCDF8jVooRMt-X{e+$U{nzaS5A3mxe?*$B4Fr$L zpixjZOx{z(K3u`kEP@~)chE*z!4N=!Ct4O|h!+tOz0QcGk|F!xZ{B9#%KgX+Ke~vy zM_MAZKk^sS)l3$oFwjS$-}Nk4OJC<-?@X2f#iITSaHitt91v4yl|-q6Z66_^!0M-0 zLw5KF!*=VQ9&2vH85#`7@@Yw@;lepm0Z%CIxe(KZ-sdi;)33T00MsG+1PnUp2eET` z$LhoU7nFdtp)ReQMAAFRGQTqsYw}X!@pQQyU|@|%ims!DID9k!|Yuimb)6DIp0#utxGm57evjM>ZVjvhg)>79{ShbZWFQd

7y8oU1_cDg4v-jkJ)4Y>2cfq_9HB7-J+vn19UBxP3-&y`d6kgp|?E8$`=20*@Gx)68}GXX+4^R_?$n9px!E~vAOx)%UuBKtWz z&s^v`!2n6lV_BaZ{ft}?7oWl@>TuE8F?6b1r8JeWCj)_0oKX%&=y<7sL>zT|rI%Us zytJkjJbC5eTVTdk7DD6X7j6yNrVsU6>xW|&Pfju*NQo@Rt{7@R901ku3bO?bl~7nY z{xnn?WhFvD>{$I1W&W-*^i0m4_)jP8#5Z!*JN5uVZkxkn&E(XFpa3`^*3Ab09oTtv zTq;rZxU#G16C)v30pb^V{wDjzu{Z42XL{`ezqZaYw<0LSSu%^ov@!b!U@N$YhZPb9 zi=)SnV&<&Kw1=SYp#f;x7Po!r?biIG0ekreBn_JCKnswB{-Nn{z9eFmqJZ^X_$FShUy)!CBRJ3oyYS`(d*cV^Z39W++WT>c)r5)JPzk|F@e(vKaw*`sUt=d= z{=siOL#Xb1IM4tr^sA1Mdb23+{wxSERI#z6lU5)oMwzvJvUN);c7#vJp$=AWQ`mIq zuiuqkRO3rO{=B_Ru5hh`^_cY)8Pg?F95!!jvEB#TExe8!aq{!q>P!E|3=zNp0L=w- zPG{=@3M;*r-sk%HXzFHbQ52dglZW#5|NOys?8vvKt!H?*^?K{bCC{SH$TTYf$nY31 zumAuRXM%*zu_-G>C+s2u;KfAN#yFQHU2IWn#5Ds#3y`4yw`6x)^XYzj;mfD&PygV1 zHu@4G@wB`PlBidgA|KUCzRyi>JnqUNP{O8PX8D^`-wNuf5Wrdl>dDiMOv3&5_gMQD z!k?EX{n@cpCiDgfO+J4SKjFRwCYx7Yqm^}K-D?0MIJJ2&_=O5xWnsKJo0-j2Mng9A z@`&XQ;|Md2IiS*Ec^44FHx+sDWas@h7DkkG$evi76-{T^U_S9^b7$JEvfKZ!ziqfvF=^<%|dIT zM}t;hsZ?#*9z^o|YZokcmNm|J#%lKOEJBOmc0EC3eltYGH8$e~vR<)9JQtd>*!r+- zI?!j`d)qA9N=|Uc?8WwLOYPpw=&8M+v3*@2AlUPf>K4KyEmeU(^Y{a9T6gs}Q{ z(!TyrU$MXWSI=7IY>KSSElwYx7?u$QadL!<=Wu!86XU$0ooZ92F8|~EdPv_>eJ{Uy zgCb_?SB9Vz%)C6>Y=7~8JZFFXdoNk(i0=d_4;r#)kvD>XDo|LdPb*qOj!L;vRvrZ8 z--Lwb(92pvw&&iRw)eixggz%O3XY&s>_k~U9WDy@bn!|qv-o;dwbYP68gkd#h~xptR)A7E}*SJXpOUEwFwp3arw%=^b%@P&n z{P$S*8;g|Mw~LPQdl?pw$vG`5k0aMawI&RHNKb2%z9`J?iKLU90d= z?oWNne=*KPfY7*+Eg`$>^Sdm(nNZ+~^G@$03{=mr#v%==*8690goqFcGgfM`@l$0x zOQN94MWBS{%>$1e>aSWTh(FeOsddT-q&3&1D&|&(@o_&~vhf$EEqT5f8(0*xsW0Iv zJfssEYH3~_!oz6*RB!0I8}PI}82BSLZiSvHYrZ#b-48>NJ8<+W;RG4QzK64)hr^5D zHe>3qw!g97|N0<;W9l`p5%Qu3I&(Gulo49`I$S~>!#XsD=Ol0Nk`MULW=OYh|Bor9S&JnsN1$FZ!$Q*h z`tL(OW`RJWwt&|f5^~^DT!X>RbJlz-%>N;l`D`FLQfbnX`4mopIJ5va!LC7^1-u(k z)M3?5tG-^&eIb@&$=Qf-3>2L0SgShx{FHs?KfGq=pCWYc`Sr~BH#@?m2!NXPd!%&M ziWbe*%Mxsz20{1ppqUcP`oRqtei7oCVCknX1Ts71y?$1-*?XiUlQ3CE0MODfuU{jlJR7SN_HGw(Z4~efodB%TlP76?#JYSvlzjc-FwRna;Q_8;;qF z7J_EZ_Rm}8)TY%=a&!)1?+(ZC)kqgD+8?oP4|m$}vxjYJXcWv-_B=8OIvf(7u9QLp zmRs})!2~#nPee$96v?*R*qb9Z{Ce41?jx8M>EQjC2y`e>Gh2pQ2cZEUk`_PU5(nZ$ns4`=R7FtgLcJVkubbHI7A|EO~S#L;s` z0ML7Qe3c>VrZ^Sy0`miv)EMT(`@SVA-v|FMQ-&O_6qD z=3-8{nOn{I#^&M>5cC952UQ;h+)l8WDwFd=7!w^e>q=Yu?Qz?CeuKUCR>7u8mzyjR z3z~~11g@4c1BKr@dnB^eX?LJI4LP8grr|B|M0KSd`4UKTZD){GFC~wYZ!tLj7IHj+n=%4 z+pux<{7lk3D< zUEmUAgn_d|_SG+c!zzEY&(b5^)|TI6-PZ2R_*p2@M2v6j?CJ4V`Vn@_bM-v^$tzzU zrR>cqv6EOf=f!xn#yihK{^n%Lx`_*)Ohs(qRLCZ$3&ey+NMwvi4)GTa>RF2V=jQ!r z7TlEHHAgrXf%%U%pR_oRR89F-A`T|3)7xRgM>F>1e>`bF`nwlx>p#ug$3FF_r4lK( zJdnzQn{vM83DhOz)>yema!kPSvDqDQu+kh>Mc4a3ZnyDu#Sm~{ba3^zf*VCQQ!Jy- z(H)8vB7=aUJ#N3d&&Ku@?d>OzSZSKv67z(@;Qkx;J0B5haOMgs72K^~X|)iSfsW`W z;m;>ycIwTG*71(n<}Gamy>e?@X3$TM571O&?dslq1(mzbm(;HSK<{~YIm_uNECL9f zP+W8pJVKZtV#F&cvg9xJqqt>Gv=j7%_~kIbDdOE{vKT0#%LVRVI+)4gJyH}QTciZ! z>vESU*8bvU;U@$_Pl~mC%5pfK9-93#fE>SVqfda+x|~wZRe*EJoh8yw5whS zA^o&yAt!qXfVmLWw2%uNz$?;cyEq>8OTyHgYh9w?n=1mR zK2>_7qXHrS4o|Y|L~YW-UC;ZTOiMYc6%8Ep2xF;y*)lL^I})u_)C& z!+*)8-@*GXJrf+M)-Tw-!e7s6hE(_2`+as?-B-gXLZjLe&^3)&w;Z;Z2G1EW2thgU zFjm=SLj%Xndj+l5HUww#q?AdeT~QPzo*89D4$ZD+mqlRW&mE|JNgZuR{yC+N>N`_a z^{<=l&>3#6v-atm5`;Giaf;@`HvIOeP5v2j?Rf+Nq=N+Bo{D=ePgviki2xA{keMf6 z-G)-@E>@t8iRxj7fEu^kan$b@KuUmQN^h~SGOUSt&V zLi!xwkJX9(fykhSmy4c4@gy#`Smi|24u5sj9{Zzb?cmqW+1b~)W2_0aJWE!q3{m~A zp3-~7AYFtr-X%|ePY!?dpT{h&3{$M=cljX9bcK-AUD`h=qhNym7Zir===z!oD1W*|z;mo|<7dc!#JQ}4o zR{`MT5zK}9NNAD3nID_BV{f0aAAjc+3r{7ir@hr;%_JGZ1V@}2Vh6}yMFFWL01%g5 zLJc9TL&Q6<3J!%50BE<0`{gU-G$#_W8Ulb1nfLe&fpYi~uC558Pa{5Rf0){`cv|kFi}g6C8{X_b%2)(*C6P*h0k8=qqPdA+II!?PI3g;N2BBuA%*2f(?L9Rq*u+P_{1P)V!CCVpg6E3ye@}8OWt@LE)et1 z!uVql;V8j=G`kd{W>d)J>+{xqUyCLB#E2l2UV*_2U|>FKQ$+x5K$E{}Sctn!t`3&h zp}wo}6`Bu=g!lzw3NH+>N;8sJ4#x|aY$?LBOXf?kJqulcsIqpxa>DGLzscH9o_yQ# zWb2ERccDhtIu)WbrtstkM`My2YKn-hicfaIbNW-Sck^a3egt4&sO1QZGs4)IgsBdv z4q5!p^Y$Bmc)zvZ-74O0}5 zuwdZKyRgXAUnVJONQF{ict|?bZ08T1v9m7~tnUE)B7^Yjv2seQW*7@dtO&>8CFYYG z4}p0Ny2{*0h~De#Y`6&emLD9okvGEDHjMU|?1{>#SaIR4p{W|~8gvN6+)~#?t**=B zROcYB2#i$Pa$?bpJ}xIW99oNSm2B#TEK&bb9Of#~VLGl@&2}eYK+B+(DofIs1(0j0 zXV#vdZ(9#+RJGS!ZdSxW4eZOq4 ze`mzX6WGv8TdWlZ>XB_Rf(kz>0t7lrwOYx6$`G6+eI+}4ZPBh~D(ZXv$JueSf47U^ zD?-IgCC{^_(fSPU{DFP$A3kEczt~OeeqO=-GC(v#z(m8G#DM@%!glXbpIA@a(jSf3 zuWh@{zWQ$uTFakzSeD3Wnwdw#t!T~|Ytl4@X@lx03RqLc`8ZT4<7eR7AZIJm(9)(9 z&Wv7}XUXs3FL&CDe^<1l+lFoZ?P1&Zsf=YvRU2i=Y7~Bhl){(9R~fqG*2v=!CMrk- zF~+b6cB5Q51Qs&oY5Avw!2s7PXspVpz0)`j_a2B?$I+-=JUC*h0y!qgDk{8FU(|Q; z>+cprLgXb-s>sxzkVZA%Zs%XkTj$BLb+@8Pb#LRs0|0B^IB$}isDk4;xNi0?Lj+I(e zdjiCQv@y%$EHzE!s>0@iZG2>lg&?4njBHzUG3|G2{)Mv$JwkUMdIDCU##+fOU70-~ zhgq-FaRRpf&R5v`QWjCEXnYU;D{;0k4!&5f>62x?JH_PR=z|KNMUt{@Qg6RH4 zWGt0Qt&6JOIlIX+rRIt#(RV!llA`y@n_qnxMN1&!C9y*Zq4GE^T`Uh;Av0y2I}`Tn z|L2En-JW)X=UR>%MXSIV=osSwwI+H^o}(ji%n8(sF%(4#Y1)&tpZ%A2*;FQM-};NE zaZ>ESoPkz}wWJ}0NsXO~q=_Ypf)Y6*Nir(mY@n$<(bs6DKCQ)8E5OyKU!StqP7K)N z-+9VnTPN-APwuumAG*m}wh>Pt9b*l)tcupl4}M}*mshX9n#f9;RZFAI-Vb9eYk@Y=Ujp4>pA|%Kh*fXG6)E2DR2mGY$c-fRYp)g zy->7M&t~n=lLIz+79sQER*PoWTNm(7I7TZ?0k&2d*KtZMCKZdqCr7SNnO!&$)gh+d z;FsC0*#jcj$^a=ZeBCoe-;RaP*mU1fJMarz?7?5%WZ}JH@R~#Gf&RSBkv`Yu2o7$B z%_;VAfpS5CVJ#d7k~bK`@27U&CWb^%2LBP7M439lD^m>ZNudYLV`O@ z%OuQ*yHJ!#t%AU#D#aMPBE2b(psb_YtYvJy*3S=--^Pj$Na+?T%i%?bAIL z-34*(z?hOoSmJiy6MV7vU%qCIGgSy+I#iJ#fR=TZT`F8HM+HaGPT9_i^?zucU3fWX z=gv=A5{)Bg=}S7mvA-%EaZjm}uNjm<*p+z;fkvZ5Eh-~WheLV%0HRjNmF?XZPTB4Q z;AICsFqr5xiYmlU5ds#$-GmO*aj9bgz>&);=+z-2YxD*QEV5^FHgx2oZ4K{~<=cfk z4I|AG`;1=ZDj7#9k{Rj^eSNvL+HC3{f{~~-%EV@^o^8Hsy+wLKQkHc4S*-*cF7TVo zhESbW>zF&}Hng)UOVI2qZ)I?Y4-TI-2LROX+$UAWDt7kB1$*a-qxSM+N3HaB3jurf zAbjqzE{LcG7(IjComnok{%QItQXwog+&h8r5H2Jg^A-cwgj#%2+hUxmNeu0cinIoj zR>DJT&^s&4_Wfg4*Tgpyu${*UbLtGWQe%`W3(%V;fdri z-0j!URnvXBk?AVRoA5JXDoH&+NQ#55)O3*?DrbaNMWloPOQ29#)-?IqquC}R2@^yJ zl|}L3MSJD-3-;s3Ub4`R5j*hNy|(Y+?bg=c?tFTv!U9D#2>Q`g#9dQ`-U8QO?vS1_ zd;jIGs_Wx5P4tBTT0@6IPQfv>RHOxN-_>k8?%H4%o#u_BnbWL_RUIc?)-^47cq^%LpSHK_{0L&P^^TCI2ds7nDr>U$ADkrS;Y zj%)2d9#$1PE%a*CPCtIZ;?v!hWNAw-Awq`DlIvt&l`X(`BXZUso}hyc=iP5Wc-@Y^ z{L?eLmu@VNK+J!E|;cYPr8l$pbBZ*_eMPGbyaH^ZdO(v&#QI0mpBd9@oCvEw@C@GxCwzU;`R zE~e(3N@0plIVkRo?Y=U~?1x$K)Z3mNC%?qS|I%tB7qyo7R_pWjIW{WTmWku5rGG)3 zhZqlzy7vq2KGtc$o3b*x{?JT}3d;r=1HZ$XY2lrWW!5dj%kw-B+;A3uRQGZ4SPq<8 zGjPt1+Vt+jcHsB+*qy(;m6dVQ{$Q`g6XG`QI-hbSzf;bl}l zI>82g;ITYH1!AGVICw3vhMKRkY_?AYs*Ob*4SB`L?4QZ1j20 z+V5d$EMqWBVzoH2D=H*WiaV$3D!#a<)ZbU#3IGDNh>d7!Sq@kX>M{hce8#hZH_uoL z@yR_IJ=L?qaKFF#4R-W|`Yj?)V(f~f=4mNQOVKvmxz!>)z#)dq6so+i*80=j;M)3a z?R%@adRh!p3}%K9ICyA2t$8r4L7vaxhKoptI?&+<%t>;X{7SW6&Li$_Wu$E9-$1qh zKs#1&jm=C@_aWo@lO|% zfmyMK;3@_#0WVi(M$8O9h1M#@M_$X52)mkjPf@{BEzjBd1I_lczxOEWewZoE(cQRp zIn^c`)uMN*=vRZmFTv5-z1s8C8MUX37ZQe8wQs4NN&D&Fzt4`{Ic|^r$+K2`v)j&2 z4O=>%LMYMtaXx6J!e|iG{sKM;ian(yLT={8`=vgX--=+ax6Q4CUlS+avneB81enHU zs|HBLa?16`04o#*PZsU1*S~A2&baNoWt;7|v)?xDZ?e?Zs3p@xNW{DmmWe}vuL>yQ z{c1grgkAt)*>iD%^pDbmI?uK8u?V3Fxe`AiZeF!T@j@!Vr?oF>x7@qc-u-dT3Zs+Y zg2G5&uJ`I49L}v4yhNKk9JY5}IAQBA?y*b{=2Ydn27}x*OvqH{MKrMPio7m^nM_&C zkK`m3RH>Tuq7{XN-TZ+*YrB`c)=50k z<9KH?D~sS2rhEXkR5pNH&~nYRR&$BVDNl4t1Rri(f`K9;IeVuLJFig*O5zCMk2emp z&zGz)fffZ{l8LXT>|K`Y9eLxNg{EP0g&t--eYTZ{vT)C$QP`sTfVsbzzfT&3W&F)U zvAMhc9wdc7fA&#k#;=)_NQ@%wiGfZu4-=0aTvqf-4oqVs7>-Jr#JOc|E#{un-rVz|@h(6LGwD14iX@l`^~J6KS6c0NKK+Qj z`Im$CoxghC&L1by*2s2iMF7a~2q4Os114}(mrDTEs>4NEtJnlFRB~F9TU-MDB5tPU zII^Bd+nAGUIa-7~33zMoIr4Ml`yk!-^F@2%O9gu>a@ykUA=|Q}+xFbiWR;IkL%1WB zXoIM;#4y%|;NgTKAcd{hqQo8W$+_QlI!)`n9o+zF+@+jZlZF1#Lg5O8G|`c?n-6TT z;vFOQ#^Yx&&}_tng^tsYL+D*qFMXE&YS=o+iUfKlV5e$wm zIi{Cz8q(ZeuhCRf4te5fVtW3SI)3>Q*x<$Jg0Af2%2;jC2Q_R5VOR$`k`URUz z4q3-to_+e4@3NkIqgL8ScwUZ6aFB0HJd7Y5yxOTBme=>X+yD3`0!0MOmdO&wa0{m+ zw)YpiY}ZFVVbA^bD6tL3tZ)KmJBfDyu=0Z-`%Cxo_~1wz;NZdorD2ig-Bose6>A12 zL%3Q4{Q`I0sA)QC=Y-H3p-9?-JdTT%X+jf+3A{vqo*o#n6VIHrHy(S|ntD>UWp}S_ z*xhA&Kd{Bt?M1jsLlams?3M>R?Ty3$c|FK5gT`Z(3&uV)m;Ux7ElEp8z=*`=sBO46 zZO=Xby0v+z{?Yi%lNXnMV4YkcZJt&`q$}%K0b@4!@`!D}g@AI5Ma?XwGg=MeA*&vo zh+QY$!XU*49;}s@y*w8lCqDC(#i!QU$O}0;|2tQaJr((xq*a|L3iC3{ls=g)9_1aEb)S&`oo8%1cIQ< zhi+)9sf@elN1 z?YkH73Vwx`PHTsNh0G;L-wVA`HWSb?6vr0E2b#~F4vQ_y)yf>+OaTu^!?jfh^Af5(JGc-A~Z7|26v2zAs*ggiQwPxmzowS0- zxy&Q}`c@yyFDC@7_@=(+3SvW#!tG(KaYdukLis8DmtHQ}5C7&}JNWo(w*Jg*1WQC! zjA}npM8aqJgczCzhM?B$yxZh_Hy2Mr&iRCJz08h$RyJG7x!5*){L(GF+@p|K;;(xp zn4~U%&t=O~HX$cA7*f14X&pC5?8Cothjo4wUx4jmRJ=hkSqbNd-#j-_(;7)rHPy4` z*Na0}S@a|XAOy(>Fmw;~Q3>B0HZW88kU<#2@h;pRxBGu#m)-l|t@i4-a`x0W4qNs_ zvlR$)Tw(2hl$eJRmX=izCOlO5WmKtA@*Ti&d5=#>RY9LA`4FFFAbzX-HqAoVg|e+m z4k3*9E~=etxx_J<3{vjN1s-3rMBk+qQvH7w;vkJVSxXe*z_M*Ju5+N)nXYvJKu+hUKv zn3#1tMn=Gy7_(fa-oE-B(+cn_;7@^`nGYwJ8M+?OY*^mHd=hzC@vCJXGR^i~aKYSP z;cuF-)$tXbKR<4vb5-+kWt53IM_f3?px-reOq+~H;Z$^wi5F}bfx!1IXk zN0Gqi`+M+I>J^1yt2)ZEw_us6v~CtA&6e3a6uJjr5*Q$gr0PZf#bIEgkiccuS@`h} z(S&eOv_C@xO0)fU#%w<`rXzn&?EkO7WrNR$taV}+F$9P&PeYZvLJA8v^QQuuwW|`2 z*`f__dP)6CB61ZJbSSQ(YNIqd6`M#X5E6$~Esm+KPQb6WiC9az+n0}EV&PEAT4P$Z z!DyK(Sntt?Y~c8m{a-&mXdnLV?Y8e1TP@nfv?7ML0a^gJ+DKl3)iO)!{jGYP`33D+ z>R0IF9AxRN0@|SX`mo*l=z2T(cNc8<>2r97Yy$ogf(2z2*FpRS`|jWh{!%@II?u1B z8jlwQTC^gWI*+|HVf#MAsu%?DPy(zkA{;9=fKQC)-&_~_b;lh+`4*a@>*4k)ukTK_e4TTae(S}OQ!#NUWn~vMY-)Od<`>FeE?0X@5q`6 zBB`aqG(&BQVK!;1G$T&oHZa^{-}?8@+S4zev;Xm5ecs~D1b*QnjTwL3_>l3R$_*63 zNAFtAMS`DTr!FbdCouq<=ndKahj!SH4jr@-DW9EyJp%+mrG6lzn%4HI+YP=PA{D`t zI7$5ayS1?+%_HVwTUE- zMtE%`$uruElgbd(nDKtufx3{h&((CNSnRbZYM+Q$GvC83J;|rALlK`khQ!&FjoNE% zhpl^m!kQmuHriRS7V=sbLCOj?W;qZF_yzWSJF!L`FIzf)*w zso=GCyZ|F4Hy>eWeLKDSMuUfpy3SrNjZ-m<*a<^Z?)ntmSsubpmCu!mS`XQ9Jh=qk zvWlAhk`1&UwAlI_t2ml$@5g&>&m-F`ltJ4d%>&H5#m%mK;ZKhJvOfj{)|va!9%v<7 z9!gEpVfR{yyD zr;!2p)c`|o*3TWX@(4^^=+}W~`h^PV-&NW_t>+2{Qe4|M-DI8958BvQa`v_3qxQM~ z9S6bN5DdEHWT{|H(yDkwh|@dyfL$eZ0NZ>c1G%?W-?egnmTSIHQPgH0;2vw5in8n)495|*7$USa_!q(q8HWA}Hj5Q?(_*ETb}e+B#M0%I zMV}9@L>S9>i7@Wh+3|rBHueT_CpvL3XDk)tehBb-UP%>qKx`K zcLIl>=?tn=*%YxcGElYtcqs(CA(g*^mj(kz&S08FN~IgcPAr5~-t>HP);1s5VojSF z0x5_w#7Loy9aJW>T5N%9-=rjxx zM5>(dqg!*foMyaSwfP*5NQCzYs{j2lG&t0_S}bx2nTMsoU-`HaBF)*MgT z$rr}#|NF-;+OPfV{g(W28d%5~Om_I=SZcZF zuI)DR6ik0SivUF5f&Xq~0F;G%uT~~R7VkMNgOxZcS{fmo=jlTO)_KQvi>yl{RC6pq zfR)*}C2Li;0)T579gv^O+r;6VO}-0(8ctZc(CnOx3d|g)vC#-2eNwO_ELPkF!mX@S zt5DGdjwlJF(HwTT9G=R_ZOqcJvxYlZ(geHl*^!z63HBh`P)s51%miq~weJ0?kgv{G zKg(v1>KW!Q$47;T%$?5KWB=%)#Sh|8kN4HyQ zBaAMAi9vc*JP*ZVSjh+Vr2qK!+ol7TF9lTYV!AGzuKHb<2Dh*iiVRyDGnH@|!I-Rs z=f68@Kl+cSZR}tNA$Rv8;7r)x|M`Hu^??Dq@0T`N_a`tZwF}|EJszd1`IBZI24hvd z^a6iz9}E%yiQ3|?IPs6DE+Q~aWYE2Wb`wHPnh1TJQQNy4hr7?2ePDE_op^H0UikVO z_V)LVSbMhLGWlI-2IS%^@k?x)@l9Q%1#t{p`gxE%u7pO^Nt!%WO@gp~WmphHT8h9a z7D1Rk^f09;C2k3Ur!%_ACSMNQxBu})`^c9%ExiTp4X>A==U(Q7AqQ#dwYrPHwuK%5 zP7WVIhB9WASX0V5dp`T+|DU}#0g^O3?)$RNuIhXGoU3Pcc6N4W7g#Kg#Yut(NKjyy z5~ZLSwk(MvgA85~62q2BDio#}r0K9_`H-y$J48t)CDI}(QM7p|016^;Q3RF*AS|#4 zb{BiheNUg&U3dBS&-Z=R)zwvfOwV*z_w?(os_%S9zI>Va^5x4+*xa2(V93rH##4o5 zm85HoG+A-+s;2?et^agg^2{>JS)!-%7@A*7+Z)flW>0UMIELOLJ1WYLRudn3Gc~7XbEatG82c$h^25qg69+F(#NW zVtf6T*~kBv&s*s$&l11x2&!(>xeRCp@DN$bKy~B~@m~c}!v@U6e0Y>@)x5 z75mC>U9geckFkt2#JxO5hwK=^hsNE{U$uYz;-A|GUO8t^|IHc8JPt;Y4>}O1{M6Vp z7gPklWTb84bi?F!13WJ~0kuW=n#6)yV^a=h%Isnom>RZ6KQ>~IzW4oB|G^K~^79S* z`lm|vjW5kw389{)R$sT54MduLK-8i(ss#caizMPqYPK|GN(wrpW4dkAq&(FkA2uxE zC_3B-Ybpcv6Sj;d;CKGVPuXAn#gAHMn&l0t`Go|oZQyXz+z-G5FmoAKs;%C1^;IWs}&s_|ljVjg0mi^H;kys`pijfh-^E>bz7TWecw_*~r2qv%EnpGetB(Pxf!i zO1MwcFh}3c)L<(_VnYB4QyxH4wyJT38Nc>-r?6JnY;`fq8q}Gpo%`sFrOvWXoj*z1 z4X9)i4S{nstxJNv2O(VLW}sF7xw;&-AlI$#T8`b2umA46UH-$QorA#$jsAPNB%o3t13mGLs`+W*IkcIPXjHo5feu*`nevU!CnNu!a*-XXd2 zxD}aszxcmiw^u&#HT&S-IBTcA4Xweu7)Nf9$HQr67&^{WZRFdM_MV>{uy+^pw*1_jz4XN^_O;Ky#Wr7N z={LtMzj(s(l_}ta4NN332?kOMXhyI8k(Ngq6&-JuWX7iLAM#w7;k_hAitGhY?d)s+ zu3~S#zhIC3HSB2!jjU;f3!Ix}dQk4m)&l8B0;ZUH(wA7Ey`XSn$iVNMy^52Z0-@LY zz$}U2t|{7L`!&w?GHpcvRWo@G%^(B`+XosW(Bb2D<*P+I_hB?0*uTmXt7M&&6NJ5N z$-R}m?*xEmGr=>)sx@vv^RM9ERlA~SO$~glLgeN7Es&_@8~f@Y3=4>nn7o_K1)2A*I94urh`BK4BGHT##WE^lkDo`OmFy?xd4?Nt^uXdxlAmNwT5b^F|} zzHa#ok2^dBInB1^*{gv?uLJ-IQ(GZDDOo|uaDb<^0$yQOz04YZoh7DBo^5;!>@!cX zEpM=BqcaJ6+jqRfWNzPk2N@+0w+LmkMI!gLQlVJ7?@Y-}k6h zuVO^Vn)9olE7-Lc7OcLIwfV{tc#k%K8CsHQf4}QBWWX5I|4R}CC_#AADFqFXY$l{v zKw~Id094#{U?{!L#GPmCv%mVXJ^DS*A^=EelxjO@91`F{5I#HQd=Rc_gvj`hBozr* znn2YLxVeVV#Bcubq#b#x&t~r~SfMI&IU$IWprrS^LEazg@h?rSq_JW=O3Mb$+RB(+ zdU??vyF1L77q98@CTvnYjmQ0&gjWpm>TCD`zqn|}8095q!wL5J%E^cbzPya-vAvcu z?;XGlGkKbm^bH|h!R>J!x4*+rve$ZA`}}1|E~c;f7{r@DZ!p4-TjDZi6}02vCJ2mg z^OE2EK$Oc1RlEARC0l+YWycybR**0RbCgOrDWgBu^OSTRuP?X5M?zE>*N`x_iHWf) zl(a1OOX*pwkIk{Bf7c3wD>nL_6ZVexoVJtiI%a*x0l2L6*&`gV4%=~zro<_wjjE&9 z*ETt6s5DR4GlPn@=X8=U2#tIXDAif^QD+K&H%v6A&a@YWzvDs!;m58d?A717Yajn7 zpR@ec4>Oy60t6N2azBXbd1c+bzkr(W3 z-*Vi(^M_7a@+>p#qbx_!KCQV+Hfm1_uoIF1tTxG@PpuH!7a`Sb(oenJbGb{@M>vWW zg6Ei5v0%Y7vfyPYXJuf@@bhI^Tp?u7n4NuJ!_NLBLf353uDyKAzWy8d|M>bfTez}f zgE(_4FZ1Ba5%fVrKtxptrK>;5(fc6`5}hGxu*RE0$j;~k^HR@iJL3vd+y*ckFP^eD zU%p{)eRjc)eiyqHhzl>=5pz>}T)5%r;3n{wz7`Z42#7xGQs1l1`hUdiv2U8OFTHfz zmKV$PB7&rV0Ul`5;@Xvc3mk+x-wyT{6!?R!Y1_Ir)ggb z05Lutl`?Z52!!D^FtAwCDa&E->AIVvY z*{9Q2WNrxnV*bKIHP=7#1jyfJGst}kmS(lJM(yo|ZHP!!%SHS2?|+W{-EU_$sPGUX z)ogqNADr=UO;Bk_ON23H3L6oJ9GS#qJTQC>di{|rGt)X#)p~x(-u6w?cJ{+3?a139 za8u-T8toJ6>%@Rqu(pheF7{zGguOjp1dADB2g6$Au}@1hSxuY8d&DS(r1DgynLfgt z_IGdqp^SH=zYHu=*66}aazxMCnvgiKc3pVupv^_TeKD&^Z zz|artf;z!WSP!d}u;NZI`zDZ!b250c7+NJ$VD&`yCW`x)vkDuez$xiV&7|LqI* zwdX!zAH+7`n|}Z!hH;2u&c#jDC@No-A?egFsZD~lSh`xmxkE=n0FZWTzPb%#gJ2Cj zdBQj}8+Q$kGC&$p`+^sOu&f~sA8RE{JDHv1vG2s`yd6J_U^RQ%%5Ske_DaIO{+T7a z`X8YQOTe5ys3G*IWYs{zvLY*bB5w&>)s)u#wbMX%B?9FUj0jhZ9e~~&q`KMSnEmM| zzGC0^ogeg9^%Zb~o2wnrymzn;V(0-d^&*-UVPjp!mUL5QBw?qX8Mara7j5C9tdYFi zeQC+nToStXVR96vm$k)M_#6JD`O4bOYl}8}ZN>8E!Ixptm;IZX(-~&`s3Yg$UWK7q%YBIX+xvk;sz3lF+KHOf z)&1PpEK~W2jHTrpp1h>?K8Pvy09a?HmxOT%S|alOU&vbFPY4HFoVEo3k&YQ|3KuzN$X#q2xXuq>w9CU6Y~|=pn|W{E-tn%d>}~HP(%tc+mWJTLAHfMR zYmqywft4M9QgQdWah&ecA55z=RopaFVz7=^kMbOSl0aY;VwICi&UoAc05`f#Ek1a_TS7Tfx6e!6a-|9|Ff=~cG#Eq^y`7mI9&^d$J8 z_1i{c&BP1*U60LL>t@GLV#X*|+WjYI5NigKedsnIcTlSMODTqGFK6}x=t zk|n-y%dUU1X4l>vwV4}FS?0zJW#6@-#1Wg#-?EXyqzeVwX@i$&>Z6>YF91m;`yK?= zeJ_9d8}6f85j--XsbYlBNzf@!2BP$P9$zdu!hpZ@XSZw`-yJpGb6NtvVBgY;3d&)1TCqVT z_wZKh$lAkdbT3*+=CfN#oB}AnJ|BXZ74ERX>LNsJ1*0OUxAws+B&$<%?}>mOI~ksy zL&&CkCGXRnz`|kzN1+@FxvCJOMU2d{_*y@4cFZzE87rafNJ5D$!v!G z_o?1{kxff$DPFS@$S@;z?(2|jJRv!g6a1R+Szk*L`!Zao2p?a`y#XUj+sxAyJNMoZ z`->m?unj!Ldip5Z752g<75Y!kd3-{{ESj}q;iIBagi?4$g+)oin9{0~5YAN}J><`Y zhg0~-S3ijW=}KTgQi6-oa4v&R1l}4^3scPC(>#ma5dtwdaJ^x#{)!yyykN60nN8Q8 zup#!%E1H1|L>RWEVDQS*x6vs-UeyKNR|>VzFGms6*DbG$9)<8}W~^<7HD>Fj+a>$# z@4RmR?&G)Y?6W8ATYmbqjXa6)FiJh~s3RIE(WoM!9Tj@N|LRz!k&v{sQXgU%Gz_0s zo}`5c7WsOH@;TSIU#($yZnN(y_011v?c5WO*qJ9zTH{&jG@G);Tg1wEu4bS9$FJF~ zi+60O@O~StOhD8H>GmY}tinLYStb|DSE@LEqQAYPBRbS-9OS z-$ht|GzjJrdYecS71!&`U)9_f0)Twl%gR#HnUW-a86@4ha0geE!)(()_DBDzy{MWq z1*CHl7*AVZ)4~PjT~~=<_~nK@_d7T38-I=#Xc>X9_>9em>5N>Yk)Rz?pVt$^j6J+0)=%5T&ou1U|FmqA z=L`1i_vY-xw=&N^jorg2`ws>nE!ul&vw%k}lU<_5u!I|271Ks-U(|v}oScTz9|A%G z2~MJdcWnH?7JeJp4OA&l-a=DYU)C|PNMS>8Z@f{oA(jhNMP2nD9Ukb^4LZVldQUbKOi0Eb$=Vo8GV+w?NGvaa zXfDI}*gF6PbXOZz$LMNps9mSa{&XZF>pmaF{*ZGcEh9?AUVP(@mEM3%yb~OkkzmLC zS4-;Eqn;N4VnU{+0Fg%*0x;NN!QbZJV*B3;QQUCJl%Xdz>%(S~z7QEz+V4YDbfQ=BE;|Qz6)c}cu`W;wY)X$YVLLn@M069`@ zulnll+&#-mVJ5C2$@28LHJI$Om>t)`|44=HIMp_IF!DivjlD+mv1lIXiU$n+IFtxgK zj@jsW2$C2x&+)i~9tkMI{yN&QPHwJMVl!=_`kKWjP<{G`Ix6^YgV4ot7hI*F3R?>1 zzFe~3fAb|P{mTpXj*mTRPydCJcJ$qB&~qUGCX1FOi4Y-&Rf4RGPn0bIH_Q=5p!s-x z^b70fL7!C#6ZWwM!tXa<`Wsg6r}%ktMoQ2BYK?Zy#nU>W(|ysH2GrGhp@Y zUZ%MG_;;Ii5t73AJx&O())@=^Y+Wti!V};dPzlCqN)9tT1#YE7Z@Y@z${6!^_vS0E z`QDVig;E0&i9Cc3lrvLN%JOBLh+Kd$;UGr?T*I+OXUQ^GLV)_MsaM@XIo%$KnQ6EC zJG~yy$du3evREUgvDN&tWgkOndY-x9AhRi$zX)9gtw#nz=j;416d63l`FT(k^3-{I zzVS2d*LT{M-F;spD_XOINok;oX)NBL;|UPc$NqY44Ws#82ch7Q#v1;qw~yJt(_;Q| z2#Z%U_WPzwn!PeSh%KR6OwcF5o+Bn6@C*22VAq<~30)A3kOI4?V;Cs7Ybii=t20{{ zvSygMYsZGO6{6ErZlMvl1q1uNtbOJ4^Y-f3h(JC+Nc6yuIOEB(Cm#z&%Sl6_L|)P) zln^)+$KC}1u4S|?vW*nuM*K>OMOs9R=#+I(3d+m>0eSZUb8RZDR%=$gb(UQN=j_Vs zW|#hX5pC6yoqL8@aet{y1UXjnCyCcFNIpaAH(**>Bwvp4P^fLIDOAZp!$-zSl%Y1= zOLF*1z#^q&8L5Tl%rKfXoCsm7kbN{m+=VIo+Hc>m+Ty8D5AV?S($w$Z2=^L=0lRxa zaYhi=7rjeIQ_rKvl3ispQgUj@fXn&a6U2Ng`pqUenu6+fwZ+V4xy#9Xmf{xyQ1$l9{)38S8ZnQMApe zE>D5cI&&<|iq~lGyWl3=J*Y{;OuC;iGPNC$EqToNG?%VpG$-CK=BVd7B@zE3wiTJN zX{NJcn`wwT+x7H<1~lvQ+9MwW(ev?4#m;r6ch)B5*?d7qVwmw$yqk8NV9=Iqwk2UCQo-%c3a)j|-Xnx}S&WM0Y&y26{8?1R0u1+sP-#?D^*|T5+L3=w%#C z0iO-PyYnV$)=dd2Lr3?XI@eM&eoZKak21rN`)c1Higx4H)q>5TsT)24)~_n!ydIr% zyZ72Xs5g6F0Ep?Sn4AxOsq>fwmu|DoXioEfh!GNf%>(}cCKm|Z@gyY#8NP+szm+84GKD`k+ z(0x6T98TNqLcz|$_+{fOxI6Q~xXIWqmZ;-chFOkh$V;II1Y>7Y+>`SdpBJbyt}1jc z=@cLq5Ofk4MT7PHDh8}y{p#24D_?xx3crh={x?}$zd2zOrN?cme4c0f$esR24K7C{ zzU>bUg=ShMxzN*lP5GSy~!!HmPhIsB39XXP)ie(D@C+{6=vH|PR;b|C9MAESM2$_x9wA({kj#| z*7}bBeAwRmk!Ni39GVOQ1*K5YD@llu&@Yy)4)H&AOlxX8ZM~&qRdpGhAlflm2p-q~ z0JG`}t$M4*YT8lYsdjY76cw42W{p2zO5kZ)8NJc{Jsvv{$>B~vi03;DXqD9E@v%%H zT?mpP9FZ)iAI;m5>4w?u_+^j#^too$2H4*D;N7Z<|u_EB-dN zIW;s(%X5peZgl}b!vC6@tj&^#dN1{W03amkoCLoW9Dnp9cxyF0!EC2d8pLNgo$v~l zr*}p%!U&yF$K#lWsmLGfP{H7EcN&Oc=iH;KJM1LIc5h9tf^WIdzJ?XAHMt5{>zvfJ zCPt1!mhHO=_6PAQLdtm)VKFJhTaTzEppt_+o!2@=JPIiJcO-6 z)}(t&i7KFLvFP4Xr%u;eZtsgjS<}nltqJvn@+D#bWGR*rThI}uYz4(c{cH>L1o!iH4xbz6M#;YA~D0eM)d0$3(3$?0| zLmG8sgY8uf7_6&RJ>Ia>m5zn$5g#z)pWV zd&u7l%+JC=uy<)BP}3uTNHZhDL-%8hilzb>igfM(<*8nsS|OMYD*>ww6k>kCfMgk|%2Jmv4b0c<%}+1d z*~c-09G3P9A(M%jdu}Du2EHy5t`pl~C3n)mP2TMR0YEhjLv3wc+pakb`2ulP7Am%I z6Czt?T^#jfFQ;w@y{2_dHF3a18IwpAs`-zNRcz!mK`02(n!@`U(?Gxl>*AScCE2l8 zOkHIi1m?cw{-n)8z6sEj4~Vg2eKz;}9E3-tXX7N+E>FFScQ9pFxZEfyH>LF~FI*4g zA{-a91(un`x?v7liqVom5li_+Y~F7*?BXX1_T@i)+1_~Jy7euM5V3OF(o3WG-)Htt z9kYB3wN<7*YsJZMO*cZFB(i|-ogNI;X?}<2o2NTC@PXI${cxA>NFxx}RKH@(u0Cyh zTaJdb4N!Hg;*6<|5P#>5g5AD((LVKwiWh+ zVL+b0$LD#Ld&s;2W41&jptP0YrxXzC7X+-B71iNHau%cvefex7V9_CJNj<&H%od*w zF0{L-!~1Hte*DXeJZN8nUjR>lq|O43S)J?poiGrs4@1vW=T6uH+MM!iyhIZ6P(EVV z!g2jVu9~>tt8kMbph-kCajd#a8{J^SarxEjR$F=-M!d}@_SM0j3jo1t(@|p$-~`VA z=;*Q|7}Z^=+w7%TTety>M6IYddx`0FWB6+t*K*=^3p7IQ6&+EuG_AAMkW3p)uWFB! zZRjxwm3++8T3LGQ8O;vUva$s(ar@)nmh2Dyp$mW_DaYO;wIr4J|_wO;wtB6;kilHM=KD;hGc?(&jbC34Q5GEb#bYc%<$1aB(lb*H=VW z!gz=Q89k#m^6yLl=Spd2=_&jkBnyLRUZ$<|;<8Ydw#GV*)&o%rx~cfAH-GnB0Ek^N zwu8qJ1q?~av!6rV=Mz?EO>z11yfx-=0b7;HQ47Re2yiT8Y=!5 zKY7ib`E;WeQY734_= zZ4X3udi$r@fY6FaQ>B)q5TH^pku*zQa%v?*$2#77hWSmSovEUxe+B;sv(LX`^Z)F+ z&AfBMzUN2ZYm?8SIbdIZ5@BjR5WSe@m&T1oOqLR=rJ7y6u)xs(-U_wDU%k==rc_(# z(BNx1KW}}<=sa*tDTp1>dtF`+Padpq(VJMP6Wn}%yrZRn1$c0vHGVp0gC`d4=9@Tb ztBktfB`T*8;EW%5xe&m$wV2U+unN>U)HCj8Eg1-JBv2+6`s~h|D>n8XoOfa1E4m$$ zo)#_X?X>3tfVQqRnP&U!2iS=rO3IW8j|fF#ol>%QIS>YnlOlr-9iag`7&@8pBf7|Z|+;2X;Zw|D~rJ<7tE?Opt zNo6q_y3)cZZeoV`2!rKQHgNT*on+_F{MQ%l<6pRF|H&_$wegRzCU7#~KttPsU2k(g1z`cRzjIZ35U0 zpzVF!rR%!AzU}KiZ1q-DP@wrC8(~3aX~^!rMHGpmL{=@zA|z_kN&_2$RgWV_Jnlk^ z_TW42&=|4Ws}QfhX!C`zr-3`v25U>15`-HAI00QkfPO=YD2Sgt81!%?5C-3e6mQp4 zc2Zo3DAlnvtuoWkV7{DtgpD*qp&$jDahk+^XMFdk3iqKEdzgh2Uj|*2G8pX_atHtn zM5op9jV`~k3QtzEcIVnWMqMIR>H{*}1hz5Fzx>G}9{Lt=(Tj0r2?s)ik*(tyY%z}^ zRR3+F0j>~lpk!sHvkDy2z(`O!fWVZ393UZ}+owyl56tB(IG>Kjl3-B5(6^Xf=CfeM zz6HD0k87qp>-A__`dQeSv?(-zWA;z~(Z97~MeF#YwcVM&Sd)zQ+`x-I)h>*?H)b)m zCCjEdzdJZJ;uO}XHd3@K-tL4NO3E`j2)_^Qw*&$W7y0C5{tMkojU{b@-2mAsjY8Qo zh2hkS<62u6bM5t{I(q$E>Z;`cL>a~~)OvBi3fHkoS>hrMTz!nAebB&|YwlS;v@-tq zc=Z=RGq^)11SzsMht>D(W&EFG)9XZ9AdkWB7dY2%e0+bK*2?^a^gB(Gh*f>%giuX1 zI-wS-Pxi6*5%zTCBq}t*%?b+>xI7l}`2xWnE_3X(&G+?v;Gx-A#6uuHc7KfwFwFwAye&I z=__IFUcxyJJ{vL>_Cpg$C#|rvEZfLMuZ;NRv;JXE>I1=A%t1`SXHmc?$!-TNaZM2D zYq*FfK`gMP=h1k{G={8tDQlIlvP4EFNEjB)=$Pu3o+A!nU?oZkF_j zwmA+SWow&aM34fmApnHR`?ZJdD?ozY0+*Fy0idjH8W84*nVgLrlbdDN;X0^-06=fh zSFtd#AK)g`iQ5~ajDAInlgnwlb8(g>MDU^Ao~Jn}?cG-H`4WIY(>i$LV*%WOEgBg^ zox{o!E`V9DWfHs&yh64$Nd)#j?-GyzpmaZ&zw!xehMFr|KFVH3M`@V;2oCC2Fscy( zs=X4mbTU`>S^3*r4wxuW5hoCQ0N=OEI@@-eFB1$2NjB*MbPsEo;l{KKI=L{VhCRhhk!4bTv2TWER?Tzf)loHwalmR#WH%424{$CD=6U?(-2vquAI5*e0)djM3KYh5l4wUfKK(-U z)!LV}V#Aj1;)Ym^OE{xXmlVc0vplp9W5-bOvOP4oI#RD}@M4$z4&r6eqX0&rsn;KUk#XxWEmH1xo{i?RzdRthUto4CUv$nEGs4E%y;vd^l+R>xg z=-z8sRHHo?05oW0rms4+9_w6I)*=Mj6Hl!R;| zAao2JkitLvs~lraX0)@9cT@ zJ+t}SF1-CEoA~Cp+0i4YsO6N#C2gUcBE4&M8xq9n4vY7E_VZT|`mi(>0sxN&gs1Om z9P9i(nj$rfxby)=f*to=<$_{YkMoh%Wmyr;-oi=jEJ2r!V@jaGn}$iSG~iMu1TCKF zcqaa(Ys~m3W{D zhwGHh0lX&Yg3qGA7%SIV_m++}t=JT7&(0htXwJJAZRL|J=Unge4X^U2(3e<%Cd(%S z!J^px5%+ah0JXtYrLIZqF08prUxl94V|DG#M{1XS31{B#?rC=ID{Id5wmyM+#LLZG zAVbdu&0l6QW4Er|vC*aD_-ZLbowXPO3^3-F1FDe7#c7YuLT<|0g@x#ez4(c1vKM7{ zEHfU+&WNMgcKl$C2!Q1U0LqpNABgdd_TNpAqW$rW&g1%Q^vq7~$;Lqfj)spAqsow| zh%Dhod+6iXLDq+~i}M<$6t$H>|o4Z_wW1?VZ}lEGTHd_07@nVQ~t!T>i7YWdsNLZRVBUJ{CH+uI82*Dpb0ac6b*OHfNWs6 zk-%CuLqMJ^Hh@W%%-V(W*31K1&`}Y7$dO`=j|^_NGMZEm4bagE{1IfxC#smt7DEr~ z0e?yd4`BkZ5o{eI(X1rJOn78s&@vbWB39$?0T@NF6YJc{=7) zB;cZ+0NRMr+i-2e7XQtOf zIXCkWMt{WNb@wm)0wSc*e3X}~b{*d|HMX$GA(-&VX>}Vu_F`Lm8iO^Un<{!nVto-y zQ^K{U%5uf1O>rQfpnac{6B7DYzy5K;6SIr^SD32q)ps?O?81Y^aUH2SF+tf=RDwnd znOsdNuF}%pmc#p3seP6cY?~S*1h}dV=F6V#@u^|djDaDy!fRdA1YTq;tv2V`uV1~{ z3f{2e!r$)zXkPV)2Tu~LDT~7s)S$X1_OIodq%fj128z%Zv)ee&3u6!Fj&g_0D(cGB@p}~?fkw4pxTgDmoM5qRbSJ-mRV@rfuO^@Jl{4ogJbU+_jwEM>aaX(wV z|MOA=Igub=V|UlEIP^Qt>_0`EdhQ5h>jz;F>;!YU^4DB{0E_*?1)i5I;crNdPtL%8 z{rdkZ-1=wOA~saOEqnAP_@LeJEn(Oq-!UaSFGM zL%O#?AYsVRv5F-fdz56FE|@{JV9Da6mMm*eF>XUo@U5Nahg%UuEZ(H1k?qsR7K0O;24)tNUl zJVBH#aN2629ROBj_^}>%zbYRK8{O*iAg_x7RbVn+0+?=j^IyQLV@PE z`bc7q38L3&&B=qTWe?}=vk9sDHP;IO$&KJq4(6c9dGWPwEszi(hp@TjVOze!(*iU} z;dR+G9!@%Z$DmJ7(l-M|7=^-y#4DRZSmCWJnLE6FcxkH;fPFjChnZ#=2Q@;nj!v`7 zf?4LqNxeirL~6ta#QN@ARm&1kEW^Y@{v+dl?3PbCwQSiDoHuDJuJ>uc2?+?XfmyeA zADZg|V*F8~1uE>6(*(#FK7m+(4~1GX_-yc9S<%ic`3%@@ifMKHyWRKi-}Az~Ky?gb z;aUL!fMrBqR}u|zW0m{Gq3&O;+jHu<8pa*#zfQiT7$<>0%d^W?Syc2X2BcO{_Dh0FD?LGrpy`k^F%AOn+^X>!5=gI_;=G6?&|}=6>uGFQKVBb zkSs=Q!$;DVAA_l77&KfH8xgwoJ~~m!JxMWS^b5=|@jfzzqbP`upth00k>HxrnmsOO zXKykmWI0B;1Rv*mKMZsZIwxW?kDokZ=}e^l^ry%}uf-;ROd$XOKmbWZK~(C5&Tk%G z-4X<(!%;uP_z!GZS~)V=$F@H2sZDc z!9#0>4V8VE90DBx$if)6>iBD53-<^+Hu|Jz6R=k`Coa2h6NJs8ng`p=;J!T`^*=va z@+%XgW(g;CvNLHN_j_K=P1>ue)1D>`PB-)iQX1$b)d+xQ@Yt0qG5be~(mr6DWjJ2O z_-`p^lhq-^@Dewxtj|>m2kJ-_2t+W#2u)JnvQTYJ?KHVLs3o#>NbMciE+{0N(sy`q zlS`^c9TjmcO^^{n#Fnxp%b}u7^+VuJvaft34=h;bkcyi!hC_I<4k;Lu#Inv|6>G2`j+EO4~m+4$m&9H61$g!HABEM4iRR&wG*zr}?e{;q?- zM#D#Nlet(a%K{lofEs&=yj>F3p0aI{rG~VKJy6k83N`IAux-FuG!Quzgot1G0VG40)ZRPMfv%;=Mpj( zteuwVH|k&Y--fBf{SZfm9^_R8R+AR6QwsiM0s7t&(s}D&!Ppq z&Uu0D#Cg1ZVgyh};8bi8ZB-SJLQ7TBD*XvYCAzjZX)Sl$n>sX0jk_|I3?jOO_jl?6Lii@G?BnnLzb?BX_HU z4$Nqo$Ojp)gmE7^J`4j^IGI*xudkF$ximcWltS}X3k**FePC=B4v=@W>tJjOcg9y2T0zeF$7)%16j{!U8ez?~U+3b4q_PJ!r+!X)tVnT8OR8HbKtN)rEc?yC9^NHm|$Fp6p z<^Cuzz(zt+i%}>R$YZzzuII}P#CQ;PX%B=c3<9(im5j~7B&>{VpJMA69TnqZ=eH>r z)&H@Xaa@1~@}^mW0)?taWBl#>?%~y~KtL=*@e`yaR9{vz%XS3+7|ER0|NZWU*=P|> zVsx!ov&-MOffFGj_%U-+->8>1N-hBO7467TVmP2hs6|>Ni2%Zjo+O?dHE6f*F*sAh zN%x_UAxOqDM!D)Sxyp8W-K224U9o#F&oxX`K4_W{C51?GP=x@nyil|2U*>P(+Q# zwoB0=tvn^GIlFPGU=5a@nA(TI9p%vJ$B6(MfYE78o>{`t&T_dK^&JH2IURR;@$lM~ zAm9vGaICXt4#Vp%kDs)qWTA3pky#q$pD9$s?bIqoAn^<%FwLL|i+M!DJ-Q$r+Uu@m_2PZ$ah z^rz%Y67V5K6s@48mIfd}q%Vd(DLfND8-xa3@14{;0szvr29^&l;O4;6=#@G}&i{z- zUb%~%Jm-@91zK$d)KF9k19R)Y@jL$VHony1t)ITX0_eA) znPGRMsb(b=Z?;?ex`1pw5O@EIki9*1y4L>8w$7s>G|U)Xyy~JOzdFX!dk|j=XJr8B zPjt^(9t3$sggu22wr~Tj0S0FRy9T&&+bk(u^8nic>j|_6KI;!EX3cd%eKyPC@P0Q4 zFx(x4bcYL9#mo{hGB}gU#z)S^JrpPfV+q@=yO$9NtI!YfRL@EPP`;g#aux0jAIFe0 z#|XvufQ-39X?knpay#YuFkN#90iqg~v3+PzQp4C&;4QQ20)Xr=fMA#=w}7QvZ?rtp zwZ~eY*}Y?t9@qFG02GN+Q(i>qrx|WOw9z)=-K*k;CH05^(AM#-r;?r&yaV-rtq@eb zav&iD(g1CJbiV?8mwizvY-~E_c2dG9L>A8BuVM9FQl3g1;8*;J zo}#a&Pa<*P>?8=M(bCj90_U0Tvo9gq-XWU=WbyeR_M>0HH%9+4sw5Ag2zr~PxCiSH z=E5BuL&^Bene$u)f$BlYEZc0H((o_eRQagEx4dqe9M*SR|Hbu-k|+XZ`*_@ zXT~s;P%3qcv_GBl)l-fSJXU3ob{1a`Nob1d>p4JM!kk`bttp&qCO0}YL=Yg2O<5q2 z{FbnVo9(Z)W^s5Nfk^gDH5H6qnA8f)tvu8E{DV7I_Xhz0$8;&| zfY2_LmRYYx+Z2?yJkdMV?Fa~0q;eDz z%;>~{@$^>DS8V9~irZDxnQpLa+_5ErXE)haBx`+KK~-PNgF}J+FSF&Vb_WMSH}NdM zUVbr$WMin~AQs%E!X!SW_2ES@{ba-DN3YrV&10-}*1%D6FZZ#mBetPBbxX16(e3_T zT~`b1mTTN%>mBON)Bv!|(Pk#!G>NVGw2`gxeAGG-c6oY}%3f+-T@!KaV?1w^lwYT$ zaj2n_sV|dvKe6N_jzKHVE?DIh8Xo9u9gUg7KL_x(W<;5s>iG%|e-)pt_+r0}EIebQ zinYPJ$}fwawjcFk1>f711Un6AZ(qFx9THt3%rki$Jy*it0K~m9KrVRZObU}^Ac}RH z8olQfv=j7t;Tph0z)GRrOg4z5`1rgnPrhy=myY^49AexSGI^Z3G5YAPhH!>gG!|ow z@sYzdfmyvT;Z65~(5?IXLwL+e=4qjflt^m56T&ESoyUwnx^(!{Hg4n$hS6rpY|@UM zoVHtvv%q;ECW5Oz>M=o5FYBWteno+ZGf`h+K>BkcJ>644J>DV9e!Mp-Y^+L(2~+5+ zy~oe)E!g-@fD(G!2u4X)gNyyam}$HOfE9OQA^5Q@Ct`+*JtJT5+M?_43BKD*;`~tx zJrRhg#=`h9d@kg|{jl9q$Es=P#6p@IVl6GraJXr2y)U6$dnBDx}pm$;)RG~1}bwgTC4+9Qiy04WBbVJ9q-w?2`k6zh1IQqGoc zh*@af$ne;d$ny;Rq5l}=W)%-WYUS{foS*F96o^uV*>_E@a{*YUjvBpQWcDw0IsyQV ztEQK&O60|wG#xNc$pe{23C+MFA7Xbqls5(9S}?VYBSyUQXVoT2=2OSU@VP*K{HNp! zxaHZknS?Xxc^WtYx_zCQJDNlFsq)hMimic(8lP4&*vG^Ii*Ej^nH3wIByym_07og{ zS@R^meE8cD0vZY0v4Ku*3j>p?wcV~9(~Nk(CGmJL(?4}2#>GXJ5M@KO zPukKm8h}`J?hFrb#*wyUq%8rUvLs1B%LHH(16TIDLM9>6>hM%&>~4zd9hVx{KR(~^ z*SS#Iy^U4UitVgwLNx?6^@qmQbWO*5|fyuZt z33SyofIilv`!&hktwxw;Y!U+Ga4F^6@-!R9&wF_=Fi@J>WTUvaZlEe>Lo`6RmzJ+W zOgnvCBS<#&RL#bZ4x<5}BrO#(^V%p>Gr(7E5da{}H&I8|2FXjcRHe91d%||K)jFz8 z0fP{IhyjqqnACN(!ZVFmr}$C*R;#(1!QqiZAl6h$0H6!ml>?+lnChh2$_-j5GJp#J zYv8rPcw6&a@0`@ZL;WR?a`ahQW+wmw0HMeyt=ClF)=%rZosL_dU4N{)qtQr1kopTY zbd0(yfQs`p42a5K6QC)(uVY5wv3&E8Pb>W z#9zxg`+*3ww{6WiTelLlL#pxw4tdz};A{K^nk+XR@Ld{#jYhKcnJ zr)}hzwp7xW0w?!_E-pY{&kNG~EhU&iI990g;A*KzP@p9(Adw_6I>8C8(vzNgsG&Wh z0SJ(3`4+4MC`}@8<5>r=*pWh#Vg4fE+?T-Ki5vHVvs3`d1 z2BQ)z@c=k7!!5V#0GnJB(q#YsR*>{!%nO$ezhel12f#N0Q{>+gxw7Ra7*i6ckQ_A* z38%!vqHp^*3C)@m0wK8q{+Bg*pqXxu6k%9v3!O!2nDjvET>&5l4)mwIg1tY>0FV;~ za2T|LpOyeb96~2VF96*&=W#x5zj|LxVj~)&S0vGHCvEq68K{-&E6f~AmcaD zxQ20TrA6DR<%4~;6AW~1`@-2q^%P8C-gIC)2@W%QX0AMP{7llG{{lNl68HwLY6k0c ziD4dDYH-^9g(MqepEhH;9v+qFsAs z(O&)hRV!R1dR}G5@`+I&KU!v4pa0exsnIMrYviX10+dsjY*kG$*Vpy@+B}^SKtBrC z5U>lxb}*)&BFN%C8u(&RTu~1iL54KN&;+9@*Q2<0K6*-=OV@cy(^xe^AHC#+U4yh8 z`*iOx#bi@VP=a(SS0SdtpuL3$#{hG{sE&2`IY18p&=53X{>38r;|MR@P#c>_L)(K! zOQgpy`*VBO^nD=!R94u2Lx7eXgVRw3plQ|>L3s`Iwu(yOxy_$$XJ(r*vG(Ufh1XPZ z?FntE)z~YWDYH&SeW16{r3g8M9r|ou&$XHE?U`WI4u{R)w%r=XAPVmZMj|LNMz9@? zfu|Yb=usGPnkk2S<`(@=N{hJg#BfZ)W*Dg5`#`Qf<;x+}m%?Iv z)UHPhn|ec^UQc4`aYeoT%?hjbz(u?fNazfZ5Q2Nwrr%Yyzx;RJXX!`T9{6P0Z63z& zM&Gx-zZJonrCoZ6w_tp;LK5-YkND(7rY{_(r1xw*3;@`#@ z>6vQPZe7MhBe8#T-VzZGwMN1txS%6nvmq}Un@*w80axl6Hx5lnl+z+pupC$mpO8!Y zwT&zE@Z8n75o`m18Ee`Ja0Gmy|D3*YOV4P`9*7jRqskzupt0`OF5ycr;Y@D}06;N; z@n800)(WgYrcjkrjBK6#f-14a zBnCCuAV5ZW%Dy!9St~xlPJj}QfD~AsnMW0aN0F#Nrb51P`Ej}N`4)@ZmB&;k`E_`Z zDXhJTH8HD?lRyMRmUchM8nnoE;Yk?L_-#vHd>VB%@fLWb$gCulTDClKZtD_==kZb}(*)z!Z`Zb_nIVjMXC$>GMiHn3#JpGn&V_KQn&sP$n9UxDRF z;Nb7x6XmqOu68!BH4nB_M2s&ED&Dxuq&Nw~%fl#hFv&CmkVZs}*lmr}q77hxQ?VJl zOfj<)m+YNCe$hVq)5k42Oyo+NWIW0f2cpukKuY=^$=XLgFl~*0{JeePw?1n_FMl6- z%5ZmU^=uU!rJ*TcQ;}oQ_)h(%oqUv%2H_<1rYQ`9O3qE!q7D~JXSn7=FpWVXSIwcQ%{veln@J5P(=(9cb-rTa?C z=`giJpow3M83|HWuUZ-hZuKF;b5E~WeqhmxEOQnU1D0oeXl%4%M*P0=6)8>--C+QzMuo*AJTsEOsMJF_HGt$_nn5<&alKCU{HTcBD$b{H!SRZUEZhWvFN)|{W{-MtptamO4SCd z+O}7wsTePTcUtwYVaQj9NUt;|Y!>HRE2FR3)BkDNzU#-HwaoAd+9->9s)TJog55dd zk#z`u3Bs2gH~Y5lJ8yl{?1^rQ=RCa4^z8=k~jkJb}N`i}e9FSLJ!$7Hl% z^S6Or#3%%@xb4b8$Kl)y^4hB0G)p@8J|e{#>G&{h7XqP=fFb{Vc?3)hbR`%BXm2;S z9(+C$@BSdu2rst_MZz=vsj5Qw9*#mpg1RKNyq`pYm( zF*bozhI!J|2L=}ULEk~l)Zk6pRSX9W+zazO-R+j>Fz+Xb+Y$DZ=Ok?43lxSE*P+{+ z8()t)Uko2@&|1bX5hMO=oXci+M{r&;$m~CZZ@febV?NX;+Ss7&w#oXS-Nez!?crDK znIF7ufAJSiS{g&gN)hc!CGTGTd>dYbs0m=4#0#QuICC;>@BQwl@$?pU>}*z#j`zJ& z5U3DJ>O*Baatd{YYnEcW57hO{5Su$fB(OD;UZ#hal6L3voNry!70=Rt>7B5S7`o5j zlfs|2Q~yzxbCOz;J2B*-8TvOtBw=rf?|c`l(Ita;jQnT-+sQu zdtUtDc76o|@p4=!3BXG>w*kMaaCgQGf0YE3K?|X@i z!|@XYk{Vch&oemu+CBs#c<1onkQOR?-?c)0`&stR8w>{Fk)sf^f28LsI{_36K--Ny zML)e$=hd3@xBvhUapF;3W)=jk2?RO}N-<9zxg&;%DeL%tr&ea)TwlD8h1Ad&iNz!` zkX`;o)-ZXb;V7+TiB6jiH32&S_z=YWkx`sT%1fWiS54mBWFfASM6h%9GQGk6(yOms zvxW-*oy(RgTG|Fl|1vrBgvYpJXRtJ2U9dvm2^)7j_Up`g>$v0fU*f3C2@eD(LD^aZ z^<|=MAV@ntFVc=>w(M0{7q3%Bm_*mH09eE!8 zPF(Z#cY5SXg4paeYybih=_i&SMSS;jifYd+O3WlB=O#>2cHBB2;JO0b_mYPJ!QG;;8rFpcob-8n6W-h&nC+e9*JCVY60M?I#pqecdmL0mv^Eo8+BXU~CmK)|ZsaU$vDwO9e#cz679St_cTN!Bqj^ zO3g;5aq1+O!~T|EJ^Z={2!vU1K;AT405h8Cr~|>{d&7!*sKf((MeX6^34s!(Utz~u zP2P_7LF!!rAjS^pT$ODVnzrdL4AB7G2T^(VF2^(|{(aDWD3+rjBYin$SEwGvlw1H% z9nb=V6a(Wy*XH2mpUBj0=F~JWmf;a=a}nd00N|=@C;Z?Oj3D^#mlZs-&bg8`<~AS1 z>MP|d(>%D99iPFLJX2yO9QrJpRPG3{%1IyJp4M0fL12anq7~NXscWF8;)lU4Zac25 zJy(lDs{+fDm31H53Pspe*q>@+&Wa<~?eQP%wyH#=3DI27rk%iCJNbl?0Ulm5no7 zzJ`XaltmistEd=c>hg4-FswEs9)(6$}-tmMd~ z*~SAbco(yF0f1RfCQDZYdgP_MJ7b7*6c}(9Yjlu`LbyVxnwTc0JL}Sdbxd@`pQUXH z;e(ycG#jpHaPoIwxg$r-8pQEi%|})bz(X+=S-YpObn3_3SsAN+ci*gufq2#qlC=9` zvK1JA8n=3VtOz{%*oZxHCS`Z-)a}g|QQ@PkSS}HRfSE`v1c=Esm}#kHF&R=TR$HR$ zguks7VEkD&!sS@KFEZ<$v!}oJsD0?ao@U!t!HShZV8B+q6m|`YvQ#HJ9%|19h*>2w zELg}#fD~cp90^M}TVHP2pMUyAo2)&?`z&2>Z@bCs%Zu7lIy5!l(H0fcp_O4%aK~)D z&uIUhs|EZNgsq~QJUCqFFE=9AiG&yT0}y&yxg}9ik0AIYnXw+Gok2ijPMRqwwg>1U zLay%?5u6VMbZLm%5+^A)suL{~+f-=Fp zO6)sd#7Dr$+@oeMLan}MXx@BY$rcIl6amREbi z`jcY_3>1oH3Gu*%nQS%3R=;4cOsp`5plv z^|9PD=S#DeJ%{n(&;St$={*Fi1Y=*D_JcP$W?l$ia@eC5Ys|Pfg1|EO)iJy~E+IVJ z#HMD1Ks0@5PjCxN9u?|5$aq`M%vriTL8L?3KHRk7BKbT5ZNdIPj7u^?NOAk)bNco$ zb%p?-66&B7Vo5Ef-XclU$^4&~4pr9Kw6ZI^jDS--OcL70Ns~MYnM(SJCw*~$=+#Kk zrbl)q#r{{~!sIQq#1`E=-ZEVju8dl)FpSYL_04(8VG=bc%D^><+?PGkUZfru z00Kx_aKaHGpo5^v{rIMS*TS|dJewWT^@-iP;p%>h>&wCHo!HV0+7UNv_iA!*OG=NR zdSqXBWeI9ujYtv9CBeYc>^oFqmPyC`+wtMvg`q$U(QHahUIfoLcr1d*;%D#@kC}Rrv}-xuwe7Ki}s-(8MP1mO|1Qg zS;C-%Eb$X~+}ozNLW*0$FR(JUS;#IiMF?QLAh2_y-{wEPV*l^|^^zs$pR^$dQ2b7m z#TI{*{ff#*@Hl#6l3ysQnhw=+cq<=06rHqRtE1wXy}>IOIwTPABo=6aC)7sYWae!U zE+{iy!NJ%Fj)L+LX^gIiyNBO9g8)4MSheKo2)47#dgkpQ;0jSRY7sw$R{I2R;!)i* z!0c3!=D=>=>;T>M4>g}|Ke*qs{Pz5}bMAToW+eGs9w|_b2m(=)Ok?&Yc-8^cT7ekzABhc0S~ng$KEe!#QdHRH zS@?VFz91r14CxjhdC9*27tdS&`_cX5)Tq{AHv_gINsNs&-z}jDTTabc_B~1a(9ccU zJAe47&G%onGTsb_C_BZBR}nN7nz)Q@LXow6H~dTFfy0npMO}HV|9Sh4pHA9`|K3rv z3A77D&1;nNcmY)713m^ov;hNv1tUWIX(sMSA7^*}V8MRvXJ0kDc?L~H-i6t9ZQJ4n z^#}8QX6pFmKQU!l8IUQpRb#aeqqXJuKGVlL*NV*g2Vni$<-q%7s@u{M=;Lpo9a55k zU@cv?u`}#0U>zeC75wJm*A5^csZEKEt2hGE#~Ed~cmTeIsrrPUuzX9Kqf6mNZ+@>* zzuv6h)@v0H`mMaNooBa_-;SR_p_!Ei0OCa5_5t4PxW&7d0c0M!Ka3^2WtU+mk~tpFd0lp@5XQ8OotxSPFAEjPgx-$uq`ahy00L5xSh27U*$fTO>ANh($or4t{+ zCGoQeFM~KNuHS}9VG97Fq!C~eT7H0mH(-zpcGoHs4SV*-r|bhiF=KQ2H|-ABuz@s1 zn@%%LPoSn$z7l{GN@p2lo11*uKK!>%+I#-iIrR4k2yB-uQm$N5q>1vk831HQ;eo3w zQ&##+#eVniy=c{!XIMIzKr7Iq{@gYY)He;R5?JcXm2CWYKf(`{Y8fA)Yu1u5o$-_> z#q=r7O6xIx7U0={Ne^zZyMEISDhcRmbx9_@n)}1Qr9;nl;G< z0Pb?4bH!y4!90+({)nqX76z7V*7D~P_Dw%KWl#V3 zn7uyoc~<(_HK00zYbkvFW1)x*Uyb$syLi&SU?2TE{r1g2ahkZvSp*E`@Y=@b6Joe$ zCEf=aHB#A7rq)3NUQ#}}WGZR9@tYO<`_x})y^&|)#m9_m4jGdR3|oNOyhv|izE zIbX2hGkA5xD0R1A33U@>Md#zpjUI17J(11(pF8hUz?sa}+SFQ$Px{4q|q_t`Nm9_T| z&$>ZCj$hE}+c?2$D(MBtQSd_^iC7HIRoH4UXy(fv0GI=zX0FMtrcw2vCZUsW zgX34`b$TL!2fWb}12Aj()l=T9`E#=6B%&dq@WhjfNF?(jf~vroWloi3Ca-)wiXHnI zlc>1!uwu*@SrWhqZ_?~tKQ?Xe{I8DM;^6DHkh;p-T8~gl+pWqKD<8jLAN<>+_WmC| zZE$QTu?TPwSyDWkP}~8)&?%{2zRN)Z4q1-+%X}RbDx7<95uK0>b?LURzJ8 z(O4}J$+3T;&(Z^tj-_P`hr?DFi}}+Fx`Y+>jVpKE4#J_u!%_ff#vj5o%eYUbg1o~k z5+fu4EN3b2IPF4Kk_I4DL>V5YZ9~92h%et|5&9*|md+&0QFRPh*NfBJE}`dM2opW3 zrM3&_daj0RD|Fxl0GGEUb#?mmV0Q#Y6lhjVX4WIk`YUU@@$jr01f20P<2`Z$RL`#X zUVkxaF@7Px7(#$9j2`A8OJfCN#M8YsN;$iG7fV2%kVBewOI`JsYX^8xa_;zW&Qi5gx8vF1-i>kbXJt1)?Xe>hsU7$E3DUOQya zROBB|+sA(9J@#If1ZD~3GvB!FJ`m=Zu_upV>HiZ)?diXZx`LU%4ByzZV0{GKk;z~h zPAUCGL&g&hrO*PkS1@qq@6+tM-TpT#_Nzbjd8@xQYGcV^@l6^Xf&lrXTj%$fq#>)O zSM0=@3A7SgH{K`(Q7#tL>g)ixb>kLrQ?x>o>gxfNTG);ZAwwt9YRcli>?8(Ha#7DS zQ{A`I(v3j18~21V-eH2H3Jjwz$wDTaYEFCRqHueZL>l#KBUJu%A)>7PydokN)X+}O7*XR#VbW}M66?Qre8X}dVls+Nt-kF`G0!bZq3eGZlG=-`sK}Frdsr7#WJ37_tUt`n%S#v?hc%CrLZY15(5AsLba9h zUtSA6N}~oF%s&aNBt*G@#W!boTxRWm+>d-r>fOV%QwT&IMm9p7fD#g!HOh8?AUmzr z{Qz%3kiU9gZHk)V6Hkz@0rCqMeaFN7D(3;@)8hgFzb%^@52To>Tdg>hklcbTE_}HaD_ef8SWDg*oMa{Rvw+Tg}Y-Af@pguudi}Ll@#Me=OHN4 zSjUR}jX$i~_+Q0xe+0{a=GS<`u)!6C5h^4Fc21Fq7z+)lE(k^J`BE?8Df3yYozL5| zzc^-d!>`&O{pRo4_x`|Nu_u3kc)b|>FG8e--Pw)i?GgmYgS^6&Sxi&;UBws23G62% z5Y%lzHU+eI_BTrQM?Y7!)LYNk6cJv)USCF7N@77zzFOza@~H)#0Qqb$3Ech}Mgwzx z37dimuHaw^Ar7-hj?+{Vc;m+)fpC;S0IAD8F*A5J)mj5T46|Qcv0)g!Cw2fN5aQHC z?=v!2kf9__n-X<)2(TO=pACJFF5v*FYPnk8W7hZi{%n84vx(_I$W$;=Ef3Q=2mlrd z%?&w*N)XQ4`wX0HVARRjsn&;m2|!y}+!+P(Vp;ZZjTxP>~vRAjgOh#1EzwzQC*b+0@8 zd35f2fmvm~V#uIVoc%VaGd{{C&>_ip>!|KJDg1ApUD)c!C(2{Zm|Ttl6- zlLOAHC!uB-AF_rZF-doexyj5pc!oV2) z=2cV1s;5^xdam_Ym!dY%XLl~o!(6;((RcKU|Ab0PkWvz%*U{J{I|ef3!AUZBa?$O> zbk7io`zM04h@FxI%>$GoG-|d;Og?V;>Ou2%^FRV++X!yn+l_;s?}Z3mHiShJ&>KG0 zdpE@})cLaLmL#lgN^yJR-`=bB{;82*$cnaqi>MzvIpJz)%^X7N4rSq#81St(=d6J@ znt)?^Q%B)UgC`z9?mUQDq>{oqPp}oRl31kt?q&GH-M%P7iw@O4AF_}Cw-?N=)tOab z&n~2)m~wIbKj(QatyP>9MFB$@$j{geREKK4d$ z%i{3*Rv`c|tFn$K35^dDY{l?flTMqLng^{<#K)^NKfbb?zxO^uce9oUxhxHYO_m`J za`PW_+bVMY!cY`X8b3*hSLA`f7PPptF@w;!EnH^7X_-zU)wM6ag>p5AE)NFgrz;RR z44npvU0>;+4@6)?0^nJ%`_ha;v-_Fy8N2i8lzr-dzG;o?LqU<6kY+)qd-78#f*OCK zY+8f>sbK3cwniVz0sTch11{mbhqZB*4w85RbWRt&*8Zbv%Vxs0D7eure|Fh^@8@2# z#A~N*cx4pz`T**4L?1p1t?SGms0OAS|F-A4^>dY9>|3%7_8Tq$_&AY37y2WRSjy3< zUt&*&jLVR3>a%piVz3PM#W?1tocnm+qrM$Y6NIah?&?*5mhZ~tTEoi zzxS=IhcY92OqT30_^|Q#KmED8TQ*iHIJj80_(f-pMYZ`a+JoReJ0eN|5nchCBbz3 z^pMqvk)agyFfeSL@)3*zE74sY$w3nL0m=NODlr6z=*RW&cI%Vjnx2=NAc=vVC0iel zof@|!TMjiAU6@nGhv~jTAjYw<1a)7t-m}bnE4MI^v9RjwXwRy%<%0K20Em%b%QZcK z4?5AIT_R-FYK5hM1K7wtZj$EtV%tgL-AbmKEC$tH{*B0Z>tcY_SiBp5k9$M z|K=CIVU;(|*m(UBYz;9*#P}{*LpOkB7R`0WADF)&C&-4++T6E(rmCs@iPIyva;7b0 zE^UOal6jQkbCnrNbb|+E>4hsqFf1PNJerT|u_%Q%c#E6T0XVx)m+Z(i(p#1#0XIBW zpB|?B2LZ6vJ0t3m0}EU*cb~LPRANt3E1|ik3N%OcJ-yu{FVP78>#U1a$_N17rhqw` z{T-&ALqP1=*N&m<6Em!cBLKu;4z7DTm!W6W1<9qHE#8FFVh^D6HQnM&f{Q%t_xRO- z(#&ya8r6GVp7gvlenV2I+;)Eg@x9hxFNd$WG-iC*haAZ^Y@|4BU;E_&`_upCirFk7 zvQb$FAx35BqdJB^)kxOX?g)u*O>%v_k{NX#ndnCLNo?m+`UkzGRaEDIdMt+Ji1UIDd*5|`phu=GefZ!_4@4)1chPF!bg>Eci+SXUb~kqoMvjoC_g05GCowwekQ)-(i~r#A3=jQN?dD{~e?2xBVN7bh>0hNxMxFnIIjEA~4-KWk;2 z{N&3+mPZrOVB4GwD;qU!8zhV9<0pKzfF!_{S? za+)dP`rbc@%Ag0?K_3rpvb2B)JUt^Xdc_lHbe<@PRZ8Y?M(KN=ohj3&)TzPReAnca zqW&v`@ae2&SK4jfK zxuo{9N1mB;gQ6NZxv3Kku+I3Yvt*&Y?^d02L4ik&Be0Qu{>TQ!->BK2{ACUbxAo_@j>eB{7u56qdY%x?E2F=9tQavB=mO!LSa;z}Pe6 z<2gRSF*e{CgAFsr*nj~WBLl-C5JCqeENd6qx?3%^y479P-L>zPm3!pnVGTxkO*G=OXPsX~TDAEdh*lr5XoUd|5|t_R_UNKm0OY>)MH3 zT7wR*WPWw^vGBOZNcYEEerX5$kfZArC>Zt|&%pRn_Nl+RX#e9Ep0@fdtQUeK#+Zeb z_VXu0q?(N9oC<{;t}H}t8O1n|}W`AEQ+WY?PW43fUVL93%#wo2un6$OZ z>&o1(=1M?!xeiL(0YTNvv|)T|1gm`diSpfkLP!2WT_gsOs35$0rLDCh`U@gGDbG;b zkb85@b*`)7gSek&7eLnkgN=s7e`!KOU-MWmZ3hD2tW#}(U8HYnvKtXzz6eu{F`a~8 zY0KkoNF7~E4Nh59Co@T;F0E#+ZsgJpz}-q66#z(TF&6;JA~_IzXDkev7v~t+3Rte+ zGr%y!jD(;g0E{0@SvgCzH&~2jfZ_l;Y?K`Qm9$+ro3|RP^qz8I~8smoxro?i^*d@lk{`N-9BaeVTEk6N3cv$=cC>AG44C>~pxi zRk46qNMO|1)VYd9`$Cc!2K+@rNtDm(F-C+x>W4vJ&dwn^)a>L3XYIFt@>wgqaKJ^0 zV6#ZcAfxBATAje8S2Me|vj(o~<*=V0!VQAiGTsz5_Eks^!~CVdX~=2;!VY-vI2Vs3 zp}35|b!jio(z`4Jh+2dv!*^5Fy{_sL;egNi`-&JGqCrTiFg;KIY$_mnHodPl5D<*R z5*)0C^L!o+6w7Im9SoOVG)ZldM^_r5*#!V^TxYkia|M6~-0FFGk2a(ZG?RoihwEvM>!LOSA>7TaWD?4l`%HN(x2ko4#h&?H|9h^)KOs zh>XG+_HF5GP|{C>$k`Y+K0oFN}^Z1Qe6JGRZ(Yr^Bc`yp!n(xccG{EH)2fBF#1 z47)6a5gjqNQJE`dKoCp=18$q`Ro!%$2-ks$L@W&WWwAgT%QmjOq`{3m17es>Cs6@b2wfWJb!7P*=z?Fo)(UL!UR0+IZf$sJGrNNgU-FBg z)9ZvAt+IwWKTF72t~*~4HKVa^-=#+P(zQbX_{B9XRANw$-^Tt6eKW2B(4O_}G?5}x z3D(f_vj_n5^bY;xq>EFZ*ZZ_y9mI!gK|7!)_>oT7?t{~QOYBXYst!Sj$_q0iuT}dm z=U}Ukc(5H7$KxWR)IW(`z|g`icIr3HKK;+1w;CP`H7xz&ESwKi32Q6Ac&ewdrH{s% zpX(w_F3awKv2wp%`U|uF@&iv=>c|~7S{Sf&37>j23C{c}Ckpl>f}u7lyLl zfsNZGkcHM)t1J#z((|_GF6yiaxwHPzS^wv78F$zwXW#qivqGj zKn+As68$kY#_++TNXy`)Rnh?R)aIF1?_S62J1PKdr5z#war|<%*@=Lw8JB~sG27Zo z9_^l4&%oO~d)@DW10u-Ux-`GYh8awKgio4ft`NQJUg%3N!)OUW0zi7YX2qN|0I1A? zbu$kL_fp1YUKjKa?Xlun)65h{OeYG<{ma08nFyqGs(s}T8o##ocsBU|8gD) zE+Tnh&c0a#Ho4!JqSujpL!K~WX8+~vWgFbf6^s_88q*SBU>Om~YP3lQ-jxWTR4>-q zzhRLvg;^$s!tIi}4$^|a#LTo0uYp~SJk?h6)33&rcG>jqZ2Kuw*HibQ}qg4YT$ zU46P$er>Nq(VB&Tw$EPgn^fIHV>2L@mk95=1i_+-zOJcytw@$ThalIx$u~VeU`$Zn zFwFyu*(sP}zbl!!9`LDUop@I<{%e^1pFV+QeTDu}e&iG04Pu%zCax=K#uyl5-7=#X z9gZrHu9y=M0^y|LF@_zw?U)^>(h>r-v;(t$S+f7~6JN0Mks%u*k2s-p+1tzsm<(_<%tR!3 zEett+hw*}fy&+6+>)Ml=C1GCmq%dL&QTj3-3$r$T3pb^v@qXeluSHZFy~sV)hd=k@ z*A*DdxfAEy>#>?t%k^CAq;?r=wpolrV-t;My7c%uWvi+U4acHUL`W zaj1LGgtM*W)Va?H`=XRU0!X5@PM`%?75JmOj3rm=Hhwq8&rZTXqp9Q48h}WeLY*qA z8?>R(AdQ}ij@Q6nzbST>|74OB6WcA(Y0z;5Cg0$zZL!hm(5>7_L);>L9s;Peo3>%=5w@k#}^L-n`U zN6+zTjDLP?k{bC2#!nqw0Dw`GnYI`$;u^SsaFHhXz}Vt#_QD@5+J}GTQ7aV|sctY_ zjKf^@QNa>w^eHS9?fw7qs8tS6+Xz6Z*JL!f#4{3Nm_e&3|Fuc|wtHLk;^UG2D6m#9 z5wUT}2Bt%Oo3oEVv2x8X1Q9@WtziRj`2rdq;Nn{(uROT%iTWTxoQ2`t0|-p3gj`Qw zQP##;^scsr08pf3)I(bTFO?(=bD?qV#Q@^{xg zax;H!K?iwbsuRr~unTd!8zDjjF3|(29(AQO#lGJAnH^)Dt0-#qYQI&Oz4W8%D+<_T zu!aazdRugPSuT?&Y?`b5-jU6C(%lJ)*r{E|%`MqPZI+0Qqh zg)QYQSLx>-EDB&KkM^ak=6|!#n%lEc*()=Ejc(qAYjt$=aXi^8i4v@kk%{a7;2p!3 z{H)lt*7!reiu5jTNo(ewgjd;` z?YjG-J^f6{N^GkuEBpQ=xJ-bWWolDlhML02&IJbbF&|m4uSpsVN!*g@vnjA#1J zTj|ysBSHHWNF0&u70OhJzAdsq!uyCa)?Xv;KeuCS0#rVqv{`7w!7>mBZfn{4YGrgC zjIe%~Qv43~1jvF9;!i%Rhsf{h+NL*qX)Ofm73^n-@5LjZWVv zB^Z>Mz6@$kkcC-P08?Q3Ene9un{8jaQKTTW0V0J7K%GyRVm6K%G&i%6+lEr7W}x-B zzzE{_=T1zI5;q2Qv#-Bse%?Ao!*cNwYH8VM=+Q0oiSQ+c_G(}%i}10Cp(lf13xuQy zm!iD=;$O`{#w249cURgAgX3j9iaZy z*12`2sWnYiLl%z9t#a7Xb&T~q$);_ueVTjQ~WwBAn@^?Lt6|PrX=O#5nWJ zJb|^?+{v|MOz6}_z<(9at7qFS_h!ByVW?`K#Q!gqV%ZHrKuJ7HxT$ot8-e*tH~6b_ z1%RmGjO|30HA~f$^JqYK3aW_cTyu($AL3mtWUNj&SH)?svz{B~ANqDhQ{(qFm-Nzo zQHUaD02xwWB@iS>clTK>jaojBicW(w8o?VuiQ7pm>PzR~Bn#044ch@3@ktnHld4nf z^FWZ9)PjuWRFnh}SNfy&jNVoKt~HT|8;e3_X{Tn-BDyuytO=&j6IJkvdM7aPOUHKc z49gDqDa%bs!KbJlxW#X@6LAKaJW|N8@wwJIZT-DaTBy6QUCg3}O~cqeA^`Tchs)~S z5IaLA8gs|WmSfW-vY>74lisfox;2q1+t8#NhOE30dT8Zm@8p^x5c;%4gz4pr1;Sdh zhXlAO6sv-_Ygbt|>#_BfSjB+#cW%z__2px*j)qZ@0Ofs4LqS5(Z<^cC{@t8Fbi?Y9@{tAPR=ptVNEq>zru0tj0C- zm&OAG<9|ErRI8=km@{9C6OuPR>r08Qw>z$X=eqv}(AvO8VwLumm^gr4K5OxLDS)}R zei%pPtA8|0Nmi4@e{VSYH=a>08KV zrIht>lwh+aNz0&0O8`Kdl*9G`s~OhPiMLNd?1bP!jSAS%usZ9EKas%NABv^PO307* zg?sv3=d`B&5P z@gpaHHNndWIO-4TS>30>6*fewW(qcPfGB{ffNOX3lr%ii)4k)>LO`Ia3E3MqEj3&K zXHLyp451rQ6C+JLG@yMN3EIy^eNhbv=v~&Tya<1E|N3KRt5UaeJxta52eLLWi2Dt= zB;h*LlJgc!#INrlo~@%ETWRP`d`1Ho5m9ykY4!wnm!=&A)j-bSxaJS>Mty!VXME!dk1;==M^wXqh1vg8F>Q#?#SD zdZ6)8t2}zw+e5%n$+ejU=6II9~>dJX$*q;28bR7G&SG_>7XL-bnv#XpR~_a);r^xfw8mMrE^%B`It!h z`f@kSK!WNxQXyZ7PR)$J85+8NQ<7ZfC`zS?Z41E3!GsNr4tM~V&FUatD3`fJA#HPK z&||W$9;SvN-_4k1eYlP~dlZIGFd)j87D8Pdn%`i3s@An8RWSN&kVm32=(wf*11e0J zt1wr&m&*Gg?a~c>wz3A_$ZLaqZq%jFbd6@pCbntJj*7yd+#J$7P=| zqW5>rj-IUGF?2l7l1G?*lcFna2O9CeM8+Z`_vb3OpQ2}y4t6E&1Sx1D{|#x^ub@61CSX%oM_s94<0Qaa-{BL4Di;&@Dqw3N4O)yr zsX#34Kr7UU;rBPXD}<)i5@UEF63p7Yy}n+(-&a5Y0L$e~U|pQS13+6k!}^73F0(eq z<`wUC)rAPh0R|%FHa*k;*j1knnS_cpKCw$r8FJSMFJGQhcTn?u;c}4*ApmHMYoPldGhwasN!9AJNUcw@wQ6D*f|-`tmUcRGcstV+_}hJM7}Qnh zbx0}2UI%$(FS^KV=Ir@7pVesYp(uee5_Dfu?ysL=UWejeLRpBgH?%p-A}99_S{>_e z;hb1SAWK(*L%1m>uBR3*vvZzo07yP#kNoES%9UTryG9>Q?;##AYt8IZ&lNEmshrX5 zaNeriD|35sUWqhmF+3JD=dWhxZR$3#Ut550fryHsNLN@P&iskz&-+YFFjg;#PP9w9 zUCzzh_&NJjXT5BkgkO-D?E_(JL8fRu}{4E)}i74vj&$0>;p_&1Ubd^6i}K zj9!pPG`fyqZ6Zyi&ylPp5MIMlp>V0Q(~b)O0*^C)mja^m!1Q$8ZF1zlGzgQ-6oUW| zUIMwaOBnC8`E)k;VG)F26%nkW?yM3XbBZNOgfR8}237zN@ zfZ0EeFpy)$sMH3&x+NS$u9vA3yS|L}>=bc;3EITM8Slbs=)CZD zt2_uN-p6K*BOx<84o z2ybe{lZY`v%?u*gzH3s4!1h6H5 z$frw>H7w|Fb`nEYl60$2B)qgbhNoM7^FG|AqD3)00kr@6%ySp4z6kQbXtXS#wf-oC zY^z*4@p|MPpt=c8(eL%g8@m4Qg-6f{vqEROO!)dIi7uJNHBQlE8l-3=UK3Xzqmcpw znZ&1T_88Ag2+;VB#x;~oZB$y12fi`LD3$_)2(R&F`ZN%RU~UkYUsS$l@DlnG_yRnD z0E}Dfz>AqP2mnA^i^YP~x+H=dh^`p6#)p_SaA(Y%f9@jr$ahd08=jIOmI`U~Pt-?x zKBT%0?(3&-peVj|uv>J%{-HH0K4cv|+&gXo0ula8YpHWtXB6kEHiLarWeM9Yx>Q>& zyZ9T8pQe0WXy&*2N`IZ4R6F-+fJWD1MavCCS4ME@CJc3Cdl1^wx$W370bsRb>1K7d zMx6frTmvwCRKYqyRN_N0e|B;c=hrotyO@q?2eBIOh@futSuLj%&sY~DByEWX3E8t) z$=VrQ0WUBzph+e7eAr-=bYfGkp-$fC*YMueyy629+)!FoIbwJ?f_KTNu5JQf5iwMl z(f}y1&e>yZ3rqw(nW$@PPsdjw?uIE`Cp5qHQ&u&;KxtaWiqg#&V55>d<`{Jf-B5;U zEM+fRVj2ixNey%*QMIkA)|b_V*zMU2;hO7OHfy}$tNPK84RX<#>)VZoM4tq)#-=o! zg%Qxt&}La=LE5`vu_RxE%Z04NWIlI+$b z;-i$u=UIGTzj9UDjuBw~41rtdnPS6mOp>%xbo3ux^0j`(-~9V#2mk?rG#CTCgKG|q zH%COky+bf@t=DZ#b%bjUb8c((GKqoNiK8b`Wrmr1M8Z~ZmuDmtgbyW3Fr}Yl#JWp{ zW{Et%DVwSU>wXCU8<*WB-Mj5-ipdH}f`S%Es<}l=?edFU4}I3Y5T2nss?0K%b;dNzs4Hfh}Sd`)e=CRmKhi^p9wwC9P z2msB5Kb(hN_W`J32;p?WAgUd=69c$kVPUySFd3u>03smmK3fCB&OGI02K9dhs-yMF z3~f&?#%=jLGevMnnr5d(e03x9-x;WGRB8jifN?OWZQlB?Hzk{a%wE~mUSWaQ$ATIzB zbG1(?V0H^6+`+m>MT?`}^b{Dp5J8>qioPH;30&fQO1dTHNT7~XvERzm5Yl~+&sfRk z*p{uv>^NQ@3JkIVY=3XvSD34LZ~|tG}CX zyP(n#YQmf+hA%9U+T%noqwR#5vBV2^S>^Kwto|NjcYr)#P!#vZU?Q{i`LCALJ8Oo3 ztZ)UlBI|SLjvzc(=@R!n<3@bwDzR3-+|-ghWt z=?at^RkbBhRnz}kM2NF_l6G(Oius$puVx6W*l?loic-+Lh_0*4=pTgZ_yt(ZQ#d=< zO4e5!u>$a|vg}!_$N^enR(N0Z)cd-Tnfgbc&E$biCq}}bHc56T*Pfu)Xa$ReaxV|f zS#r1B0LQ5~HV)urxi-LNW8fJ)O=78vQhisvQ*=-9IDFt=do8x}=4$V4CztE^Zqy%| zJq5so9%Oe@>mSa#f3N~9D7D{?^*UDShGj(?MP!sXMLEW{z-F_onZ<|+plEFxO1-pQ z2sk$R0F=t#Va>=K87Bm+6EON90<%+`2n&T{;g)Vom|MJrz>wE{KK@wrVyik*9@+O1 z5GclSj}x`giHfO65-6b1uLFr&Y2HV z@{3}uYz-XO{V9o1`UKZ5Hw$yZu3aXlc1=3GHB>!`;Jg2~eh2Cw7bDOwzl0uvea&lg zy2l`Q4S?TX`O?fNe0UCxf#(fl8WZNLV%{cRSIa}fUJx*{iEkPx+PnyoCi8WtC3~zs*x$- z5-pc!3Uotaz?RYu(t(cagEb7*L8xI#Vq=ihD3PQgq7_ti+8NM?>=t3{dE9_6XZqU^ z00P+w-5}vgX-XVV?$G)Q<`O_mVuaRVf_2!>oVUdvNJAR-={wI(3mW>4La`|771Ns%@9 z`og0%9UV23atm!C3j#nt(t2_vZUx`kRI5h<^7hbZjle-(D!2KwzJBX}dwrYUS$}`C z-%?3OYG|i9?3NX0%gl4n%~|cThKt&$W^%@Qb}wBW1cV){7{V-^KoT+hbVcxo#&R|~ zt`UnsDT6$gE5ow^&N|mDU2I4e>LOg};-D>^X4uPAfa^_}>zDV_Do#P@h$5(mVmSnk z{rz}+C?a4;akn+_TpCwi{D(DTOXH@|9&`4Nk=`zH?lKu!36Wzt&`;#{~= zKP(Xg;P|rD3M>(-6X~2;eua6~1l z;Ef8uvN|vMD{F)R1YXU}1poZPvduluq-|k%Jaij&Q;b8m&FON`iC=&tC4|Y; zaLI>bCQj8vqnM0c>Uzqo6^^0!AbX;L^%{ z>uT!VOpu(JU(L(c;aM3eDJh*YV3Wb^#b`!~QBbC4Lwhi0#kx%z z03~-*3#TvHZ!ugZOt1#_Wk{E7a5tTzZGd4Qy51_ekfjIY_rJtm^Rt|nF$UxX!PP^} za*l~1b^sFHf@VMp{)&Wybl#>F0@(RK{pl&Ne=k;Fe$u$rJ8TL8flDsj;(6+a;xaDH zrx2*nORL>sCY7pI4C10+}-TWq3XQtS2EynUh|JBenh zWyhvKUIiY`7{BS^ghyIRvddS90iZ6}X3{K#k5rC3BLILV&1EA_*DxGEckDdDGpLs& z$zHl<2nc#tK+rERI2o*L+=W&Eb#ScU3@6}R_|}`+utbkb0Fb&lRqeBjC)weQJpuGo zz?myb2=(Ow?H$Bih}iZu+l9}0m7^R3^+spALdJCHj_dX zNF5qsiuut?>mU$ed~?_MHP?xQ^z3nR@xlePW%NZ+f*G1l7-LP$-(js@+?+wKE4HJ4 zs_pFCW(hP_ePcJS=W)Ugc&OZvOQ3eWDrbuW!!RB{xtC=tv1$L2>F@ z0IaE#ISl4Nq=Yla?SU_PJ33yMYF}k0!TLCKg$9a@0T(akt#sKN4=VN2wL_pmWY%=B zuJK`dKRf|}VhxW4WC#?OSJVK4dU&a!q+vjVch!u|pI<~_(8zF;&XJp_2Oom*53>WI zXrJCx4Z58G(u8d%!9g$*gC3n^{olv5`U8)NW|!b~C5e4VXsAPhX9=FgLM(Yi0)QYK z`X|ikbuOYD;7)NU4vLl~x~P(PRyd1J!jn>2_tI5Dpy3Ko$`|d_3n#5Kubml!01y__ zV2!Sc3oyRQ+&k-WnxHnNBmfMfO=8=6$0Vl-;G2GKk~Se9o4mdK+dD1*MC%`#N$I2C zehz3wi_-Rr&7vhj*n0+$`0h z`jSfP`an{uQ2XYOFY<^3wD@SQ(e9&_%;-~F$pcoRdh%PLVUuN|08oE+m}e)zAzMZR zu;24&*tS4O zyj8FH@2fZ}kB0D})Ah-3bFtNN{qvjsc7mqzyn#W;aRkr}+N2qai~_6pn$Mi(5)riY zs6?3>)YJ!_yQ+aWy)8>O19zMIf;W=8HU(m@3B{oY4Sg_*Q90w{33|hE%B{%xEh4u# zi%MVdeGnp)OS_~zm6FVYCZ>iggFvB_W+@?4Q4Ctg1iu!rta17xIS4)xj5IctR)hl1 z-DXNQ7|9DZJc&4k0HDWeGN;}&4hB!M#xis6G6a`^Vf1GxPoqeR|3KcNa<$~*LWu5U ziL)`L+Vs-4Ah6QG%!MIRg1p5u%=`&-b+%+>_RWwcNAx{O@HUO8NJ!sSxgGLy6_1h> zu7Bf`V`vg-dxMS(hlPDQc5>Qr0YJzQ&EDMVpWiD8;=lxmtc&{^5{z+hDs7obqA$fu zR$whJq-zIrR91An(VZ2Q6CEQI(Kr&5*J@=t!OmzEESt|P;obzZ!Ey!#1$Ga>%JtOD zPKZDyV%AIBgFt4AXmNcAl*E=`Ss$2!X&m)QB4Nroz~Ss}roA0>mTU1G_FE2c*~V?*b@X{V6_E}yrd$HKC3so@=UWleVQ%B1y2b9GO+Ap zMxG+FXEHlu<8F@;2&Z-f((rEwT>+$CsM>kLGt0V6&q_cGLNekR?|X`lJfRtwCK7!k z2wxZ!_tJJDAUzB)Z+K<+q=d~)=FV2^+zae}$-WuU*0^$WR-ZQt@d$t08q!k)D2jvkD`w%t)QR(>Z~t@=FTP|Nb^Uvapnlvd~W3KKtTXd zq_8-0hwwr=~vSyiTtq2nF4v?Ue zsF#;#3O0WVHDyT#PilvP$Y_?MwN96{w_E&6{{1?$!1@4Aez=B70MK;bUB)<9*dPrM zF)IyY9rQaB@3XTf<}q&4;tt8bbh19_23XSI^TOiT6t*4lO9*wLx9c)ATUna$f_O*o zdCBWD?7H7-k$)O6a$$;VI_jfnm)a7#oLaW*7!LvLFpu}H*tETMln09!mKZO%`0=_( zuFBKskN}`_eM>x06%+spJ+$>tuzVx+LoaO)0uEF`Sei<3U6D-}S-Ct#q=i!~VfuQ% z7$c|t2{7+!<`2Y#O`-^uY{B}c2q!&AyZH}PJm7E$IK4ga-srbQWp*@0@c^P@qy+$y zo@!WXLnfFdF!v(NVr(4twOCuw6HqL^aFSi}q9@-yrZa4F10HNVlEQ{{`A#R6yA ztjL%2{Ybmi5(qB!h}G0Cshj9o zXkb9*1T%!)ugh3|*GVg;E?Zs^E#-cwa@C&{6!1dqEBv*~e<$umc-!i@zD{boqiX;` zz+E2lF~qR~sAuuOn8ya7|9;}Bii(m%Jmsb-7fekEqVoJ^(^qURVfk~!5U4^QC@2&Y z;HRAQJIp}CoeE0@g<8S(+`h+RY~SjsQMd4;_q`Peh+f6`NbOH(4RD;PiG(*aG1Utd zJNvbQC1xhnd%n({NZ^o(#w-Nla*Uvu9cMpVX==-7Jf_58$wv1Re}dg=k!HQE$vDv{ z7|`9&x*e}$G_WNAMCZ|w3t<@$5+X+FvndRzlT%!0!w^e125`$Ry74z6Rep55+7hFo z5JF_4FcvYAfgna_6=pY=o>;W}ah5s|uw|Acq;t)KPoXdfbP{*9rS_f=YzgL@#vN=o z8^2(5CSoPlBY{#A8M&Hj7P+zv;CJ~#0GMURM(x+ISyGe%kMSVgG!gFZdRNYt4;`_k z;gfbTej+e8&m_tVjEGJ*%e)KjOMXu=H5VKu(kMA>1z#A)x!8GI8oOX``r+4DVkGVO ztv+z|sXR0E2OZG(+9<^?b9I^Jf>M|b=qVTE0Ahn;G+qm(S1>59!K}vij9NSr05;0F zcWnz0Se@C6KuLhDv2;0qu56cIfKpv1sFP-Cbh`wFp!!#@=o3-CEfmwSk3cCf036-} zWoEZ;89D~)46cEQaW=Z@^rW8H(G<=6HOQNV0FTNgkzODD`+6xzrig0$1_`>5K{#-# z0?-5L*5Hq37JlTt&5oNj-t$zxtv(Q@i21i7QfA}-HpD~vl1SZpOyxz*rfNrHfMkTU%b`Ilc#L1?|AU!kih4v(tu~m zOYf@e?oKRc(Gpky44v`aXpfd!J5LXl zY(fF0`e_~X!m&wOL(sSz1b~hZQNkb(oxkQBl=0b<;|hp_Kb+KpL(_wHc~}mBlDM=U z9;ACc);yeb-sxzj;ShNfc7s zay7!{s5YU9o%}|$X{ukS$;uTNZwg`{JfIf7hM6z6S%hVtJ-28J7vna9!)teZO*+*_%QHmw#Tp@NW6uv-{5#EIVe7!3|LTqsuh2S(Bq;RJy-6)syaR0?PvEfIK zSl=TT?F~PA(C+@`-S|#tozIJbXawL*?H(`QCJhUSs^IIM1YDG0thW1D!8ms5*+JaS zr+EtDA%P%3ISIxMQUQHfh8Cpcb3r6VjJ1dvQ0F|uazT6#(}zrkXVVaCb;`|zVi%PK zO%-TX&|^p7jN%r-iOhl}Dr~omHdFl@rfF*X zD$e@+r42Y#PTREE{kAV}c9VL7v+)|+{Nms5qB-7YRRV^Ts%axkg$>P7&#Rn`tL1B3Ht=K(-=K>*yg(^Neup0F_)vAT>UtUP@&yIP(kQ0{GbI z7cm-@DV&nmhw!$4PsZNyK2orc{m$3z#G}V8eQDH2ZOZx!LkM~>DT=CVc3j20 zn!JM65D&{r0`CoadUU>M zPV8Vk4sTvTW0S5C*d&YoseqU4UV7rGyj?z1Cd2}97VykiPoK6}N{2iq zfsyemfs>^6Ryb$dDk~=QHi%35p}P)RvJYI8VT%(3Jtd6OLFb*FI$Qt{&}Go0H5JIK z#7#HJ#uuA)m*g(O=t6XKzs#*7gE@toG|i}&YF#Q@d1`H|8ycOz+Kr9QjV`SF8C~A) zQIfV8Mk?87OBXKN@==D|4D+g6Si8h+N=cwtjUT{$=RVsl`K9(gOdckd9bxVAG-_c2 z^eBp)rZ|X|E&v3^FEyqV%K)9(&Om+ImQSNSh!Kh!9985xV$0$FBOw5!&=jeGdFo5w zC2c)uc|>Z&GI`Wt>6w9~O?^|&zWvSz?Zh81*%#jbyyc%iYN=A63 zU<5PMqBjI;Cz4>H7N!tD62K$;NeIUWoHz%|*-KVq*8jR69JN=zO$Jv7R{8!jn>*aOJ+{3JiC6J_BFhS_RG+E#Z z@kBh=Yb-X%x_3zsSm^+m3jVvJyVG{;nM*JUg_Kd$f0zb+pxJj_j0)I>o&v_Gn(GTA z_JzM%uy_7%%+N6c7LL}DI%RtVF=2zs+-U~?VbxeBLHZuiG}tXVR$vAXU2D_zHIsa zi|p0$b-Vq|EN%SgD=l*uGeJ$Z`ABT7`c4Q`9w5e9*3g=Kb6StTC2?-vk}#&w%kEQv zz)?D1w8LLG&Jr!QFf}>=*G$D+m)g&l6*ToHd29tu66izCRu?iSExT`m*_!I#69ODa zZN40&+>aC`K|ll7L0(ZP31_llsuu`d{(Rofe|^ygYU5~S=qo41>c8$40#tJ?3wncv ze@rkd%q+Dx&Dfm->;g#hG%r<9DgGT!8rT}v0$zuwju!y5Sx#J2Fi~H)owG$~UXpD? z`wpOX!nmqhlr_BOV9Z0xT89Ms0ADtl0r_^W7c@{>r8c*Cg|-Tt7)VKC#xFh3lJj#_ zn<|N#$_^kx%2v7euD6Fkzzxmm6~JR0U*38e4FE=^B51lRY!lm;MnLH221#^UI+n3Q zzHFzzTDIpuxMa7!ZC^tO0NX&lz_NnC(2hN;|Mii1QL;k6>P3=vwJpIM*}2AU{k}bR z>sxo*qknqQKKcJWX^9KFF=iXKK?1A9n04?FA5ok3*u(=jBq{W385k}mFWKzSWt)0k z%HHvPZ?pq%WL7vrz1U|#2Cmu&OIFbd1nR)ZvEKJtz3SbXPzs6?<`Z=y_esqsy9=7V z{F%Ca@E0Dl150ng__vRxn~+BhW6S^zv3F??1XPJ-Nd%CJEoIKw!2VY-acGp;zIfj4 zrHvpEcpKCixMz@n*`LfVJV)r?OBhuy(^tUNpAndM1~oUT_SIigL%<(tT8SAB>17cL zBf!{b!KUwJ>`8tlhKRfXG!Ff-t1o58-spG%fVn*c8A2T3i@FvffJC1dh})jKChXi$ z)`}PMu4;l_GO?)8N4U^QQbXc*iEPKfOMR{x`Sl{Jn5a0!j+QRO?ex?0mb*A&17nCm zV44_Il-8?GqwBq6I|zuqz#K3j+kXquy!vqESzrdKvCc<$=a%fiS^PzeMHc8{W*PRL z%R}@&_*0MD-+5uu_PrjV>;QA&eP{&W)>Z|LJL82KhT4DH{4Lnq~xBTGkcHmpslW!bYF!p3B7561H+{1WY6REJ4FU*$U zBJn7yC#M@EbX`1w9`F*@*B8om^ds|j?Md#|GQd@;5&)zGK9(>T&JvOKmY1P@Lc!%ir&MxinFN#|9O;eDZ-2)N0D-8j z0#bGWH98`mN!i4~F`F4i&3~Dd8b&b_If$la0L3x51d(+ZcaXXbO|nS z2xl5VTx*`G1XlO}KX>#2`}1FT&X#vQZ4bVC!ru80Ut{rU`iobzy|WVqv8Sj&3Q(VE zNkP(S93N@jX8#mw(pb9Un8D4+_!Qa7wghp>4q_v4f5P7Uf9|ule9Im7x!+i}r~hUa zPXXNQNMf`JUw;gkBik93>B5CSp$c4?nyR(trmk!3X!Iy3mn0$w1;5>xj@oK2-+$+* zz2$o+ZTefeaS)fO$;&W%Od#3TI#z+nOJT+9QupH#?qHCvPK-l0!WyyQ5rHU-c;T{( z8Q{Kl{66>Soc;B0e$r;Y7`Lgpm)XSpJ&0f_TR^Iip}E&rUk+VA(GUNrr5s&JU^IE# z0|yBFAibhjE3~QUalO(@>mc9=yY5=!r-bJk9WZ;QXr~Teu<^2mnHo)+udcj9d_CWvLLt0dXi2 zJ3M|T_Lz?>*v#T7yZz+d%%)JyVj!n=`=!1GOD_%LIu%&~K!qSUC=)qqPOW@emmA&L z)DJa!uyL$u`q-2jn#rasYfm*-Y?o>!WKPyNCzqz}@>ecd{?oWqWe_`Gp?08Z139DA z69OVgY<_f$e7Y)KVup?Czxu{yD<4?2?9mzqcY42Wm-;W*V17UFhq-c1Ju4<%29>l8 zs9e+f2-!SZy34Y2cUkP`mh7+p(`kG4k5Aj^cQ7m6%}WzY;2;+0sIVojm0@Vw6&3jn z&4c!<4~qosSP%A!NrIcW_*oUo0uN8aKxH3b#C=c=lKUupU(6nPTgC>zI%|*p?2~r> zaqR16?y-Sc<*gCFhYG(lu<&T!8XUzS)~}G zb<`!=)>_S};}Rxu0<%3zBc_FyL}|s)ehCUSY#OxPmDcc?SMn?Z(jTSmOMkRvPkkIE z{@mZOTa-7S7`6fPag_SXoOe`j#Yb?saULcB(lJ1+86pc@TO{`ITi$h-#SfMEP4Fk$ zLjX76%}oKLmsTL4I2r2i7|1U01o+T@nvn1pX;z1Yq|evw+()pSIea@dEdy2o&M`Jz zsL@ABK zDtfLGD&a*cm9TpszSHjh#oO%Er-&i&pP#oAj}auRw%7Uygp(nNk+vHyAbg0DDgJ#O zp~Yhzh%F)%2>->7C8Wj>M&i^>rPL94N(#pdbB&eeEeW12)E2Ckt6F~aoZbI-_t-c5 z-~$%lRkP#-Z)l(qlprRHT+e|6b(G>j?>YcMRY;6A z{?g?o`{IYcYG3<#{4Op`T5@?W=7T{LQtnmyrRsxMz0)dD2PAe4k>QUc1OWCV>nCyIl+2u3vS*$+8@w@~QW&Oh!4{eqFeoWYP(O-g@^z%j5`r#NWzb?buedu2>fc09RICLV%V6Qp_r*??Cz= zkzcfkE9WPL>tQo#;-X&Vqg zaThN#i^R5moLTjEr|l1Z>y#}m4A~wDm?bnw^OoFn<_}B7MoSypZ%2ZmiLz zh99-QS?155&f8xvx$Qx~!3kWYq9K^>Ze zm=9X{MA~Ma%v;1mp=KNz3sjC*sH() zfY}s5@6j5_@4vzNOVMjVI49b8Qb@s%rKwS*voAQ&I7*~|Z@ zTkM_(58#p0N2%0-<<8fJ;4^@ zq6T_OI2>@T8{65H0)WqeTpEQaU~n~k&!{bZj9v2<3TOe;BpC{dF@m%W!XUyVUwJ1) z>bMBOJG9qSZxL8Uos%L%YtL?UMTpI_UtX}m7Y1x3hl+MI%wRgbJsk>W)bse&$L4`= z7Q@Pzz3PXC>~BBuxLtTOW83uuz(txdNqeGMq*j($)G}kUtLllWee`$d?D4;t zwcN~WZLp9d&=P_@v-C2{Ua}XE$Q7#-u9@}NFcXEbK$KUL%GaoYAoH$kN*MFA^vV3t zjJ^A(-(rb7@fhMMDJ7B^S9pXs>V1XKvYP2j_bh{?Kh{fC zn|Z2kFMRQmzmY{NWDz>Pi7X@RN13OYTE8o4jMpme`lMv>?l5bpss& z_jFY)9pix<^imh5Yzfma4Jrs(3cYC@gRI%-7wq^K=WT57q}6aoSxL68#*T@gvt}55%+F0j<-U@=soF7hHn=jkp|9ad$@<)%^!pUi8BJtXgm06sh zgZU>|p6Ms_n(PB4RH+7Z6a|UNB!-nIw z`>t_2!}h?1Q&lXOH8&F>pmRi3kmoLie+gzNdU?+YEP(q{-W8l ze|y^QVP=-O9YlmWD^g-FT|ERe@s7jL;D1Q;sJ90yw(lERmS?J(CuVl#>{X7F@fR2@PxNg^DBwDucXEgU8>8#kdrzV@obIhCj4dU zQH8-JhgphvhuNFocBj4kbIbOT-+aO@JqrGu8e^;0{VXUAI>E+|h6s75Ymz2(Oq zwuip+Zi`Jq{m_utA@p^*-J(WMNUVXjOC9Q}UCL0y9W)J2x_;)9LQY8FpPNT0QZSwh zUK7cSbvyIXCHvU#eZ>l&xzCbIZ?c0qqAxO|Ow=(p1h(2$O=Z;aI;cZ@ozch8)*z^f z`Rf>CdZr=X44W!zIw5v@5T5qEZQj1|A7QCIfM$m7W$Oj!M0AC?k zv=E7WMSnnHxpv~%347+VIAbnPS`Ne0xbRo*o(h;FDl9_}A0=(_@910Lh@?eH0w7t9 zF)&W>xjpxy)neO8ACg>m5Os7rT34=XvEPXwkk=qiO{8pS3ilHt<<*fw)gcnf>_C5F8Q8AuwC&{48=Z};x3g8;Y!1B<)C zsNjslxtQ8u%^rN$m@Uk`+D`rJx)mw~4CKVV)Egv#?OG*}YMyOoHJg+dKn7Z&5Y2I- zHfxb$20uK)Q>_U3oK+~Q-hUs1qZ z@hH|()u|*uN)8}TPvUx1!ZBU@-%|6qto@mBDR@!%?R?Ji>~WCh+Q{qT_U^kLw#y%_ z+UI}wGOmNH^;6%XxMzRD9{Icb?Sb#Zo$(=l59g^nvv!s@QfMyXzGIJwc?d)7^iVw6 zg`ZF!Hyb#pvvBSgsxW?R3i<>O+JEu6l6~UWp0u-nxorLCr>$OOmX9@cg0d8X*_pG1 zcEt(cU%LlL=#nZ{O-mr$NSqP~^l=+AjuOB;@eokAEVe)oykfxa`PpwaBW8P1Mvmkk z^fKy4E!9W>2yqk|Z}$%CAt1Q&k(eh;gXA5G~082nN2p8-z%cWwA`3G)tPL z_0c+Dbc_H}+vdzVNRUx(S015jZIje)n(2tByDJxJ%;owF>%A4b>y`WL)?cOe`x$mP zuUDahff+TZrK_VwxTO)fJ{THoD^{z#e#W+8DNfyDdRW!)?JTK74H5h8mH4I|znr#U`$ldef zG&)g%`jBL#=mC8=FBkElM~Ix8okL@hu)YDdZW%#^%NDueS%{tTVysAQA1*dB(holk zg~`m$Js7yCg$pckIHIzbnjh^&CUp`A{7EZ+Ib~n})0%z$51HYg8$?sbPV!7AWsK+) zi0lOO2v5Cu&lz8Tt{2e=NQWR;NYK*izk)5DLIBI+hB*qu$@9`BJ7ROUe8pb#Pj9i; zyys3!3I0@}d!1zxk&%*d?_TJwb zwf(PRLpF8-tl=FKvq|728XNNIHhS2-8UV(!2uHmPHOR29`t4ZA4?|4OVGbqYO4k%1 zZescgW;yGJ{%W7A<67TceQsyY0^w5GYA}NZfhCd1vMXHPP93>y$)}69cWM_QDKX+= z_9%i~hhRFJan2#+?4_+iK*T8ELj?Cj@66dhdiYxi!F$oZ^2bLAJ3Vdv)trrIh9P>m ztw}%x$27l{f3Sx}g(NCKjToU;L8Dw%hlWO9r#vNZx)d6QxLtZYVSoCwU$Z;EG-hx3 zu>+R9XV9|jGhT+_%YQ$Ht0AlPOUd4Qtk{UulDwDMFsUaJg z>i1WIu~ws&%Ek$rvQ*x>zAkx@jlu~0Q}-p0OVp2X#~Qx&N|2BglPlw?y>{l4i}vUL z&ljxr+_a_9d<-%dCyW6#25t=jT#5+4;(4!@SJ5`V;IvfBS{U&PapfHfPu~#MStv~WMJMd17{Du_%2Y*FgT7|=E-XXK*-@WrIAb`NCiHCx#u}Bpn zSI#Ev*yClpc!bCo2&NL++%p5gfT;#q@No^m1_*gY0XP4GqxGi6f?NS9(b!ec4PLeb z`^RkR03#ZHqxnIs&a#z+zW>L!Bp)@m4RK2ELLD}dR#FBn3Byk5s02r$8v+ViZcJ%iy+LM3v z1^b47aEIOZj$zBZ=`xw4VufikSN9o~JU^W+EAPgtM5}hLmZx__m_Z=~ftWOB{54lj z_6A`F6xFd+uB+E&cAx-2vBVUrVa)&5TJ~TJXh#f;IQytM+3A7UH*f2GZ7e{2CEo)MhyJ&Ylvfnc7%dsNWV-Txt zsKc1)P9*DE0U+wVSiN8iSR`krhi&|o<97Ma=PbTB09vv`7zkPOc=`0Uq`B_wBbq8~ zl@K5cXAlkyOhI%jL~(iHGZ*ajZ=qqg&^$0Z&aBI|0FAd+)<*f=OIHU05d#^c<-wtB zmf%aT%-Xm8tJm1MkJatNzkbOsKNGi!Iac=!>?IJ?>Q|O5f=Prr zv@|I;uaZhTM?Trov}I1`?D1beZ%=;koW1`48nfG8M;_DCC=iH*m<3vk6yI0WQN_=@ znxrx#Ax_I6Vzn#7LX>e`3I=uSF8WWNrS7GHS;kl&%%54kazX~GJXf?&{imnwu@4@% zk;8AbDSH@=00z1+a|s_Mb}>}g;aD2(ELru6B;5dsXJvS(rIjRW|AMhrLJ)gxF?QZ6 zeR-Q>SGHGw&jEYr2lrX+)+LMMr>)i582izuB#iLiOIHs8flYmYISa=sSSE)~ux>G7 zXP(I0;m^!kUtvFx#<5g3BH#{k9S`fxAZT*Zb?|Q%0MruUX$@6deC)CvdYCPx+1*l+ zJ+%Q6{tw>7ZvMJD>d|2>6~oh-<8qyWKR9LwUo&mpGv{%0x&?$pLjcie&`4S{q)y%?Q}RBu&REiRKq=NuV~BmAC=}#gC2J*Z=!@d*%K6xB^nLPUVb? zI%_FFsZDeJe(!4|2ngzR>r2jnWAd}tU}vrWVBGe-*X;Y>9V=P)pv8L|A* z1S01cKGMN0uwR}VRrUdZxkoq9oMhjo5XJr2{C zTVv8yBt&>5%yKd+-z(Ak+A0LRkHL)+S{8+K)-tLQzPfl6JB|-MXYsiSv^tZ(99kp; zz?F;}Gk^8#>cy42oqn=@{0QHQOfq-fowQvqqixze0%PntYgmz@RhBPmYb02AdK;VT z*VO`mfLVk51YXA3kj5ONVSZPxL)z!wHyj7Uqv%!AgplXLLa*nIKb@ zRAGxzELWLvplD@nF^Q1JE&^<5HD#wiy=4FK$YXZzyHoZ}|M(tD9w3kqhFQeO@qX3% ztnyxEo>2+c;n)C!=ft_=k**AI*=$7&SzwbdJgYF`z76CLwU%kyy`_=-Wt6H4+SyETkxKUa9z==u; zF-&o%a~NYKiBwiQnXzY{K5waoL9_s3moiHU>`(orGYPZmGadEie=TP|%H!IT2w%Gt z;ZUn*f3u&tsqhQPguv>m^&i_!9n# znB}H$5q=1a1j&iV7Wgc}`qOln!d?ly z61h+>1Uy>>y815*BTd5T8B1@>H&bo{ta~^Il66w_Bo)em;@;SK}!adj-c?kgqR!|S zW9&vIv*^*g@b%r3u@d`Jk1!+9eedt6(;E!2^V+g;jl$eLs{E=D5Q#MzjG)r&3IEm4 ze%(>%Ml_El+KG95AR|gR$6hFO&AAbd| z$}6a?!RI*f13W^XeBLuQkz!eZP`)!qQ}!4C<_Y`krz`fYKlC~qe>*~8pT+J(}qbIK(N zB5dIIn)mLrd*5@b)0Dz8wWr=C>&K(sst9rbEv-iL=;XT zrT)s-E%w`S+ckGLaj9iEB*KU#r;yWKR`j+AIQ=3kmo~|tX>)(Ox7@0^T_&hM+a>L@ zUM1$i!te`r$2*7Zpj`_~51?*;3z?0{ z5tK5RnaKMfEg^#mxbs(da0LNb;ct8#a9PdB7DUMOjQqS|q%di50J4U0^A2kmwSF`W zL>d$;SUN?_jlYQ7m;c?86`#o=b7Kijo?;YAf>sc8D2KK9Iec=pEpe_C>J-g5gw<8t z2TSQoj9)wfU@EdpC2JVeMj^g2u}1Jli$wdAY@DUF{b#2>fLrN9_QoGM z#70~ zx~sxfc6Ar;IHbcoUDa@GyMoq9&Fn;zj&LE9$CBd-d((Hm#$NM=N9?hmnfKk&lJmI0 z6?P#A^zmU{iqRjz)L6$?P#ySVonOS)XOu5DC*~e7{mQ_vE7e@y~zG79Jb2%-I8mwL=5DqMQYTATVk9 zsSe}M(ni_jslqZ}lvOoFBWy?nh}l4XI^2}dLy605L{u6+V|!ngwQv2dms$F|?neOO z1*%Zi{sRcanvu%y!rjf(wnpNqrnL4~(~aI~69iVFB<3a@4}IwSTJT%GC$-s{9eb*5 zCk`)LY#GZGCR{<_m1bu(ho)@1>U0H##3MY2k;G(hm9`HN68pfNW0pexlm|bId%y{E-*z&3o@-GZ?8piOR-|&Pnn*Nj1tKl2{|DKe`?ryV0^W zs{743ihPJ%2+puf;H+(`Q^P6$yzzZ0d)X5?`^*3LYjzyhsiB!e*1z0mgQ)vcxEGdT z{7Pbo3b-Pd!W6EaeQ-$$sIz?5+L1t@p}Fc)X$|)0@5L`WVNdMQk1 z1>BGZAdPL+#pmkwl}|0%;`u=vl5IsCK|n?z9)(ixc5(6shw%$Xr~MMVH5Q3e!SdYn z?Kzt`2rWhXq;c+KRPXqS22mKly4#JZdj)_7v^^#}lByFG1OQ^PT52q5qxTNju_LD} zx4cJ_C`V?O4(L4ZbAP}4kvD-#O7Z1m%+hjf75u_yUa(6Km2CGu=9z(ov5h&GB^%KD&PY8Yj3vRh@IbCB!ln6(hBHCb#B{4-BjFWH?5pWoytkLUD7(coSSy^ZH z&*I6l%N}^|y_VR^Tf;0n5c9WAd762_{&`yM&`4Jb-+tQr+6DyZ2rV7VX^Eu&r7eca1-Op@7Kt&?c4m+j7)BXm-&$%O z*6UPD{dPOkvZ>j;7=AO;cYkh|W_gcDJg%4X_|!iIB+l-aMh;KgvTdYcB)GW3HnA@N>R;X*&==fRsQOFhVn2`nLkzV5To> zIrq7ueew@a+v1Ti>nrA5a3gAk+g|CJAmz5JK>H4ACp@;x^?KdYoKcz&8qWGZV}*HB z0W2>hF51W~6?^Rujs5@Zy=QP`S#sx>&p&t%l=ofjr@PuryO|!xnH~3avu1yAfRNQoHn8lG+)%@x$(BPxrK+YE!Puqkw`p z&p-YCdENycP$;0PP!7O7z=^E+P&hEc9doM(5EPV0Ft15|_jt8Hi<=P4*TCZS=K*U3#r%yShMaf^`cym8V^TKvW_|7X8-uO2;-LQa8WT zt=_Mr#}?z4DiF5DreFFD$J-0tz@I~!_G5}WH;uV%x31KpPOHc{#zfvoyl3A1BlJZ#-!Yb>iabt|A6Rs1vIN%=QH4{^hUxzVc^Ct!X_aatNIADnkX{+ z#}KgEI$=8=>b17*jK5ai6NWF%NK&y6xF?CmM4l{Rv~OG(Y0cXB2wabN{Jf+vC>S$``vdoZs+MGm|L<*ekb!9TD-RTb}M12{rX>@ zvbJ4^EH_lN9J$s#OsAvk)!)|#gER!uB^n!XSrr0ejw*^a>2q~}Cp>ff(ic>-4l|c! zyJirHJkjs+t=9L&oPG7Vdu{s5CHwP#@v4oze$F~44v=UFS31a1m05e$B?r|Wm8e64 zc%fe%1tRg)$wbI=m97|Z*wy-3O!SK2Lh6GSd-0#0vv>aVls)&4?z00g5G@Z!kxV;J z(d-XKoS4bj%*!b|`k%(_rGJ0Y(&zfD4MDOsfrY=GBfh)qC z1*~b><2iDJq)~#C()LWYVn=ZQq$>l6> z>YBO$STTRSryAF!)6L%3>XMc^WA0J|6qr;5Ac5Qd?oo>z(D{f zEtoKRqn8aY0E7+@K}15MV-l{?f+dnkZP$Z4YEP0;r&aA=9 zGGCgVB9*Ee)O`~3yl!zoKLTTRBSNY6nLKlCH8p}Hz-+zL4YAJIp3+{MA-}+-AHHvY za^{=1|J81L;dh?1&ievklO^-p-@Rae_s`$A#1Hq{VD(X+jw>UNC^B15Gb_xaLCet| z8PRHqK-T;O|6`_vv7iPOB`{>)^>O9sMvK#|g@lyD6zn;pk;ohn;bul|~4+jWxnLP5-nMtd( zV|;e7!yf$~lD7RJ*08z?C`d5;LYl4PC!WB9I|=M6Boz`1(`-|&k|_V2XnUAefK`)2 z`6|U{y{nwRTTexC0M_f}5Y-dC=kofNo`;CI1RAau5lIl`&PeZ!L%h|_*X&#W@<;aG zUrt!{I2j&GJFUIi@2PYBj>IfI1<9_3r2-w35ui#EM(xIZ!e<>~7U#xFfvouJUFIQKWF2 zB9swv4X|90wgXK;wx+D{2rtB^IM;d9>VqS8-xu2LC;syXE&nmz6*ooIqF_o|%l85w z5-ZYkn#=Ox881mSL+4udMe(E`)NEBQl+w7USJ?pe3@NNx(Z`!3%M#C|b7!(@q6!D?cFCaGL=TAOiv*oNJD^7Cc#X-Cn3;9RO-?a;&u0rYj$YP4Hi$hbshIc z%bXggYPZ;aj(4e~hglBm!7e9jg^o-1;O~5BU;2$lEPqHDI)t0TP9VrKYB~-5gjQBH zejR_8j%&ZL@ew^QI(FUgiEg|_-y2o~u#`|lztkzPGYC^A13ByOw!(cyGC4t@W(kaw zB10hKpbF8FtSe%+(Tis7uGtWRN=k(Q%L2VTQ?jv>lXm>YS?llZuuLaQAX!$e@b4B` zPXQw*<(f_MFFqncK>tg&jSiq&+d?L%tcTdtj z_uEJ8*-zH&@BjFWz4h(4EO+V%OqGml2({SyizoZ@Fv`r$?fLiMH2IYH9%*ktuz zrDGG~%oK9!v31+*)J6OLUmfH8G&6Wy`s6{9MDvi$6YAG5ZG5N>+AAD$)dPq9`5Hai zCooVJ5(1CO%LW1BC=FZzn}pFaHYtQn?fS%+eeu^Hvt6G;-9boI0uJbM$3d{w>sD1N zR2`RF1_AY$wg}4l_Fm*u!lQSiYqc+*n6wXH8nyY4lxZE-r%e}l=L-QA@8#geEzv9S z2C}=6m^8~$R9A1p_TRhH^0@N)1dr+94t1h0I(F&jh^&_5G?|v z2uYJ5Zp%Yy8~j+ijSf#)y{P#uYQ_o-Qr*VnLqS(Ic406&frcnENE29f=aa14!CcBy z^LC6RHM@s)+um)g{dUQai`kd*1c2r9o0l|5-p)VYS zf-bwO@e_D!P9|?EU6ICCAi0|r)@>>K{G$i#$U6h}SO5GiyKoe@!ik-D#_c1&1rB)h zOC?KAg4C?#<_N_rH9OCc2aGE6S%(|PN*IQts~-^pd!(P_Ks?Y!o7sAiG4L2 zdZNQFy)tRV3u$Ii19YGWA2dX?Pfmn;u6JExWWR%fg7A?s1do5&Y8@Fxu zV7&7%gcl8LH6ceAEPGM+3VCG&6Ujl&tK1+)LO?+84F!q~)>zR}#p}^ryTa;vf*Eo; z$IPQ2qy0~{+t>O(Ztr58_u}s#BN+=lR^4T}YSvojyXc=zE6_(y!>9+-0_WQaNp6iL z0j=`70OH4B++1J9FfX0#W9tdfB4S@k<3+#xV-bkL61ncBa5W5bM6SaistV4C2W+1v z0Lwr$zxXiT3k8gDXAr9sgSbw8*W=NQjpc$82 z34y3X1!zY!@8fV(eSppgBy=@D^x)F_^Y-KKU9!pJZMH43&1SJKm9{A`e^sGQV}nM> zYJMXZK?DqSlvm=aGU2zg+s16y!@btEleN+`xa)vgL{g2PqSSLw>iZ(kj#uNn;Xw~6^fnXz=%}__Em+R$C zu%U`Wq0wU64mXe$uPn*yrKwB2(F^HAb&D|nd&(cbm27+qR zj8*WII!uVI8DU&*4FrU91jlReRS99v7J)jp@0rjer6WWVe00$6`Gqcf<@Zk58-Mss z%Us%JEybPIn(SppCr2)+|23m##sZ(#2=GaZ<2C&&v|#q_n8JFeTh=$88)5qb7O|s! zA3WNlUeSEdEZL~H#?)OJG!+FPx@;$Ga>qG4__G7{x!<|hU2t8t$Z+v6a z&c9W+!PE{sKhPv1yh%v#F5{lC6rekG1kHhvt5G&$Ur9rjAU;M3Bu}Tg4+}f^I=kWwIQCjC$QC|v+ z{V<Q+Nb`>z4pY@d+eoubKXvWZ`cY`7~v80N;f3%G9YvwHwIzW>rn-=cX7n# zhn53WbHoI6NDo@6=w9lQmA}st^^-rfrJ%nQkFsiob3V1f;oXjA8G02?8n_{PYpHqmVx~YIg3W z89Vd$m~>w1#^S#ZFA$w)_AiOo`=6({}&A9<$GWeaKqBh8y2uGy}9jW~L?HsR-Zk=SC0X9EK-s zVm>e(tw+V>7DIrJ7u>yLHNv$~gk8;%<9pqOl#8|?G8~f|p+n9!2tn2t15s%Lk^hcAZXN`} z;tMba$Px1v)QJ}0f>>q_s}5{A=5X7bgQ3cHqqQe(J6~wA-+cUe8~N`#?9G>^ZTKRB z0C|M-DR~v}?^*$oYN>B!v?rzyez;J_x9j1>p&Pv$NgaAM1wGLhccuwu>@#@=k?^5t zla}q9voHL@gSMR%#8Y2Y7QYl{i4R|$vy9dr(5=;o=2t>pAURV^BP<#SKUFI>4vlAQ z5&|S}-KE7xb)%ovH&Fpe)aO`oj-DE~cfNVn&b>ZrUG;+)bGCRS%0jwe-6e7WfFtTT zZR)?U`Hv0zp)sa6Ng<3@SdNn2&5nI-w)-BA=Fz%I@>~o4R|HLXv_9iv-X#&X=$Sbx4Jy$p- zwW}l@|F&(w$EV?0MmyPi2?XJu?tVocL8rHcsB=VHq2W9 zd~i1sYMb#?v#}rwv|0Q9w0-`!AGPN{Q?{@FA8*>lmoC`&RIhbscUbpa2lH{URjmKr z9su_}ZWj4h9p2@9i^yr8ReaabOE5uHurt|nHs3yC-AAhS<=^_e?fy)=)qBuSu=X#f zzC4WI38d~`vMwy-X)daLu`KCQMupAy7zQ z&3|PK+>CcOyLES}K8FfIs$5~MrG}SO-UgLIy+xQG1X&NRg(NHicR4nz-H{M*r{3Xa zJa@wj0L_ur1dzx(K;%pvB#UJ|52ZVChqwRM7*oajKlv6L|eHlQfH(v=ztF=67 z23pV%w38@ic06IH{$beK_O;ml1RfEOx4L0hi8ZhkQoqQ)mPb;O{8z&I%?GFr^G3_N zLrlF+`d+;FEWHnP{ei6g;xkX!iNBb%Z~W_b?c|4Jc4+QddS9b~q60|mF+3*6u@@`o!l~qLXM3|V>T4&9A9!y)?kBInm zVUCcOEDPWfuo($g1J};@l96UWO7SbUPcj}X`zyIQGXKq5x}|PUf93%@@ZWycS_V<~OV^Ji zQDePSV@&ZT2w!;Df+lX*>JZR~*AyX5&XgT{+pTkG+D=~_2OIhj0I|{VnJ-ICxX5kR zBJIa~W{!3Lr0sngJ}^*)3Z~i60iYeoxbv*suaXw6@Z`E^}oUA-OsJO4g<1 zt3(FO*w9m5cIty7+0wB7thB%!F@QtuwR&BlijDHA0j`o#oC9YKzT$_)FQmKLZR2m2 z?EUPtWuMGj&mI)Ngug5yB!vW*mJHd-B(+cH)%@d-uC1?Zk^`%r3TCcDmD2WC~Q=|3n_vpP058ybKDR({|wF zyX~>(_uJv8`mJLZOrFs2Dl$qG2KjSkGR9ZeRw8}iDo_J?y=Ih!bdVV99<@gx!4cVw*31jnJXKdfoL)QLaD>i@g2*U6K zgr2k;gl*P&|6-4BSOH-16;|7m{j*j(L1H@G-Jg1~_I#?(&VBDR$%1f+n;ZxXa>3YT zwfZ*JIiYVJx-Hdj8H6rj*rF6bsVW)0hLbk>GNFS1V%VPhmBSvVy;hyZ{Y4Hx3JxU6 z7ZvZa@xNTdvaukt30v!lbr9fcEktue7GM)^PRZvVBi9t^Ob@-#WBVU}!fOBMF`Io4 z_5LLi^;`xQ=7I{py+6b97}|l|jF&;8MG~{W-X@$WF@EG7A|yZ^tTBW@>5P9FUTi|h zZq8R~^qccH^(-`j6cDz3pM*iBbwVEm^OpsH;(}b6l6rH1MP4#OMhpEazOHO)lPo>obBvyw|!sRVfoICyL6#Q z4g!Eoha~|BL=i9o2fE5&b>!bKTZ= z7>3VWklByrvIx$K4v4|51Iq8X%ULEOdh-3~l9VC_4Y z=em)c=DW;rgdp6e1%t+-!G?y7AfQ!RX#gr9b%~UoRWbsmGHGkiLfRAUHcMcjZ~nXQ zTIu~MW|2fl)Y`6~p_?HR8ZhD${>^?|?k))6tVQ3dhYR$YeD>$m+rAW_1iu}Ma8_mA zo-~+s5}P=aS60Yu%8EI*b|U!ar>&ZvhujzO6re`@z&k75Bp>RgF1ePf{(uvng^*YR zWr7Kn71Sp#8w&zW6C7uZ8s`{$wvZ^SdkB|M^!}0$#ULR78|&RxXsy4aj{Bhcf@LKf2sgc41BJYpWd6?t0!$+wF3 zo&R~vKJn|jto0{(A5sQSr00?pLL1nNlyWRuh zK5{uehj;)@w>0&yj!Ib>$XZy84_V4|kuX;0VBq`(8y9e)G5Z%044A7${)kLclkicU z-6%;d605k%6avY4J+tW&KOKE6Z+~<={=PF1NJ)~H8k@v6fr2q!r7=P{l#QEw0cv?N zMLs-ZUC$Nl%=gj%Atz=K{$(M*R&lgg<)Za!(AT1Wt2~-_lWddn09s|jR(FjfuVw8QDoCc4 zct^MLpTqFw-pBV5&J=~G!l|MM%VGnYbt`F&3^_tc2^Nu34HnhI?J#C%evRLL@D6>b z9jk4j{o$JCCW;Rzg=~g^G3}W_d*j&7W>sLq8=JstgO)E25zb;~fkah`jl zOT4o9V}n2-jONA03SYn&X8rk&oDJ^6EjTBi5Nt=lnV<<+ym}+%CuSv)W(@1*#kZ^VU(RTWf6=oRMQxHWlX+sK?CT>~8rJZcY4SbD1yFQzBNylsMzWgt={;l) zezAVZN}Y4|%nOfL&t8~+Sn+g{j$(uY)nr_w$ySPFYvF6`yeikJgT1`|=i7&iYD% zwPOBiS}==C41pK|8x#W2Ff^W(S`osB$LB!CdUnAkTZxp)Usdan8@7a5eBDDHL#NRE zD!buSa@1PytJ(uE3|fXsV3~K6Hd7n(xxgy?oj1Dhb8Q{B`2~Q$_ZvM6Qh*3rS4t?< zmC~6$lCTGUdY6s2jd|R38A4@{1Tt_{O^7PQ!>xGKH0HY?i=3h)2FQ&h$d%Uy=xe=7 zV=fwZE@bc=JuBK=R9#Tn%5-s^o5I5aid?DH`YSta{57+e|LsZp@UJdg;v6;(^Q@0m z*sz7DRf!S^#<(y9^G`O`ldtvN;_G4v#1OcPAONkA2wzurNDM<;3HY?_5MCqQO7#q5 zgb-=DFW8mbSi40tn>Vjd1m_w{^S#=?_R_c(t}dFLU=lZ*gr;quu#bQBpr!Z2?MeER zzzf1-p7R~*kJ=V7j%$D7M!a&%2mlHBFJty3(0%C)|_?fF!PwH>M0nZyaQ z0~SFTBIkn#Ni6_?7#a+2OT#?^m}EoE{(bO(C-CR1Zd|^;vRdUjM?2QD=^Y&98C*GZ zU_IsCHvLxCj{VuN6<X9#?N}%-8c)*U42uHWVwBS=Pv3vh7b~ZSN=Wc3}2j%SaO}+a?7+ z3K~r(seY&E>gH#UoBs`)kT(bcSiEB5CPxn<1X!Y#(7^X4?f#z{u-TrAHp9{YX)!#z zUK;06&z$BwR`dO6ZK$czb?!>2ZQic8I`QE3Y!Ym0XhkZl@2j4URKK-P4cW-|XYA;I zIAa&zpD^MB;Yg7qZvt>ZV~|8pNRePD<%?zlPF!LL#1Po15Kwq950ws69N0~qledVN050`PL z6w@bo5KKSO*j5C}H9j`JEQUY~fjbNVh+4FYr-*iAgC>K+%^26bwav zu@&M(E3%#>N3DlT4NkRJ-GU6gI7@G`CR}J!SW}0wva@`d%U$hOdB9473C+2tqH47S zCbfRDmUE*=`H4%{(NZNv*36JyJUeWCpg=?VfAv!OkP|FipFiX6Ilx0)+%u-Lt zInFy^MCqQETIb_s^ryGiJJx;eFZ_-ml30>L_L`awTy{QjcBOB6=n7lW<%FXmJzu zaXT&9YU%j064?PLCxvKAEqfVSj8>Phy)_7O4G)G|W(>lH^*`6NLf2+;?^)sSYxWcW zbe9c2*JG7T%_E*xq3J|J@IS#N#nP~HAc!8SaUS~G=~L4SG{21RFKgfi`>8kGQbk>< zmv+PlgM^6kYEKgXeAlD>cJSGq?j};i)lJAI_bKmwVH^L>pmmHbLdFJIbNFs(NEll8CC{n$Pv`@dbQrU6> zfQyY{=DfL>xHz4FP{#-+xjktQ{p=n~>?_*14TC0xRpoq&wIT(^(7tA|kuP<`+!|=t z7(`2d-E3s4(TL{lX4mia`7;EXx^)zLZ2DN;UjOqmcI-0)S$M zvxJ~PK{Be5c0_PR!gd&`CWjp#afu-iL*TA~K%iDpbAqO>e_N~dZf_wqv@%Jc57b)c z-B!FwFn%T@qB9CsE!}Jax5j$4)vA?FE1{trOMPT}9__GC{q)1u-bc(A!eVR9-}N62 z0bnarrL89bfXHI}KCjm|h@{mb1-B`t3zowcVE1QxY^L*))m!Hr?WIamKooJYg;_sm z7MPnD+*SV88aEnSzNtQK(QkdPb@MGeA3Zxg-ER5mKC@E;1PPk9Q{Td3_$)@Wl^m{t z*akG-+v5UgaRe=Zye6Dx_zQ&>i-e_H*yOnC7y>Z_t_uPTP}kfw=D?zF+~3)sww|3Z zRRZSRSt@i5FC!~|h)t5fZAtQ8D2Y#<<$x+$0Hw2%kzeQwY??kCo78yZVunn(vA zfk8fDTfHa(^42Yymcqg$KWYtVp1-dBc{}`5J8k6U2|NGFG22#q&}ZC2oCIN`bZwO= zS<(bZkkIe-l*M2h4P=x=65%DgQSF-btGM9O^uXxSrbFx6b*)HK4M`Y%JJ|y()2yYD zGvFV7|2^xd9*^`;$|`_kU$+wA_&V$Xz0m%kh7&KHAUOTV$TOT=Hc9uzenq1wV#<_`CC0&DE{*NZRiEnO!zBaKXxCQLB`LMXZ(rA_UcU7#6nybT^yJUt^Q? z*s`nyW%gHXx32kKn|-TlZ~oCmJN5sKlSBzE00}nIMY0GMS$D$#P(w^=k9>5W<$iu-?6`g%&9t~6C!s`6&iQ0 z_iM2YH&Rn{w{o>g07!~P*U`|Xv|LLVX*PvB^FfW14hZ>{v{jQld|W()N4I^l-!78%6H&5NduswCCY|I z_pP zd0PfMIZvN>giX-tPl@4Huz))o!F-62J+K`lgtp=Pke*v90p=q_0(s5nAXvHorF$7`=+!zD`Zxam& zDy2h4CzrLnTSlHI=JPrpj{D)(oF(JZgdLinI^?kOfwWHUA_u zM&1BbmN3SW7p>S^wZmVTu=;azR%vO+@K01!?M^bmQ%%xP2C+fb4{ih2fQj2e_>7RY zac$!;_iWA*dTDdM+cmtEm=IY36bIT-4Al?_?)U;SwR9wG`{OOP<47wpF@~*B8}nJP z)J{Sot&piKXUcwXlYB%1j9y1?t6`@NU5O9C6K_x0xBlR$o%%ioL(>WC;IB?f1oHVv)KKD_jvafu;t_d;Ni#UY@J#S#ce13i&N1F&-dO#pMm z49uRt#vF#1Y0$kJ9=@U>*H-jgUF+BT-W zwhy5IgKZT}Vx*na?}ZIQ4|&?sRA|d-03!5>zLn=*R%bt&v&P-eHTV{9fZ}*NI!s~FIOeBSc+<2d$*-X=wQ2oS@ZY`ORz;$^|R?&n{T^p z4}P}O4m{13txV1!FHXxFH%ge$Z&&R*{Sh6yEpKqwK4i;k0Mze7;9%OO^=TP}fHNS! zT-YQSu+U^BLSbi#4RGl5+li4~u=02j4T09nNGZ(BmT|EJhlFHXq3A88`53IUF*9hh zxl1ipyfkSqPJL+4o=@AZU+S_{JF0*l)NDiv6jAXgfrtST2}E#Yg}YS+sI7n_@jGq+ z2r!U+LW5_M%!NGkIjaDohnd#84IZjmx|_i0m(lpi6N-2!7y@yDmH=h+8z`x$!L29} z)Arh(wl3;h#mtMerNVM!x#fcO-DenXAFz%CXmasnh}xv=N zokQH3_lll>r@tY~Tf5X?ULj{R=mIoCcbA}`(a7V+QO+psD*jWUtq9AfDh15#NmR=G6 ziXjj~;3hyoWH8zqy9$c9X?x;@4jN0#(rNSpO7o7U!e7pB@sCIw5PdJ6*_wM>SO5qe9$j(TL1>upmLM zKt#Zndaq5NsMsri`D1(Wuivn#iv@&)jFso{wm{G5&=UP{8ln#eBHvM2{yRDzf5#Ar zA#f`opfMS3J}et!GS!o`ZF}3TrCsU2qj9NkAH_G^l&Ge)D^Td3#kNIH)&0^#%$H_u z|GmBT>7RbcT8EhO!_lhJVsK$q8B4uHcTvy6a=_xUK;xn<`L*SgBvH(1M?h523jhE| z>KM7yl_8pw3JmOOuKc8R&$ok0VNFE#EHCLC+S$4ZN=*s;;BU6 zSMauQdc%CyBnUMX4WMA>z`J58lr9YMEd!wh;WtSaT;h1C#rme7wCYIJF8{BW?D*?d zYyDcyS{}#Hl2`#{;H6=m0$$1b2oe?%7b~pW33gdBFrtOwYT((*fJJrSC)5aal4MqG z+UHZdafu;thaeEf!mWF_#@j6|jW8V1sM52vx-SaorH725_c2xnE?Q+|f^m8X4W43y zKp{!BTXpOD290o{%3W(V85-e+)X;&ezMm?o;ZQWo1@0kLm-C0Iw4TU%DH!tgkZ!2n9ifYn^C@xKpQnqZ(WHfvX*E? zX%ve<3lI4Aqv9_l#;ur}u_r%upWS<8rzMy}$SOgtlUbkN#EoM3J{h}}O}%wMxaBp+ z0)R(`S`-qOOZ1N9ta;T5en?ggVAE>Q$|Ea8 zC`?#Orr!!&A z@r%Ol;&U74qQmib41pK|Hw^;BMYG-=S?k}`YLjn{VRf%0yA+LCADb(W|C`eQ=q*}6 z8C=(s#1@rJF&y-GFs$&2?@EC&AmA< zeOqe@l=ikh^6q|^1b}E`2RuhcA`?!XXo2pwHU$!%$L(agYK1Z?s2HJE>`;wA2~S0= z|Ju-=bj|kILQYQNqPe2{c^j+pSPNncZJ-HP(ore5VQ-biL!+G zOIHwWem4GyArM30RzLs_fsAeg`v|2=JOKS^gnH!E+d%t#)(;7&vMx(3BKI~LBR)&1 z=e#}liv!kk56mAgEolf0At6B~Qph&sf)A}sG|0!T0L^BobIWT0me2T?uDNNRtH8ff zE|E15EB4xO%`SZ~#%#6&vqYk90a1e$0~*uIB4?6vMWn?H-^JqznZ3Wg#o#z!-kg0wkzYVEA=6)-WmwXYvQmq*(#T%u>BzNyyI_oUGaI#e>e})G!0KH| z%qwP|K}|x~3q;@AFdBe!ILXWby1=nkuVRay)p7~qIDwUBV9|AifGj3FIhIV??cDK8 z_VT|yYL!d-?ZHZy4Ls6ixh@!fbq1nBz)|9QYkr?V^Aarw1Tg9-Wr6wMWMUI)k3VAw z#1H@i8eL`Ld1kX2>)JuMuc4&Pd`RG(dGw;3^a;-`9fHj3NfuOt^OrD2o+sMhn7v_p zpU&9N{};~?WGqSh2-%JjAf*t-NwG7&DOxtDp#_llQCzMLfp`hv>ab~?$-$6tfdR3q zSh$a$p0}xUCDx~Nmdwb+G%n2$5K#!5h9YKwr5-eMve02>FRy`0&UUvPCWpZN_SPSd z+n@Zix9#oUAGX>D)H2&a#xCjeFyl#*qan$9i3Txa%Px9B$s$ zYH)Pz((9B}RGv)Hw)E`H{iPOEwC0ajPFru%b{`xhNsx}o#g5{O>)N>$MNfxpq-K3G zP=$WXRi=pXf7!nJ+xJ-;>;I)(%?iXSs45(*k{D^ZRffh zSOZgBAr&{4@$bN_!kAfPT(^3OO2c5avQ))><&{;&RdZ4MrI^>+nh#NoZkkK2k$y8e zrhzGtR2!~-ew--;;erUl++zpo-Bx_BU~m2}NgMfo*&h39)_R^ukcE*v-m(k8(4tNw zs(4|@uqP!~OgG33rbzV!S{RqaZL}jX?(2t%O;UQCduPTFX$~`acKl`=g6CRi3p@Xkf0`!#PDm z6)++isJB>zm1h;=$dyGeO54-K`CxWmRaRAhceJa#x4@c2eP2uV*+g>8ru%+qkAJn> zp8JiDW0457VEWbal(nWhfScR{ff=%ZQv#L?XsJIk(Az7YzIeo;zW8&C?ZpDX8XYe5 zkVkuh2*H!X1vCJ&7@aTxh42j~=p1f~;gQDb^%Vg~Te#DO2!7{tEtX3lT;U@4;frT% zx|p#8BW-r1ZO}4%wgG%*0d=yGK~m+4S$9G#HDAyygzBhs?U8uplM#Faw#$P7{wpG~A!i;i+sYP8a&Q?cgmiVgKEx~L_z@yaK zfzeA?_K?|x)h5O*_z#10S|g^atwFLijI`Zix+6t;RkM^_+WNP(+2FQb8$UMAG1|@J zLj%;16^aW5D;!@qM7`1u@)D{`j|oNZh}M&V30!qtWeluQ z{f0fgFzBx94Vr-z_AAN@KpmZlHft*;Z0xlW8yy+3VR8sO{>6hf_$Y=voyha8T5kza z0a<_n?qSA|)aB9*tPo=G;HAh07oV5<5E!CYOfejl$bu2~1OLEvNW=7pJ?O*__4112> zvYF8=wxQnkcq5GJJ9l*32Z<3>@(3}~{yCFxG{{G? zMl)qi<{vJrRSBl1TcEQ^3HVS}y?>Q=SFW&$^oQ1aXvRMMix1k4ClQERFbc%tpHp}T zkX)>xnF(S*s5Ab&b_m1*z#6bZj^_$g&_uwRJx@Sjg4*P29SlnbIgu$M;t*96Goc6) z*Y@pUgqaBC_)8+ux1kyxIWc0Vu(KF__nh7TOSAUiQ+urAp1h@U5S+A@T~IqR_(d#P zCxB!?LHJi+#PGj1xW`vrI|PJN&CFkSiYKb%Qj<^!ISGS%sP+>?zMTB=oW1uqC+z6U zC++MMVX)iVZRh?Sw&U=i4ef8WzI|la+m2=nd`@REkj=o(NI2$x>}UmK`K~(a?hPXW zIc&mnF-RG_M@x*M6}ReBFG(9wxAR!k^-1d+$XQEE+Oo6gMN4ACQE@KL4=!Ao%IjDp z97NYG{Z=Gl2{K8Tx~|odsfP#VU?DMUi9P4-(VyOH2cARFYGd5zX03uSQYS!A8au4G ztPcXQ0I(MPFk-8dxo-0GtWBN4C8p44Su_CB;nh*;X-%$K`dls$L<8VfF{ZWaU3~zq z_4>=tM}&`;)_?SR%P(8_y&N9P+na${q?z4hkodK7S1skO3&uWup=gsMMSFR!Y?t4h zwTC~Iv+a+xTV@yPLI`IKKP0JAH4{n5|F>zzvHTeejagx5dHYtlWYt60^Q=`X+M*|~ z7kw52BFPQZ_ZJK!26apM$)m}M_XJLpi$2JoieQ2s-&bC zifZ;fCR19+uffy{Rg$lz(TucD+hae|XHWj@PO|*T7HfiQ1(z0-E@(!u4D_{s>WDM} zsxvOv4uMzzxEid4l|u5OB>SYzkJN19)SR^z_aFc;TjjK`;mHZrk^bf~+N(8dvmMVe zh&8XNNTn!}B7p#HKqsofHUzDaAJ5tcXNGN-C4s}IyY1j}t=4fkLqaAQ1ae2Z#f`1% zP@q&Q82*T0-EPLP+4?1ZpG62n_@wV*k@VNZq8G!dV(^;rxU>lyJvwjierv>D|Ese$ z`5}zGyo~^L1gc?^QDBAT!ZKN~ikB*O{QQ`G@W!mQcBQOmC&|VJGuFSG1X}wtHgr#i z_3qAFz840^vR5XL+FPVWs4ZSEp+l;72?EYU10&^(YbkCnBh=U=5Sj}hJcmcm&!K)7 z<7Go^M?WA+s0OlKBlB;td^Oqc)VqiV1aBdPp2Un*a;NRF=LhW3pV?)tdw^dGx8O7` z+0X`0M1;Vf^a;S?`+J4)$8|v<764WQ7q}(nU!SYn^rfOrk08Ng)Wh(1v?mh~ccYrR zgJrpD^2(;%y#quo%R$g87)BMC(UuE3SG2Vl`{+un9ePzGfpMvpiN0(lf(zkqa8kf7Plud1V82ulyQx zF3E@&NtK50{v+-7nV;*o&PUsfmeklVB8s(8-qYB0IUT! z_)B4|Y7-YpQ#+gVwf}%_AT5$>T-FBxEud)jU&Y$Lq@W(C0zH!;LO`0qu6O}S=2BBE z|Bat6+H2#d?8D)+mMgFE}Iqd#Z+?%QRZgJ=lwiI@L-9cG!7MLZ=LBwpWN@gwlr#Z$|FFPw>B z;=VQv9w;7+dF*1rMuxF@kjoxXP#36QG{_e2zuHdYjwS8X5(CG1hF~qPgTb9`_WYLy zt@D14XBqfuMEYbf4D<+uiw_PDy0Y7@)`0l!3UQAj?1@|1TDW}Pejma8|(R|-H2$dImJw?Vs z>nSx2?sb%^dpzHG1+Mn<+hz0=>Inu;n#b3%2T(vDgah_VoTxDS(UF$67SyMtY5tYV zcHhUlZSY?Dp$(FnD>5q*g+O)63~YvdX-{(yt#lPw=^u@O(uJ#!Th@vG@lr$Rv)lD4 zauscQ=Jmo~*N6LcHw+F-{7^IxMcoa4)KD*r!MP@hIP+QAm@wINgc(H}_+H)K`sRea z`|@e49PMYB5U-RH`YM*J5+WMZl=5+*MJ=Ve7Gj5S8nC))%nRB1DKzwUHLlb3x}yS< z$KKVFt+>Lrja&a-+~D`7iOSb)eLFIif4pcpmJ5=3p4&o2XbGwq6;`kpsG%a4{Za}$ zrKC3OY^1yN@ueZcR>LkqbMUb7#Y@(Sd%|>|88^(gK5Oa1kR?ua*^mD4vVG^@d}N8y z9hM@wR}R<3iuyyhU8SU**`wK0Tm$)1yX&J~I6QM2IH#+DrqLl z>Y10zuvhM-ih?J66Qi`*noXT7*_+=wXD9xC(#GD$7v&N&bQpg^L9W=sy0~-&j?Kb4 za5bVX0oek(jIg_b=X$*Eam|%_LchYf3V2#AuzXMkr)Lv(YHZ3rB5>AwU6-w`J8PA1 zpTL-~)3)!!!(d;Rb?-zw(2p{`lR6N7i!G?g(T*w2w!90<2nAKy5U_-hR(t|NbF0X> zP}d|i2wnK;;O!A;%Di8()27c>?A@2n+T0jc4HfcwV63P2ycYS{GpYJ3p|Nn9$q!AO zcuopi3K=^VY7>_1p0P(hyWJlB+-|%iG-?AJyn*q@ErGz67XSi^H4sf-5zg@~8P&!U zHga;trY{$ecyZaGh#vT*jFrWq?5DQg$4wD}0u-BJ8Fd4>0)cUZY;v%Sv7cN0i(ny% zZU69I8~jq_kOnwPsJ;ym|j4lzX=ThC?{QHY`^u-Z7_a@o!&gHGMw!^xu z!wmszE+l|!j0G`8u+0CwYOg)oYsT>CSojWS_;kcyye>^NOtqyZ=3K>7pw?#P`LfMH zmx{!{pE}lM7hCG~Q5SOWP}wp)#LM5AwuATg+nz&t%kBr?(F!Q`0QPf8y}UPLp-LoE z*$~vpaE4xujpYje7S)rXos18$ce~ogSxfv|oyxnV0yl~KVJpd8wrr-GYWlUKQLHshT zIVvbys5F)U1mCS%gjXJKp4bvtk$_!rNzzv*NJB9{&RYMsX6&sOPuTlEx@?zEYWBOs zdTafJ#>W!{0b!PCeNy;~`3ohT*G0h8fprpyVC)9kBB^SLGM%D*R9nN&fS`jm#8N}0 zSg^wQxJ_KZbuKq$!)&L&Yu43|Htha{ZQC<|?Z8g!+ncwJA?iR_NMXxRst|Iw!dQ@d zAwhn8d4$1L$AGa`m3t%6Pv1`2_x|HCd+TqkR*&JtfAldD8JJ- z03o#QjpLZR2;KPYYu>4OgGw~f5W#Lt-u-w6A}nQXnSLygIjoqOvT}Y5zv_hD^XLvc z_>VEP+S6m10bH=i9u}N7N*G}k5hAD}(dB&}ti8R;>-t!}2EF|EbyXH$d<6tFUYD0> z4D0xf!&@u{+mbq}XR&Zx^it(kOB8T5Bk0%3H>d68?;N$cZ*8;Dvn(Z*yR4azV0bXtb6x+x3|Q*G3)2gn!? z`VkgBi#CYz<)_GsmzVN%-?ZL0~BVkPfGc+Aeh!J+yk^ye*{A0-*ZN?wW zjkb0XG72ljRH|S$M(B(K$@EyKv;JQ=ov?YQ;ZG;94JW^-{Zk&l+z1{Jd+XI2+0>W}5-&OtML75hpDDl^y z$149~-NxQ4*^A#eWj}u9v=y;4X+O_3wO(sald78d{xa@MBo&I5G`V~xIkz~5z-8x- zK`3poy7d8qwBrhQBixoNVY0#4LqaT`AT>N!1U|?zgrbzzI(+I~XTsCb}Qzbina>U+!=cJuEHEy{RPgz@H z7mFR8r1I9xKfI16J|2nF$KBOmvEG1(uF$QrG0;*&l8B!3Wtjc`v-Zhff65+wq1&oC zv>CuPk!W`TDl8o|4g9M=CO&h65ZLkpfUAKctOkhk+EvkvaAtbeM&8HRY`ExwX*6Th za8uDOTIt*Hh4%<=eDycE+FP!5-_>ip_A^z8t)Ac9hN!!AthI=t61^hd4H+ASvg3a}W)D8U(;ofOkY)FxvK?Ypf`ODW42p>?2m#mqQc=so zjS&NijwTc`E-p780jMQ;A+E|*Ah#B;b#Mz|Fh0OYV6;O~vN z;)A-lPFH9NPU9>oKR%vUDor4V&)L(zy2Bp)Db^&0Dm5%fMMZ7U%zuITHyR~_KG(mB5TcS4fiB^?X?50d@g43jJO~jYve--uqajMewCZI2Q=q9tO409df1@6;s|?o&QGBK=1_w(F zj;DI+N-Ynqx#mx2_B?{BRJ)P}1=qsx>b@Khy`l!k0>U~Jlr;k(fp_uT8G;R*nDza( zG)%ryvD`!sEf~ulSoSA0WEhSL#GhjUnH-n&ixM~+(8?z7pNv~b}aNP1KTwhSf$uLF3TFV8_dyrOF zD;fr?l`u?KyJGcoAr$B8*R1DkV2D?*p{jMmb(Hlkp(N$2tj-i+<9kshERl^r5gld| zWeDjUYozmp6s_h<1XXFbdmh?m_x#Gd4IU)936a*U1!CT*86CDC5S|29)@cY9>jl&d zVTX{iOMOye%5u8Q>`KOCB9hEpl;<4+tf*z&1*0%jr*T;i1PTCAvvq0TH16umxRb&; zse07EMJ>x=&Cf7YRJFc<^2jBjK4+$%5eu@tT6pXZAo?+9+k)P(cMpW~y(UTYl z{^A-Hj06co2wqh^m+_{>0e98~?locx)Jv%JRT-13V#j$KYyHrE;x`BFQ$K&dr5=_* zL1k2}ZjHiuhZcl)3HvL5Mr~jDY>qU z?FdFcvb+UDHKa6-)*AGi0xTQkCFHcVSm+&fkQWg~XWQOkavfCQ5*c0ADjAzSH*0T< zd|=->e#~|pB#yw-d+h$FhOB!J*L1*0vSD4dnj=Axh^#i%4Y3oU(o7F>1>RsStyzn^ zg86C00evfckwgGFI>qHiA&_&Pqp?Tf!7gG6S(z7Z%bnI)7uMpaYg_wCs)-fN%!d4dV;)b$AHND~@EDFs|w zQkFGn$+`H)&49p`7XSz(3+BpACE&jlY-v$?j914_joI9E2LZMegBq0PIOD*Jqoy!E zE_W0Hb$1m~N3cP#1D$RVZ?%lwButx$pNPCBm33VVB76Etn?F5gue~;JC;!tK zJ8-1O_8sZ4{(a125Cm!mSn&l#5^2r&acM$rsw`x}8QFr@G98*!Ij>Naz9B5gSS%&= zZ6X!`fXWRQnQDf)2lA`hC`t##k;n;b~=+^Fz8lu^^4|U}Q)CH=g4U(}xfIg`qU$0p2n@afgM_pUP7o2aHRL$%!V=di zlA@w4q*%vKkm`78&ak=!mi>6W=Vps)ReOT#-zwmISY_Jzh{!9i>}!0*@RvEan&vzP1>n^?ZSo!S2pfeJg7=32#l#3 z%X<aggc$N zOrVqTOE&!8S$qGDwDla$SZ;6CIu2xQ&%=YZ<3O+F+K43&%H$9p(J3PtXeQ$_W#ei7 z6@T0S1T-v5NZ2v}Oku_D33}AGxT+a)SCwu0jiR0VVAReYov=&q&)LQI@gtw>BB)On zIVAf%eXs6IvJ{iROGKub==LxnP+}U?)1@8Yiv+^J&^*qEGkuXp9dl&5YU=||UG?;) zKY>on-!UizL=OqFCG!hB28tNaPPUHNL(lBBPyZVB77s{^20RI#WY}M5*(D)q%wfFM zA$ey|MOYpeQEaU>YMKu*sImTk{{2x)O}9bYHD?IO8D-8BeSlv076b3jLZII8gNBmO zcbbhz00=}$bVa_}&GaRZbNU(LFBNZFrO!#2)_-MCC>s#11PdcjIP*DRl^JwCED2pY zhT^|vhP>@XyR^q_aCgCm9=dD;dzf7gq%FUjpr^f5t=Q`eOaH4Awpv&;`~?xx317|Q}Q%!sEdQeWh1 zsy-JENY|kD=xT|D8>z@^Kp@wo zA`tHV#GHNdSNm+&r^qRg#g#HY0aOX9ByCF-jT-m6{1sIjf8SOJY;6I+aagN-S`%hH zI8X}WYS(P!qe;t?{g3&7!?IPFE8!e8p+o|NiPj=^A-I2{swCvP)LCoaJ!73a zS}eDdnCp*pSkFBz*0no_%|M4`JCFieA#zug1_Jrkwu4{CB`L#>$)UTy?FWzzW9`K#$NFx0o+N}FelYl-gr^H>nV{6?ndiyV!X=DYhj1h`_@xL2i8-3hQC?`kwCEGHG+O~ z1Dby|j=O-NeKxvEZcCxh!gp2i&|xAevX`~u^xu!MU}t~A`iV5yMcCo=(^J+qKvuOL zW}KbW-$Na(C6cy?)o6wWaimVAlC8na!i*F>1Z%lEpOAVia=wlQxGd^5BUIa@Vy_X*MnRippOM!LTSCt)^Y$r@4|C~A-6mMmA2~B& zqeq8qVzg?b7bg+SVd8V7p(Rj{k%rfSfaO`RlvmqeMuMBe#+!#yFSOm;5)L&!n=V>% zeDQ}vOiMefmBzy&fBh@1`d6QWN0SK&D=HF$n#)?_GsMYkzGLbBTH|ZEfEmFq(oAI< z71W5gQBC1h;exXmzx-%YmMv)wAM{LLrgzgen;o&~wrM-`>9YOA*B-FmXGl%lo+ivN z{GMf(IzKzI=?{lKk@L?CAg z{8N}E+7;L*1Y9~K17MvvTpNtztL|C|EGM@s^t1#B$Bo68ke72*YAjGE36EMwMLmZT z`bQJv#1NRX9C1`Lcnyrb_P(|Cw_q=@&HDHE5NDvxx_9TTZD*?`+YlZb5)6FH?GmMY zsIU}OWBpVHZ#AESN;rsEx`?kBs7it$R;VSMDeH*VxAh(Nh17|a7?{&reMrTWZC&q33^t6p0pSGC`Wt+Z8xY}tH^1~0H{>S`}Wq<_Helqk&3Z^8nTkf3^!{R5e zLj!4_niv|ZR)zQULpppNMR(rFeb@1b09rLWx=9ahDr+(DP(jlTjotOMJ#;a!^F~Fu zq;C~!Msp%lTJLvK`6ehxO#A=iFZfLm(CafBv?Esq3%g;j?>vlR@vC}OT%Xbq!u&-vl zLns7fH*oKS^=yaJ64vnDZSDaSRFTP%yhjgG=-eXX2b#)tmg&CxICZkp6Z?92cj zJxFYsO_qBlEGUTWE?6iuVp1Vxi)5WYM=02H*zl2Jd!8H{=TGJB@<_$T*vhlOuGGUu zAlee6lGmt_G)C~vyW1ba7DBqL#r14GH)u4xLH@C%ZK%fJmtFy6Z$z62ta`^rdUmw9F#BLEy}s;O0G6B0X}UrC|4bGGWhQ z@VDm^T-yQu<`5PnATtI+=27rUeJGmi_@ZYwW8h+2;=NlBfvqb5fODGNYnCOWA+XYs zyM7^Q)5i*Az*0!iKpfW?L$|({;wRj-5RjHAja746ngBvY*DK6+2v_Tjm{u1FKdkl9 zWC4Z-V;dizu}dfC?R09yvUwQljx(0QSgN&;h?D(E>)nGL!QM{m$FQ)q3$KF?oKSNt z6tqx3yk7jiG5K-^D7nCKw?Rz9%#3!pkN^Yq*%p^L0~a0F4G~83Eqbgf8pUVT(GR|x z1>hyO>Kfh4`#Jq4x*}^Kl1MPfBag;J)#fptES@ab<;zocet66#M@lwx7B%t(1dEY` z<>vENoY`ST1cQ=bCM`jlKs~?|mII?tTL(#L(wcG7kc#}okuzKrL1nJx3)$#2m*oOM z^Sd=)cem_EGyLe=VcgWXwOHfLe?OqBesv8GI|`-PVES--TBa?q4QW^Ei6NUVWARVg z#66F7+h_l?2W!LNjD+tW;5qq6ow7kCSy#1zMer0=Z zK8d;MjlPW)dQ9`C=P9;84W`c=2h}uq1SMA{Lgfb#X_HVOGUprG`jquro*8R#! zw~mqh@XRWLLe*w4oEm9?$+g4u+jB%9gi#J$vNnW(j_xelgDOFZQr6x>n%ZuJj#i$% zo#(PlpddC*m&Fg+SY~%3?#H9{Hq`cuG#7O}F)w@|sGGGBQ4f7>AlAGZatyF}#pJ=zashUj^Pk(NrY?n!?TbLxR>=*%gINos~L)zC4n`F(tP?mUtu^xt$ zt@6KbFmG8YWZ~>Q*=-=yj));cWFsEl@9UsZF zj`piSER3n#Q9JnQOZJuj@-x=`1UErStNB^aiIJ%hmYGI{_fsDWsU+ZOLX^gmksCFkn`@C_cAoAs~Y{aVRO% zHS6{yEF2Sq;wKaKz^cTjQtmRxaW|j~L(i|{kZMUWgDy|QTxUp1#WkAsmUHB)MGcY2D=BRG-QK}(z7uW4xJS6n<%nsS zMGGPIInVMit`KHrlM|B=9_zbMC|RLM(xiFT;Q6jHi!YTpMjBat&k`tUj%|DjJDHhz z+j(I>9+g?v=wag}LS~n`P~Uf;{>R7Grr;VH%vd)KrFw377Q{k;USl?HB z1Us!P*JT;*3|^d#S--`|PKG_hIX}pT5q`AUkxz@bRDmp+sdJv6}j{CMiYu z*678%`TaM0+qSF#ARLrMcbUA{B2H3GRm)|&^zN+X=MexJBU9ulLe-TA>&izrJL1Ie z7a-s>Fo+x3X9#=RU`ArzzGh7l8gW&Mm{agK*NjT+EC>djgs&A#6Fy?!4lYV~kT}5g zs&?kEoP&F9pXNC40pyGz4l$K)^%R-`=DB$^GIMgyP(J%bWv*q8OU9+j;roh-{{h&)Lc zhK&C7W=R-yitDm^7K2L8ctzSbk1$YV8*b-as9PESbe+t^l+91=@{rr81>B&pq237l zFrx5!2o$G&748 zX-&UcnJ1Xpqrwn(68W5O(L*2Lk$D>)KP45!F4=a)_xAg ztQwi2^D_BcUUYfTVi~w7RAU3C&KRD{dk=?7|>D7+k#y*T6bq66J z-ml_o?k)sCFWl(rvP!pa3K=-~=Py+?FViBwu)<}IacAnp3CI~Q8& zSL0{k-#V&IcWcv%g95sh7%K}*tkD(;IL?=OhbcTFvM~NS+Kn9W(3-tMz}A>eO2|%E zB{+ol$iToesQ5Do3m#a8C;tEKo%xR>$#vgf-Cfmp&pop{GrPk*xi={uA}LC=4oZ|P z0k&Yt2W&{N{|>`{gkcyk;Gg`P0n314n>J|+kVHuo$z5`3a=A@hpLbIE>grZd=1 zkPZxeu|wZcXK}$Qhb~1`UY;S?1&8ADia)!9z>#DC{CYm!oBmh>;dBv6_O5m8>Yv}T z)?Kz|q12*P+`EWar$Mqs5Ryc@-f3pWJC~eVd_%Kkz8hYHZbx|E>D_~0AJI8DJfPcR|k1ZNkH&c}Xz5 zm;d!&mY;vuj6HdD$03XHeYv5_gc#QAS( z?&x+1I^PQW%m*%%3LlcG=F+?H)(G(+e=!1l+Bx+-&mJTm+qh->Los_AU?vaFlG>Fk zszG<-2H+c+i=<0wm#v?N&mfLiw6KL!GxzK4{jXu&Z-%x0B1=N|y35wR_=&yzFJ|nu zKgHzoIg~h&26)K~tX+?BARQ8RR7nZY*?>?1+$W@Pogq1!cr{(h!SjUb4I;*;`+`8G zHSQ~q1DeQp`W{o6vL0_1?8=)T+1<5sNC0N7!P-~V4eo#vGu2ej9E_Vx;Nf|V18^s8 znIgU}*_ghQ%5pUR7u0c8oqGZB(plvj%Oy6n_-6i$cARx#e))Zp;xS^CPxwI$JE|eqW>Pwf7G5jp}g}6S%*JkiM96!DdLtulQ z7Sg$p)X81iM#^*1b5ERc0U_7nX#KXe%D1g?>9&3DAD=_?f5s|ju%y_-&=V;%u~1)e zt?8b_%kcN&+x~*U5oQ29;^@>GR%Xj}{}-Gh_Qnl%GChvIOV#QqG0iYJ-pJzg(0;>M zC-@%tdsadq&OXoWasrf>^#KffkewpQ3uUXc+xi7R!%oK;^}ID*Ae@2ZhE$_shOqm& z5Aw_QB!xHzLw!tvc!bhqqX@j6fCT&K1_0dX06P|MWfk(m!YB|BvR)j1lXf6#12E>vr3UGK+B1 z0LzBX{ixb|x8rG;fNZUW!b2QC8`BhFfR)1x&8Jk{aUznfc}Ji7fBn~#c+7vra1pZTl@?g)PkQB zM@7twEZ}3t$vP+BvKPNPWiS8Xyq)_R+x(Wgwki#O#YS{m>`4NpL>_OX^AByK9HZNx z5IE8dfatoEqzubtpK$m{VeL2uO4!p}p>y*uE_bl!cz-tFUY9DX#Fs@Vd;R?*pTD!d zmIsBn2$Kh$7&Z<9UPj_}k58rCpW*2;0!oapLoXgg_+l4-%S3Ew8Lj!(dh}qK%+mXIHR}FXG>o zp{D9xTdurq7oVB3&;Qz!cIi(WRzJ_opKX6#j`=N?Hn7^rNdTnjyV=3!9+0C3+Cx#_ zBggF#kVnQ$uYnUl>Y7#+ZnN7U2D48U|@iNWwk0Q#Fvj-dx>R! zO^Ezyx+OqvrjJH z;((J`LS;n6n__i)V|PeglMfuIo3tE8yK(-bV@Kb;f za;mMvsF=|}ubUV%VmEy8(6mDAeY{#Dc^^5lTKfGXb&sD5E&uM-| zCQmF81SjU+x2KrGh#vx64)XnoFaW-Z+*#)g2Di6ec$Mkpop(7<<)d|s0WCuMB`Fx# zVn5iZcYEE^S$fNfItd0_XJ|Q@#h@bxfvm*o$N^xlE9{N`Z~Y1bS9or!%c%;?`el)_ zQ&@)qkVGHT=Y={^b|)?=RTY1xWjJ6HK_~1fNzC10XDrCiv;+ zt)GrQ2L}R2iUDxVBAKD&lFm@N*}Zo-faG4?Y8V_aOL)^V`^wZkJbW-9ENXiT(Yby=K4n zCtt9OzcOphM$^{kF#RjF614pbZ8ZKRF&HBL54C#nV|xsNL(c$cJzukWZ?hgw7~B7a zHulT4c7}oSPkzV=R@XVR-RWAP=}Lds*1wWl_kZ{bE`Hz+THWu<9lU3svhlOw+4t-k zs$=f6k#gR%>36>7pObkEdgu_yw&z1Hz=RL(_wr3B{+ERd62%8mjLW}RpJL8 z0R#>|1EB7k%v#l#W$-dEv>W%D*7~4k>U})&Y-s_O;Ko-e^d!V zz0&=0c+HhLz)+;27niI&w204FLIU?enMxi&BmJHD93c=Pu=fzqFdQDWX-pv5rpFB; z_-QA9`E7KkIqkG-YsGhMb^2pF`FzKI`(M3guVCCq%KYtW2V4GA7(Z=rY_ujn-Xb8D z(5;P@|Mc+3)1QdXhX4YHo&iuBiKyz>TuA^#-!#E*ueR;-+wXJy?h|@2`Mk|M!_I&iEdCW+ zgx5JznR!21RZ#lZ>E5!2?ydc|!Iuq(Kku{nG1)$cKv`>SVb+*_-sj~`6))ZKQ{Fsk z@JIos)TwfmB^_L6r*p7HsgJ_n58#f!Q^V|K(~1?W|6u{J#IDy0XIaZ>8K4bkjP{Is z4?mv3N-~hRBz}0!-lb2F=eErFGm%Ah^IXVX+ZJWMP#YP0?pdkOX<(338J;~-(CO_Q zfJ|KZ>Bx^FoIh5-yQ{o*tTBVK5PhP#!CD~t618d-co7GQNs)YHBfN|Kgf2&|^%0v? zST*c&FuV>8DHl;1l2)O!o=El-shgZv&)XO`4Bsu01{}ziAbE5h(=sw>Tb?>OZa3~x zuTk%^`cz&0V!WHsI^z>2A^Ew}MJ7~WLi11j{)3JnTexj6qx{zc-)YF!g(J8M{-mFr3aX^h9V7^-|LRg- zE(hYT3Z$P8Qibx%I_RJU2%HFJ58b}*ZFT@$fn0Vm_e)0?9#Z`^p84NDZUTbosLZak znvp}?DSTQnsM4t=;bI4TlR8*rd(9Q@Cg4dfRGCYn=WCOkfB)FafQb zXPnYxqgV$ql*psX9X3L?l3^SQMV%bxB`kugRuKijP=?(Skp0sTu_O;10{d#9ZLfBL zVG;3n&ja+by$rS)D}cr^P#RB+H@Ds|3eQ!9$=1EVVLnx4m_@AeN!?it|7!mx_IhsG z+=-$+{?!xqOTYeto&BX5YtQzqJR?PC8At2Gyldq0m(;;cB9afgEz{d9Ym9cVAmHd+ z(&%NK7agoQ1+L&=RVTl+B0wckcUH3thT(rmRFPc(%U8R$e!Xs0%v@@tjQr)oz;iF# z_?blD_6R?0maK!8uS)LD^L7XUCICXM@9OeH9a;?|p?$#3-U{YB+44~CfCx5h`P@}& zEEH`Xt6wvxdUpJYDO)-}ZROdHt*)%w+yC*NeelyeJXdY8a@uBVb5_~_W}F4y?{p9s zVn2anL8WOSFzak^R~|ktSWbcuQKCD<5XiQFAfN}i%BsV|sz-%wdj*KU_-!okL---v zj`(YgL&OW$8FO=J`8PPc47}FEobTd$cK($Od-0c#+jHM|*``l(q9g~MR;FO~+27wq zicrKBKuJ^nv}3@gi9r}qI=!jI`iTUrBRA*6K_;R>UfU8D!uFGdhf{J4Sq*P#5U*t*-_9Ry^H*HuS zo!#AJYwrq2f3GkL=-A?khRq+xo;T}(r_L|h$qNmeIa9Fe8IZsdu&6LoXtwS6M#*OX zddhzGx7Tg;#<~?-vo?)*vBENn4pVM+uqMt@fC#@pErEp|r9LPG6&S1BD#pM=3xOdW zQ)($)oU}V=QpYs$*XUAD-%D3v$G*%(7a-ULoeasdz8Roc=wq@MKkWJ02FshZb8Wlu zxwH0}uP@l8*QTw15vg4jd!H3y0rKKcgx}@WCa?0K{0FTq_7d)gJ#P{J4Gz64HyVvi z3Bcj(0Caie-V#k~{oBdFK|&kMVl{IuD2%Jn)4;k97i8Vzl1`%UjyV}5&dw}~<*nsP zBcWa!?wWbk7z~&e+1)DVslC;oh*bPaLy_Q#GqTR?WNy3YtR4c8Jm9sMZa3#?$y}e&oW;T zyCwxr@Wa9hxDI`%L`tZRiIE1 zs;PPWrZ9P_DJyj9e$h~NhLeTc{pK6;3CJhBhkHOw68nj_w^G+i^`5PBWM`qeVY3T$ zTR2g%XJ4ANQ;#h|@K4+P$*RqsV(^R5&rmXOgxlvMt)C(i647fE1jH_(`sb0`5{iMf zDSLLlZpY6q*_;3Kj$QuCRlD=iiZxkEsexQ%SG-WHf{@5Uumsr@u{$o&rHU5a(S?A< zha-~W0&rP^IcfYnYRHB0mnHrWr(B+?m%?8cvAul4?^Wt%(Kw@-iJ zw7vM7i}vJ~=gbyR4rDmD0j_lT+$F+K24VqV)jhr=EV`owf%KBUn1FH@CAh!@95&)F zbQ8qkS_bkUDsCBmp@scqdT+^ z2z^=iatBsXo#L?S0Hk|)&#j+9)ffX)OE3iWdyIh&TrotD4X}8-OFZ^=ofo+)wo(tA z$frs1779vii$pe*Ip_wLXF2>dEQPxS+f&QuqE%5 z*|DdYm7jy8FOnHjfnr(Hd=CW#AEwhmg->MT+nY!BC6^pQb@8ka5y26CFwO>Iej%O$ z#zcy&xUCf4o2s8a^FrIEtLsC;RnU#Pb2)Wtb_?v+`4>>pO`^s{qTd<-(xIXh$1tYb5eg~LWy7Pz!ZT7eS>&ft+aTX#2z zgw{Nw7b@*kXC!` z(ah(G`1)Sk?p1z<5)XUrS*|Fb=-P>AA-Y0*+Xs;mHx71@s!7QoGI=_}nO2=73I9svf zm#~@e8!QWaW!;wl&%5^1?_4#zj$Xm~V>YvX!WN3hogIN@nG?t`M$$)#Ni`A^!e@{y z$nHRk3Cq0qaIocZhfa0Kb84~Z#zR1DvKtphpBo)ChHyw=0L3`&H36Sg_CEdC&3Nbt zj*)hRFqLXj2MYbt#T(Dar*hopqaeplochlg42b1AY{Tg-IHucWP-NUVOf(M`z-W)H zT6d1U%cnl#*xrVH?(bLZ{7Y5qAIEHOzik~Z4eWA>bzRC_(Cz^(?a8u_oXXE7iH9KJ z9qdeKz{Drs4mSh>jSqBwNCzNz9!3ysa_$ZRK**{^d+{?b*&6HQ%@v8(AiK;)B@h=m zFF>3M5aS}2vK-UAIcR_m@%&sst8olM{v09&^A*Xz%z%~HO@6Bt=^mhj!$1i@#E+Q;9&ZENi*L`$5nzzK`xHk!!#7RX47NP?9p zM4=-iOInYRb0zkV@i#)?0YbnLfAVw0e_!=8Kl&=2lQ1YS?rx2rwSB~Tl2jI83VKXi zn)MICG3?x#Yumzwu6_RZKW$I`%8VU*0sPWnV!)pU=m2*!Mw4;hhuIJGe;B00qkcFn zz8z)=gubD>Tl!~!$hkU)z{3Opcx;HV7jKK`y6G{N0ej89t>5n15B_!EUjOg!+sy4# zw%B2d887)j@knbie5oEWOWixZllJ!izhuLb%Ye$a(wmVAn03+-4%H250v3BD^YB9Tl zrQi`@x*sF}u3Q?4369%MUH2kwO;Sn3`dZoVVyLVqDIz;(x*ZJrfUoWx`!icQSF^8v z{WW{)i}SYl921fg;HX)QboJLj2k7@C3_x})tIkfsn-qN1SST=#qdQs<2xCG0WwZ6= zne9M_0W2OtIg$*m;V!NiL{&uOK8+I1GhgZ1TR*;I%d6P9>(-c^W9bgC^!iX+#Av1d zuqjh&cZWZx; z&t7`GVv!f+o%EE!$E=bW`o^7|Za(^X@sUid>LBO-&bT(WV3zO13 z%y4bVbL;Sk^R#rgf#|kBCrk#hzrSaq3y>- zkv4)d6AML-T*{BSCvUPBpcy`z4Bq168ugHEf=~MP{_8jF`~UWez5i3T4BnZudgm-> zjxE>>%Oa)Tvb8(Q)CtW+a`1U`%erky00fV$Qz^Y~e*MF2HJg6B?`cH4-82s}UX%cA zg=Xl}QgYIm+0U+vRIEcG`(;kmKpJ@0E?cYqw!Qr2CHs57_o|)!!n~EwQ3FZ;G#P>T zYqcK}F7)q`&A5RmDc#mFpn3;b=y{Zj5`a-qIlO)WUxf)_fn5OopcyF7!?qhhTK$QwL@JT3A<7oXguFFxnBAPW@BOE%_RW9yBdgzi44XKQBU)b|X2s?^DC3BzyFTHG zpB}Y+P<|^@9KZu-(P40IV3)gFY@;y8$%3qRmmt2Uo3m`kt74d=Yzt2nIF6IO_!pt` z8q{-;t|wU@sH3SL#;+6wByQJ$=D)W|z(x2eJ#u&5z0;Ez1w|)Z;(2WIO9ty2T6Nw` z?^9%dCm{%zy*MY8%N0^Al?XQ9;p^@QQJ$pxpe>iq?6O20fW5O!+}FGI&JQ;1um0Ny z_5t^W&SO^J03KD96F8wOuv-Rz48}T@I?qK0Ky7*dE~Hj36fD*60!$yp58W$8?4(++p%+VcIIn+yZG!mn>{_tmH_quG!QHBuXXhfOAH;#z#H1TDxJ`%BnJ}k zYp}Dex2+kn2)-B%e4H4=O96yJv~|ygYnecV*<)dR6DC1Yi5!yw!t&i=y{{>0QI}NL^ zoIz1=9?1c4aao9P43lelYndg_@!4Fb66d)ajqY(PUuVR9Y_|M^j(zWcd}yzK=Z5vy7wpvX6OLJsfn2A#FM1?H z8l=_8tdtuzwOF#oSvDMU=Ju(VigxU|qRm}^*dw27Kg$aE6nX{3b+nrqxfqZhN9cCh zJ72A-e4vIhTN9Z%J1t-ct3&Lhscp(IX*gNe11a>~_dRJViJ1{%5uq0o;1~cEP3(b! zcF6#A5IBl3Ye_=ibxRQB?Yx(X{A=hTDQ9P{+sXGkN)xv2-dW< zR;#wo)nR*^&JCzcwXEJ~S#5^Ha=tQUPdtC#PCb3X${eColhPhr^SsljuQ2FEH$8%o z7QHZmUqaBch&nT89jog^GcK4P?;KqWFWi0m_`KvjZr~4+h+`S=Cbf5}d$>%p@i!4% z@`+F~)mKnh!{V5BVU%H@v|*B+j@Dg88t~({?e)KT({BIg3%2r$DXZV%Y=N~!n=Um_ zWCY$Y6YI259UBSG*b+>HmpoLcv!4|Sx{^c4h41>e!LKjH;63{!sYTjl>!$;j@|%Z-HF`qfkO9uxL2G}t8CGc_m55LX) zynhQj9$p|%KUJ9i;ofW515wWs{Z|!Qz>o+hb3j zV-mrvpI*GtUURd3xBG_7dgQM&HY7dJL0=V~-DEk!0}uw{)(&*|fFb~dtEA&Gp^KXYW_(CdfKFi(Hn>5j3 zX!9z#>k9D%b?=`~z}@z|+$PFTzuWe9%15eTQYGCS66HsIY7KbF0F&ecC5c~Px=Ikm zKBovamz#Fy&+GR3x31Yo-(9ofm4@|i7p=YCX9qM46~Dcrj&M$#BL->M>9blOO}?2# z8@{P6#=GI%d^@CLPoV!o(dp=0o+AUW1tdcr0q+cXrd}R31JHF#bdXUI+{C5(j5P5b zg--^6>-%`gGzY>mcI-%H5BnZfw!xlg+1yhb_T(3)?fEay+G!+(rIX+k%xJp-ByDrE*P({$p(uHP9 zUBOq&0ws_1&_TrKBk z>T_ILO2kvd*OOu0Ibs`DRrWyC*PZ?=NTbu|=w0lHlpAkZWxk7v?y8-8tzoZz{h}?t zgl6BO_Rqi+G_e2(9+AXMM8AVA04=vkA4Zdh9t?C~0QB9>owzEToQ!d#+*WuFhwl`> zq_U2WhX4Yidx6I5d58f}=Q(V<0P@;Q^=+cWCK|7ufjYoO#7Zjc6=(5|z3rOCV`j4e zAulreC5mIzF=i#=L%c8UL4(m@2=00$jYA~(>kMwaXyAF|qKGLc+r25b(*e5Q7ywm8 zaCP{JyO=2_*HGnwu{s@qBpkT%T!8^AusFa@N$X*l>Dmw0?Z)4=?8CoUwOc>$*!8<0 zLku^SyK`LA#K)3=vSNBwpk3N@y#-uUUDrN*W*A@)WQIn%rMq)zkx~%p76B!tYv@i< zLRv|s1p(>q5>!AMM7nFJ;p497e*W*{$Nn+r46)Ceb**)+wb$8u9~{O?l6|k7`q|fP zCXO*8TOFa=d}q(5BUN14vOcG;}*u>VqoOFsZ**<1@!TC zV1()AI%lK`Ejn#acnXiWGBQ5qr-+CO<=x(uMcjYj-Xix zhJwD}Y00gp*T^6S>a0YCPv_$vI{3}G4K6Q1_W%ON>A(PDON`iw!(?XQc5f@a-QA90 z(!0@4=ez(#s|7gE%9Qis%`>@obWgRC6S76!w^>Kcjwnw)v21&+M5)=hFOawa^y`GZ zW6wr_1<*vOCxN^86YG%j1nd-!-j@Y`THyT1e@~Nc{av%Quh)3Csp`cUsfwm4y4YqvP~9kKL&u*!$Iuci)7Q6NU%%BXc9fjt18q zY)&4@P24=E^8QYmDE-h2k?eq4Q3SJ~&b?Z%yJjEKc^D(`T3M=hHtDBLKkhc@Xi=3+ z#dDjqy2bG^-%ke3Cq&wd9X;&q6^|qw&|9)rOchfLJ(Lkms%o*I{A9H`JYzvNO5JcY z)+lwjVOg_R9PR!KtX6!oKRz)DTXqh1jZ5Gcr=~sj@(XreeEfNab>EWtUIn;qq6kL= zDZWWJ5{l7su+&+R3j*0*rSN@E-dQ#z2YN_G8!%FwCK0a`c`*wecAvj*yIc8DU~@H$ z2_w-`D3~GZHP)3HP2PeMXUFFNa@bgCsYIeIC!zl=)7YT|R=0d5lyEYW65jabjOk{p z<^_z?*;}SVvDL!uiVq(d*gj=!oOt!kfT2RpB0{3g#-i0I#BG$z9g-%)F?n~_yky=SSwiV1LPvQrRGbuZ{v;eB+#|$can;@M-W_?N zfMq7RRYR1x%`20>Z)EVtXR?ixPF#WSq8;G2<&0wx(PFF>Uolw~dx6$-%sLY;S@IqGO&EiLBwNbG zZN{!17v%fqW+9<{p`CXU2XJ_BLru-o@$qqazs8Ie-!A$HoCHcCI($kdAE#Z4dm5bu zce#E_3{lAN3SD@-9*FhV>{RIWWyn{I#D?{}4X+$jZDWJkF8msygHcM>e(eFV1nRPn zRx#&1j1x{$=(4wBaHwtl!S?-&x1JKG;D^ViX*JR1$J>KEI$IPq6m!>YTn$043mb-< zB)&!!0^2;6Y7xJHL9Nl7nNPf5$(!xN6))H$l;69-Kf+7=Q~aIgMnvAnQ_3y*wa6m2 zUHmmRw*tdR->5s@-!XDer28V#JGZOYmg<2WNn?TR0n8TOoebV}Ujjp}yTmkB(<=og zH_BzO#v`8HFPv@vz$y{ltLoY6CRATYzJN#xH6G(0DDw&HoEW)cw-;}73LK~37n3uC zf)m~I-xy7d>6A#KLA z4wsF2WgQYy9`Yc6k+Yh84M*($l$OcOGj=Wpi&9PX8%kGLHAq5oQl{{22ACQ#2aZ)h zN@g9%{cfp-!|ieR!*lWJ!nDY*>=iF&2xh;Eb5^dUU$S*djNq?%F2Dbp7#N+}xmODY zPqTu^!F?FWzLS)#3nmHtY3v?$ZxqW%ES{yrKPbxez+sm$}Df`>#z-N8-xCo8Vz$rwFDc z)6#d&w*{P1jT3zHti$45p_F)Hm7o{7SG5YKFFp2r>J}yMz;Q4b8MZq!r9;I(pm)TT zKuQ5lwg}C)M}GGb96!ojR~2y;V9AQ7!8m9e zU{S2$^`ICx$bBTUz8l9*t9|LK&~C%0P{l`SR`&9EegW0o*nE*$W};Xext zgO+is&$5XaWmpwCl$3}E4~(W&R1Yk+>{HcLR>kiIQqtzmIr8%>KDH7gddHqGIu(hC zx;r)VEOPwN2EQ_!p=3iMC~|!2?M~(aS8|+QD+jlDu}@JlFAhU3T8iWG6b4w}2RD}` z?-o(b{_Lk7lk`d#o}sB%JlR!5tCdf@!VXaddb;246B)~?8g7A{JdT6-y(9|VABZJX z^uKrHFp9?T;*PGUa;{P(o!UbotLf>)$)2J&7u3GEAGfuV=j47{(Kpn9TMKA)0$(@n zwA=cwEBL{IAZV3b{9R`JuN5=R>YdbR9P zx`8+kia#fFlrbR)7Z+6Jhj{M9!E3Ucm?$16zdwiZnyD zl^xU8pf6bK}E%?Uo4h3zYXITI-f2lGt;n0C{(V*>IiRr^eaaW+;S1I+qdiC zmUJ7;I-jwX@K{gf$_n-}3J7pH5~3(d`_bTq#37nnQtpzdx8mS3Z;SC{)_sg|lc~V{ zdjKXW`_YuI(~s)+9SEgw_4@hZ^ZjI%M_d`}CP=R9`}H3y^W}LSi4lxCW7S845;Dyc zwSGobX}O^gMfH7(SPKtp?WHkB13~b&x2N9r32bpF7;>n+QOhGU zoJ+GjbQl*#id)e(&sK|EpJVv!#u|Qa5wc7=W>%9P5x3vMiZYdZC)eTI6&Z(Ha)I^5 zPI+80!@|=dt>PB{B)DxqEa-#>W8qfzAqJC++^MupEndLg%W6n0&H$tJB}KC9?vM>@mhO%jgplH*66nwA9etzeU%Bg_!V|8HmX41!92vN8V=e(GpWv zV?pC;joo*C-lW<$RR*tnf}_vg!j%IulEF+kq9xNHTJjL;4^!$6I6*(uNwLMZc`*{0 zm5ud{I+D`rqa$JTXhPL zH1lENP(>OV$>o6G+&YDq|Ag{->QzaV4avl3K5R8`6W||m9UwPmw+P8^=6_uFUF^_m%Nnia$;)ECp|Htb_R(U~x8e8$ty%(aic?>yXQ zPf0LzBHYDENK!x(uBfKS7Bou0(cBUu2D2oukHl+)ujSKCSf|?GgbihJPrGDGIHs6L zI~-cmpC7^x*j6T9te428zsN}$j}AEF$obLoR=XKRhl~5nN*SH$WuxMAkKNCo55yiB z^B@$5m}dILjhT_ATI5k95SHSjPEy!xNV@a>`>I#mG%_!^eVDZZ2zxbE!HY8s)V|jd zibKkauL$yb`yRSupgw=P3YaBIu$fMV`#Rz5z{=y+ycrgj*~)C98i>3;bd|(r>TxCb zf^s#j&OK#SF%xe&*_I3IW$4QYG+Wuhdo5Px|S zwy^ntVF-%=EgZCvv5%R}dY`&_^bb2*I;~uovXUbmh?VLi zAU3dVx-|x7r&S#n!P>{WV!mWy!Nc-|cOb789Yc%!F3N(v1X_nt#5YfKuF*}(rA3Kv zd`Y36f9U{ZzHDo5iNSx-+&*=44+#Rbi7C=to3j%ZsXf}1;w_}8s#n+)Q3r+Njd?I9 zlFQ=BE-+YxtIFFPRGFo&GDsfgU?gVK$?iW<@bXkx+jC?eaN-@$A;Hp=yTlw0a$>`v zKDgPF$sxzAuHJ#ej_VTDw0W{i= z_A^4Qg(c}`W%2jfM9G4n~PYOlO&`8`7oLHIB}RwMIl0?+J()yZjyw%N060~ zM|^_lh`KQCO!W=N^}FxWwx(AJH&-X;&|_MM8$ zepA_Hz4K$=<#x@6y8LBjap9fj!PK?hduRzAa-k@0d4CNN;-_+(7eBDp&LQD`+nt}w z>TvA)VFD@c`e8zpS#gxvj1U?@h+wk9rQ3w}brHI-!b$xJzywO5X)TJOab1L2BEha% z1B4Zgb$oU(x&^lJ$ry>PP424NnTH%6a~uy}(x`gmRE<^rDwW7kaq1~EX|@`esCVCG z4|kYhoou39OCy^5%%uW&gN$mQN%d%EC$(e`RM;p6SLsnHvYSs`LbPovqRo6!! z^7r(ui8=2WL+;@Pou{UR9uY9#Q~4sXBmpjT&AoW*IyKJCd%sPS#lA+IKr?$;yvoT` zn#(E@wVAF$S4%?`cK6(KnMVkgq%p!x@%RM5ZzmuR&>D~2yBHiE&`xy@OVG?dj}&@3 zz`F6RRM@mSzh||w>1K|{FwfMWUDvZ{g+xB(z=xO0p+?l&331_w!vKh>#LA`PMgyXmd|rXkNZ1sW6%u%o?5%P2j4>M z!m95<qT9nweV(=A+A9`ut(NT} zY{{Kuw?AIHJ^9|tP_*x3zo1oSpv}k_{-=-+0^=TM0#zwm1^A&aqJrL?t6f-;A%wo> z7Z6g-(x5vv#RDXqC3Z|D`Xsw!;hw$lNm7g)ep}o?^1wHDl+0YG!w|^`Dok&K7>)5b{g)M1ZPZOz_XmSqdPQ4S{vdDOTSw(OzF#Lisn%%D9JWJ0*a zYhr6|D7kd@xxrzs+w;;FgLtY?b@GVVBnCW;JiHY}E;=g5VcGt?gaS#$(aEmXJR=2- zk!>^~dJIAK=9Jw{W4Ddkl%u`y&6y`Q*eURw8CRK3-cHwrPns94IAxjemXeR`^2BRL zE6n}#(@gGPjy|oRhO?44bl;U7@AdrRFK!WtUZY{jzeURcHnFW}s++47dwuluSE1d8 zUEfpEjT$G5?>95P&Rz*Uy%T4dA)(zQ`xEd@t}OZM%|xNA*kupU(+IttImw1=TB1~K4L^(SwslEM#Y%-J=k5pctyLY;kGvbjeaHt^5Vp#Oi~+fX$?cU~qQZ(TmKFRK-7tFE%M7cAsw*6_1eF zJ*yen%F>tFMCC8{inyA@y(Xw@c+(Uineu(hr%zbPPc`KTa+$)cn4l2oxVL)D*$J$v zbAsX^%y&Fr01N^INT)ZGOe@UPi7&!Hz2E0oi2NBKCt{H5N7*&gL~Fx&Xvvo#=$&<% zW59h57kt^BpYav3Jf?UZ4go#9wMv&42Xe~8pna*qP2ho6R2Da2OYo!&T25&<&%hmU za4*9!S11rnpD1sUUl4Q&%kh{{VI=D2!q|5#Lpbpnd~HiJCVKkz+ml?1m;myi z<4-k06QX(UXIXAy?4RXnGUP2Y-M)`awT*Uz-(7we--JtOlKM%7`K#Vxu95XWI_A`g zmnbj|F@0#gD*E{S!^-y*CvbLhV*Pdto7`J%)~6khKsfZL;tI_g)Wv!$>9VJR@-A>< zz4HD8$h!+U5@yMh=>}#X-Mv$9$ty|A!G8s6unY`eRfFF$IvC zg8NHN!CDq1DzdZ;h1MfL#a62ecJsU7Bf~H|#f_ubYFuPe=hqj|@e)zd{H=G7bl;m@ z;9GEG<+L{qsu^nmB=xbSms&~UbXX63?GIGMW=$~BA{sn)xawGA1Yi4tH0`Sc&*ZKS~CPdi5D^I%gf5@ zrNUlGJMkjwPV@0@Co1v=!ee*>c@11ID8Qqn)_7rZVSz;_$#q`1*gLExth!7525UH_ zN1ZXOS$d(p?;NwtCy(~ESKEp^;cO}ATKy@?m5^o=?c+wfsKlSuzYqWd%N)qptA^B|)pWE->kZ>sWLL6(e$`%%C-z?G% zjcP}T{1o&2GN$;$i!kd%C96+a-wQ0m`YOWn!{gWP59n4nyBY)I2U@$FyT)LbF+PtU zgxzW5sJ~f=jSC_;rxbCR92*;Bc?%;N+J^gs9Bv}-J-Me#tYaFqz32HI%Pt|U4{xTs zM`!HpEz#fwMxE8RIWEa?i!#A*#w>>m@34&0&poZr<4i|O`1U4qTu8@|D2#^dhX}Tf zAb;dDci3gM-QASQa1pLW(cG*MrlX_qUFwWf@AAFt7Q!}~C$*5H0)NvBKpqC|Btjs= za4Q%R<{2SzR1m?kytDFr&secoMq}H|#w|T6%)CfEg!oJT!3_*Giq`d`n;Qdk za&!p9YaJI)+u~KRE?j5jP8Z0Js~9L1>)klKnXp1vyh9_pVJ~M3y%0o5YjALYO&RfZ zP?6~%A{pg)`dq>Ss7betA-h=v$V&n4F!I7T*Gz;h`7mT#)k*w-r7mY^TzR6+eD4z= z$3Evml}g4gLL$f)O<5)^F0HYSDXFc&*L>m+k7D7XdGJxxMC!{g*$W><=~0fW(l?C# zCOnY6Odi?hFF_mW%m874NJ830Z|x<7Hc8$!Jh4ro_RxwMaES|;;~|+0;#_I8Ce2&EQP|ibpqUXW@{}Y^A^QZOe3osOJma+32`}1R!7O)yI&t74Am( zkoAEuXS(iR3ofZ4ETxsZ+#XB-U8*FRtKq@Y7K>f^;k^2k#Sds;IA&lqxcO%G-G|4O z-8e)Ql(h|C8JjtA0!4{QxJwgw8J-7{uPdIc!0*c#!h;sFPX^gBjMT-vv-(I>1$e?O z$}?AY^hM?dVl#gP0wUd%S9n@Ik7l*vR19fdyg{j;s-TX?7d`3=2_d1CISc`5vBG^m_aPu= z?*8 zC0E!hE!c{h9!-!0mh%t8OkWft%00cah-GLM_yqqj@;}>xncR&Y1~(LEj=5LPyqk8` zEGJiK$piP$InNq4**-%(&(j|968Pz`JhIWcB&WHt>c5&3IX&GH&%^8f{;2eoO=E-W zckv7-=0Q|8Tft#%Wp@HHN$=qWlzsa2DU&63pYaCbzZ(8+NPCE$5^~G}y-*&7wbVkU zx(1seT*ym)Xr*x3HCvSUr-9yV8++5J6rm9`Sfyw|sn^t*M-5Bcq0^u6Tl3`J6S6n% zyp{8wAV~%VS;$97u#Nn;WNUCQpfZdDvuvKUJm8#LVwY#?|bcnI77h}H+XPX7fc7yx|{ z7n^0i!Z$!K=gmfutu1yG&C9<6Acz~}o>PH`by)}?B_*ZmAtn!ZP5W~(@?Vfu z%+u4Q6}TZw&*F0f<3Hm2ltGI6BO}5&Sg)-(sN1Vl!MUknc0X=7{~wSmOzC)|vhwdX zT;ylK>~RoDBNzy%<|b5Osl~Kjg;V*40RL#M?sRlZH;bm8R;}mF1;+Ks+>~fSPLv!6Pm0Q-zQ#T&Ip()@{ZQh{{p4;m$ZG3*-hasKDSnH9o&$1)M+V`p0) z^+%&jfNhSNH|Z#tS8?ySMCkSLv0Kl>NYsG)$GQ?bMzwy4n|Sk=ohU#hZJ-ejk;0*U zJIK4}57*7Ffg&?ox?4prWC?RTq_B%sZsJr+FyN~D21WFb0q4-cSqj*z6)t}aWao=T z5wVnwozIUr_^06a;?yzhfqD(FMjOZh;{&pNSS&#@=83?l<!x9L-9Bi1 z#4sA;q=~^Xnp!o=Do4tTZVb;?lRoi=+m`t6&}-8&B~*Q5SOH2!Y5fe2a!Wd&34 z5V_)Il6!`~@OE=tXiGBmW-61)t}Pjb_%_*1Y2z<}<8H)d1h>K9 zP}M=%Q%)3Z_eJvrh#b?E4-{Cpsjo}7V*wl)l~2q{@#005W8GHfit86S|07iV>4(%% z$P(?ELJso*3>kih0;Z0=fD9yu`rM*958K>?X1fjDr#Zrp1Bx=8KKaj9-#?ONw5Hu64=41%E%eS)f zzCzE;@biY=qr7RAFXg4*n#)Ts(p)Y}{jG?FMLC40DBO8*!`ajK(R(@ZP&WIUVHiz_ zuX4VG8WLLzoP+gX8Ivr+xnA~|YOcd2qTEC11>Mfu@t6$+y@q&cGg;XJ?SFV2MhgbD zV2i`=Cm>5S z%6uCf;@d$eU+)rH;rS2EdwRm5Ay+%I4GxaT)F#{!Y}<3H&4h2BrwtxNu=;j^8%{KsGm&Febf`Q)nxnXNuOK6YNhf|Eme=VWP%{@0t3Dnp^9JX zqUjgfubK&i-Do3HRGfjLcD&`Ki0}1Dpax1Gd60w5D=Iw;ZY$Y2VUX{z>E-}aPXEvlHa2*)v z%<~V~33D{ThK-jl7T9S?@F6#@LkEZcb?|h8sQGxcm-~g4nwGY3-!r3r)?wq= zTbS%_;%8BpZ)4o6tJ2x0XLT2S^W*ZS{+u8C=V$Yd3%@<%+Nj`cE(z{2?V1z5(&;x) z@|j=ZDIPZtTM^miR*m^MC!d2RTsno-F_|c@(sCX#XL>-h;(I=CFPhLSqCJf!|4Wd+ zd|kj=uSuee85cq+{!%tAO_VSPX_@!!jH!i`(a;kP>3tWQdJ3jOXErN*y7Sw*6!+G@u>XDGI%9}gnIF#At2=pp!!SOUjJQ4;)m} zwDdhq2X~Ku-d<5-+e)tZf{#|G9BwYF|LcL*}cM7@4-|Pgn$F=Bj>S zQ;EO!`A3J8A%Qgq{6IJ`LzSE|{N8t6?2Jeo$(r9VSdHgVJI!po&aLCx@8sd*z3~&~ z9FlVEdS3BAms~i9^7fpF)s1}ioAaCP5*mp&NZPUbR+qC50IBj_h?ZsSSzsOJ0&>6Q@wzL;y&caw z4q_P}KcloBL3%3n*P&-;5LdE zI{$E0ihID)vz}o6%fsNk1Sh8;umj)v$m+kJ!nekp*^;AS8qe4?UdIbE@V|fV zg#CZ){-)=O+u%JK$vw*9a3hu$tII*FG0dSMh8s}QyAJz5+l%Lo$b6_*m-SWPMmYWQ zH%29Kkm3AqFYr1h@bFKGT`f&_owu@5eyCdI8wZ)T^em-9v0h?0Ps%sQ@wgKI(BeOezrlKw0oZNBC||t9Le}tHOg*95v3e~T7ar<& z3Jn1kcKA$-`u7O--lBQ}w&Qg-fBx*0{-9A>ndq)TDfA#mb6Sle$ zu$~bdw8~J#j(JLITp{OCDdMIW)aC;y(xvv9+hBU2jxs|xc`32diWV9f*74SOeRUss z(Bki!)r_W>rDgeztm#Uvcf3|*M-9Txl%cI$AR1c9K6SL)nV7-2$Vo@>Pu3)#W3%X-wdFZ|^tw?9nqUNa|)@(^K74e$SV; z_o{bVJ{a>Hepsg!_ph?zI2BMWln*$)D)Zft zVc@BhDM4QhZ1EsfcF#OhpX1lb{4Y5|A<|fo1;2&(3e{$7l5B{5!_}JpWGV7oIi7}x zvU|Juor-vtRsw>ivAVG{gt3pkBjS*k$0NxeXIb-qJQxCwCkL&j(C|S-#*S{p0lLly zAi>RQ8`XHuc@N0R08fM3zI4$P8-g7NP3t?v{{81hH8hF`PXBLo`csE{ZHz#9M?33f z{Gn8xYRhxzD0$)80_6!vmlpzbMgQcX;7OJVDHRw-rMU80Cn|Q%`daf zV|v`P* z7X5yDo5E3%TvDsgXVG28H<=RVGTlL2MQsRtzdUdBMemKFqJKFgp5xZDq~ktZ8PKig zfrsAxjpHas1RUO*Y$gE;Xu7j`X{-+_7ki+Vf#1n&H!H+Oux2eq=mEWbER<@y>IzR9 zF7TL1pJM9_uHWobH&B-!$;kV=KBIt3GME9dygwNNNJvPKjXGuBs#nMQk$87n;hL{I z95CxE?~h*ONt|~3)sm;5*wvqN5ZYmUuFDb?@jsy&3ZY>Gmuy{}*-{Zk%!gtOmz$?t zCWT8p+40}H)P({^O0Ri9JYh18oGYq7dE$$65EJXJlBltol+}}bA}sUYDG~_OB1-?& z?$IVgO+%BGE&#fe6hiT@@rCdRwE0*)lDjFCZx^+DzVv+9pVDQ@T|2>KN}=;hXT--g z2>LsBCSU+YLIWKwx@dpR%{H%Qdym9tH-|?dxwADJPk;p-Jx5xMcN?w&pI7S-gp!TMx z{(#2NNFJ~Xkq%1s(f)oli4GbyT6?>q*!Ig+MaC%TimAD<^X>lSEK4Kz!xumPH`n+> zy*s3Vz# zGWf~mOAThN{+{tXcYJv|>}~ozHHqAR16E+`72SfQX~c+NG_gB?dm4__eznbf-D^CEqctAHupx)pUIlS-3<&L*2`o(w%2`y-GbTb&x))Y zL&fW$i$>u)u%ml{ddH`w02-VyJf3{^ebz)nO7ikIi3bFH8Xa&LIb2H*4;bON3K7e6 zByh_5vThSPZa4mpzs3IGv%?SUauA{;)3!VqsB??dq;|R{z*)T$-xIwJpaxL<*WS`r zMs@#_HvS1E4G1Me>Y<9Exq3;7+gmrgTjPjHR~nw=<;%H)%>%H$xlYvgs8#h$zDgLS zTij1VB5f|w%RUB3JDV#-rwdCjoOjf}k=mCN+S>Cu&?C5I84uXH$rBbfbDZa3BGtpn zOCHOY^B+75eV`}G&QLl;ip-;RZvWA97?>KbrG*&f%*csgeb6j=T)hbUUk0axqblG| zCUFLBSGW#T zoj$zv`<~4i7bNL?=^GhtBH1K)`vPqLqJ6)^VZZB#j3)>fa%Q{jZi`w(@!iyTm5*q@ zzd`fI_B0s(BH8&36M+N6SjzTbO(0{Ci2m!Szj1C)^#hjQ~(_sSG?pQrX2!*ZJkoe*zheVW?jP&iUu@!`eH3 zXAn?HJ4i;K2iE+V4618P^l*3IYDQ;P|wI5 zx`*M>Z5`*V;^*zT7EN_|^njbf`K zet>mo_)6RM4-m8Irb8`T`XQE);jGt${ibWu5iP{S2>kKG!9WN&q-_DiOp4~(52*iu zCZPGP131A0G>uPMt=k>XU6M$XY|9gO3T$>2fr_}ra)Eq~FK1LItoO*f(^tWsAW79Q`VSMNRo5W)Ag&r?7T#=IqM zC8^C<-rgQ1Qmz|M@e28^snfyhIKjh);@RtsYdT{o)mf%@!qR=4V!UV6&u@BLAmNd9 z@t}_2Z&XvR>#5u@ExYuo8xQ~A+QXl8WrPj#e55;dDuv!!EI%yM?MtsN9;~m^u`Q!O zT7v=WVO6ZG{w33IqgKvY$UAGr2cOwlWq&igxnYbt0=;gR@36x8kWnkIuLEQD?2g)( znK-}(N#M(#x+YGfzL7Cd5mPXDS{6_;A@h5ZrzHd1fa^%bxm?iIc!#9^5sho#c=(UL z8;zF%{?!f+k^fQSCLOsY5&)r=dE_BfDHqNszdPk=Dt07t| znxA#fa|IKjxn&1V|EcG-70DsKYe4YVq3mUq`73i> za3Gj;haXq|ba+mkkNKZ*b*sE`fEWbkLSS0ay$##uSiO^f(L9aZy;+F|+QZ2V4taw4 zz_=aUF|r(RfyON?UnN8TEmk}ch?b{px}IF5EZQjVKSdK79`K+{23e@)3VlqM9qJM3 z`^cX7tG7cUJH{BTrqqbTJ|i5$R&^d@BZJ+|YD_0Pukr5KSFkYxp7K zYKOTXiyPpH4ERU5{{wBSJ>vo{gd4iIy}nn4%)k05E;_%lp7LczaWeBc0N{1M@tFx& z9F!7v&M1i3J{nEx1|10i{dIp8MfUjU7OrO8reDls47zRlO}W0R&IfKD{39I3_lz<( zGjN*8f6rE=X+C{P1XRIxRns!xgZ8s;7g_o{k4a_(uKUTW>@v*k3`mncXN4Wslwy7gp*<`66tP;u}Kta|^L z{^+O(JP`hxPc`WV0%FiquFXlvq4X>;8!))#7#h{>B zq7vLX*#G$7e#{3Xx_NCEeX?23J`59&`KG#y+g=p zJ+~VS@Aq#bs- z^aC+^RBmusc(3?p&qc?lS(yl%hT5j%XQ9m}+afHo3x}F}M|F6{F=@qoK<$I6l zC8ziN>4wa9qcf#aN8dPhofyQIs`)b&&#!8Gbn!13 znJSLyKXJ~f3W`E?i2kyi;(yyZl`}Qogyl7|S;ur>v`J{v6a=uk?+w(`@U=VS=NPy;0*obaW%UXC1WD z^V-S3p~&kmnOjewGZUh9pMV@YZ#MgKk>2IYR+;!yrvv)IZ2tLwYm~e6yweBpfL}gh zCeS_S4LP$#ww`hZ)Y!27xM_WkA;U}!+M{X7S(R6z<{v6(O@f*)a%M7o9X_O$d`q-7VP)-)IPUDVnot-pPd?CQ=)LbKi#ja zb+lh*Bps5?Q>1?I}jv+bz*zeCat3wS0byrA)Lz-Dkh>GR9P46mCTJrsdJ>+Rc$Kx-c8 zEh6>bxagSyMa?Wa*GL=uo$c(U5}29KU;@mCyJ-itk?Qh;sK=^Qg@uI${UacMWN)@^ zYDvoNy$~Lb@3ylizW=BbwFei~SnUY!Y&kD%uq%F+R=W07QO>AiHc85kmWx91nLWJ9 z=);;|=|M_j#uoz9H2oJKm&Yp;-Te8Zb=u$Z>_5GKmhW6BCf^muWqbA}J9AZOl1ht) z!y~z%>a9&uF2(o*c_-^vn|yY7gXz<0%W32NWe%)4SCUL_c9Q82YfB|{rZW_33=ro0 zx1(BBs2sKqUW!bR^t@R95ISHf63$IoIPj>{z4)kkH|xU^misqEIj=eY;aTTa7^8Nm zA%z7MZ|)fFNWp=oj-(3dlPGJY<@f?-vfJy?l5@wVTuWZop8f|7@>f*8?fp(>BgeaI zw~ehmiFnd3=REbE&$$#%ouJ=v)b_q_>i4D2Uw<9T#>l;1pkw}bny`ZnS`GIrsW}V4 z5?T$$2`?Bnt;#XEg;%D1K{*Z-?HaS*#oyt!_XxkW;D)TZ_oq>{UNJ6g1q&$bg!{E^ z$KdV^{)`Icb1*20-5Ng109mxAM{f!l9`VYQvSV9c8pCr~1uP%FUU`ztC7=n{J9E-; zvCjW_bf19d40Igy#5p%-gEzZlQU!S6JjaXvkSX=kP>99ts9a3jVkt>Q`;Ew*M*4?B zPbu;U#F-8Rx=oG)<_<_MzU7*j(Btqt5~gQ?1lYY3%^gv(3HzqoHi>%{o-v^I>b{+2 zQ3r)UdJI{mwE340K@>S5Utv2`*hxYjcd#@#3h0s_SAUDwvi2phEQn;FuNEXS?EawU z{6aIJ3Dx!<3}z6qZ;}zKe7nRm+< zx>&ZD@!^d5tm9F{xt(VT??!KgsXB9zIjDmvb3XlxXhjnD5Le2^)a19{`w1ab#0ghB= zLMTQ$+koP!uhI4FrFOSVqqO@-?EQR6zF{seAB4729tmEE33U7T8&n&E1Mt@KZl#!Y z;)}kJxDL2#(;fgoYO|wH#(5vit+`D`W7T19>&t}(yV>EGdD^lIgtjHy3XLe;KGJbM{U_Wq%1#vG>&7sx+KoU46M_KFEu+dw?Adi~r` z>u17cL1ws*`mlUE$=|9@AlR!E7||7^c~p$9?mK&KdU7Nh4^&G| z2L%&flr?^E4!2;{vTC1C8Z=Gh&Ecq-^{N(QM?a2^|C36#IweQV&%=;!}1*VdKO)y8^YV`#a>(5M*Cs$7tfej z>AedK6}o%NC|xf=EbuNPwRj8-wp#*63yVg^nAw4m89Tv#0A5m~^p|JCC8VTJj|HQQ z^2F3F6hnK78lD!7XuUcd`lRLcPG9BR#Jl`D@nA03n08^?NRi~QMyFT7^Uq*AO>eeb zr-^t?V##XRC~z^Ezair+IZDu6I^}(WQ1ng6;gilW^HEIE85`$}j{c_{45I}t7e7+B zMve7yOfkHuLm-YXVg`<7Ap2jR|NO+30A zK5u>I+hZUNmZnx!G!fqKyyIeedx>{1cvrgWNc;bz>8t~q?)oUc5dzX85|W}I-8EX2 zF6r*>Msg?!Dka?|F+vzfN{vQ3Mh_SvAf2OOFVExi{=ffzyZ3(YIiGWG=~YdJ6z%9x zPW}~lz`zg&AbAr5FqQbDy-fmyd?oXAyLVfcxa9*FE+Vn-A%`&p&S?=qBr`~Rk(uui zHu>{0^(zj3#QH({s7hybIMt0KC)t--U`)WfGW2Ni5yS58!EE!JmSMppurEHvt#M4S zU@zD#L_{KKP+e4qs`)m1XbdxDn@5%(0HSirZ0QZ&l+tOesu%zKc-kH(&Fll^#Nd!> zV?O5t&fHfz>4v+P^a&OVBW+P&Ma4?d$Sj!FcjZ)vl+>NAuK#w43m(!ckA>dRlaK{} z$A&>($^beQI=@l43FM<>fC)=Qk;Ry8f=p3Wt0tW3j-sx(Wfdp;WRt`YyF4Xg5hc*O>bf3DvG4}>pq4GN+MjKueJC8u@}g%l zbD%BFztcIZ&^i1;SznD_VDZwZnrO~F)>ENx>4g8A`LzZU$@5RQqbre)+C`mhLpdJ5 zmNMQsb!WUIk~Gc?F}oa014u`U)$<DnRyAp3zmt)*sladcXc}v~m6%dNPtjctV~t!9(9ZYh1kglk}0ZRec+FXs5xHIqJig zjzcT5UM*8h1*YJ3kLJfD@4^T`NlWUFjTnVYO=xN!=ipR$HCxt~Ieva4 zAXiH82Di$58Cl-OFEK|aq}DA^Eu2YH7{iQjD|+JokRt34`;EIFe;T^Fn}`}}UMLTv zN2FoFCFws~qz-_8$j_-}Z0#Nj2r@fP>T~3-_Q~=d1(;7#A=M%^d1u<4t(NVxdJT_Q z(4{#)J3q?;%nbqL*}R9IWM@<5QZ>h3bOs92ruG0HIbWm86ih_!$VI7;`!BkRzI|1{ z?~7DOuj#|e8+kb9(}Oun3oB9fi;=t&CWhdZ2F9VAA1WAMS@@s`?qQ?=Ff{fzJRN^H zHsmeu5`WR&fqh)tvA{6K#|92Aq{wT@J$0Yaunn5MoLH;fIxRhnNLzKEF@Cq5*iVbD z8GQeFp5hSL>4GeVv;w}X#F#UmZ z@gAO-+;Vy}m>1Oe>HD{xD_TFgj=FjF^ms_rA{X+LQtfB=+kpCVegOq<+OFoGz0Mg? zE?>+Neg6MRaqs6MV8IfEPk8x#L?d6@?_4P6Z_gtXxz{&Kq4BrtjVYn;=h$}*WV9s1 z*O2wV9Ps~%D8H!CQn|qRP2<52dyz%s_Icphs-nh`IW6^7A%py5(<8liql>-e?TVJx zgGe_|!d%br`05uS{@GGt&6e0yU{tMs6k{IL<6n#j4XAu=r5fZ6cM06&Xj~*#R{G7po)_A2X;t^rOSg4sFRDF7xl{ zQ2VuFH*WKw+NWgNg1Re5OhfJU3^(>n#?na5b%rCxa zTJ)Mn(J%t+*k)J0%m%1rN=LV>#2@FxEIsfd`7mfz@*#6# z&%)wA#z9;hi;`?5omXgN^F3mL1NTt6Yj#t-2JQx*uMh-e9YH*`7ub82RVc~*!syq0 z7hU3y{yNC_o-x0#4f@?vo_C_C7N{0ikbpRef68Tm>7|l*&*z9GdLyPV=cL&h#_2O8 z8L^jB`NE<8_vI*{aIdL0wbF)XrjmqrK*mA$FmHFeT@+QMMdaJabal(+(WMwoCyxAD z-4i>@eHKWf0En(Q-MI=2yJ#^~hdC`7$?0QtMP_=w-T&^c?zy;Q;E71WNZGXtoUr%9ymCy#PS1;&V#V*}nHD>A{-D zV2)Tq3qV89RxfN$QJ(!GOhAVw8ht^S)ykLnwCnC7*8zZWfrL3Vj-`^zJSwIcePKlKGa!=PYD67p~rmpV7A(kt9Ne|gf(2~!s{ zSLBU42gYrG#Rfdovx)xMaOh=QFFX=SX$$Gd4^Ck<2-japM_Pn1$>MyX!16|G&e>k-xVI;wl+rX-5m|)zJQ{M%Ma(xM%jX7qc47|U|<-1p80aSHLJVdr`eSo zd#cdveC%2hc2@WUs)HWKE59xf5Y+{;C`ma(=1O<9N{@3to#|&Sqz_2z16YbT=Q_xA zn7vG6(i=f|n1-_fReqr6M_3AE?co?o{A6LJ0bd5@C3G>LPWZVwCO71-8&VoL3GWqM z4rKIo*>kMm%Z{ftWy^BEPWFE%(878de}1l^yKi82s10a<1Gup!L3&3>)#f&INGIC;X&60M#0y_?NXBJMA0cCUJCoJH=; zW11)`n;Bfq6tya4ZEn>=P{#{rhoJ08?%g5yZ{ROVhcw~obM_o;xt>djBOdp%?sU1v z&U0qVcD%?$8)Uuiww>i9L~~f)2FCQ1{HBonT{wmqO*@NiuIz<#^IW`c;0u8COP&;f zc@SR;i8LEBfnA`MI_N^PuiYs=xApc!i@b#VCPMej2&75J?8U$c6db_8?lk_wn&~BI zJ}pE^TW0wPP@5FNqcsTCMO)lhY*Slml7_bzjz8|kq|9((Jf<#CvmUN00J*0musv0l*x&3^WQW~KE87I0 zy^v_Qx}1kr8>92>+7OU-&c19E_rktat7Rvb7Hm<@>Ow0yD>5a<*qi$l zS0zl^2uIQ(l3_st12-$7Gh&2wW$nG-mogRg z`(J_c{swRgj@A+isdoI)E3!wOaQ>~*`$4E*ul6rhgA%<29_`2PQi@pNfs%g@*~9xa zdW$Uc^>0C_Z3Y)2=t6XwbKJK4{0!u_ia8(#I$Q*LOV^dWG8lmSFZ{culglN5XgsVm z!ikKvVS+byZqJ*Vr5ODxfYAN>Dsdg-vVQr6e3!tJwM7#6-SLiIDJLO-@**&Jf`lXZnEcSI z(OO|+kJ^0rwz57Dp=exeeR{(9mH*-wjx04lGj6}yp*TIKR~mdxOn3a^J;c>+8wEC6 z2FJ;LKf5k!)+ktVUonP+XetU0=!y_paGf6VJY;w9dENf=t^b48ke3M0ytMJx6Z96= zkPBJXh7jFM?G;+$!p_k+yo;M5T>M&`&^=6hLKX!yVzViD ztqKO2j78aygqNWOQaXX`pI&6Wj3-?rA5J+AV^8rt|Bbra-FG5+@$ZGsT>@*&GdxaG zLPC(SeSg0)MvsQe*>0ADnN}2haImnX&GutUIo;-00t5qOzaf~hGz?-Emf|K{IMnH7( zA$t5JVO-$^rv=amI|p{NKD`;l`wM+s3~==>=$*Z!-1}jzv)`4 zGN(x%N&BCl)%FwXQHeMWtu|-`dndrq%u#H%Y}Y%b%EdXjZo>7=oHD~wq@hcWahvDQ z$ie5e&xv!+n#q=Rx?}uPPd3S)cT8eoS>D;GqrUAo}vu+VmhGZb=q~r>pTy#TiISE8)G=fj@ZC=E<{|CgVMRnrdi5=42$GztUvPEskW6i zGn7soJe&eLjk_$+iOu@K@Ih)*+l^YAG`%mi;i(=)h_%#YQj33=wzwSDAFWn1pUe>W zVkS@Nd9}|KAHCoGp^EZcWDX&(fVilNtQ&_V5=qLEBh&l|HN0rQ_2C_HgU{K97Rzsr*LXl!FtA*Br&h@kvfYDBq=}ZhIHd6aI5vw-uQ^;d`T(Z;4E-&7*~hM^OvRt zmw&(qu*FWzGw(Nd=PxaFJz)_@c`$Om5PBq9DcbV*>#jmOKnBmKc(gWhO{y7Qy5_UCvdM--EY(u`m!GPQb|0$ueIGA4&yzoeNd~1O@f`>*l)z5%7%y$a zW_|)|VqfE%^lW`s=xk1oxIbyJRF>54cCROQP!r~UEPH!=G7CA2!XKWZ32>N?I6k`KlIiag7_&z5hQUCgE%T%#1z(Zwy5+LG*5h9jG= zZzHr1->&B>v*$T%Uw~e#Lh@?Na?8hhn|$5MWN&RjLv9>$4}sE7l3&m2DEWKXlZmua z&qCAAQgjVO^<$>sY6UDVj=U;0mEnMSnAEt$A&->hC+0_7?F;LZmMygjj?qscZR}E& zo?#ZL7cxCtWw0-pwH5f^X5XJA_7fDQv8{2jGbedFKJ7~5HS!#q(l|_KB?<%$%f7sS zW^Zjk65sH;Z*KAG;l=#xH@|HLSrZmwy{JxzpO8zL%mf`Osem>y(rA3E-(;*=Ypt8{ zpnA3`oR=(yq7T##*51@|u-*M315QK_{ZoG#lCb8cvNc;-h^4zYVBiOpB4qYWC|LeE4%f4>E?nabd zr=KoZu+6%;+I&X;3U-(}60VDH6d-58W_m3zRYLipl#(ENk5MQBE0@x-8kdL1+1mAU zB2Vv}&T)@&5H#kD6VG*y0y&;gP$@O@-Y>ws%NQ2a0ud2v2zR0BzV2(Rse8QhEIZ#wzDB6> zYH?=b`{&1*P0VL}ZxJyE3+;^~Nw9TLla9ywK~wa`_rw zEvd-OTXLEZ$GPG6rbbADf_2y97`>#3uf-4PnM&5Kb$;4D9?kNMW>AZb$D-*z*gdTw zk$*+7LuQQt<^aB-Yp5Vk2PieJHYxx#gE=-x`U&dP^9s>Nh@P zUKqALjuO=ggDVp+eJ++(M6zkJiwgYY zx0Z)JK$4PbQg>5&zLZF;;vS+cGFfm*OI$L-KrEQ=UHm-L9wOB|FF$O2-d8A8Kf8>U zEZf$In%-!ExzZcXajvIo9Ic*0Y?VqwXJ>JR85Yq`py1nwln!+(zEitsuK99w?mos; zvCeqzvzwS|SK6Qd!LTmZm-%uiG>31h4DHRMioQgm?RZh!EN4Z1HQb!n9H>>%=`bUAt z&(koI=tqR|9@gQ4&6darIQ--C>ducc&SGO3oqq_*8#(F+)9+{u_or8O{GP_AWw_|F zlj36yOEKw=*%5WfaCe2)CHiJGJ8WJDSDePx(rQryShn#+5~PhhhVp`;qYXvn*cbC4 z)t>SnxAj;U1H_CgB8o2Z%r)EJci{ZizQ_^DlGRUkg1Pnc>9l7iiU@gNxW@=k|0|uL zD0w9%4OeZgX@tItjaM_qk+SYSDTW9sF&b z{mxW+ky#kx6Bvv~`t%REjdZ>>QZ*l;=Wg_vQS_8%pf5qD3<1 zODp&3k3^nTQNdvRV=ll}?_-#vJ;OZx-S0tf5pgA{>!|zU#{%K4liZLLHADF=V)W{u zz+_0);wWg#Js>M5s4bI7Emq47ni{e8b{@TA&TA09vgr$KZi-hdnpZT#AZje<`gKpo zG}|qN0J2d!KjS)MfW)i6gzHqBHK_q-Fce~KJkVBa3gYzsn@d`-B*}hu}WMuE@@vP7JMyR zIY$#WR-^s0C?;IKnXWgc8S?`VJbz`s7^mM@x16r4(`P{qvip(UW$J)=(S(bim;B2& z>-d5p^6co*r4Yx+3svHx1P(B@qZI7P-M!~SXBaQOQ`71C41e!n<_RzF6)i71>z%6# z%z^f$F`7C{!W<*?L@4irikAcLE8qq2M6dqC@WFY1V9PcCHBd*0qL=myqt*9kFq%hT zOkjnto#|9w3C!<>WL4#0H2=?;I#q-mRRL;^{*^3JK{*oaS%N(2VDW9IxATvNfL?nQ zBRI6jg%A$0&yC@9VBHhHCGo^3GE#Lg`oiGg6EU3YQaIe=0~FQoWJHX>eL!}5$x#Hk z>f4LF)s@O_6{~m2(ls?gR@XDNLydAfgtdgINiK4}v>Wi#AKPU|b-u71dj8Gp$VMws z^Y_CiG9kZLE=BGxc=hU{ntl_ky8Y{7$6>z5KgllZU;oz9oZn>vaZ}jdHQ9gmL#>uT zDV2|8^P>pu*6mT%-z3bt_o;37?E%t&f7(awaVM|qGb_Qeev4KrFZ2dac&>d@gL@9W zXmfnV+*$aRgx7k4%kbXi7;R!UnD-boJ1GW?O%7Zev+UQT!b+zu=QL(g9iVrAtkWVO zpcpf~Kf$*!FjMlH2S{v^_4YuGELt)Hu!}s1zS7*9SzL$HN(5K@-ibE^Yql{fqzS;y zIW}IQ^0dX|0Y0`Kh|6A}2Z23K-hBDzJJFPA;%S;X7wsvj6Y^TVhRtuP7|NP+YQn2O zyeG8ZrODrai7%Y>BqG^xbM;Rj7qME8PP zyjZen>5F9KH!=Ru0M9m5yniv=_Ac%7lL11mdNv)vcO19gr~JW>oAwV7R%C$Fvj?R; zgczES#)z z4!+z|9^5Ps%caEpz$S2wdb=j?l~=HHbuZoyh2RT@tfn<8{{qP7(}BmG?Ly2qyh^Yr zrn+-dv^@bIN{&1ZF@lp{}Ds*^mg?B&xB8IP3$N!6YdOU4Kg<~*x%H)NaN zDZb%c*sF(!|ED;H1A;)r4?-5N#W%NFE9mxxR*HdDu3vw2luYj=0L!ok!!b?u|2pYG zySU$X#JJ&SpP7e#$Fr=bA2pD>^WLQ8P~N4~0)7-X*)C+fM&#U9gKj_u0u@<=Mjbz@Bwtq8b$pmI+00@Y6fquZ=Npi=gFoU?2#9DM3)FI<$25T zCwjqq%WsP6?n?tCpx8dtCFuFOUc9Garb;ugAq`WAwf&G0@T+%@{u~)?QhD55CMc>^ z_hwvJOZ)fnFOrg|^5w7wUi+Ir<)x-7&cSX|I3J4Djr2S>4v6z}M@%R1jYF)MJ64OP z8&tArYv(9G%^hr$8dVnE{7k!bh^oN4dPvHn1X#xC+l-OGdji?2DWKTWj>ITFD8$Nh z5=%@A7Bkfr!T_+6>r+)gEbpdfYROBj@Frd(2wwV?;guYnW`x!UPVn({*gr8JD?cjo z@|6i2$Q*m&_H=bj=0l5#Pv*O;Cr+8`7WSogI=KZ^|BpUUkiMk4jpE&Gi!lOhV*m;t zhF2d??K!%~|3B%~K1FJu-^JZ!;oB(iMo22rlKBqO zOBA6A9NWEE^mCg~ft-R1w5}m;wp%DDvF1)mas)C)3;ZL|7SsdQOT0bmc)sWTd&VC? zyDmH?3Fdbf3P^J{%H_%j^enSH!++^HuF_Uxq3+g$!P%Jvcn~&Zef&Pcvqa{MxJl_Y zcY)-Uvz6@>UC1cr0?&)EWtEQ~jlP#@%n>8!f4ta~+Cb%%XtzUCFYdG|9793^kx*pd zDelO0I^juyqF8FTUvGE}=E?5!kYgPS)!~}&+!|D4`VLcKvFO4<)|@$x$wLYPNwa)O zo)D&W95Jr5tWh=Q)a!Hf=qTJiDCO>QQyt#1wR1X$L^IH;APeolhtIQX)h8fQx6fk& zAzNf~1xp53E4ghlKjX!y4Dd0*omKjHL@qk)RkP9^H2lsl6I7j9B&e5+ zx|A%xGZYW<%zFWHInNF%SG@z}qv127dy{u(?{$gd#OBF@QkpD}pF%)G>Va2Jn>wM; zuA9OvC&=kjbZ@v}+!3D2kM(}cPyBbYlkw#DjB;tOx4b35TEVuD+%Q6Akw460z-o+7 zl!!uutf;)O60L{oh zv*bTQF71{NV#(zbYb1O9XBWXyoAKDW+rsRno2zpN9;7M+nOh90fNY`MklV}9kbv90 zd-B@;Zja|5VZtp0RY7#%RJ^kD_R1L@b*im`PCSE8Qv21No6TbsM7RRRzGPKySrt{d zG{Z9RumNA>b?6`D`1}-Cv~w^GsaWOhlCrzWf2*Q{{8{@jZ}hWus+@pJ4B2*mO?6d>#}QnQKdX92fsd87a?Swu z+g|Ao%z{tv#T-z*;#qP}Gb4pl%!)ztN{4$+7hj5leI9lbTG(85DTVc6E>u#22fYn? z*qdUnQmS1smqW)!J|QG0`G;OGB!yPb?H8Nf!DqG#{ga470y0eFOd&N=xkY{jVcy3z zQeRa(Gum#R(u$N^zdp}7C|c`xm`4Y(&=N;F9DYw#^EUi5l2{o|IYeIZx%j5bZ}&r} zgS=hxuTfx_s>6fy3OP@EhE9A}DF#!Cug)6nZk9kXV~vr&o1b_9mXc|!Hx#pYZ%7i) z{aW@LD9jAldbeAclWza=NCBc|PtxQJ#D6g2-|z-(;^LqtWR&#M3iHQdO#Is-^XejP_B9 ziVwEAp5J|`@i_fGJ!I?ztr{V;KEBD;y?!Zq!cg_>n;u{j!#W=;d9`Cq7Ymz$@TSK< z4bB$LAyDaVB$Lyo49Me2WA^N9-)+2Z@*QElw;2#j8pi`83xR2{Ttuqo#@A$?(Pq+a z_n?3v`72iuK&^n~7az}>;CP;1d%Ud7AvUsY+x=uHhNG#;d4GJ+qgQ1}hpn%p%+avp zta4*(T=gjl!g(==gFXJK((JPkv`Pckejy9Dld#C&!?V;*&FjL{ zq~|`&i!D~4nc2!%GZ&@mogyV=ld0fOvau90l`}(t#knIGPlLv!S1$lHN9=x;bcBDW zHLEwFqAC10u3}I2p`%)hZWsWTUgi&dWC2-`m#rV@=>8Jg_wlI%1t{Wf9I^5Zx}F5C zJOGJ_D;LOaUF8nBsDtfhm0{PB2LcTt8Etow$l_67NoBXTV7tIeDfA_a!x*gsXG6U2 zS&qGC3zJL-LpB|8&!1dYS9vk)w4qUW{@H%4_ZRfa4G&5kCnLy-_&w2XXS>{?f*wON zmGpq&X-|Pv5~m zEtR?u8!XZ%xVS*D`oQ^k*E>628)G6-_07AcJ%^o@{d0DSBgDd>zQvLgel=`8H^S6f zQffOQ+O=5gmRDELWA~CKblZq5=3JdC3WbsQ9&+w z*kTq@&zRHVj&;Tvj-f~5{M}A^<-_u||cZBE&|+TCwoe0_GXsXuj~Vh-+qay+#aODr1X89+>0pq7`R^aju-J& zWr|*a+?=330IN0O+1)tcN z81l=hlod9kj@~~&oL?J--$~0-MqFG80i!-i{oR%TxbJf7%h+Nbu-p67R~FY6)2ScW zlG*x1mX!19_0-lTRGOS+L|ZBg>ZzPNA7eHXDbJrbc`6SztHJ2DkV&u%(gHOEO@o%+ zP~b^nHmEC>Xp^iw#+DoZ5dEfpAU#<4aTrn=irz}rUBBAegA!}0m!EQjPYfLbON&kb z8HO>k*eP?OY*)1|Fve`eK+d*mX(8Xp;-GQn;o@WBnzz*4BUF#= z%oh%ha^yCXI0e-Xwz6Nw8Sk$Ne`K2L)V5ciKedobLMLT{ATGt;e@88;!mh zs`0CXjiN=b6ZmW7j?e=glus|LR7Zg9I!~`><8pdizZK@YxCHuw^6-N7SV_zc%nGZA zWUfuV<)d&`_%^m*mP`F-a7T4Q550}QNavo_b`iz0C4G&5pXzf3O$!w*(ktng)?ldJ z{a~rUM1{>Kczc4>nwvq5+IDyZ-lGg`ciTFs2sUWxoS&nVJ6{2R!+&(#WOOdib zK%e9Z$Y>F+3k#830BB-(D+=NHI@>bjG4O6&%fXnf$m$KX{hyV++uzV-@N+-!J-Tx1 z@4bkY$4g{GQ=*M_2cZqg69Z~9u73pYDBEJC+t zTf0VI9|`{x%6^7Hf91C@EyQ^B^h%`=@_nH|wOyt_tM&nila-xt5>^^l2n#IO_xdKO zoq>_%lpx|IU2EdPlC~WUJk2NRewMQKwIdO3g|gY!LJfJ_m_ylRN_+->VrD5v^%J6g z(faJuv2x|cOGAUW{>YM${M|qzV*zVnsK6QLU&+`2#ADxKklc@dmxL=0P`7<~DP7*N z_fr{bR8w)MTG}XiwQ7vc>Hc*1NtM_4e%7+ROM#uwMBSD)W%)(JbS(Q$-^9LV>~;u8 zHZeCRwp~WL)qX>&bAxYN2b_vKz?v4CH4;Jo)({kZh+o!e2uZsC@9llQo$p~dzehfz5AMk*vHmf8(|hg2?iIAaS& zMRCJRg6}7sEjwTA<)aPy=dhBTZBd@jv={u60y9=8}r>UM?crj zKO?3!pDbX*Mh+zc!TVdZ5EVi=;5mLN&fBaEBRz`b(kjKp+DU_|IdNLrNa|(d4o!}K=?yjy|dy-HoYxYi`-K(XmozPyf{>>oT%;U<${a60SX_j!o-H};A z0H3T{unM7>U7CV{V%d%1t)Bdxga*AZJcbDd7kasMEqwjR(Kn;?{0)oGb@u5uXoZUX z8vT~}E0hml;*G5Ihw$op2cHKI;c=5GPugo;An7HT5F|s->b`B{dYkKldwqeW zm*vbQLqycUrN7wJCEEDn_V$gXZYZeGKaj=P^ku-VK}xgk@{QxA-NEOC8Peu2FnA#L zz&~(UN;Ya<&z8H0(bLpLW$ja(ba0dd)8uYMN;RHYPafi|NN`JUy&1P*Z?RDfKvvl>GM`XvqrQ*Bue>BbU=yq?ac)i)Pm|0TT;rDc@laM^vd}>8mVk{ z@54+6&MW7l$2T1&NW0MA?gw|<_C$Kg@eEjPnQ2KJt-2N(Cvaph`u8cp`%znc`s`#1pbs`)r5KEdyNgB11_u-rXs zy-FpKglB7j{+s^Rcm`mCI^;{Jyhwi~)a}u5+V1Vd>@*}LcI~oQnjyl+*mvoiXTy&A zMoW7v&m88LZsCU3hBynu3rK0TUO~0kldNhWVgj0mO24$ zxwiYM6-r~+7W2|+uIhANi*z$`d&9TzpT0Q}m zoh(|kzI<==^DwnV`(A%|pI!;Ld0mFCNYtHQoKw%PQQMXpufS*)e?;Rh`{ioP#FbV< zxJoKDCG=|E#6dCNWNaG90cl!zY;{Y}Nno@tg_C}Q89gXQa*$$g&kTFQpt=;I}om&*D4Aknmuq;1A{{mz~H2f-|JnE9{c;%XsQ+RuN7Wh#h2QseAi?VBW z@D)&|H9^lLm4QK1*4pg0g`+swBXDT~w8pu4otz5a~l$9~OXTfZ~4O1Fq7plCQ0PG&NGemlbrH+2(MMMvqP;#eF`ebXYKwWFwt$L7d7 z&GW+4tFDj?S~ZtI0FIHzrnvm2ph3=bm$7!U2}+OIujZi@$VI9A2>~Iqyw?+%{YpC; z0*0{ZPLNi;4=b%5@j^km_Fk!;#T)l*jyfkcnA&m%cBN<)u3seLQLnR&bJ5Y2=xol` z4hs_W;))BAmI7m#yD1gOoNjI*V%wYq4bl%~(KR$IjY?MEu?BEN%{Y3)Onu#NrR99TvE@25QHy zub1l~tXl)8f8*`uPqA8{M|Y52ulaZ8$Jw~xQji9>2&fG7?B6&DP87gPmUh=pS?|XR z&Ma=bq;6$AwK`wqED3*ZZ47Ge^ylR1c~Q^2Qee%Z_f4?Ts}G9QbkP$R3K-#5>+Z}` zW$~`qWBjzL-Kz!92j?Hlk-cqvrrN^lG@i?bTRhYGc;vAtzv>k7!%+i?op^TFqu{@q z>Heel=_pyttzq4Rj||emPj4Y8ud-;LYMr7#n51P@9spUI%HroT!|D5~3DV#9hIW*mGkMdVL6a^vJv(qi=THvs4M=^BW<6> zy__qThj}5It&V?cXFg-KPCi}fV+NLK&M%~e%wId^Dv(8X9C(O6|4WX#qj8gh$%3`} zceKQe?%vz81#97cElgns)jx{)=Xh&ZeI||6%9t=~QqFK$u*uno7@T2Sx+k=I))0l> zWtZRT%ZkGe>Xf+aZc@<~Y$)Q)3Bbjh?VNh}AoxzGj(Pa>(hr;@g6mY-RpxD!tZmS9 z5$D60r)?_6FM;VmYOhIv&KZn2n!z$4(?B&jxLtkhEPtX?ABdN%z$j1Mnx$fl7ax

jg@(bE7Rd0LaKk^?#Fi3+{#%TGjUe_#?l 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

0I?^mpoQ39)YPCXTjEQd0(etOf{Yu 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 z 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∨z(oaCXhMuHaw^ef90X`YkJ>XwQE2o6dCq#{c|7%TV)w@FySI@DB9&-U=G|nO$$a zYy*Nbb;d29_nNZe)noDXfHPVf6u3(k0>bz47tSxHx^RHX^3>P91P688889e<(U;u; z0txD>wt^lA-~Adggi5% z`8GGLM}RWxfxHiK57=WEaIU(}zNm4s0=NK)OEer5cTCUIbF>@M{srp*4qXr+A6zX4 zT$W0LK!U&{K%id6Bwhu)EqC`(ZH#6e)BO%+{)4i;Gx=RxU%zVG&5vwr<3&5XxlPu= zw)HwN-uTSh&1eIp0CxcuXe$(;?fpu;M%Txpc^^xBj>N_)n)A`bFaxY%N;<{L$LRo9G)M!yj2)gylhaEdBLoh+Lz2^Ut${y( zcY523O@h|8NotD{QK?v6$}64%YmmVFvx`KTh!C!3T6QsbjLk}qdP)#b*QRoYA)ug2 zSa~{O=E4LiRG7GR2uMxdl}mL}xRC3$g}*=4+hlKOjdGiSFCcSC^HMp}5SXA%b8~;T zV*FhQz~2G_o&r+a-J831SlzexzE2$A+g*VFA(aE&p`r6geAC>xqiu0 zzcP(^hXlpG<$7&ZB>X#4Q2EEX9pecoPQ*YVz$sILKp~>=yQIOde|BKCR@MH(U;1gQ zpz*)(EiRI20QsU_dxVTpK@KGVXs(K?#QF%v0-FLVDG84RIHbP`0?z;fU<bI7@*<=Or|4dDFFbvMvR{051A72)4!wwcm^Hzm|wYqg|H1)Z1pPrIlE&o z{lomTKM9+VvVKm+$u2vekEJGzTe)N%7XXl*d5yVD`j+9x_;@jam5UnV)4SS}D$W)J zrjpFN`M-?*m53`hs)fQYVDV8e)L{iWHrt0KK;t&SoLFP3&7hfJ2{OR`Pj}5=>Q#ae zK>H!$_LP_r;zhhLy!btgn^}6+lsK13}K<4pXn3zfhqx7Eq6vIPPRzkd4DKPGw3{1No z%Q+7M2;RtKF6Koopq_azmmgiPbz%g5sG}wvjtCZtDQH$kkVuAt)r}1q8QCAy-*SfF zPW@G@H!60aM*b+)8fB#Mkq9V`R!M4ENSxBy^bgpvqxq-HF_0H5ZhCS^La{)Wuw?FldNZD0x^N5N$UyIOh6_h zQrDZmeBGJqYj6H#Yf|+u|H-Rp(wp}7|G*r?4`@n&PZ8{zo0`RC1b}kg6y+A`;L25ur6*ztt&KC zePvvf@ALJtF0k~{4NG?`ARyhK2-4k+fJjL#-6gGbN=bK@bW3-GbT>Tf_gDYtGcWF! zyL;_@&CEG7XGTd5n0p%>>ToEs!b6cGl}j~nrSi2KrXpUh{N9iWb*hjS43CC1;Fl+l z?0!DH93}2W*OzE4pcf@yD_(eJ)r)Y3bfT+}$hsBWlGJANcTl*}Bv@R~?bTqt@HO@) z!ve#me>(SZPuA{dur25#)>WgGQ2mw=r~Zlw1PCm~$>U}5)O?a9&aH?UmERt3=SdvwH{(x<^H2wDE%GhZU!GNAL7}3szRy&BW0;{p#jPRn_IrJA zr~+NK=^U`nluz=`Jc~oM#6hzTbt!6)U6P*{N~7ZF*u>iKd1a`}%f@QP?JIFb^;fF) zOdS+U)`pamaaZ;hVK^TS|D8|}^H3h@&-OQW}~>;rnjKoWJ(i& zXtvI6l%gQnLcVQ2dd1<0zL9}}O^oh%?x)Ry`%opoq80dAFOVyOk2&=#_3a0P6GWOJ zJu?&pLCy@SBdg$vVDsGj)Uy~zt6dw}w(**E?IjmXky>MnX3<1o%ENUT?t#5i&rys= zt>0khnkj)UA?*hOwXD(;(0CrU6sV4>$jwsI$yA+IcRf7rUG6^-r<#h>7c(Xcd)trw zbt>MSWMIae!zWSBcCN~13{H?Lz)eC+QW6`aoCN~DLl-)vFSvdq4JM1Q-#~4&A9K@#8aL>i zyO;JHXYcwE_36i9qe0W;ZSM;NuG^mrlcJfR>QwuV`8Rp)2wF<`cFpsZ*U!m9ZG<*g z9M4a0b>=J=63TFrZE7M>py(3ChG}Td4_+RYd$PEFB5#=3FSSVmuFbR$ZVb4AL0bRZ zECvZf;%MnbW?NDP#KT6SEs`Vcl85Thdtn$=3G#$f>D(T%TrBrdyE8D4A7 z8Ji-P#lN}U`dlpVymUjnw|G9LoY$@~X?spvshh~OoHMr zpAn2MX%tVfkxhJK@FD0XRJ^57&<~pThWBSXKNoVp7`EM&+H3oKu{5~taVE_^EoIqzPtltDwqPO9`D=7L01q8sh zzb<|>=U(e=l<7TdCw8`|ZJg_{?mJkYdb?j@KR4`i64(J z2?jzUqj-He@9XTg8I#Ed9w5RF@u;lM2Obe@;Ci=Tx{G%xZKDdZ)wFRhk6uT?_eSr% z_PZ)C(uBL4hXb0mNa4(L!O0O~KT(uPAF8d8uXD~MI+i-pU#33Aalx39f)F&`mV z6sa!;J20TNBW62{et`fupZ$e55RGDUo20-_R_uE6=f2ArS!}$YQh?^Uj z5jif*)+Vi8Jb7PSvvBKWFjecU0LF+r$2S**EmBm0QHrsqGm~l;{QZxQv%hk_yOdx3 z#J?MIJn$HlSoFjLyMQM}3XM>pVz54bAJC1cYg0i6$3> zH3^!kw1n$ZltZ1m+K<7-x%WDDnN+#`4jAm{s$GdhKCi}7yk9NH;zUlXA4bWBE&VHW zv4gh#`gG@VpXcpr1N}$qN56}=vtV?k<8H` z!9wQtgw^NC>i!kH{w8T!h z6DfggzxDof)&j=me|z}!h9$UmVl%d^5Ip{rGTL%5-^{1q8k8YSc=X_&G1x`fo{I&6 z#)M&YQEb1tLHI?UCxYLNguOIc-OC@s_&DUHi%zS`sYSZFaV!-+DCOOVj61%aOh_H^ z9-Kl%(_JP3SmoHVAG_IqztZ#Kx7%al;OWMela&bkORb)YiiW?OJjtaNP%)=S6A zDJLpOek)IjXwkcn4YY_tj>J~=1FlOHvMb|#d_l4!2$tXd)otj_jBp`r0F`++M}bBW zY#DqrUv+tmF?=UgQ^*L z7qBCc$23$99Vlm=d^CR2kwm$6ah%iZQ3C6bbrGHVA2m{`{gWrCgTb#;-%G9_&SRRV zAH1KFl?|8`B^|Onk;xmOmEuj|>NUIK81*??mHRe0?-v|3YGbY9-Utc#eAm?qpD9Xk zLly-v`cyIEH$KzZF*%@CT)__oX4gp=2+pT(d}I$x%*47s`@F&v49^sV&e`3nkzkGP zfB>?|-*35`Jj+NPIrQ3BaDP2d5HOQN?xy%S<^!J)7h2tW>BCOugBwg@LquxmsS|pr zPc7{fT}57lyHQvLAz4-l=$OU>hJ6r#**kzk1SC^ZWd^8%(13x5e6tl5c2)MYe5@UP z!NH;5Y@4&)+OpUx4dXhCHR0ARo;(lra6bOyuQb8+(fN$*-me|$ zMoB^!UOLnCr)8X(^p486b@wlr7`L57AQcLmOD>f$0Y&@(?%sP3JsP11Ilqdp@U&sW8cbZ%ZO|7Uca>Ii6XfC`H>M>;Y z?EfbFaWGMKKunk{-Pq?fsaC8s=mS+&Cacs!vDAbV4H}eJ4m)(^V8rid38V<5^IQ9P3rm|=v6HzCytO-w={HY@@M`U6DSyBPx(O=+JO1G+|S z+j@g!o~S4a4vGC?>-@z-JJ~L&+UQK_cu1mR*}n{Jw-SGr#+>6blzpsaK~qum65X)$ zQ~g@I(%}FfKM(9}#d3j${SN;CzR{hy7naqPs;I5DOwzR`?ToQXei_VW6Ju^$8y?8< z+V{;DKJ(6vr*_P6FB{vRS!*B247Ct$+6N4NcqPM9+s6doF^`m_ex{zHgC}pCOj)%% zbVE#34jEPtr*_`UY+pPnI{kLsS|hL63HouQKcU4`VVySz%;S zrx8HDZc=y)A+t8fZ&A7L5Bwn+C5{dIKm;<2B5vC7fspKfOXNYUKwM;a=zMf4hP^(g z9Cfs_{UoV-dR6`QZ+KdVjFF9UMU<^X`N?x$DUKuk6g3T!0Ep7Ziu()Ehy(S>7ymO0 zfTEMBKEirk;1Lo4P-@QFL%a@zZCu>zU-lEC5AdZS^Dk;l69W5rW2wV6O)Cm#AQUWH z==-oA1BM8d)%sFGPyNwK7VrN0p4E8QvBz(O^m&%dGqm<9 zchd&xPv}tYroAb>zT!M2pS6D!X*0XO{9Da>k{~U+F1flZDy^Hp@uk8$G4z34J<+Dq z3&0)&p2=zVl>FKyB%tR%6dLtrwM9bbI$O6j#ulXr$^06ur@3xlBG;7S{3xb9^pU<3 zt&Kw=K;VAS*N#dys!(sY$JR*-LQ(sonO@i%sFEus_E`2>IL;xtCP(cE%7|pqE%OH{ ziq29M+Z#I_%!Q!ZFZXlY41s5l>-VjrH!edc%aJquOf-UroZU&HQc#8h(TWjC zAwr?VKu4m)v$!n&&_n}2YN+^n#K*v-SA>CI^;kY{3jRny1f09c{w^Td%dnPpaXyX5 zP589?WX6<@n<_Mx*WJoY=58p!Zw7HF6rvH$bv7iRE#1*XqjJ*^ zVvVnV00D?ULSId^Twq~3+%u$u@}ED@ksU|dvgR5jy-g02*8C@aFx+h#pxYm-3 zLPw$4jyk{#<)hNN4;f4vi&0;*&Lms)&WQ*$glrnGR%cp@_Y<0oJ6nI$zeqo+y=k5O z7)sF@CTO~LM)Kv zp)V&0cEGN$mw|M-%AzKHU$gj?Wsz=ZXfw)qV;xlGnG%r6Kdk+^xW*HQI=~9bjdt?n z28XUCyw2U|l9t6M#CC_j<$hcf8=z$S`f)mSeiyQx0ae05!fO?GaizbS&+K?bN7^!a zkq*HN>r<{;a6J&Xo|46O{*I0?xgB((HH94+?k3m+YOz4sOf4*=`l8#{*F)4yZ` z?$s?-ZQH74MozM)(Dp&ZU0$^I1`knNhoNUV&HGZa;B@)7w~SII{0YeZqTR0??+snk zj*E|wS-6I;S+7&t)(Z%w>fg69etwa$eFX1b19B0p2n?Gb;1%WWn+W6YgHP(~SFKV% z6UuyZ66mEL84aW==)CuVZ&wn>lhhB3or`At{);fWZuB)sk3##$z1ljP_X*R}BGyyJ zy7Jxx$ae=57`C%PXYHf=p?HsCda52H|Nh(awl3ka@E(-yW?Xy{Ngz+Cmb2BP!2q;ik=p3 z$&tx>rl`p?+jSz|i59E6dnG6f!2e9=ito9p z&5F;1Qs=VM`3`%KYrRQT!|^&h+Dk4J4R;O@(1Jp>FE3^l6;BMEIJwq)rnr1D`KW{k z#A;#}8JErr7SRVwPAV_}jh^yuj!UXFkp`|h>e2k#o1Dh{le>E3=)`HiXZyTE&P8CN zVa)8T=@Z9vpA2BkB@PQQZ0PC8R8?i@vq-TS;h4CMI~r6f82%8@ZpbN~+2!ZEEdn12 zS{eNjv#Jbr|Na};`xI*oj94OL+wJRyivh8lHFhThz0b0?f{k^d`x2|b_{|@1$bSf< zN4sgjyM_MdMgKCP7hp-T?~5T}rjbR)w;E+}#HOEQVWQ(-xL@=Ng9D>L&&;l93>jiw zqmL|9?VpTnKvH-`A>E%yF#K%76lNWSE<`KB(EKBlb==*2oMMfA*;s6=Gc2pY<2$Z@ zVM2?2w1dVVB~3R}k}Z^+a4SNi=9gr_3?Ii&tpr`=h3|^qxgGG$2(qr<;ls%?g-d5q zHBEKxaZvDZp#lA8r}2tfu?A|J;YIBZYklsGG>VUMimd?%vBw{1_j+PQ&UBwbPdwBq z+ge>vijB0zXfu~Su6Q52KJ^Kcv|7AXkvW*LpEbA(Ei*yz+p;I#<9ugK_cGjsRa6q9 zXo{L2Xk2*8Gt~WZnfCLbEKT8|r`9m;auV6?oI8l1MB;9+5u7 zxn;_aWJnu)VvnN$o-c!~DEWfLEd%nXahAT`YEuRvcst#l|E7YHe91@0?5*Vb0SEAu zj3jvS!j?}~?zS2Rt)^*HL&DF2Z%f?yl##N}aL+lMd}5u}aW5vfiR=iiCs%e*fO3G7 z=8Jq}>&f_;gS0ALZ`!ytO+DrJSoC+(Qy7&%!-WR%Ggryx1-_4Se|{JV=5YNICij#W zOeD`Hr{}1yy5sa*BgT0V5aWNQs&-2&EvyYpHAT$4kJ<}TOBnbN)V?g-YH)*LUs5(J zz4JAa8JC4`&?V1l>YEx8>b|#@ksseKM@m9MSTcZO9+JUzFbu|i@3XQ3vVuw2 z47>_NVUNKqw=1P?OITIWBw9z>_49h2cozLA*_P%}kvwVWeuxzArAu<2)bSDX1VaBj-1EI~(6$ zPDa1gBuDZ*Iv~i`@paF@2ZLokYZwJ5ybZj6>G5cz!%M^4p4PQcJE2oCAIV&pHZ6zn z0@#5C?gBith;l>GW{$#^WW-CVInUmpiitlcyFQLnR~SA;%ZIg?c|ZMx54i2&TFt1K z=KHqKD+M;h&2GmL^K@;pU)uA1++VqC_2Tzl7~t@kLrSx||C1zQ@2^cbEV?u>RrFR) zL|vTpJ=8k@7Z}DIA`NA}m3ZlZ@hXxKK`I=l{4Cy2AZX|$LFWD+hV#Ggo*o#~SOW8J z!+F9>P>;`Ru9~mFoCfG<%!$u4{IM1%w z7@M;Tn7NsiW)n0Bac)FEWLE*Ecnu0EvSt9^^#et9pz5X-1XuH zs{Gq6VJjk6Msq(*Ypi?OYk$t=RvSfjggNJbcWL-Eb=8l&xEn+0GJVx!thjUiMb8s( zUppS+3*5Dd&*|M1E->bA**k@$&}L>WdFdsJ{rr%3uEu%_(ch|?pY~i?Nj<@)FiUp=plUL z0beWi1gDNl*CPTX<4a!dbmP4wR70I-8?XsVX{$lG(A-`4laP;5fkd=Oo%`W+)zx5! zc6)!hNp&*lMfQq{yZ7H7;!*pRyCg&rHco``=_L)>5N`n}AcPf=UwcZN?2XrcsbFS< zB>??0(Uyrpz!Uwd-noNZoUIZN(;ovtH3rCVigR=Snf8OAbodQ5sfl5W5IsvTQuA=* z&mi6Nw$0j%u23c|2z8B)aBh@Yo)Xc3W8{2VhOG^1#@RxArF*?Mo^PU@1?x(=p3F#H zF%J{ibY*y%Yo|5OUv5lt{XyXPqa2CkIkKzbT$PB4674w}s3QEe{@uLKQak~n7*)bw zqVHc;fa#kWN~p$1r`;U;7DNdLhlxw5)eQnQ6UlDEQ@(G@u`|A!wND0A_6gdduqDI) zSW)l^8;QVEH@qe-=2@(SRrO{<;Amk$yKCMQ=yAF)wZPnLewmbctGxY|+UO_)67SsY zj&3TrptSxRy?AvXEYfm|{r3c;!R;R$JyIjr={H)dR-i9Zj&_RNWeDnDM4;@dsE_Q< zjRn2ExYP~Z7Rn?O{k(PiW! zd~i^zTZRomoQCeDW<7Y9xKPLrJS4lbq2e>`ofldHd1@1l?=$i-j9d>ZRny6hE3B|o zJv6LD;DUJq1|fN=RDuxk7oqMU%*8*Y<1)!QaZt9FpAJko);B~iaiCVBRuPuyyUYJ@ zaDPik|CEsgK$%NGj37T5kSI0+EYT8Osz!X2`As~0U;(?U)(!S*)n~zC6ukmgKpx)c zPND1EIAIZA6q8D38FvY16}9s7AkFvM*`MfaHqg1bTn}Vj5ym-$2J-zRWza;@m#_n# zu1V7>V#|x1V|kfT(!WToLdi$TJGd+vgkYUFi*yIecXJ;s#wou=fqvfq-^3UkbEBDGutG3c12B#ZztrC?F z#?tSJ?mp)Ht{pG27kPLTsr-0e``FcgZP)B#DAIC;*rew++IlvbQE}*sW&0RNvS%jE zh#7*`t{FpYguxg0I4)cP97yNwV?tHNzxbkQO#8ynAhUtbExnzvK<5AEGyIQ0Du$~z zR4+?S|A9@XL!e`32v&$spRAqm$ko#Eqte;J+O# zqkLg91e4 zdE=6C73S`g{=25cxDmLKx1dU?7}RNc-S|jO+IbO4^5%QBAnzf%(fZw{Puf?4a-%ul zhbIYnzEkUZZ(qyJXT%(=E{?b5=)hcrt4+?^`{SM&IZ3FN7<0i3ps@Z~KHgp%(B0b+ ztBOgBN*+-~Vjfi)_WoKanD>z=$=AFq3>?QdKn@h+6sFHbqBhQb36z@Xzd0v@oMHc7 z4H=ErJE8)*W&C;zFMLID#c0REI|%-oLo0OEhTF%K{b;|Mz>G*vIg;o}EAP##hM4a< zKvli>P&MD5UeiNm-`ti56+aUI$sXZ+3iXpx=;f>Fvd@P1RXWow%N5uWJ`IXxp&J`J z9Ta(&zDnSVWWRmbYGEtB-u6Yx)d%;Ff3Lkoiw%v&t7l9#{yXzxIX0iiz-o5+YuZz_ z!q)PS7!e5i)a^Rwm|s^kjE=78Yg?*pO67t@vt+$qb40eLGv^zGWUW#GLa9kG%Q4>< z@%_0)DPtvEDj*2>Gh6$9=Sg~y&}ZP$A}W_c?W?24vzI(TXnku?FVBnZ4-W9h>XF5M zX}D}mEcbEd)C$F%;7W_peNFU%_6E*l+T3)86sIUajHYE1-Rixs=+`+g0=A0PCW7pb zq{w~(uQnn1N3(xWzbG8}|F!l>e}F>ev{%Ec!gGH$JZ2z z=V+=K>MwpF#E0XG0IPoFCxBVHHS2TrLIyj70vV}ax^pcOXe{lRq@P%&+^p;F)QgPBa@bHpc=vcyKnfi>}#(e0dnv@G`whN6? z-l^%Y_BObFlLP&zk0>Ht{B4;2oaf=}b>tOQ-=~U0wE#i|4?(n6sZB2!>q&8B>iN0c z#Yv2J{Ww=YvcPr-hN5qbqF|J##L=IcK>Xc-7lEQSviV{#)z{_EmViGtxqbn+l*Ugp z9P^PP^;Uva*QImCF)9-WJTr2nvKOn<^5h7B`6qZuA`a*2IUDL$z6d<)ku#}iM_U>O zWT|q#6l%N?8mPG|jXHNf`8wtda4U@z`>rt$?Le$2NfE>!^)1p=_(6CNo`AnMom||$0KCtK8j{b!# zT?Dl0@`db`UV~u*=0M{mw=Y0$Me|6@p0Gs`gC%Mnun%iT`2EM(SQuv}bTl-+u{GjI zM7pAwH(>|+FUk|TDr&V74v$u{d;4UG(C$JVpnuk!rA~Ese_0DxGaS@#v{;rd<2Riy zk&oJytfhPcM=)207%u|0gZ{`((gEFhg)?#U^1_3DnL` z5N?DXRyG0gN~W2$NX^DH%XJ19hAT!?1WKuI;kOYa=Lih1d- zYK zjzS$=BTEP00}v_#>X3ZSG?Quz(117&KYVI-6)t=hOYE5uu$NeKqL4a#NVXE4i&&;v zYf9b)!5){q_Kz;P7)a+V@qVTmiLE>06QNJghm324=5TfwfSv!TbNtug^Y{Vwt4hRr zfWIyc6kDesvmdVEYdH(!OVx{&0|P`jMw>p-dhb{*hgE;lR`BY3hu~Knpk`mHUulj8 z)IUmt=x?-Y`Gj0iQX8JLtvrcz%qwy_Q+vU8uLLfrHb9 z;^}^E-om;A!?7xSLYgxn$^H)H(A^wak^=bRaY+?r^RsKYqM-!#H`D8DLOV;`ptdKm z=Nob7=qk-x<>9>EGaOY%&yQaFS68KDrSr=UEBc1ROln#IA%yR#cZW9r zw35GTs?~3f=x(rl!}+d4wHDHgG_f5waGG_6<)0ste)eiZtV&xC?^yFA$KB z-FpbPZUknOU+y+!IIycR{FmTL)dsV&t;j48?I!Q89S&Nz=7+rtU%vs;#}6F*CNlWM zGG=5&87@pqWo=hnH=zp8BCz3DAL&5p{~shi_aK zy2!oPuY-HZvsTt?9E%mUkBS)Do|N0nZl7eocb6_FtBHJSv3B@L2a;==Jh$He&Z# zZ6x}3gxfa-%PlDUOJ>T&1IcJu&)$#JC+0uR1LKhzDEZdklB8e-aG5Y%sS))_(4ugw zuoMf?*KBhG3lRO|ouwFpWNv=x?_!X%%`CI`(vmWv(2E!Rds;pd!AqTrLX@u}1!VU% z9cgi5dn=swPHZKh;Fu`yuES{85+DBRG#&IbMSnRRb+V^8@y;bAQ~4jL*c4)`)cI-q zo@9XuwAK{semn-rHGr+~v2i}iH`@A^(dlwBfBVS(V;Ka%qo>|V{a%A+bqO(1p-hzo z=cSoVncvHv^S^|mXJjzox&qSZNx{J#yb~;Hy`ObQje{#(Da4q__qDF&HkZW9N+tsm3U!d-T{UVL9>*1@N@4|}a_KUVh%(KH_I1*r4H^N^e^_VwhgrfQuh*?z{A z%beL-t}7+-jND9WZzDKqusF$%^I&da#bc%xjnB5(dAKnFz8TZrd#-UR_Ep)-Sna{H z7tX*V&XfdAO4 zBp8HL0gNo*SBP{O{-d?@XZYKc>}69h`|I*JhUHXdN+RHxu;qCgH`2&ElnRW`dtYHa z35=+Pie&6ohquE&Y+h0om)DjW>b<5;xVFh~?`dRFTc|I$p88V1g74upp))`T0z(|A zq|RUPz0|uQ`>S?O?|P^Al-qaFYbV5K(HgiThUsJq4Tr|aCy?1QK9y<+R9lyt93M8D z^hi*5V4+RNGVw=f#lfiWU!;U1Zm&>o{y#a>0X68@&dhJi77d5)}Qc{Jxa@l3g z`=*Ev-Hq)^`64@Dc(iuF6cFTojzySZ7$v6LX>LZ^1bpd}>8@6kggN$jAI-E{*DRPf z<#>^{A#2|$n|F1kV_29BVm2Vr=IjJn*q{kAbku)47 z^M??8Iq)s{K1HwIy91M%=6-^YU8k+#8dkK7SHMqYFV?HVP2-smi#nD!nG;s#WlQwx|?;Kf0+_Wwx56 zRwm)oT+pU>G#xYcIekS#i@`q{sT_K6g*hPSzm?RKG_dX?T#e zcZhYaeiwTJ1tah$5Y|{#lo!4=a-7`T*jayL_5I(#_b>Q`(o@upn3&2!%4{$KeI-TT z+p9S~OTuTE-dYo%pAW=Ly+#30xIfgN(247yV&c&(6RJdYw1%gP@k6CrBChf-8M-Sm z$?occj^|BXEN9qT!lb0f=f||PQqC{bGH&#oyI;l9qsAwav2NTGR8P?O$b4x}34nK$ zr1pRGsFs%5ULh_ZJ4JiFYry+mGpNxyEaM7K16G_tL&8e1#L?ohWW8W_zl^m~`*ely z5y6bq%y=rE(ZvW6>WNQO*%TZ8^4Iz<+eI)}-pp}QH|+VnZZyH=QJ5jVxP^Pi)~~Ia z+G$oTj8A3DVnm_`>Be>udCL`~NB5PVJK#c!!LI|rY2$N$Lps+8^twKA0Ez67Nc`mD zr?yJD_eZv-9A0achvjUombL8rfUmD#W%hDw>71R2YHU>?@#8G9a*5)sflktA+TfQ} z-$U5D&Vj!TM%{<=%>o$1%gYjBM_P4+HeGA$EXzI{byC|x$wlq!sI&+*`HdK+aCckVofEd1_UZ(EzIP9+d}?hU|{do zuCfSOy~^~0ct5k6x`EIwbM6%zVIfU>*?lqtM3@>RoABls)*fZDvpcFflwDDhsc*j6n@2*UeiA{`U~#XEkpZS~!tep}EZ$V{Xz?6=dF3)5GFcZjENpBgWA z{&D{!$^|mR&#_7_n>4iw6CH(W?SIagJ27E{hEE0`bz)U>?H_&@*9w%(E#)&?aV z$gFsbGJ^v56b<}>(OTy_bkR5C`6F{nygWyTq;%!f)9(ztFap{%1b=F zzAgoK`JCT-@cuZ|@!5*;thQh1X?r3(@E3WQZN1nhtl;jj2K2jzM&N9CR-CKJbpq5| zViKrj3+WKCD*s5abo%{rhiO0!MadKz*WEk_!&lZ9Pi+X4-g*4b^Nk{d2=-Tu$+7kg z_|-FC@A;Z-bKKD}`WfOClr%qV{?urq+*2ocw58mqng@iAw@_mvK5M*Z@y>-4-D z-rCn6UjfrU-)~J5h3%5#8*idR_lN(uczAYco6WXP6l03L;Q<2z^kcaF>ft(d z<%azzI2@J1T-sLUzu4Sma?z3$Pk^=NovnO&`$7o%~AYzDg z_II=wY3$2ZOTj|6#|S!bH{QxW83GH;02+TY+&!e@NDmKk>)qxO@7yYk-eCqr?XNkxH36W{ z^coIOXpHzfYF{9}REd3Qgn1jc=y^2$uSR30$Pz3DzAPmHeiQMCHS>eGamLE^-Sj;mMDbNk$37TGh0Ke^%@7qo;rz*3E8*l<5M7$AFDkor+ z+SO29px%D0aZJO0S>yVAa_^$qVD`+YQz7QO(5m7&m0zsqv0*b)T5^r$6Zt|^-9d(QH`!~g(4WDIR+!u;m(*d0*=LH6yZPCw_+RZL4q#L*TO^vrIhY(a# zlZ{#C<%26Tb;nd1sT0nT|5DFBUc%4oupfaKeknDJfB?$wPC{(pu3|Bb9h;!7xyKDz ze+lW~QRz6c`nSXbZdqwGn94K$2|kPQ*HX`;CtHfl!&5|Y4DhkJ42K+CzV+JjM z;26EQ=11J(5H3_MJW3V)dspRTIC$2ujqVEuFTg|4$Tr0~uU7z$_!GgeYq6mECS*OE zsThC;s>@?lQmMqtI*zBc@0Q+!iI1}83*66yojb43v{c%0(y8{!9vYGe{kEjmU&5YR zwKqd(0^cYxpFYU#jEF5sGCdLrnnqm&N`-4-kLZ2cL67S=>UFqV%6hzcWcLM7kvLH8 z&A8eX`w0Tf>>@=PU~+u;C-!krd8LGgZxbpbFUvtb7)8yNiVZ}D%J@oocK>Fh|6!!P zpqZ~!BZR|$a+FbV9k1t0BPVd<_*rA9XS{4nGU#T&>v*iuVAtZ6B*bVT+-)m|a7?-m zeqLD*wX!D$R(}0FFP(6Nw5r$PI}%^QCru0_S1nB_@#V~{R;l`uWhQc2%7@a=SzYE` zEX~VawXOD%X)OkUEe~&yn79!shib1;Cp%l0tBamPCF2KsLGjsq^=qHMbm30(Xkd&I zv(x6mP9Q`SNgRxW>=eEkj2km%$w_r5a^Dl1ASyofs{SP_LSxSx(lrW)yeE9VR|E7> z=26Y^$L3y|+Y3?P7tI(9e8+uG6CHbj?E$LZUo|ayP}BjRc?S~}e$K@;JnbhL)QMS* z1~uvJW4N*|FljnDP0iE%BC780I80BFW74wYUY}p&K>M04Z4ko5btxr(kB&zmtA!L_ z{xa5qIi);p*)di-@!!dzg9{Y;T9AdUxRyxbF`xIywPJG+JU{4qL0Zz-edH_6s_M|| z-_MHu(L2m4eR@aM#+qfGog#xAEL5B*KFGgR{ouW-bZFgT?bUZqd@&`4_08k+po`4$ z{P#z-b?(oHzj){BIolQ&^=iKDG9W(Fyc0!If@{URzBQRs@E{|KyOwS3mwRd^{~vXRA%2T_yWR zWa9a-rOp1H(sse#7Pk+HdX3@v3NER$fuOy$Q76_ssw5}@pz?geIKSD87x{z%F{%JD zHBjV=0u%spP5+C?SYQOLIm9oAN2JxlNk-KDbEE{Hlb?AzGAjh?(2{r^5s4P=*V&lh zMVXr_&7ZjE$E$8Ik=GrE8rBBuggq;$us1|Q;Hw##dxPqPsl-x!Us3DY!v&vP?wK*R zj9~*R1N1w(@9&^%_~(>cOKz~UcVY-k;(Q{_W>ZXNrmSRqaL-k2i)O&%Kq}Zmpe8T1U)%C;l<13;3%(;}*4ag|v ziwMSY=sp46=QS9LZA3nBaU5W)TDX-g6k5~{0V{FkRxcB8si<0K0nN2063(nU5 zn8iArn-W(;q4Uuo|5!H{0I#?Eiy3N>w(W*G*rV0y9MHTW_4j*<{N=SDYptbM=}-4D zh%V3Dp8_AGL@;?Q*0A?OUP{HcDZEYT!kc-A0@x2+eN71zABuGkTL>xf`o3Y+L(r4A zQi<<(cdFE!JX=0-2fC%{l*(?(8K|KWTi_0evC&{(_>4YzJs4aoP&{YNBkHVfG^^Mb6WQt)2Jr_><5Ew(}!-(b=Mw!V>%ZE$B@yC+yF{*p(HZsw?` zkIie8Ca7|0g$YbO6I_=WZW}RUy7o-9sW^7;X;B*a)PLVn_T`fW$5APzyBi%17-I{n zL}%rXgr?cm`#vqi=aO{o>=aA0eU{vOg#k9)dsXbSPwHahV@&9sA{IggP-ZM`oGaH! zcoC#$UYzqPTA7RbCgy?QdrELqjht32XwPX8>vtE9b|`g96Y>z8U&?W!k~+vP+?n0_ z70eo@5%X8m{V!{u41y&ezh56w&bN0=FJ7lRC8*`WxeZ-rA;^5bVR%)k`OZC)F#H3l zia{|Pd#$}eK`?iCjw2xO$v9jv4I#YSik&J}^EfWOE}65Q`^--x2teaE)q7R!F3psO zJU!2Prx*sr&x=s+N2O9svmDOZnyt`9Xdx?&9u@pj7Pamie)$@eZ$0jTS#di$NtTkb zOk~e30!=cvxMoVnxvdX9xU9PGw!O_*bsA`M}0UIbT0KUztdv>t9bnDer#vnk%c+@JM0^cas?^{;4#JQr ziB@;qhv9>I)>1-;{fAO{_H@16eP{k6zy@1Pxbh^(m;N~%+%RA(gjNg7oy5jAxkJ9Afk>33fmp ziBdSYhlYnABgc8qyb-6$ID9Zs%;wh(!N00`%d(c?{`zp0 z9-Eq;fWt^UyUvwBxNnHS~qgG=1Lugd-7XrXf$kl^&}188L=SJ=Gsy?VJk^22JjN>-gHSLBN{vY10~9>34i@80L5SEQ60RFJynnCw$GUsH3=S74i$D8zrzp@FXS|G z?{Uicb7NCi_Y)xsbt!-fFz z4$$h@wJtaC_uC#@r#zCG4x>x+GJ%4YHd`25*MBHLnBpJVmn6ZWy1uF-93XQ_!%pdM z{epbbHw5d#Ums)YAq%y4;5~gW7{1Qd^Wa!9ZcYtG! zYWKrEk;&?Sov37Fl$v=%d3(#{S)&8}<6lk6zl`4p;!tZa$Y^8y{tiSWiR36P1OpPd z4*cqx2nS>uMQTs}VIBT7$D%r>o&!KVD5-jeOBb)LE)%k4unhDIGNOC z0|uRoL<)yw%h+b52%AMY6pW}C%^3UW^Rk@TMc-`D-_8@t^(<*ujX1wcoLN+>{9rrp zMj=5Z^eDDW{Ew4J&3$LcKMF~HZ9xZ8bqOuae%^2govDx`+S00$E4xz7EGoPx?xDi{ zKrfwP==(~%6O%Mpo$dGG>Ik_pz*L=s@l!;VAuDDUzY{&iPYz~xv-wm7uC&Jr@JeB;^scvQ>}7w~sgg62eaH#J$78(}-kPl55{{NH$dCZjUhX^1 z7G`Y6EkX^YB-!+{7iV;PFg)`V*V^oR>YC8suX+r=!k zyt;LQU4rU|Q?_^GA+kA@fD@S$Xum%;S^2agHWBzR?~^yxNlWzdFST6rH0|NLWNa5# z%o3mb#K&#>D7)W_RT+DpW zBS54nZ2VRB6WmJ@O%mQgCG~$>X;Ue|H(wbG8;G2G=0a_9{Y5*Sm2Fbd(CCw_9!(`g z8&TW-FtgbBnCAtt%FQLk!alu-G81FA@(oj8S*6bO=xQv{{^@}^Pzj{=e)q%4@K+IT z-G`o+ez%0I`Pm=%69Iy}s-Up6qg7Y;o7`Y1xBE+(e3-v4M z(FuuH%~?`O&3Q{M+!W`mx71jo{GV$lzJqc(eiesg#3?p>cs&Z4Ei#$p?JtoNNZpgw z4*2@Y#(Cn&P7_-J*5%5*j|ZkNJn*||V|rYPhe~QANU3k)g-_B|qJxD$PrTekMdS;U z3_-_Hc=t(idxb+DJ}dn{HbMiETsTFG@GOZ-J?Clmw9Hrgy31DQ56sMX^a5pnm}00Rc# z^=-&cO4mz%eINc_M;<<`H>n9-YK}nd9S%_Pi?9{|M3mRYAo2H<(36}#G=&H==VEp0 ziw|iNfv>QFvc5%X`dDcOKI=i-Lnq|Bem#cTwSru0Ev|0uy)f-z*)4Td=KEbNAm-R& zK%&A_7)FzX4bB^g_b3t=MZUC>rpyCDkh=2kWb-sVa0%AQR>5sO#CXl8{|g^h1^V9q zqv|cA;)<4S;RYIa5AN>n?k>Sy0|W?e!QFyeaCdiicXxLP?gV|EbI<$k`$qlVqkGg| zyH?elRkO682!^C>&Dz_!&Nn}@*9>3JKC?POOkmgTRkx+O>aP5kj6+%oYc`m?Z>zuy zh*GM*n&k8jL&WeO&i*GeC&^ml!H08d${@X+Ed7(hr`f3B6Aei1 zVZtT>dVn5Y{4euf0zM-}*&*x6r(eAjPJU?xM3}TvW@+14N0oUyTMujSF`OaidXKeh z7&5F4mg8}jJ)EBjeZqk?Rcohe!83J=lMA;_HhpJo(B_BK8RE09jXF+V$39DLrcmV_ zLc{;Er?SGhJm@w+M|kkM*J$O*`wxaIt~bmwDZhTlh7V~nDEg%R&@2b=IT+53LV_cs z8SAH;r$#wIk8p1be_gMBTy3JaMhr9I6%ODTG7OghPq@$q&Ega8x5$P`J(}D}h$zV& zc8Cby7U~Th1o+(s0pd{zFd;*OYN+uaZSuV~mDyJc$Ka8&Xjj3?w7?Lgv5ahG^52Af znI+VWge?)HYAv^j*pVY@@FsA)<>^YyzifU?{J*#*zo_tme$CXva-_;~8NO@{5{z|O zvOEFZ&v%S(3n+8r_iS_z;p1N$ZrpRO9|}$+h^vL?Zb&}lQGHwK{9Zezm9o||`;BXI z7?xx;%JX|llqxLNmq>?Zx1J#|Z0!23(Wz^~>!OTC(Eu&2WGLv6391DvBbYYL#OX=* z6tAZ#c3PdiaApK=3vNJyu>T)54f2@YK}Ld^`a;*z*QQ$;O=Fxa^Z->LjdEtd^`HBr zhc<SZpB&c%JuYN1Dq52#BWyw*o?v7jJB8oaIFgs4|nRz@TBXnxyWt9_mIN`vQ zfmZv7ZJ{7>JBx3NjU0G3=y*on2>@;eIt3}v)?4F%x?Wf;M5VV~S+Yx0|9j%(-}GbR zwtbBx-i28eXZxJpn*VQ?Vg?sXSnF~OspE7K-;CQ=a3QNsjD*vPqDOCuLlem0v8Uog zk_JP>KPd2ij^nP6?HXsJ4c+G&UM_~tF7;X90x+30xU5M4|6brr%WNH?55`xoPrA&k z3q>EB_r5FzNj{BLcN`ip=O`dxhP^KOUTvs{`Kk#x2J{aN0a1qh>?c_TaKC|+ua%lcm%FV7G=_~y?@jL~M4i?b zus@)h+cjvK8TifvTZJuwLa>w;=f#dcNR-J8#Bm~Wa6|CH$kP?c+5M!GUC!%uw`;5- zS?bvuF1MOGpOl&}@^@n@A8yK`Bq2N>gbV^#Mk*SY>H>GWD&^Of%-7cjq~h>f&FR6x zt@>*M|1!zAAI3v5WQU{iG(#|XyZ?(qoiabR@pqGw!^REPAnYnlnjLX-suXI$-& zEuzx9Wi%w?_dfo#xSI5#AH99;+U|6C@^q@K=xqPlW>J)0@5Ft?xj|D!+8~Stv&xL{ z<$8Mu8{z}`oa=Sa=Oz#l0!kbPBsLi!u2Li&{Y@J2+f~-?#J!I7w?oIL7S!eJt1EG{ zt%<6#bC6X`@D~61W)>2F?t zr~60drob6&th7nxk8jn!yLnL#p>Kb#Dt11UR>{Wb)AT-16GmUIzJIa3)u0VtKOi&m zVE^%ns=uF$jRLL$b`9QjFBXGe)81}4PG%^I#w%$?8SBD$P-$zfjNM05z|KfK=i}i=& zF?|6ZO`yXbrYU{D3`f(TXuJ9mx85yOZ^PUeCwoMHxOB?6F4^Q?j&BT3MoC;7T1i>^ znPhIwh#oJBGlt9J5@JH@!Ue{{;12byw~X(q8@f%mLGuxX682wn2O}YFqeknPF*|Up zn-C;W#XbgGgqEBghp2N(i`u;#0R!0n$h9Ftc$9`}F=H$HtJc~RAqzS1s0^dm;Xd2R zcwp@5>ot9Zi1ya#YU^ji6sV(=jB<1MrUFG~80sBI3iT<;4cZtU3eH8yjRkU+J$=}e zTc~#j6M|ursGP0{tn!k&+o@Iew7+^13T688Z%NnyA#7_>XIM{$gwh3K7(6bG3(`a5 zG&yx^P4w?A#V8?(USKGwR?McJxg^Y1=euCSAwo|J)p6`-gDAP=q}FJQ4k$GRi**l| z@rdDc_=U|Em(aS8#h-tK+$TPVcx8(f=eK@)ug#6E{J5`L>wGm^oNVX({V1SY3-n>3 zC-l~uGG-Wmze2$*m%AzpU&z?u9UDY4|>FwVtd| z`w^4OaEh+OJ0k&~ALlN++(XoL8QJx)rNB?QV<`A{Rr5miisSX6+i5Z+%FXs2_dJ{( zfMk&aLk&5pN|QeZ=fsa+&XT$pDHyDH{|53C>2+pILh!^PCIiAgqnHj;VZL{Hw<{Jo zfX-HHkO8(=0TV8w?*D25q`p&udfI=nGSie;@zxedp1WqPj7bjvp+%psQdUJdqfZ8H zl}sxE7~3%M0_%cCManf`PpVPmMh;5I43OU-{)r1|sI|6>{A#PVeKEK5iEiMn+Gc%?h*?Q?87zgWO|39|~x#`*kDOaJ^T4ev(=D zMmo1jNeVv_j*E02mh)4@Dj5T6OLG_sTPMs*(c5iWsC*pBJm@9}4Q71Ckt2v#pMgx{ zDjKidouIn8-rlTXU2FBGO*q5UCwJOs#10fXIL{uhY7(V#&x7$QW!m;g7KnYV1TV?P zwu{H&FEl@syI!VYvwyGReO|}dER|?oS?Db3c~5?;A?48ePGLHsQUD_hD_<8+-KI-! zj4erRJG7^A;m$V<&P?c%>wc~$N=yrwI<$U&Cj7$kyjjP5le+Rh)K%M^oII8&JYinmX}EafS9*iv?;TCOyBF2Wg1@psZyUuhZqiD=-NQ670EA*UokF<>b}vrTeofWCzffcG(R+E3r=B{Hc^AZaSeA zm{IUZw%qb)#lMyc9@Hrf_+)~X@RTupWyys-Yv(9DX9@VkP?Ab|NpKXs{HR+W)l%Wf zv*T%z(~Csm<^kq`?;J4mFKcoug6+)3E&S^9>-+guN^(A3I&QFU=oCl;#oF$A*j9O^ z-+1w$Alp*vYD2IKr}+b|V-Snvx&YL$vm4f`Ny!} zleJJFW`I3L2jJT&0+)oiyR1f8R;{{v1e!YE+6yg~H>#oCglQ%1sbZ-J6Y{A$@n8Ax zG{}Ml!0VVErn?a#qS|$`YE)#&|N2E7CIbzKOJGS%zcDn_re5n@t*2Gz>NI*=8UDap zCTJ@gg_J$qolmZ0kZsY`T4-pJNC?F!;uTCwh=IKHqXLkHLsECZHRhOJAclwJR(t++ z=r`J0_sej1h2G#}FjKb)&iInLqM7zFYY9Te@=RfXsxg=meEDGI9;xU~EeQ%HAO^AS z&ZX}L{3AbGGwfYCK|Y98_yynr)`FYJ=<-O;69Kl6#|9&r47u$WHjE^~^n;%gNSPn< zkfw09O{9aK-MR`Aj9RB_`leZ#zLOnx?Bg;<-*4KDgqjR3^x~?AJZd1%IwtE9WgAut zpNK6HY=5DQq7unS-78)e$W=hYspsoE_-m|32^Y{ZzTTv~YfcGSMQzpyjYE zfU3)z{{}L&XK+z&iR5N`hqK}CGVA@K#m-Ht*_QJq{DCh0as28t1F>xVF`TI?A;o06 z%KQ6h#U`;a@m>5FW`g|9Pq47O@-Eu%<4SiruMHk8;h8)$Q=z6(KRqmackBB!9O~c2 zq^8!li8TN3y+I1hGK6VZ&dDD6z^;^g)UO|3UasWRYJR=iYEoRQI|VNCYUd4}?J7OJ z363O0%M${wJ86>{^8Lo{!gmqz!E?i7UuiU$98I8|L|n`Q&$IOP?A8jJth-;Id@-kC z$KE%0*jexjz^6iL7(UIv|DWV862ED-!l0PaHo->n~R8PLMg z8Mi7@QF0ug7!aIPy^+_+Tqruh+|(3IH{vvA4o_Otu%B7?7x@N4kDyN!!M{=g=o^nR zS<1H|o&4LvWnDPIU|qY35%)>1WVX59MYkU!hg0Mk+dON+mUT^HTrtC>xp_Kygh~RB z1VdQdEyO&q40Dh{zynnm6ZYwFgE4wgB1rhZ))NWz$G3J>G~mlS?P&XIK!J_y+$hwF ztROjSpdDZW6{svDRR|Z`gTEm*&Dl_5+c*vHE*%JT5(NwphGk1LvxXTeXYGZOG9C14H8Umo5C2I2(4r8#GJf5PS8Pwk~!M>j4z9t2rjOkWc|FQO5x(;wFZ z4I5-$tGpc!)yoZj>(oPpUvd_}Umw92l^0!al-2}*>rwPL5Io>as`fJIgyOTE%I!@= z&)k#n*T~#m=Ml#k@mZ{Mv6V!2Mr19Ytbv$Gn#zT9@~D?wU7uP&t|ONOEsSHF>Pn4-L4u+i)FVU8oT(auY_eLxRvf#P zP+?X1Z5>LtT|=tJP}i`Qw>IqTj$<7})Dz^_Ufs!|j{IG;hl`Du6JPf|fE-C0kz$Fu zWJDP=h8pHWHFzHZ+X?8RbSow29{oDt^uOsDNEUeDR)Na&&tm9zMW?YN4VrX5xsb4G zu@Up{sqUh!LkSRLXDIL=Iz-*t7mSJfk~q zN7I5^eV>-%=o_s72wJ6JbQt5-otP!nkcBshy^>k2uBU!v8`Gs4E1~)u;3lQZ>Y44I zMr_KJ{5HS9nV@{BDgKdt2(Mo#B`Su?n>+Rr6_b2f@x{FCx>b5PbK>80?U3lNeyn`H z3;B+h;i0#?-KnpaZ#HZ{=QFK58V#=*w%BDN)kd)KL+hwjo-El|d(JOuq}Yaffphf1 z1z^bqbk9(12PT`t?dNqIO8Jnph=%Ii1Gs_FEvWxFSoV^{_NpJJzxa>DLQ5OmCNcla zUMVu1a-4t7_E>Eblf83Qt`hrG^p=|Nz#}H>$~&3Va9`)HHB>(4dVE2hjnfnpXyF)+3)PSkNH1N zLB1FiPBDc>p!Gpo(Pd~>p74YKryq&%$$Mf8q@MUYD4&9;z_IG9aK&gU37D4GZZa~G zLL=lPq=nf8GlIo1Ox6s)mIA0u{}~KiVPw?c6;hxgI9ThcW^Nz#)L)etY`Q>El|)zS z(X%G5^?J#zTE&NWj#7mUTwARn3>&nxx~zQyVNBskrB>?bmv)pLTov!M@z%13hN!2jQoLjl&&US7ZyI`v(tHFPZn5Q-_4Gss><7tiR30???b zq8;}h@6kB~m~69y4||OSHt>l1$>Jh>YucO=$(-<(L)EZSQ2bS zZaekfTu3|!^8mm5Cq@92g#qqS{Za4`z21ZUq0vN_1kI#CLdbvd9K(69)|4ctjuEY; z<69dFx&^h{Pts2x`y{F`lG$w=VfqD_14(MXv7DU>L^QsLjp$DOa}*ML81O~2^uM9j zBu)x<$~O*}te501r`B)=hB}QEoQ;#63a_V|Znk$HN;YiX(=X{la_^fP2AQrEt7R)u z)7{@~9bsb|hm+TGBz~tja5hO6!#f~(FlOlRsY8a?297kvNIrKaVC{i<~PilM>E*e@j;R{8o^fU|2_D+ zk7Gg2dw~Bt??(FA?2V|)w%v99hu0wz`hqvz)dW;(|YWk&xGai%H1^aC#%04*Uc z7%~J=o{I?mo0dB~U>w^$Ts%1pbR4q&gJlHyMHWNCj6eY1DO!lc52WRiRe|0ll%jy5 z_tZs64!I{syf~Di_$CHTcbB9IDpZd_D`x}{5h+5rq0-k~lqp@fellCs4h^RlvWG|o zv4>LHn~;NXav--fTBFMTy(!tSo|DCmiEKy7UPX=7aGfkVPE}H)mjhWsw0w#)iH?;9 z(_S58Kd*=un{>vh0VxZT`#k#pDKH;N>@(nB9qw&EMW;_?6{|9E5cCy~d{K>IKM<4U ztQnp=ifk#Q2QIUqH_ehh35$w{Z!C~mFPvVShmqmylfQtwZ?)m!*CCh-gUgRlh%*4s zD$GIKjvEf?Qf!sC?=r+P;W6^nQR7VUkiDX1_7h{vtWM?Db<${oSndpn+^ zd^R8K6Ap3kzV~F!Ms6m9*`)^K4EV?5vY=p#+A#)nt-fsSt|42Dp zjL_4Xde*{nUZv}p_Xy`kl)x`ulmBcCxid#E3;7y{XE#KIJLQ;!k{N@@gSDt(J4?TN zt6}@^t6|f{U(cnsDH*>aPQ{A)g&H40gg&A6LSQTnBBI~jOk0;O!46->@l4;KuZRHX zxF?8#YB@!ue(V=G$3xom`y5pW6flVi?6aLAV_%a~*T7qwRw}?bDix)K2t#QcP9sXu z82o^FP>-o-4jh+CuS9lE!k+vQ##be_S-er2daI;~Hg(-HhW(X9dgBm)&L$k_oM22>Mm)mQKrSc;k7)2B0OZ;Ebb6H_;NM!k}77@W$?cvn_Do zR6Dd^neZrlPIQhP8*ocJD6Z2z^4zS^~HOP?MEg{D|kJ@72`y_k?S5S zOJR0f9i~ZqUz5Gn`0XL9Qa^oNwHTWp;U@X_FUl|UKdE7zi#jk5o2doAi9EZ(U{1(; zK>QRcVeLr`HTClQ>MyJY$beg!o>mC1ku{cs17v)TT7lmt*f1djFaY&}4xi}kgY)l2hTe%n!n8?_CmQ zxSh1Gxu`MJ&7RY;6^;o7uc0hfv8g2rsogrN6q2YWd}7;-FTA>--oF_?nFLjSeKfEt zEzUUo{JpVq;V=k>r3W!^LR7=jHt{#p$p6JrZ-|LKLEWC_(W(UH(RN%VrrW0&6s}&= zz1epZEq^?Aq2YWq;sW4!?*H^Kf62dLlzBJuTE52Ys1t1ghJ#6YPO;NX7)Hba`fKQS zX^{4NJk3<(;ja-z0LJftItNe+eM78l9G_Wzb#s&Tx$%@t{88eX5&WQX{6{Og2@Toi zPsU@VRg2mc8ag6c$KQN{c4qzB>d)$ChSp9Sq30=NhHk@pxmCFVpfGHX|Gm~bcOb9jI$l?F3=>Si^ zCX-#*p{Vx{RPbVlp`VL@&P44Vg%&w9+9vf?=_}JCyr=Cf?#q(+UCc-WnRt?<*OPKf z>DEERKRRuN&p)IF1>~<)jYD`EAzi|M|G|wHLvIy$+;0yCoA1bs;prE=n2M2PPXU}= z7QoDm7>SSAlwfv28iLKWv1{{PRm;|IC<7008?5f@={ZiV8=7;D5mQ)y0|(n->AT5K ziWy^zgYRFSsz)?BMJ>dn)#hoauEgS*R!@m@QBKmqMkc#XRoxz1<_( zr_=4Qn)GWo+piKnuOB;2+0Hg2yB(liZTrazYgf81ro&y&cw9D1t4+Rd+aG0z*AU`_ zI_fVd9mp<~&Vt_z(0Ns)*sjA|H#)d4pUD^rkR@Qav3?nap>U%D^@idWswoGk+kVF* zp``KmzZm+PM21CPLj%jY{1Q0oas0b`1_PIM_&c6h7FfNb=OUZ_kz74sQbfH&jtzRlJ zp4Xp}yyROKV0YCvi!na>d3blIJhB7vFw!k-a^0vd_gg5HU2=fEdCW{ue ziU*?ad>vgiF$tOz=il#XjQ&nxZG~$*C=W6kx=27cXL$dVr*TyCFOh>IJ`D+R&O&<< zq9Qlq-ZIUKe~rLh5hvaQ>uJ2Fvn!Mvho3zr#QPVe(16O}Lm&|D07YvcDVj+l_iv%t zpOSn;LS@JtfdK~HTU6X0BDMf>Pr!upqsd| zbh>z&eBY@c)+@K_rZ1Gco10CstG(um0$Vwl=-18KY%2|F4yXuPz$+jpo9LC$4Jox= zRlG61g1%6EihlXN0~`>h=hTdC9kg_?)B7J{!@Y~7#xh)Qz%+8nN1%7FX^Bm*xWkt_ z3;;>!V%_F7uclxbff8(@ZkaUDyI|w;erhAHMWPY>Ym8B}9IXL`j=@UyuWa^D63ZsD z+!PqXARpKa5n^n{Z%o1Kos^xwu~P1xmrariv6E@sq+$KYkJE3lOzGT#817y~*{^YX zg5lfR`kkkQ$0ehfo9Y0H&Ar+3#MO)I>HzzV(+24VI;Q6KA2(R{7=oH7u37kKuQfim zazSh!ZhGYzDdy6~?h27ibocW-#veg$9|^X!MD}w9KZki!*xEl{ILh@-)~-HwHFvOo z+nyAv-K=2((y;CycuqhG{pqajP5V#hX?J!|Sp5%Th+OYJgbD+L8DYa~mB=52>KwG% zAXz#8aXCUu4dFP}vmh=UY?IWQ$>yvP?jEDZ`a=?iA039=KAN;nkjz}wB#YMAoHuRF z#?Gu#vudrO%`Ed2*9oTxxlm&X+7_*KPWEqLp0KSVjDJ}BcT%}^idmt-2^G5qc&OM{ z<|n6S{2tg7z8S8aBJ}5x0Ds4CEoMca6*hYc|GpGOc<^F{PuY&Ug6YqiJED8N$k(w4 z9)1z#ps}C0;^jPi8- z^Z?y%O##d!>e`xg&5iU=fBmm5Zhj(jcg)3-lyGn?LH!v5hm<-xxyx21(w zQ7Ks>jWuH>wX)yFr4zuT@Z>zed2Me#H+eN@&rNaMG zNXYZ!<01;hATv>SkvvrZF?rO}NK=zd(xU={5yf?Yx>pd`&-q6o9o5Wv;KP5lLVgVj_+=>&(gk1 zwO8B>SmwIlT~KKSmodV?PAsI>R3+MrTx4&C%cS>UTXLnUO&AGd>gnJ^o#B7(ED#8; z4ucQ#hW3V}BTCU~41*OgpcWtXwtPmqN~RglH|Y_1ksWOVl24s<`;l)kS(#$1 zCF%NbXb!9%omrA;;FO_i>X7`!)2DGv3#;GiuD%8FvEMh=zqbZ1i>^7UQ>_bG36Prw zN0c6dgY`gL2w(-|_3%O*pvf*ocjfh5s1nWR5N$pFO%v99)9#DAZsvA#Sk~5u7Ddn( zS}Fj{)LWywMBZ{Zx7(i8=9%73lu#me@D`Y8)l*AswV9L;}T9N5Y6MY60tR4M!jPH;wN$7(mod-kp z@Qx*v@t{k>)tKhZ^MxmY7lk98@Wu(MmJ%s6VbGxpoAyt(Jq$yc=d5|uk*ePe7b=DNE51RV)6Q(xm5OkNHt~aJ8hbhWK6TFn75tw~qk;Ds7AhMu z#%y(O7&5x>mtOiq!l(EiQ;>(DlQGIM{rHqiOi1YUakrbVL*{*~{Ja(rt#|ai(-o>) zrLMPai2w~^Vlx?#%UEw4cn0D#)Q5Mzt+^JM#I$CZt`w4&B;&rTS7trVmq~ISkZ_w*!M>ZUddo=<6|&E6X_GfOJt-zcopTZ$?`dqW z6CfOF|Hanxv|e7<{Lw;3oe%9}_#R&Q_O6uO4-a^6K*@Fk{x3x#{Kqfe8~F-e((}_4 zmZEemNr+)$3CN&)%sMKHxDMHd2J3W$+HZ3;%;M+g36b_ zGQo;xlq;P7;H}pU#5L6SOk1Fek#?s?6(gRb zl{F#hiv!D`z8CfxD}V6Cea%vHrJz>xQHiktD+1lc*cOV4Cx4R;x`?mavd+6Ex36g7 zQc4Sb-x{SmfwBCrs%y3vpqs)Ii}cIaS*%(z7^~zROhDDLM>C@JjMRVSHn2h!qk|h`ScV zkp9`b|HAMbu#sHV?N0^g6gm(ZvS*cc8HbMoVD=D86L*JWhi*&u#Cgdu^fKtyeM2X? zmj9QtOk->uUw`Wh&1rCEZQ>31Xt&$C<*nxO{kgs*WoxZ+?8VvRs&gT1h@LKLFL9nk zZ;Rx}uXy6|W#1k!ifnvkTJ2$fd0I{I^fnxG-9PR7#xq?N%Fh$S$(5DJM`Yi@f3K1} zJQ=gUqZ=sQ{sqY)*-dtIqPMChYegKBUh9mqyri1?vOZNuK)dOwJ4zzr((UtGx#-f>K^f~35TRbR!hth z(WCsZ0DQ5KtLI85;j5^Ud*8f!5f#2H{{@IUozL{{h02jTVzXqR@g_CAIqLh zv29o$R_(CyJb*7#k!_UuNUGFTQza4VaqD_)S{xR5J?i$I=RJ++{2P_M=ID|c3z&da ztx+^^o&Lz|#ysjW+kPj64ecG@mh*x0WvP9zrqi-4UebdKtyZg;tgct9r`!dKyJ|mu zrS^uUXmR#fq-`8v)cd{yEVT73g!36{TUYE*6^YV%9F2{T+{7~9aepx;n!b#{{B3UHg)JZgE>}v#;BwD z5zaHfQvuBGQQXp(nq0t^yW=J=S)X(lgedO|m%uyou2pezDCPaTVty3_er46Qm;;>r zDO~rn3ug+;0zguO_@R6qGDK` zv`#bi4%qd5x`C(abyn_{^vZac*b2Y-vc}u;Lvww=^Ou`dgIT za9gy1MG2@gQa4WRC3|6%?zt}`eUYqRcBc|>0^87Gi<#*g;r8=sL@LZ?uzbbY*cBy} zI-f9TRr2Z2fx9v2DnRlBoDpfSV`FnTtJsB6p7{6Yt1Za3p)L(!F77}D4KD#GWw*i* zW0sU};wF_D0KM7W)JJ4O#u;vpulVPDTIiu#_}mANOeF%rM_0mES(>>)fLoyU7tP`= zl5F6Wnu zWesvmB3g-~eBz<<(ZLQ!sr%O|fI&iRr^Hdq0$K)n5n4^BW50r|UvqFmoJ$Y;E8vT) z?WK?X^3Z9|)@eWPL{o{6!|3hf%;m;Ljfb0AHAv)TF`4zuSi8){f%F39Z}FUp8axVg z;`pGl2D(n`!b{+n;~s7S3Q1`$&`;BusK{fukZ@1kWqF483C?oIHYUp;*ra1`|&y=E!R69jeB+*Ku9vDfnygCPieo9xd+O!sa7N*}brnXtMZeGEzWntS)*x=Uz|?&obt3V<%! z2V`R~)i=9;U+2Gm%WIom@5@V#E2CAQW;>RlBjTlg6h<>|!%N+pDHcTmk{frdK4ig9 zzp-F2WbsNT=-)BV!W8-UsO`f)h}eJuvSlsQ315=|lj`T!=W1_Ty}vLUlhKG(NQs&; zsO1{t)i@l`gL@TrP&h|bJ7;Sj58@Zszv}jqN$S&3qPPp+fYacy#_Z7Qh>+ww)_5pi zGNp>!rkwehfUdEBRK2|{3iZwW?0O2fERTjPNt50m{C9F;-H06p%%lpXRU=vOi6$MG zx%2i=a*h)nZ%@eTKKQ2S@;AprR#;6o`sV{JtNe`2NroizWUReUblpipHDs$xt~F6XiVG_?%tQ!fqZ$z$kN-VNdmNWU`UH_ zhbof|R5xqrxe_H9IU1y|uy@-f+}Osy8j!+XCpT)OQl*8;hj)&8cc|-dnwmy?O3fKn zd4!3L5aeoJE+1uynD_D95Bgo=gX*dJ(0?hq=kM%tzA4wyINkDK-6(C~q^Ghq!H?{^)9B8QS+*`8CX)mq4{Mmwu!IeqGd=Fn^US_WkA-7oEol6x`} ztlNUhqsam+P9@U;ml&H@6)*N4FoC@|t>8-?Z)a3p_!aAN<#bu_Mwo{+j=dbpfP)-Y zRU(-+QweYip}+5J8m*({lbe+jnoqmvO;baLD!tc!Fz+8;YfFS#NmA!ewZD}h@e=7( zQLdfZpb&r|$Q)M?zp~WnhIiyH%U?ZBp(FBdey4<`$Rs^2U8r9irc`U07Mgayhiclg zwtw$jo_#2AZ_DG-xr(z3kQGLB{0u9D=e*qAnO4(NuQv3XRqBxN__XH+wQai>{i7Q# z;4bgn>TzL|S_oAc0!zudc_HW48?zqLdGxuyAua}E01oZ=4FfP#&GW1Z=|4;ZrLq2OB=KQW}5T`=Js zOZ0YUa2>K_qW=$1)KeeS(|@fTo-$VWa#|eZL4#H&3UNR%Q*O)6Sb@Z4Qz!N4TUIX5 zg??7ZlyFG2e5QaxVXmdCwUhogUOjzBy=wL>_`spj_6Bu#4Xxy$6Z5*oW*qaSvNrU! z&sX|L1NP+?t250OnCd$t7w7fXSOsJGd*aF^3Cnwn_p}ODL885G_uT$Q?qVpzczU8& zrYabeu|4FW|6JSo)|T@sVZV@E6-j7FK%)aywO|F(N!IuJ+!w$W(i+RK>SfZmmgF7P zzSEOi?XGdEc1@HMj!R{z*m9Vmu~z2Fm8mHt5>(AmZ;0K3((I)JmYzSQT*A{i_l8Ut zIjyXLlad0psDFRX;H}!%S!?pTm*lK;3w^o%y$+%hMN~+vb`Y4bXr&IAky0sjCM|#} zgnM}IPj3wio%n!{<7)xrOTuLkD~|{q82$$!51{;x?D1cCd@KR?8}hkhWK>1}UT}4; zou2q9C$aJAe{Hx0cW^B0=g7whYCsYI7G$B}B*T}!K8cl5WFOnx`PLgxUl4|v2rr{oaVDrrL|nI>h3bBU&`uy-6|f1h+U%+ zx?{yEXl2mP1!66+ycYndaeCs7mp&w*92_!rLI3YR(fkhxmG|X?wEYSXte~r@ zVC-p4GxEt}sd_WrxJH3WrOWH77tvQb7L^fmuG7iO?e6UsuDcJm!|T|LXvu)h7Ow|V zGHF|@%E&$9#%ZrpL^KG;FgRwHU|8yE;`aRvJpZ1?ldDe3?H8zo_B}_ae}|$ zuC;sO=*zxIR_AUT5IIs4!CT&-0lb74r83;B@nkMA-R}3Mmagu*(n`zdmq2^yP~YFm z9oU^q14~T$4YJiHLZ9Q>W$NJlwduTJ<3z@aFQ`UfX)W9o zFqVo?OLP+wn!p+*IhI(DT`=M;a!s%NCngLqNa*~|TPRDEVqUU1HAv*&@_J^4#@3yP z`D%?W*CDH9+B41*4oSd)uQ{7VHAa%0)|uTs0A9AfF2~Y+9U-}2xkI2EM>wb_5)mvI z0OKYD;4cHl=Be=n9;tzsBnZ39F6QvEyr^MNHsONd&2|UKz2g`4VbCN`^?$0g%Cqe<9SR2 z7pWpi`2;I!fOVi6kMuKKRK6F}-m7@k0kVgG^Uwg(5p{<$+QpCumX;j5Vx~JFz^#Ul zG#ju8-QuWz+{YxN?COysbbF6xAXNUmiMdCb$1ZJdbPD4in@2?!zVFW8gn`U`6YS?_ z!H@*_X+8aw&Rqou{5PHXe2e;|NO+YxT#bTs=&iuS)qZOzxSRo{Bl5_h4tO`+BHH}4 z2QgrN+rcm}F8+?{(FgeP zat11!2VX;^-D$K*ddx!2%TTRlPi2D|*ARc6#>PxDoG3 zDs0pYu!;UaTZKWUZ0pCL=uxUiWqDwAnJ;PcyX+j)Fx`OoJm$tbFb3CpGXZHFwC^f3KR|uZqQ{!hqDfME#uQ0a-zv>TVTpG)}98AJ7x>N?H% zL~_0(V&O&o{I{yXKE-7Ux(ay6%JdY8k!DpYOaZerAw)vaFZySlKgXdavsW}fPmXPy zAN=3fggz>w(w;8HiVf;$BK(WS2(t<>#dt?4_F7TFmEipSX0z|l-M8S8{dw1>)8hXK zgGm@-oE2zLL6wp0(QluCC|d&~n3HsSJMalu9FWqADZPpp{g)n_)~178z(Er0O;;iY zl4w^K-WL;Y)CM4WG|5T7)iE_#fiw(4+g&EoYEQ_Cq{)i+GQ{Tz)=TLpS)0K1Mhn}& z^3O{IfVy$xZ|{FC8m`&*HLr!9{#+HxFLxt=E>+HZ(NTL>1;xFJh>r35+{A`KOjMNe2 zC)Sw~vl}K?y=Qq}c&m=pLu&*HNuK+Utn?&hPAd7-x<*kROKWP{BFy!!@T2O>INB_z zvwo-_B^sLS3i|A#zt4&>a0(c?XT5h;UCjFU@Yk;y2~)!X-l>j!k1wMO6NT5? z+_rB!)lG6nKWMouP`jWxNsLtd^21*JGxw)p{EyMVvnF6A)qmuO+%g{37udV1?@V<( zvZU_`Iey`~3EwZ>`=ERLd^h|YOOWY&WaFyn1j*!Wct*|np||sD4^wm2CNZ``41lKj zmT~2Rb$!gTXJUSPhESQ*$#8`3|{_4Fi`=9Fs=x?*- zP}r$=WUkL7mZL`si4qZ`c~^1Sm8e|h-N(1$xGr7R#{}mtSuz$%4IEO(+ZcxQQf{>S zSbU1B(|O!VPfvt4XnOMTQ%|b+coJM8;q%>G`c@7m6p(TdRcsHSKtM7-bPhdESNct6 ze0D>DTK2~i(%*~mtKjFM!$YNANARsH@W*g^9&7EQ%h-_d_e%zJQNZNN-x%L0lV%gV zl#=9yij~C_CeOZBc+FB)fTbqmlRH%pXFnuhQaDLa0Ru3}3%8q55F}>}CJ9q4OqdpD z?34wykij#Bu{2{mwK#8Gqj2jjuY?@5| zbA}L!62W_TOUrP!OJumo_S);_W3s*3p&$*kLm8ChFo$9x3=YwNg}CW@5SYy5k@6M~D zS)qy>k)dgZs}RLoT6K1w?>L7j645?A+G$RN>(pMW6Ikf->v^pFB_a6r4@BAt4)nWE zL_4NHk%1(pb38R*I+b)E3l{weq^AtZGZa~Fj{83V20{70?v(Ld-byU0Gs^67v^B+B zi9^ft8^rXJf)6+AbQb|~ZwZBFlLT>HaHGltt2g(Rw9HTA30YWK(n`FhdzT~d{l2ZW zQ*Q2R&KRTs5MIa2%asD|IZ?Oe)D%Y$o92|2O?z%X?#zTpCLvybop zkT=mG6s!Rd8cT!@0Jo+R&4KsHFOwtiOUOtAoywAXVblo= zP@AS>-Y-fD#^$MpWgyAAJn(aIg>K~N}A?5;TNf>lS1i?I+5 zVE5jg*iugJhH)F?4;2{3Q)nI@Yf|jM04mpwuAr;yRiCu!xk4+K+Tvcif##J@D6OmU z%uevaoYS5i%0%+kP);!)<*L$95Wuc2Z!}Qc%xru10fXJLv3=U|27sTV;Lz!`MIJfq ziGL#m&K3ls0^n@DuaAASjwc^>)$-s&Ftre1{|;GDDc5uB?c27r+p;@1w`@A>S+h@! z8bq(FBs^Tl>EXhC9C>p7LoU70Gp?R%2%K>VRP3^vSSM#|$_ZU;%7xY$FU;<+CEh!O zDVb|O%jC_TO~|8h`>g>?#-43|YfKzyZa==!w#xFy^r-bc&rq&!HFAV^A?so z1zW{FpHJagybIf_EkZK%*ix_)Ue~(Nv^~Niu77UXcF9xqYk%((mUhVD@N=9oh3GQf zYvicNCMfbbuh}Y|#V;8DLJ{M?;&b>MqQ6>aR z_S8V~oqESQjh-#b#SQl_xx&R3A#h$HP$~fUGMw=$zYQ0>nf|IV9n29D{`F5yYzZF{ z8!Pz+$%M$1On_`cJZQCFBPk$E<9#e?Bw)JOSW$i~Tjn#HVo8yaVuq!K+*2M?+e9hg zO$%;5hq>|uoqW{(y|P~;6H{3AK@|sdFt!MR2!R(G0xp9IM}QAPVqdwm3tJ#8vXnS3 z45GhU%91v$(&fG8t&e13`UM`aav=rY#Y@JHiQqTE_KOw@}5<&R@brqCMm)w z;Q@Vx38WJet|1U23|ED>P&8B(-_E*103>LNFDZGG^8V#W3KMTYa`Zc`#>n??t?;Wd zd1AR+^r42ySXuFvtZxjSuVF=2MFdIfH7wMA?kPy6nI{dmU?X@msK)5eb^Q_!mIS4eh zJj6sx`c9_`$(uo2GaJrHT)o`4t=W6_N@vZ|$~_ymE?e3_yES{sC{kfWVBmy7wFoYx z_Z?e=z*&aC$-cg`{N!=$4uO)uJ_sDbZ~g=6E#f*M)bhM3xUquff9r!ih}gh}I}keR z_%u+d=41n2qK@x_nvkz9>a_kr9pb(h1OnwuI-8Fxi&@$H8_^%1+$>plnOjRHx|nTe zKtA`rYAcz2`By$~^XAlE zAvb_uM41D1FErguGgdtz;GaeYy#Pn8&V#}0Clz5wc4kZl|_@yfs ztlq5Ijn}Swo`8+3B;q3K{^#GZ%CKvH{bz64vR$<RYH48mmMx)RH!t>#V6`vf-Kam*;$`&t?h4Ly#ndS5}6m#G}Y!L!y4+4?< zJA3c!V;`{y{bF;WoPDDGTKB_8`skP%xoD&`CN2%jCGly^3givfv?jkPnSUQB;fp}} zO>~9WA_UGZ1QtJwa!QK{Dfi2QR&F~ZQXD8P6Vm~V7fhlo3Y|Lfop=L?F&nD{U^cXk zRV)wLj&%l?aHAaCQon8UDR~00xHxyCQct?DK1i)<$qz$a_;&fYok4;L6#o^HMDx*V z!^aXy01%5ULg0mjK$+FN>ao<|B8gJq1zF`?kX6Z1gg2A-5msmN*cmzPJX^gC#>=zI zWKyTgy)EMZq5Ff&w$i?ABNYG51mSOl^&bmx3(Iz8ir^12%&@w;c7c0T=%XgIB}7)L z0JNojB_2IkEB81yRku@Z7|;(j37t}CD15=6iRYE2SmG&;U5=_rD9Q^nPS2TmwqXuMGXF!&p)MSFKBr!)YlM34#{@5NBJ0Z~}3t%A-?6LO(`Xm47_%KUaxB z-ft$t!noaYghM&rXg!WMCmYtPu3Iv?V}pLh*2oPt*~@IH!}|>{*I%LYn)?i=?s3wF zCqbcDkdQAT7?ueC+OIJdw-6mxTU_SJ2wIt9-5=N}r{o`x*RR~N6pxCuvCYG6;GH+5 zibIbQx?_|D0FbH<9>xINVv7(s%Mic==qL(1%a0SseiQ=b>n)c$zPMgZz~+Zqfh9%6 zAXhV7m{m_UrDm@PMxy~?0i&kroJ_P8+x_R@NV@*X|NduI+rDV`zDb?)@fA;Kv(kiE zO=VG#Yaa_;I)P#cMQ1%23}WM)(6H;2n#VDo(!F)tV5>d70nE#cHm5X%*~btEcuGU} z+sd|6wvy2(6#?2`u8ZkdS$&8X=Fn>R zf39qFi2+@)mGu>S`H!gsP5fxP*R?iQp*dc*7?x}#w?>jrb(c^W=o_aVlUz|1R-k2Q z8WBFDMJw?_xh(fT&1Gp7de}XVJN~fq;{FJMX90na`mHSXTUqw$_~ zT3Cxg3EP|7wzj-RCjSwhd?YB=3 zmTQ%^lPi0jhq*u3)T>v$AQ?DIc&!}drvxN$Wx>6nx2oW~Fp>aXz$x=I0{`$>h7q5x=h>bAFq zBig#zdp{yiA+PnvKcUJ1WB=(ty=hywx9!e*+cw<|8{&s(~@WncWAOVX`a<1%LdD#{Y_0aR2nQ`#@hIT9WEOM}*) zs0GlR=o0bd2!SVsfWDI0USJ56%GjfXu-q22B2wk#y3iH*IYOWib;8p?i2MdOeWc#;ij9%KmU?m6}p3g_3d^_Qt;v0uchI34!Cj$CD}$>Igv@p?g9av!P1I z;i_H**G#(Bt)U#0+cQFx+X;|)Hfq;xilE;fU$jwwV(FbWj!LkR!?rc2C<%yfujMT) z$GG_8HBbW~x-1L2k%*>N(*6=33fBo6$y5DkEBp9wZ~yP$b+Pv>Rqzq8pzLx?N7bX~JyEwfAO;Bt< zI%7)+2dfjN(ZC{KV_OP<^~*O<0E}&Uv~Clu{!Q6m@FtKqhtdY<)yt@DD31L-mjIXh z0MC%!as@_X%7@ip)2pd%a3#XPxR37qzHkNK_DssP6oeobG8%V0-=d^ zl>|l^%T+tv6#<0;Knr;T$zDqn6+Wy2d`6B!m(vYsF)uZ_G==Qk* z<{5gB;+3A_h);VKXm&n%E2jAV1&(f)2TF#p+%7!;cH5i9F1al7ooEY2!x=rcrqpw; zz?|n;@aKGJ*kYRgn)M|b6nT8`cN`(7(WX~9_oDB_{#-$ji}_97#@OX z$WE^$ij3d!xyBuy>-dAG-YlsEj8&~88} z+4)FPI$i_B8oc%PPsumXx87RI?(g2UjcaQpVcfL~mo7N&fBma?k5MV0(`#C-Pu^!1zNSl_gAE0aO@) zIIeM)W7Tu&89Yyov;`kSo6CdL0V6F&(X?IMRCBLMg@P#_tZ6=CcWxtSs!IMfncvkL z16xHa@Jqk{Da)u%@wu<|Y+O%CUWrX>bl+C4;BleLGG0_!e%X*yfqe_FTwP*|5IAcP zhzfwS_Qsy#ctwZPB3!LtuiSFZG?AA---Q3OU z!5Gr5pN_N-?i1G{1kNG^B&f^fGYIS@+jjgi#N5It$~@*;gW_9p#wBDf7US5itFE@# z7QQo>#Wcg$6Bo`DMmR4~PHF*to}WFAEkfX_&;Kb&&IVHygW!e<4)!P)lVt*fA2 zK;>4;W64*t8z}m7V*bgNzD30nV!_Ab)LMJ6kT4DMR!YbhP^XefBB5Al4MqWH>+ljG z`k`h!+gM-A=K{rfa|1+>VtA#{Jb9`5Aa;vgmiIG|+&~G*Ak8+CpxU?hGh3JLf$!PpC-H!AnGR zW{J5XJ1nkIFlq4I zvy5;S6an2{+opIXNT5%sjPOq5mJ`T)1;t6HPl8>%>ef-)@a(PL8jccofux`f6&Bz* zFVK88p27H^7F^H0J(Mmdwg`c<4FOqtG>?7h-x3VZ1C|ouAGE(S4l(!# z-+~w>HI{H3Di@{1Llu4r-;yq^a(?~~!Tkis zf0MzVr1SRvTL^r(^MC!%zK1tJ$NuKeziaEQD|Yw&`*vlGICA>erqq4MYCIexRAn2^ z2gutmQKCRem4&dRHDML;3_@I5xb>TrQV2vGWN&C-qjHtCupa&{;HCv3IdqnG^E6u+ z|Nh7qhAKD&sZrw-K0mO4w}1w(Sm9t*LOc(V9ejyVQGCZ#z6D$|14~qNvu0p^KQ`RqW57UDxEN zEeX^PHQr^QXzYB#=G0ek)h!RfUKhk0McxcJwqz*18+gG@QIM#bf=Vb32Yvgk|NJW` zOj7&VUvJu8cEu`JIE{Fh;edpH6X{ea8;`=nWF{tprE zkM|Mc)t(Fj&YV5jsqw4=0>Rx=Ol?pG$a3#(ap~XKhxa#ds|-!Yim$Fb4~}Cd=T5~R z@`IgWPq3+#>a*_j8j7|hYYeN_!xN`^w`7L%h-G6y*D_n9$5~dp8Z!RXEk8(=B zjvA{Y5_EP}^;PS;F28vAoaaaxusALs=#f9q(^!uTEpA2#91DSy&hO*SKW+dif}vc# z@z}QtIDyE2ms2k`U&rFxuxnlH&bUgiP~0uuR6pF>K~+*Bb~07{L3scQ@r?4|5IHne zQCu#5mlB!8KREAzuqOGi6oBi>ZzA46I8TDFFNKrDJ!q-3OWdUO=d6|E-N)G)pT-+3 z#aae|UC&bBe{gu&s(xO1tPqU-F}1I33+sXvmv>OH1hac5hmzh4FHv(sDehpypc2p$HHyYL< zWTQsnn7U{ZbfTuxhI&5P*rD-5Qr;`rDB8R4oP$=%Sg8d3Ue=&nBd`pM~o=0!XVszt{AJv z?{iagTywMt0eKpa5w95`@U$Tiu*cKBOT7M>g@8)Tl*GJbHbm^D0GLfv8*Gc{gDgb= zPy|$oF(z7>4UqxaDN90rWNoU9d{dCIQ!_fn2caP5%;E# zNZU&Mr0)iXyje#9z;)r8b0z9>i#-gam^`?^%HFbdm2n&4zh3QFPEF>~d}QCd^QMid zxbd~W_)DAjM)s+%e8MU#xqb21zCfjb%wB3zRuI$3oN57OE5Gw{J1!#xA_Pts0>^!m zB~5=n-- zJjiOX->-qtyJ+?1C{3N7hbDZjv5V*7@4~Po_=*D(B#yT7c|1?jz5-;S-=ac6$IDji z*Bw>zRhjDd8|(7uk`O-25ypY?BqbjJYx*Z8aE*BPW}CP$olNWRZ3baq)_%r0_xw#t z9@}6Wf6jJ`eLMs2HOCuGEr<7`e3-8f8Hi||#ASH|)ER1>cU&R-Ab6K?jtk94L=Dba zgq2_H3I6ysG!#9~(IsOVV)?HUt~w`?UyEuvd!y7YU0Ai>`F*@uX4mbN|AM*5WNfVf z3;O23YeN0%b_c~ePX(9Dvle65_1PC1&&NHF((~eATto<*2?!kdD$m52;~<|Q1dcKw z!uw7PPy%FN&M`4z6rF(vLL|^0hyGB7s2P2RZz3A0x&6bUZFg`GQ-Ss6xGAR#*a)2~Z zBIa7Ns@zKWHK}i&8u7h%LGj6>w4WH(Mze6Q#$G;H*XB7e{@($4OS$&8& z?uSF5e7)sTJr~#e$rfo_YSxmLlk$Bj?p_%rq0|gXQ%`6hWCI+E(9pX>tQm;#M}PAk z3_#C*`robE-u=04-@or601d2)&7|cD0hG|Vk3n8aBF8ndLS}1OMJaIc+J>#InO*w_Flo3uUcAnC2+x>Y z;v!?XIs}2)Y+$uDf+c0%(`N#cn8GPla1B+J=mbqfomkVr8PUNlCF;lkbjrdnj1NTz zqtrL28q8`$5_^BxMotkffDv_E#9+jX7T3_T$!%CmUuUUCzOvXN1WpYCB*XV6EH3$m z|3M%NyAdMjAfI=>MfVEQ`a-J=`MzkvL;C6SSJ`xTk>}fPH2CIF0!ok>?(SJ;9BVWeuW<#@j<{k)1yydwYV?FWtnQnb4m(pBX7X?7M%xht++_ z{`6n}1w%sMdGj@rf+8Sd8OBMJ zERK{xh)NJ6TosrY_yS7Kq?GfSpcIfNfCz;XJI)dEl*Le2={ov_BRU#eguv-Spqz`EpK97JR(^nA_PhZNKkgo z+WxXU626;q>tK2KOVT$P8f!X5LIdC29A-(I=@8Q&ftgjgbi(`$hcnyT*|n`ZnPe%T|t9%W^%~x70(50FAa#3=|kadtJ;Bwp@OB7TrA(q& zbcl-xfoBK-bZX)AEhfAK3#XCHQZ=pn+||6+{C9d-%w~>d?d{N$?^b8X@+;aIdQ@#7 zS8Y|(;k*oCT?|_~o*SjgiC4zfsRSXET}#FYMk$HfwkF15O7-C-KvK4E{Q0*n8zlD4 zuf2tauWfJt@U|_taPyhft%aNa`t+*1dn<%b!j#;>C0zMWQWW1>*k<);lh$xwk$3c9 z+>Q`9fIz_p`VI-!2f}t?EMlsKxlb3?rBKuKQ~m+re@W~WxBP3K2HNI4DrWvUb#FyS z6XvZ-`w@eHQ7S<fOtRP6(xMGvt5xUix_4`X8 zW>B&awXimPh>*6cScO0j%PZxj<1#`ZLck%wH==LPndy^(gey6-?o2!1ofL50M$hAO z=lJo?V2M)dBF{*QG#O8A3I}zCEYLFqh2H3z4X0aF5x8VojRar!i3^r@vW8Yi*k8wL zh{L|hJaZw&%nt@?1hb_!C+0UWQDM6*ZzXSm{if$EnzAXophQlCQosm;6CHGI{f;#E zW&oimUxL&C0l7p4z!5OT&1VP!pWT{@`hG?4JaAas`Wp55Xs(8JZOaQrUER{pcIF{8 zi_=}RTo>f~;9nhYohrWl4Pv>a$WyD!C4g&qXx%m=U^5wG&g9#y?~$yJ?=!oDG62{A z3)N4P3#4OwzKn^0n}kg8!-lo%J zd47Y6CoqJMO~!mreOGkPsD_YLckS-p4{R{FZC~kp8n%@R0J#X6$^&vmKB;mXn#bi_ z*1qzmd&CwYa9$x06#(b;&3?q^QVJL`8!m)sSuiWkvhYX5Ubs@*&g+v2SYf;4-7#@j zGm?p=E@)I0b0wxn9g9{X)W9l)o%@F!@s~a0GD6_Rgn%o{^wCHnSZswfT*wg|DZZj3 zih^=eZuIJ*FIY=`)hf><@k7_v(K`7#YVrr>Lso7keXrwNB=;KiN%YmWyIU3e?z^|G zpWe3*{%UA>ZD=ol`m)u?2XOV(4HN>YU4FT3<7sZ)l`4t@c&N{X4_TJafFufTP1OZ7 zIAvE-^TmhpOx_?9Q+d4T8v2&!gu~$idNPF@$-_wNv?E{(JLBI7foBB)X~SrX+AIHP z%ZaIZ%53!ygjviSck3pH^~uaAt5&u^FPYnNT}IfE@IA-suXUAYQ!IWiOFy@qO^BW5 zyUu>BumH1dEdS(P!@_^l_O_<>&JPiGFn+%C)@@sDU$w2L&+PS*~PR(x;z?h2$Mg@9zT6E&_M+lvc<@+%PpG!-=0 zG^NVfc0dc%Q*#d`frp|=J*I}0zgEXUrDBHzn;_)RDq~#!n^y0Q?RS3tXROa$|AT+B zW_O1x*8D7|_)TzQCBKFe>FT?4-qo+iVdj0{Wi|if1TDZ47v~THQ2}rcU+UvMlHB%% zN=xSa;B4VZ|AnKLzg3Y8Mr;uR5dsf_ zK*>Ru%YD}8L7gA6FPy8ta+_3bXf5?wSNKLHL?|KP+|79i&@AV82Z+CKcUGzC+_9uz zvGw^&ND?(_dy@?GX5DgPC2N<~DgQ+Yr2*F@p16ka(MdU%n-M`k8PJ&}gaXyEP9_a5 zD1*H2!>WJya|J1v&%{YO(WM4;5c3rj0L5_q)P1Ip9)2Aybq!e_%cj#~ix4<%2$aN4 z6Ic`1zcJq^z5(S@FKD6WJJNqvWPDeC9SQf6G4%6G$&*e32?wQcZ<4grKOfC^wyPxS z^Ta%ZkyG1d9R&b_|8%4zf%MrTIp7v4I(Md4-AnA%wU-G0X_2#ogdcs9^D0~b)8{;E zSTk!{-awHr;a>v36aXYrbL9h4s zXL(L(#5uU8z3_berj^4j-TZIEu+YoEJL8NvJZ(kF-=CI+DMOKa9> zCf4pYtV`m+mfS0wFlPy|%ajdKX(izWp_jQ5o3Y|9o<36a1vzC5%kgXMY`Bn7?(@ex zj5~q?q3E!9a(PZ%MhHAJ2o&F+tm2Yt{9Dz04RbcDhR~SsolC&xkOXU=|5f+u=j(8* z|D1S!eX|voa^tTdtdBQ`WZ$pa?!9f4Z&kbf{%xnXJDXdaQ?(!cztq#fBWLsW4nj@K z?%$(gKyBT|Y}SqNJSFK&$F|(Qz;&q5Q){ERqZBCRdu9C`lR;fIe}pmg2#{=+C?5#j zk>_7{3hg{hsRO&9TpWk@9|ikS!SCqtV^052_qgM1LSWI#zAyYQJc`h`W|EfvMX{l| zr|r-RLlYl}8=U+A-l^3M6b7XFBQ!O|@?ULrthQXU_WH85E==ve`5(S&Om*x03|FDb z)nr7~8#LFMSEs56TF9YN@Gs|UsrV?ji$TOiguuCiKvV#ntJnD?4-Tb z_FHYOAuD8*_w3m25CMR1y4qQ?5thPaw`X$_f7Z8&F($rpqw}dV~Y?tO$bQUrpAPqf@{BN@-nB{r&;gi%w)CH*fdJPu;6Wv5(8Y z*1BaAx#QhrE^oRa!S%*HJ38Qebd#e%F!>=wiHFcSuMfLEy>|2y43jhCRSpVwIgvM8AUOOkg<$O#sq6I*K;sY(MA!(Q?Up z>`_~2&g@|Ae}{dCfjeprtUKykjng*8Y-Y7SnlEU@4RMFj!!96?9 zE9s!mHLrwgN6KTJJP|_UA=VS?4Kt@xBK*43SX6sN#^i_~69Z2c{$jSj~Si0WMk98Gu5 zUV7hX+pK#40*53Aabu&=!eG;Y7*|ek5oRE3ZM+Nw1P!%N9b0hS28zdlr>bsnc-7nQ z@%O*MKzf6lE{VCXalYkgZp|65{K~n@?14cZ_PQLxy}@~9+5Kq9{if#IXGkrvgE2px z!YaoO$46-3Oxt$!WNxiu-9GqNpW(`{V~;=Fw_?y)6D8zlq@h3emKU}$rdl~W0c}#z?xao$a%Dn!rvi`E#0G)^>&{qbdwlwV*g3aH||J=5=Htc9}fa}^L z`|6L@>~Qgs{lS0!+w3i7+ux<`wmep0A+rSz+S$XljcS!OTlSQ^U%tGuS1$KV9$kXK z#P71K!P9$H`I22ccwa5P;meVkKe3JC(Q8v^2=`Bc=T@p%_) z>gafkq?B0H@Nup`4Kb_avW&SS#`*%rKw|`zGQ+k8Ha0XL*2Y^LxnuspkZ(e#Y>Xd3 z_?xYdH*o36b0nF?G_&65fby`zn2#c4YK7*Hj^l|DpuHI;8uP>3run8o{R`Jolfp&iUVv1uFselV#~V8gxz6Q>Qwxy70Pj6th3H!ctu-I|?o zC@e2Rh?Ns3)FmTjvaOs$Ni19=fUF{7)Fk;IXTA9N|M_EV0*vhE zf8Ddg$*%q7M-OogcxaElyk#>Guv&jcJhXf7;eHH%%wPP*`_L)5J$&~841}6(Zf{#- z0)oa_WGEx6<7H%qh4Xd~LxkM7yQPFiZPvO{X}c3Q>Q4#@0@nnA!vS;!W74IP%!`I3 zlrEi=stZ4iaQcMdjB-ut{t))^S6)E3Yy9s0#V+pp%$|Jw%x3JZAO7WI!z_n=_5noA zpk+`0W`y7p;(t)HZhhOvgTi{PO^ySg%FkK;x(FKuh3CFyxuFGLjI_EK(7x~B$`*!zn9@O;v}Sv7#l$4|?vH;3Ci55V@BIFbji72CaBDI! zD@B{eIu&Y8T?=2t3Q{j*Lw^?g8n)|;pg}ns4%abszH;*Clx#{pXPhS zjPDsP`jo%^Y};})lxLq}O9#e!^RQ#>SsO(GCI)2>M!#U*VZ}ekg(q>J<1tM%aoQN{ z%$Soi&N6%OH3C9uxmHj)LF_!eP*Q)lELdJcN_nG$8`6;13zUmNOwsp=*U^=s7Yv!n zUB17(PtoTKfjB?nH;8e3OBj9e?&ie>hb!~l>Q8VmppZLQ}E71T@hlIOQn z5>rSJxEl~i41l}woiFUA5bLla2Fbq=d;dAc%?io$0)avuMCITqeuMWpYdB+N1>uhf zhgWgxEsii~(LL+osl4enLEtVzKq|S%*odP-6);5Xq>Puy{c#qRknR5{K?(PvMwL3A zdR%EfI}#NLeLd~ZDt^dIY)BT$LpcmANn+?kfz3gbu`Pw=f=10ic1;an`g z4>5y_F&lA)xrI%$iT$7dbPpqf`}WrRx$TV}+sEH&ab9!R-ouMPLAm$7i=n1Gw?}9M z%n*$V& zLbLbDA=dlbw)^QJ$7Z_r(O*4A`rooApX|a&Lj&MnylZnbULJq?1UeT7}ou>cb|vAa>Lck)rwI5w69Z21eP?9)K2Lq zD2TBZLYVns&X>8%XE9CrRFgtNAOjrI->X63n5o44Vd&|o7ekZ)F3LF89+9Cb=JdO3 zt^^w!vPsp1LH5;O#eN2i<6r;Xt_|j2vUh)jq8Z0-bkt0PGuwwzpkrhk)JsAgtu!$i zaD5x_Uh<@nAaF+^kk;=z`r%J>I}-eoS`cc)I+q))6|?(uiP2!|I0In7n%YGg(FI|_ z*pM&QLCzqYJP;2o+*+~A5Q&qpu*cLCCkP}6_~deGRw#8jXB-KN^N08h!rvjMxyL+H zNzE;fxr}Fa6^Aq)s!rW`3=toZdYu;z#rYe8-W={?Fd%nlygW#X;Zund& zq!ECI&Env|iVn}mGYs#-Ov8;|!Eu|88^fI8YO@C;fcervV}L!nj;)R7g4AQe>@258 zWi2T)>nQY+Pw-p?AwlbhrdgP3$Flyoc9aj!DV>r(4+zBh5tq9d$GTTs{$e%P7CU>n z?3AK9RC&+|5YvnCtq!^e88NNq{BT#>#`tBwY29wuJ{bI&ZEURBxVf;kx7d{$jCJyj za8o_QYIT1{%rYit9VUQN{4fw?xPu8>mp0qA^*p^eLE!o!kQe~h{|&CW1tqHQ(m`GG zb0UFDj{_Dk*D+mG6p!|Y82I9cRj;hx1&Ii1$0s@=g5?EvrocQnQ8L{m2;40QXpRXB ziE(5CTm*#**5a2J%(Y6^<2gzGXnR1K$tu3g=XI590&R*2sF)Bk$5gGv%XF~5T$k+t zjGW;TG#Anag)m2I2|2|1W(XK4iD&pJA5Qn}5dY2yI=kS z8Ujyk=iO~P%y;dJ-+9Nz^#gnVoA2U^5LbhJ3O&c`^=$?qc82?S`+U8Q#5ww%%Kc-fWvWNQw(Yz z4yk_%frEj}hknReGm)R~*IG{`J=H$GoYkcH#3mn;hM$fHxw}x;2nxmdOEx_(8Gz(b zJ~09`?_+IM$?39MWw}C#t-3D3X*>@ti>we=qbkmB>7)k z>)P68$Nu0y`+I)>*1POB@(~8ow59ZS7;PtR{^d7;NYbFvuC>I;vA{bGHDD zsS61LSAsxd09*-dx2sSHsU^*Hc{86*Z8nD82C<)I5G;^B@*vP)-gLS(m;ikkVQ3G?&fhTX+rhw} zuJvQ~y9xrA3d?mw5>GwXp`jNGf%uO{g1lxg7~lG0wWM4L0vAKTQAY-w#+$}whJ$P1o=Evy-KO>6pH1ciYprd<9OJzIj)pq(h6<+4$HjzwrLCQiy~(GA&i|Ko zGL(FJlhlh+ND#O~5U4@?rD<@BKY0ASF;-Wr*BMCnjAORXnxBH0ENo}NDmsC%$L}{8 zZM-){)_>1F{L?+#{AAnyxBun?TibotJ~`UAR0Q+z%vBEq-pZ43tSU%nxh>O!?FSi!mzAn& zi0}#|mK$sH$C2bZ88=~;Tog{MwXx9@h?)y?w+w%N4VSHtd=W1kTdkYwCy&?h)h9qh z-kF8(AKxRUkyPmwq+J%Sg|vIhQfe2q$Lihi0i>V~>5OJCYQiwF<*w5E&Tvq5e)64{ z>-dVU#bi^JeZ7x+N%6&W8ax|eXm8z$19CA2=8qw~$(UojPh(~GZ)ho+aF0KE3`4xI zgAX5>=>HKe`i2J>$UPc!et!Z1PrixT4RMbFKjVmujs_I`aH~P1^mf`4DIIn1j1a%m z8IL?^A$8_!4AGDMm75R;1{K7y8e`QdU+))(%bs6cx(fdI-Z&OjQlsOd;LF5C87_II z)n%2i>i%`v_^N!K<-Cq?QoEZc8la<}%tzMYyew*P2g!?#>rI^5!A*B{zfe$ut0#b4X+|KacPbYh+FjoAmVmC?rG zCK>>;8!Ih=T=QQV13D5wP5P;?u{{y*taBV~m9XmfzYPAXv@MlQ5V#BiL4xlxm6fKH?1h$2~SMnYRhm88VPvkZcrMGX{N zSRu-vbr}@ohegu@;&O(z0`l7Bawo)Ai0A_8t=2jIShpD%1xi;?({%0hn-Wgr?~d2{ zOZAihvg=5&VxgfigsUtv2x9UwM|fk9*v3*Zj;+z_!@&%ts41so08Htyv_rHJA&G!_k{N8g>GDy2G*Sdp$~j7 zedFl$A;N#m*))A?)h%ln{tiTdb$w^TT&in4aYS9BLFeFz5Kyn+bt6V^HPBd@>SYiT zj0e46E-D2qr$71VXxsb8pJIqlL_ORo#v)85T=wY|Gt~2EGYUZ5*U^A!$h{aEEYkr@ z3E9(OTrU`(>O*jyOI`(igcK44ZUqDw+|PwD&yJJ17t`9uJu_ah=C2~ns~m=C#`-H4 zei_;`tiMO&p*4~CkLn1c*6=QaNNO^N(Z+9`O(9eMav^f&1nYQQ2g+G?{CXz$F;nMs z+bY@8WrDyRfIy<)?!ZUBu#2p`z6i50KEE8+ZFGRNEbrMTAADw`$9+54!&=eNfb+aV zR2q@W89r81NDxR6ND#OJ1SAm(1S5aN2!PmK*m}6(1_bXz7}jgpFOk7Q z5ot(Jef{H7i~|vt5^Bw$DiuqrTv^FF+E zH`1}RA|*(72nf>B-Q6JFEvb?FeuQp@hc-_RgT|;_IO@An=#P*ecLJY0eNfHyb+Zv z{-j;D7$#&TV*(g#!J_P-^qXh5m}CJ}N&c=W-k4nPiuWBW1)5Pa&a4e7-;&g?Fih;SE(eVHN6@hVF=zEzjJ3d69Tf zWU|DK{#*5H8w^e3yc_m%`HRfMP{vnXBTLs5=Ti4ipBUNTsP|d|&l(8*4ncY!j=r|) zfIDMVx*oRX*P3W-PpZI!^Q>on)1B9*?_6r0AJCk>4sM>`A$$FKnAoY}x|7c~al)=5EU|)ghI0jfN0wiJgz?b% z-X`u^)Rsp3JM|gt9KQ^WP%$yiMC-{9?c%R%5G(E)qws2Iu}Y1HwQcg;vxbXZu}s?i z&a=82l8yN(^-pde5k>`m-n8lZL#`l$jq>_UId#+M4KX*&Z?&32tI%n%XsuLw*-qR) zeoK)sF6`$|1I*M;BvN1`6GqSiD`;0`ohRQg1MprC*KuJ8k!bSvzlK!{zP4(L0r8vuR)6lB7rP}ML14O&m_;r^ z;J8GB%J%l3%LRQ@^?ifbPd&+Nb15ReROikvy118BcXxw_2_RkZdBofP6}GvI=S`m> zm{p$dPJ6~ncjy4iB}7Kmqhr$XybI3;vZVX8y$2J*hlU192Zp5?|}Z2r(y_N|Rl z&L7>CFfXlY>5sM_V;1;_&@KlmDaS+`A^CUqU%@20L%W~U2F(ON?S)lzy^$EuG9|c(_?s4pD7i*`Frv#3Q&0KH0roosYlU%yXr@;ZcU(Vn#;SRNy z2O|N-N4h>Bo6$Bgl+kGtZCyv*bkh?T{?|>@v6O2AWyYjpx{A4!mhG>ik$~x2-y0tV z5R`mAxPR>~ba<%1KG{)0dgI=nO21cy|CS}i@?PF-u|!iC^-chJv*%As+#OBwqdSe! z>-7O=g_E~eXmKOi@+Y^!xWCV?xPFUvbn$XZm>k>Z3a_nkiiE(`uvKE(qlb2^_3_5( zYY@zJ6{qxQB?xrT?{jjNa0)n9v5<*gN~@&SuXhneVP^K>m!Z37I=Q$>rAv=F4(%h%ik$*p*VOz$tKbNGI{=Afb%_P2|C;@y2IQ?r` z<(B3?b)inf#1b7BX+3v~)M^ZV45#aUpg9iG?gM$-HcqegrZy3}zoB5TN@o7E8GeQI zzght1!D6t{9WB;9Pd+poT3s_JWg-_zX&b}A*W!pDe9+H<*uVu>FM`M89Lh6vuKS&9 zvEd@|<~%bi9=HU{Ok@vl1RF(o+JJeeP$Qep^D9fwKDuV^lm!ObO)h~xRJ6rw5H!N& z9zH~|fpF-Y2B+b{hgL!jI`kvV8Rs(EdEbc(ognF$eCL+}`I7QY6X|8yoIZ)WQUGsB@1<1`N9y zeZ&Z2T?WVz(h3BSN!}0X>)gWhJH+-gnOto21=Q~vTelY{yfntr?ec`CCt`pMrYGyr>Fu;HCOI$bH1DA{Pby~}~> zBY~}A(w z@Gtst_N)y)H)qWDh3Kkg{+&g0{4HOi>Pm?>ql6`M{C=3?UyF=am7EAnU(84@r_d&t#CN-?8yDSKX3BEYvhpT0y#gY zk3Xr9>2K`Vap91^k(E`!WF73fYXUSlJ*!(O&5i_MqzI-3)3T__K{gk*LP`{UEqm19kXZDDLSq0!oCga47N}@*Ywu(vl=w~Lgfc9eyw1JWX7nt64 zWA|ssgre(l_pr-T6FXvRd`hP0gQ&!W3Q?F-U=RD`^R|1&13i5f!WxELfs8t;RG7@K z0i{=_zpP&y5SDtek9e%r$(M>&E!Zl}^TpVnqWy?$+dT?SE4UHwlB;?jkZK#5m5Isi z(>>BF)Hg93<1XZAa$jZGbjpJn=%fEs5pbt(yT7wi-E z?eWQ{z%Sn&A3LKdRY7W9HfFXPRas=SHJQg7>p&^Edo?7`!V=ws0=}1~;eB0y8=`4T zLS5XKcY*X2^_>?RR$ka@@B?(!he##O}Gz9*B}8$A3_$sczCH3taM8R zfx|%U0!d&7t~Bnh10D(#BZo0{nH1;;Sy@zgfzO8~PA2#DK~Fsn(~UPv0%R(}-}9K^ zjYJLE$O9!Jf2jkBKksKpT*0qAFZ z6MPCH;C@h$T5@*h5koiyN%xMxkcQ)rbXv z)^a1r!olZzVTI)L9>>#P+AnZd3Tf~dpxf%ok2i+ndI^DYljSRXu_oy}_w{Ob!K(-b$)Zl?d?S zVb9OJM=K3KA~7QEE11#Qz#fR4dV+Ci_y_&?+NE?3kx=)ABn~=fG_Ac1(NN=}PP7Y@ zrH?%VGRO&6dA*s-trKzB9A+avUnOy+*DVshzQtJgWWS?Equdypjm-HvT-c8Xb5SQ(aeOc4NFu-U&+nT9f z?c)>@DdReH%DXV$uX~T`R<-a;JFm{#XkYMzSVro%oh<6S*>Le_PoYgcB*m7)gC<^n z@cNS|ILi6=(YdA$;^6^bmP&C->^yTs5_kr9A?y>QcR7%KOHskvprpgLn5{6#LpH&u z8-MMeuuNzo8bRvXjPXuMXs>v{tQk0&VfmaeB~Q1pR#_fyiVF~%QO&&K@7 z+@ZegoF8Aiu^t@tz2~`PuN!kWp&$@xkY0+jn3xMw>I=8D5tX~tr>SFjg&>M($O&ft zx8sP8iN@?BMZK?RDSR$%)|jwU*FC zf|VEx$6^aYOm?YcumM=TqFW8(g-Tpf3 zODglTfu46g2EE%Uzkn5a+Y0-n4L;0F+`-BewBHa%WDP2`t4<2y3Efc?!#Ki^2ura| zf5g`So92AAOqU4m)(;CTR7dw9g=g82=s02lIh4yT;9~qDnh2jzqpD5_CgC0`o>dgj zOibc;p+oM`57#~Pc|llv=s~i};c^YQ$+POd@*j_-(qxX}c{mIsLX!@ee3b@r+Cr1q z^2GTj`*rqE%MP(~xt4D+a>M233`+*&IVzjOdBo!syD+wB9&H7(nK43HqII8W0M1B(R$pDk74aq&R6(ZYvxwepe(}E`xRL9a;9EIMbBtcGFUMBhr}! zG50ONER6ZVDiE9~I*`}dnY;nd61wbag1{Z{b*gEY>j(Q);f`88mnVpJ@{?CRuS(^E z=V7Qwfe^=Tga*nQb>fB^uau``O80~3%zkmyz9u!QO(WZ{VHGU7D<#SA?wNlA1`a!e zJs9-DyS!yz(;ebyUab9!AKBPeBpv;lRESGXc&hj;9DOg4NCOM9w8P;#Z5d+fS}xi2 z7&%`bbtB@c<@Ds0`*M?%nYi&xHR8NDs5uVcfX?4KP&=|^D)Bu)-;51J z`Q;)I=M2Y`+iUmGGV_+FNj&cek7^IPXXLa)Tljx99<(f_NW6gKP*{XON_J(MM0YW+ zepU;(D*8_LCy^uX7NX00PoX-IHO*R@$fa^?*9k+5k&vZw_Wie&C1}Gf`3UUpg5m&F zp)=%3g=l17#rw|^5GD>n?O(P#2c&Q2nd+KUGTv{lQUk6hdj%G7O`-?Ixn%4q4(o$7)ctIpprb{_ zWr~@k%0tP<;qS}f2xt&~CX@H|RZZjIZXtiGVYJy9w}>P!j%$k+TB5-Uk*4bd(46ik z+`qluV{VG#MKId-qWQvg2wHR-s4brAx5_0y%s+E54)Pe(+G+m|kGNUhaDRTzfqVE1 z(QxmCVIURJ5YZRQWEJf}4d4IQLDA(%nF|5tQS6XuynEGkmGDz;Q!Zd5W6H@|P@}V1 znkUtD1ruZQ$Lbz=LO7nz$L$ZvlMj4LRcnS$Vm|;aXX{9y;5K{AbyRym|1I|;8>}b2 z5xzxWoUv7x+QN^}1;_h3`Zq?vd+v3SnAn}~Kjus`gUgV0R65LK!V`;4-=Z_E7q*(u zUb-DdG0%*@4ecJTx5T6MZ*=+(;Z~9jmH|N{El+B?T{j1GSK7!abCBxySBbi{W>l_YZig%{taP3e+aw$a4a9e~EkOqWekpR9XD@|Tm+F~m%dM03WrELXY zbv)asE)HoRpqvJghxhU|orQ+G3Ra(WN4yQs!~dPviBIOHV?Zkvz2A0N-Vx`q@A{Qb zIW2(ovaFKy7NCeo%`}(9(dmmh@K-J?;}-tlp1!~4-QmwmwlmYlZI7%E&)EZ!Q4C5$ zL)@AE-%cG75Vux@n%L)s07kr=gQU=z>S^v8sILZH|K5+dbGeTY-OD`MZ~!vLPU44K zj@zerdk!y)*rraS{M{@{^M&i**cE;Y4aUw^M>yQ^A?@pBEJaH*x}V$~63;xdV9f;D zEX9-s!^}$*5jIjoy3rW(2s9*?q>{1+CuBXO)FLTGWqkQV;sw08S$;IUcWn34Ka;-G9qCWgVAuCgkNx@SYR;e7#iNBXpQk}tv4wts) zM_18jhbH%XXwKu!E|k2!0HezIN{mQ>W$GV*IkqU8 zA-6qJ7Hw1rtxU*k>LsginK$H%Rp3p5s~Xd;r>CPv(I@le=OExiWEfIDG*)5vl!*o7 zGcZ5X9kT<3yu*TV6cp1=g%W`0H46`ZAKmvzaJi4FHKu<`GXk>@-IQV7S8Y#}Nd5XJ zUxL;cE*WHGS5xbVq!J`PdM{~xqB`EZyMLofUhpoq-1fCIzl*k>iSXlxP3_AshVOkw zQh_jKNf`~Gml1Iy>L#!qsX*a(MnMPdvm6U{o?L$m>U)~YugQ{DRtqUyNv=c;MY=X|XbngT|W~xVfl5i)O zK-7q39Tt_7onduUaZzYn=CD!g*Jz`D;#%WPCI)70{v3$6E%68ZY7{`z8}yEsc#Xhc zCP0xx6ELX#tfl#z6f#&(B7-a$lPo_^hk5mYhj3OQdzKSicKZz>6NO|9@9hk7u#872j!q1YczaTM4r{=F!ANuaqQqiG7))|L7O9Gbuu}=zCNu%dFUnFquGjM#qXu zcd4=tlALzMGqafo)!jF8v&S=fe-Qul>io1?2~%ck_RnvJ`Kl}WsPxF)tKi!;*VMll zJ#$-cj+1VjgC7r3o8&6`u!&MHYGMp`h>GmF3XEso#L7mcOdh&;4~hS5&4%s%`8QlA z0d@1xwxBAcP{lI2`=}{wTg=ch&}$}$TtAlj45Z*JH0?4;J;@n(%ib3sai1x|xKT_W z{*4rPb7QqI9%Z|^NkwE7N_~lK&6X`9Dj`?Le z1hIpPOJOqsycApC2ilUEQMHgq?c~F|wqJN3Q0>v4Zs;(ajX>{Lc}*H@Zg%cPY&%bQ znduVV66sMqui#7@DSrV=)ynhIav(O-e`@6@_&A7&fD8sgMs2TApIb)Y_&d=GgyQ-b z9#W?al&3vyhCu)t9yA5>Dy4pDX;V&AV!t?&Xqud-DXKc~EsZ@WLVdXpAr_;CUFd#q z2jilcY@|qpsPv$<65ns`=+A?jVc3rLq?%4}_uDWrz4!(v+n8*!J%l&}YX%VKj1{Q- z&%we(htKV88*5v{LtGOypG_tMR1w0f{06}9hoe5T`&X%At_JT&7E4+zL#cDn#(!A- zHLMvJT<%N{0VZ7bugzSIJq}w_3&z$6zAIDjuLOvv*e|dDsqfLKPbqh85@b|M%{3C8 zh#86`N{N&3!947f?Cj6tXi>$0|AID^fS|~vlGpRf3e%H*-EV2&er>ZlJAO18mi&yF zJo9q3TxODuTW3o-H_O@#WEBz*&(TZoArMOi3LiEPab zft{BHHeyKsIAQ0zgg(VR*coBzm5JyGRlC2DF+Q)F3!93-TUyOyyV(9+^<9bJ7&TX zY5Sw^w{}>yDq_od^cQ-g1nFO+^dE)9LvIn5eQ((uQl){4 zTFn-41JmCq>*qN@dUX|>+8FjXtedR@W2N&Be7g_F9*hhD1AoqZ{|W^*cauyqi_bKu zONap{s&WN1CPoweDbSY{}=rF z4^+K;(~*J*FrW8+&;UJW3=$bZ{4u@5Vg?0MUwgEykl_~{+>~z|b*P8C>KmwVMCy9> zyK8UWP{Cy_z80;ws2ZN8=NK-;22)2czccI*nZT=L^Zp{>*s27h!1<_O2rCi0(?J5Q z-<7$Mgc9GNdORA+U1UO}OLZN7pKDywYjyT&4X}!UbahZu$JhGpYgl~046@LIqIXO! zi9SZ5!8f78zw&cWC6X@^ugi<^3;uj+`pDV&A*VS=zvWYJ076?*S_bgE7dJsO#)fZg zGQ`cYgk}S$`?j8$170>Ns_}>LxVE zfT5iFz#|H?lZ4YA0N>-^-(OetpXqtQ?E!3T9C~Yv5llOUXiDQO*F(z#74UM0pZ*s@ z+DIbr{qupsP$biHON1m>FfqviA65f_g_N+UamjVRV3N`yYU6Q5{INyDa}h6S)F5Rj zi2g6mbezl%sh9Q)YB2O0Y2eqcxaZgLGp~p@A`AwJThrX16y7poEw?ts)y>d7SzQ-x z#44T0Q^t`shJQ&27>Y;S#|&^KC=@TzR;IMv)7N}b9amFOnn#02gJ;KvMb3Fq z)oYvvjbJ^OPN5eMsLL0*z!DiSgVK(NtMKs=j9%^ks(twl%?L3AW&q2bv*r7bLu!he zH_E$rgl<|nD;2BfznB)`=lyFD-X$Xg7@ym;uBpdG>MBqu&-;dMQ3CGO(yRPz)*qYJ zdNcqsaBKOBF^}WQ-1aVdIgCe{=8?_PF{Z6sHaa)0X-xVr+TnJJ7c;Z7;eO;Y`K~36 zn-sa%RJ)&eQtR)~PX(%N5BJFAqgK5NGakpUC(%kf{FPPJ4w=Ss+8{vTaO7bHIYEi! zzg0mG>hJYdk?n|jV54KyNUpA2+B1KOJD{)PM0YUcM)7}us0)4@>B2`X7Z4$iJd0;| zywsr??j(c`AifSM5GuZH+wrv)YMEs!_gQ6Z&A}Y>eb-~YzEHm0_|e(u1cjA+e&|*k z;%d9e{6}Y5LwCESJuAmSVDS9fEr$Pq@!p)Y)RfhrEZ{K$p*-g zZ(F;sux?DimOQuf;UjNe5!&-1SbILTvdWQhL9GlQaSina2$ElrR#xF*ya#0DmWgrz zY-F6QjAub8_Mh99K;`bN9)fV2A@--2S^VH2TinKkk}d zd;=@Iduxm9nYb#>nAI=D$HV%MhQ1-2Uk?MRh9AtF?5Up_BFP+-(vX1#f9i}UR-WM_ zvXKX*ZW5;^JF+BnV^sYKyb{;!;JHQ^6HrEzxoWAHBez1`f9Umg+2NJM*nr41S}7d+ zbX`vEcKq}^YXZXP{#!^q&GGy?m+q)BtfFps1)+7~#Qps5emN4|BBckD?XgMHy&JES z_{m9@4E&daXn+cP*v}=5T04G*0vgDHH6+$^$jaIIm+^Sr8a4LX6%ljLlysDC4B+JG zIE@)YTQkBCg`R_IvnlRW^%O~~jqgx*a;wiW5O@J%-sD7gOKw$L{Ldg^0H>Ug2|X$B zA0pSS+2eCjydz?*>_oXSH#_#y$7D2QVgoqIjc?BoY`LAmDDT#rJ3wH)|m3nFTrSW4Pto-cFx zTpk3CV>j6~4|xGd;EuGQsh{%(>?c}TlQ~$|S5hzmY^u$5xK2p8gZ(YeXg?!AXT+Vc zY^V-7q9NiV1;~q-9ZCmxXTrMu+<0L7FZyhHIA{B(#g_})NtDKyhoE-Nr;_i7*{`21 z`mWVS1ROnqq$8mXXE&_NY0DvJ+`pH(miM(OO{X97$P))V9S9};y%P(dGwiS|U6{#f z1-@wPksf&ec2E*+6CE|ET|0Rae~1pt4C}l~X{c4OjoEmdQ(aEkAg@n|yEa{6Ko4AFhA+WFHtP4P~aO$So6Ne^FbG;_@kdfD9PZ+UVJm zh&JCVK7S|N_Mx;BGiKVb;;iX=uG#Uz;tfCn>8&*J521jRFRC2h+t;QnF7f<&^i2L% z2!Mx@VIo-4pUdzC#=SK&>nW@6s!F&eWJCI=*K4MFx$8IG;8?FCPvRwNX}b$gJFt@A zZI6tSovGvam%BocjDl^&=L^RgMO!@LaV5kHrLh*k9ro4WH6!<5cS*5t0rs1FgFLwDiYNbZl#y?@32Sgq?>J6!e7+@euL1yI{yMNaFkR}%Lu-k5^f8PPS>*``+ z`n zpVQu5El9T8e9dlrUvWdrD-txVGVurbYj#-Ad&dUM{Gg7kR|AO1fzbfZ5I0%(g7?ke zzR-U={x=gnoEHP>y#X0)cdu{a0NMCF-`Cg+frEt?1?v|fQ_{GQST6?(cqeR!5NHto_AEZPXDxgBTWQ-OPRHl(bJv{`T|Ns) zb-hMO>9qDYTFgU$EQoiA_9+14H>_JJ13wL67yuQ$Ne!MROVe{2@wl$7^mD+aYA7 zP*+<8ml(JS`|JT7W<8w+TN1zFM9(>8@*|}k0Vi@+zynTss4P;-$ANG1%5yj9_7zF3 zHK}+>dtWwcD?7I+&pBW9?0$6^b6Y#h!{vcqxk?R*?d?oi_h^!rZeQ-K*Hf&q8@^8l zz!#-N&tns0D(JJ8dxqcC-WWFw>g(uyT8-{CXYLPT@KwPg7H#vqX>KmhGT21{*OCQ) zxEyuKgg)0^_>ewV3Os*1NxJG9R`BMuEpP5(mHq@@Vf;))Tg_lB8ZJhJ!gsZ@hkj2k z_q^dWCiMFJ#$4nuIKL?{HGQy;%sd{N^aA&}e=;e|& z1cDz89x1kR>cHo?yWe{U^U=}~=~KU;zxG!QzTm)0JbKcpf{a&Xb^G7=$vXZgEdF0<<@ibygd5p|MJZm>(^#z_G^ zaXt+|7=_Z2E8g0JNR|;}!DL?Kk7un2-YPJiA`F*c!AG^WSsNa&+)8)ax({et zIBVUoh_Lfl`pX+2-VXpy&w73zhVV$rOer0$!_jS0{sTlp;&4-F!G!k zk?jvhYnjtWa3?9Qry}rbW<15MqyN-to_OUjxvdoyQW{F>&b{di^u->97cz^#^-UE#MWe?|O_e=C3SiJyqdM)BK>^M0RrMIDIn= zk#7=x^>01cUY65c9Kzks`wfz)MO?H{_4c!&KOzpGHNY*fClw5539gwcjotdRDrZv= z*L^dG{H<3ZqFcK>D}AkK7V`gmOkPTO%WZA;wZlTpgEvq3Md`UsZ=?aG5Q$r}jbQ{n zef=Q>zNrK0Y}p9X1l}PY#~q$BEdDkATDu}snTW~b;b%uX=*7^jeExd1^X-_9%$;4r znNGTCb_KQwf`Edp>#m_t#6PjG1LMomYQo!;#TBign$E^cVS5);bby?KQ6sI$0KdO7S~e6TJN%&^9y;c1-WcFLz9L-t7|9W{UN`Dj5%#0a=NOyw|7? za@ol$3Vt~@WiQG_jj#=J0}uR-LKP|^Obb|Kd44MP?)KAmQx)!GLAWxva) z)phNrkgXC0&|2NnZtrb0l{X^SGIJV_HicFbsK(mQ%mqc?(IREM`^~#M>b0#Zxqoz? z1If#_g!@&eI#xzL{28q$f-3*n|L8DILB~Px+@NR+)BmrOM@RZ5f1YBbrQ<>my1yH} z-Xjw0#zTB`p1Ysnib-`s?RRQ^ok7(?yrVGrA4mA|bwEed7$~ZBfhIBfD0+~?z%lBZh%(iB>ixYIP-Pha6@4g)6~FJi78FWUv3eci7X#fnDt^MC zvqR|%aBm42=_Y=MOtMB`E9d+oNKgoY1-4h}*>CYrk`cO$cJvWNF+2(yrPPy?=IpAB zS#M(oF?+MsyTX=JNFV66r@Im=%t)*x-|$j+(AAmYwM*rzf_SmvFVYR(unkR<&zH>R z{J&eFiy1`5_YpV^O>8_S*U!Gi0Gql_M#;|6| zyhdIflRdGU{cY>kfcY5?X6ajvtgj5PBUg?XG`hPdm%JX-i{|gKLD$vGW>6~bG2C`F zkhtytdyi&z8TX3&Cjc@2`G}v`M}M;0dJwg~@aq33y!+qRR}mLC>lGp|JGIAr!nJ9gHP2pzcs4~6CO?i1 zWa=Qt?mK*MM|>)iVC|!Y!}3|v@o*1&`BSm6Qg~POZb;KgUcj`YPDdEvOS z2>G6guE!{J(-DgiVJ5)XZ=zW_|3B+i^MWJDpAIDYw#g`BXFe2J zqSH9&D@)m^nrWO@xz!TCtNri~rEL*9>~A*(AE*jM)8vvwEj z_$2gMnOhM)WN&ACA?{yl`TwTW&WEV?P4TvDuz>|Z(-wFJ7vM?u9*F-Rc3dBgnn_u^r%Entq5^s)8d zSG$^llBMHlPd*opnJ$c|?ba_l#(NUo{`EHJbPt0J0|+4$aZ)u+)m(_)#?ha5CR z#bMin8fXpdW7~p@4(b-Yz?P!0nI?vA{7qz6@_WUq=-$bQ8o8OTAml%s8q2`?&oO-Q zeg64BJ3xS3gNap0w((E2zbt#@P?A)?eBTYWC&rsxVPBu|rOaMPCiLDir77aJZ+$1B zD+6FBzNXZDoyLHs^dL>Cq%4Hrk{yD_qAXu*j4?9oOA~}RfB%-8RTm*D(5bpW6oy{# z;jJNSzbC(}Sm7O@7Y$d35!vB`ONs@M94tr>?0Cs{P{w>USY4fQNS*?RBV75%C3@2?L1DGxN0h5B8p@?#GuUyR-V1`~}_ ze=ZcWXFN~E$$?tUPwT8oe7^}K4LZiLTU)Ku#xS1jpk8S1aSlSp1VEJbNIXxC_etqh zB(enx+K)e=84?b&+fV5Q=U=+BA#O=y21au6>ySE+ejk_fc=-)pzzZpjATksE{+;X* z0y(f4I`k_YDgA?Y2^_~Brr28J>Z<+N?z;$=?g$>i2+Z9&FgSnoh{@Gs(MB* zEM#Uqvbo|>ZWFRmAU)Jl#edf`!_wcv&*oo!h&obgdby?ftLT68fic*~@Cs57H<*(O zCsEuwu1A#(<$ly;P?cqYJD*z|NVH*%rR=jur+s5r+X3y00Biy&pjWmtoG;C(9DG_1Ft$oeUJ#6x^BELl;UFWLN>huz=~tWu=wVKYQ`w zT)m8Q0h*juk2tI%{?n{06PO#cPS$KQvb1n?w#S3mWm~n`VXfB$;i>f#f@iVdibHyD z&qu1$F{}-kgHwFn6HoHUMwnyrZazOyEC!JKRf6gRP2W+-%WjT?KrKPfL(kM3iKjh{yBfygFkLsABO+EYdk^NP7L#7)ozrE;EF zuHa|%N?elMw@Dhrvr%Oz+HzV984h5Hv{&fndMw+2oX{T%D~x}45e{7G3x$3;pvay$ z|5ztk(-w$H+FZF9s^2jOPf9|m)3sh#6v6~k@V0-7D_^zIEsM5C_4)?1Quq<{W=stD z^|Gx&ncA+YMo1{rIXuC)-SIu;l7{8z)j_7sL9oX#ccR;;*@C=!&c#Xv-^^*9{A>=~ z2Km9aztXgR>zfN%7hB?CnrE0+TQyXhJTR3{`epT;K*=0~rU=X=kX<)O@di-M6avj!U7wnl-+i97260K5?-qs(S+1 zWGFG;wnN=+MreTHBg44LOFNocCO?XlPrfG6+KkhRT0e;rJo)IIbmA6s%b5nd-)BnK2Bpe2t`BL+g3jh`Xn$RZn0QQ(i>?-%|A zpZQjZ1V`Msu+f5C@jRX2x;>MVRP?N|s3#~V9%Gnzq!R@9br!=`glH6UevDXIjGiL) zwc{Ur6nlY?>BvFV>+RMRkG@OWf`m_rXV&J)S%V@(x8<_uN5(7J$?3LkN6GMIftLye zr^gj>5u0(OH)GhCp1k!KTt?xFBIWR-#@&;@>j0@`dl9nN7;WoIyT_sp^|qjGlE6k) zOH8*T9+_sfd4tocI2WJI&?Pb9|4WZv#tf3()-<&Qtn4bTLprVD*qgEru?hcH;@Z(T z!vz&88$Hb3k0aBzZ1CCAO^bAAe`8VO!4Xl$Pkhzm{KYqzSy*uNL&=^sZnbc#YOwMW zDWB!%*CJ-kU@TuQZ_!+*LI{uEH} zYCHL7qHr~eVn<{*;y^glOlAKoeUxQ@RD2vY$&a$364V)wFWY^aFdE`?f|&2d4w>%| z*EvGOM(tTs=s^Any+>gHw>wV0=eOjwPC?8yK54iHL_&KK`w{O6KLk8kRQZ0c4GgRj z@5Xo_sb>_CzC>0)8jAksrpQyRm(ee*h}O z4xW7M&k))%LbI6&npknRo&WuG2AM=;pNNXrPf{JtKGau8`|d!GK{gq zs%R5P-yiBzT1Y3q{WXXX>BsYQ+e-dOy-Sd8x<8p_b!kkm+z?jxv}9q8;ZyMgkQydM zt%sa@EhN4%9u^2%iQaXZ0eHH0tztAB(=SrJq0O9vWv1z(iC3DS(+>z`QGC>qpQ*N1 z`vK^DBd9XCZEFOd#EN;+-n%~9RQ>kzBUv;dDRn+(&_aBq_#&4*C~PM56GcR%v}|sl zMa07CQIwahFcO!0!V_^L8DCJW<8WCzEv52XQDf5w8y;)O-6Eux>wI3<7#Ovi$eUKJxj|m9qfA*C4B$b>fUsCD{r{o=uqV#dJjHZ zMh#NDOD&c!MzqM>=+bo*_p>^CwXiVlf1>d;D$GsdJLnHkxS;>~pK~cllXG*+!WcM1 z?z+-@kUR0L$;Chy$ZN_W3#qy?-4r6m5TH+N?vQgAWm}4Bp3P&ov34OL0q{jOEPXnh zKQ`D=(*0wuJB=UQ;AW}+Y>U{A z(x<@bzd+g3olWti_mE)s6vJST@jJ^!cD-aLKZPXd%Hv%Wx!TcbU`%}xkHNMSlq}zp z;GkbXv|QqA3CD+MF)9WN{loI6tlsA zd509R_4&3PlNtH8o#p<;Z$oHuyaK$j-?Gl!#a?(Gr$Ew+(YejA$}yQg>zBh6SnDjP zq2|K=@11kDmGCtx8-APmXHFi>Z;Lw!^9^$IeD(J7UqOkYvaQDLTFbeu#LqF)M6-)4 z3nO0m!0y?D)}KTFyx8)<xUl1=JE~B5cPZGp+>}x8 z_zAVRd^7^ILz_cXMC)RkJgV_mWFjv#L2r2MYA0I;2hzq1?H{L|9P!VA8Qn!hHTgn> zR`^yG!!}mLs5q*7R&9r7d|8;dkO^F;kMa+{F*3$dPG2m=DKcV4Wou5E{M+5Vzx=Tj zncrC%0^GbSq@iZl zlTZtILye6LI<0{oQa_m)$yQHZI?`k)$3~JnFJ}FBu?qOkp@E1_;WT}?QM*?g?O9PYX(JU z`Wi4%5$Exdzo=F`U_QXMQjZNygdpEjqrx=kmKs+17s31s&tPGj zLhkUZU1ycO-5fT?UUq{!!;d^Fbe0c9KMlQqPLmI1z5Elke^9o&2G*Yn3; z#@DsZ0?XZ@Oe-)}YcT16#SKd|o7F&=ZkAu@_D9i`CuGMvUih*6pqH8ZVZJQ9Uw%-} z*J9s>*-ulEC{XQ2T}zT&kGOvpaowbWU=!Fkt2$@rnFt7`&zrqTHIFa(jLK7}D0rh< z=ltubETe3a>Sr29-i+FjZUE@Q?U;(i$2)o2?2qz+v~kB_rFzLmS-ULpvdq@@yHe%I zIz5%4-qT2gIkgIfh1!P?49RrV7$Ru-GI>a*U*JUEF0`(n)$?&>qT8a8cS_CpX5Mhd z;r)T$O;6f#d| z+HK&KbB2bMd(=wvlt5SC9M=f`d>;9zm@7wt9Uy;~N;rqNozh5Uep5T+yRf!)Q+c9^UB)c z5^%coOP9idW9T1=<0xKXzo@Ds99i_h>+&1@C{#Tj%FeJU^ZZC4q#DQp%-A-tlx!#nf=M&nwIbF5CQnFMxZuy`O2=N-P%@c(Mys zsIcZ#qCTmFQtUXr3%{G*kt^@r(C+AeBBnqNk>k}64qeGHC0O3kC$)qGI1Y83b~*kP zshJ-5_}VYIf*lM}v9?8DS}mUM>@p3RfP*eQJrckl#$%ZE`g^G^4016BN*|#N!YA>~ zzxE)_(lEW2DN)_SZB>21C-JZr`_R%pq=5A_4o4hh5tW{^>{Dy)4W;b-wnfz)mR9g6 zEKJgSysy0Ri|;Er@CTZ{$YAWO=|kx|)Ayh>rr>Ho7~g`7)1vg4h%{Oa0gRDMQf|J% zzj^462}_laV?=WLdt(7Dpbpx!uoimcp`WCGM>e2|YGc`T^_Ry_d*!<#8!a{pCdz4Q z%`EUEmx+F=>Z`@WB3GLnv7DdbJ;I}|@y1_kIbvs>GbDSy3L-97Hk`#-vNZ%(#Q4;d zoP}|-_hT=u=)wHkaJHq8Mg7B9+6xQ~!Nw)xw3mNqy4BA}JRD%Z?Xyof^*_S~{#+-z zycU7GBPeb8mo0t5rlC~j(&f4*Tsn~`G(8`i#v4tlfD^$Bio9*76v?M*z262jJR4Fw zP%oyRO8)ZtvT{P;eQSs^8fH3u_&)Et`uewqqQbfIRtbj~=yfgZ@j!;$+!m(}o}g7e zk(1g@Crw6QhQiq-L>fL0%HnV1XMqRc;<5*MTrt1Lq(i= z1S-GZDLu=rHz?{iYh=vng|rhGiGzmxZn-Mj)|<{g`4KMond!e0ox;?}JPo}*a%2cp zuB?YqX9$TIUi#NYR?3-?_)bZe$B#5n{QN@YXOR2%=T*5-C2j7lS4NUvBUmUp3kJl- zBKV&&Bu0edl-yBJnWR#ovTZMbHbwZ%Q>KdqcJ8^t%hz)xBd1_B;mJa45!|3r<9+}G z=SUaLNpKTWe2}J%w&26oUpPW%1`XWtsJ^v*?D1uC+Jm0x`(lK43qH-Dn=*DktWN=>ca4o)sB3-IRUT{piN3?47GD5b_!l)d>s!iStjoT-2gfhW5 z+~f&H!3>W0^!S3=e10{!7GHGQ@913jD3K2JsIKt&I7%|QgrnRbre%Ei(z9`5! zTag#x+NLzYkrGbvDEtc*Pes8%CDh`D<>raOJq8FFY_TEKCk9`kWL~WUazSM0An$nO zd&YPxKUjFTB-eZya#jp_J|43>mHcIm-?wmFv690#>abdnwe%i3y=%bG)ZnABNQiTd|j>eLQ!+DjAQ1pH*4Sy zfKlw(9G&l4-}mVA!9DA+kdH_kZ+h)lyW7(|Wu_su=mB)!C=?(DL>;~~b>6d-`m3yX z0rFy|I}y)@OW$1Hn-;P_ja5(S+}_40K@b<(L>Zx+d0GVCG&rrhi3RMr%B?Li;C8xf zLj`z_;{5pN_R!t8 zAuQ3{jQr(5Fhg+sxXyK9jP~)?_7~ zA%=1bW^5i}Z(?GT_xw+vFAXG|$-Dq5%K5RI5;0A@@HrRvmKS z_Ct9yrW)|aUt(@~&bOrYm6NmYM1>9L8ndc|UyI0hU^uF+y-crTH)VSG4e+1nWk$8z z46hh53x0*-s0V>Fzu?bdU1esgvqEYpTRoBzz^tt< z^IKckcc0$F-m(EMv)IG&SV+ksBX9JAQkT!ip*j6Gb%W+cYK1>M7hu`Pcu)egjwlAP zDx0{GZLM^~3JQ&tMUlqXVHDzx@eQ|R!qgO=QU>M2B4f}gGg)BUmf@2qC^krp(VfI| zvI#7%3IVrz6t}uOjp{CXg~)siW~Ns=f8P`8!C4^MPSAdwrbrGZ-wBKSO$Y8Fs6>X@ z&XH`Q<|NU_eEO91-xe$b6mEU=wL`dLJv(`?vRD_`Rn}dkl{0@-ougA&l%X6-D&613 zQL|JxYxB%-tAl>-7;OLU%}s@j0ERhc(Uf5Kq~Kx0&OGz%)xYEWn#VKcx=VFp9ePYC zrLgcf4RV8L{l^c$cKdd$gIPAH_M(nm`|v!gDG#5}du_hXY1zcd$=5Q{8utFvuqK=OV@MITxF6e zo>K!rhbV93BP;#|5Rgh$6C@cig^Ib*8k^T{B+ya_k>Wb!>dVdfIHL6`>LHWyah(i{ zVxPaD$n@44x;qFrNKB8;)k(h+3{AF&%pKklK5de-+6a)W81M{uP*lc(bq+aW;2rex z){UMHfBwK@rhMZf+GW#WAaa?Snir2h-fV(TMY=sh7Zy*x_0DoOZjXE1SZ=?LTg-j1 zlc0HNV86c^xxMjfo`K&P^~}s$Yif*Nn(xTA-LTfoskmBuJvZkXAA;`ccPjkqd?NGq zmD7UECc4`Ccm!*Mp{fMid~M$i1)30?yAJH!8e;3d4^kLyOkmiotyUdFhx4`Ycx9}o} z#t}0GgGw_gEN%O~zMQ>IzamjCH5R|_A9=vpY`&1b9bIS@v=Od8MIEaTTAg3|`OR~a zZD)AgEGm(gcn%eMof$1XXlsHi6ztUJ__;#49)%%Op7m^O&tBw?0qCUC0YWY%;8UkE z4hIh$CjVCDd+FcQ(>Ji05VMgA4|4Twl-VHJp(}=FqjIz|7w|nIIw)MIRv$0Tu?xPL+ zl}uwijLznuj*ya*cKYd;)%BNc>hR47+l>uz&bX>ugMA3^%36$To31rf%K}&*k5|1U zCUNwo^9SNbpW<=hR6YtrN|}tQlu~`dZJp?vgdKqxPx+y__Trq5;f{7dzq<$Of=CUG zF-krB>@liQ=P4f2mcaNs;^-nSA_FD|zNP}lADhdOxbn|3*Z`bCBz0zt5Q}3!amKD`tyQx9pWM-C6uvl0dAZ z>HNqirb%B_1@AZ)!;Dn6a?u>MvvbW8o$%Vm5)k|7zu6S5W-1q9iP^~@gdEU*OHboZ z-aX9KKI0M9rqwlg6jQ&J^5*qJeo2)nE%-G*OD*1)_NZ4kX z!td8bQvmL>@8coHwEqfEJ^Aze0>ydQ+g#8!PBsA(P~nio+_`fN(HR&?mYOW{v?`R; zXY%9ILuzTE7zVrii+P%`VI7}itwT>~pBEGsgdP=G8JnV@ulaUD^5WBl$)tAASLcg&Y6fXQ?Trzbf6K8P@Te0mu>Ek_*N{_F9gDewov(i+`o3qs7q;vrZ8WR^gWDgiAH<~Yb+)3NArJV; zO&oK#P@)|P>6RmP4c{Mngw-f())2OExYXOKG9ba0vucu7^vb9wEr1B!$I+uTO!tuDUExz;laPO5Gw_$|6QgTTMK7Rr~ZI$J27 z)xw*vBv916m*fKD+E;_hKPe0yH1{oZaPU(g&1zMCQ@4&LDalcoZZj4vn-6t(2~!^c z+jR)m4dNYMqYA-1*F+A5u660c6gt$!;^fKrFYUXw=+})8B9u>~;%^5+Ou>%1Y8ez%FKEC|m~W5B>? zT2Sxi9L~Y{7Wm#sU^hampAnJlc&wS0pW`2-uDESR4S3O@qsQreUSd>{ug!Ik;nOoE z5loQ@Csx-WKw#D0v?5gO?j@(UR#@rAjh}&na{>8%6p!Xr0(j{KwL@}rz2!EW^F1_d z<29byOYZRrAERRVXtC<`*;kyt#wY63*n0vqtUUwM zIofW+IEka$=KsuQOHe-l^pZcG#Bux5zl94~2Ij`eW z@`oE#r+_#)BLvOKRP6QC(`I@Gio8q4f)|gKNTT0@`L8=eNg*6n!q>zuGS5EKaGu3D z1P9ptcaq6@oLkUazOcr{%z8%OSKdG3HgG%hNGboAo$WVRvDvvS32^gd;(D%OZHPDZbkU-xwld#HFW(9Wmv?GXH@7 zV3h;SF}*WEib)K%Cn@arbYc{5vB?L{6`0I%^&@?_C|%YJ`$=N-;(QWf8NQO`cnUGf zl$NPcrb4*O-zGH8#5e2y<3DF+)G;FD=9A7$yi=W=n-U)frJG2*64u zXyQzROJGCA&AsH)>%`Yl?}Pc!Vc+ybj=3}m8h(rSBDn(YNehUnAI)A2$jN>xm#B7j z`~`s$5?d)MKQfuJ*{PTFUNAWsEv~maCmQdrKu^7C@?N2DZp{?X7&~F9k#X>*I3_-f ze*%-8)`<%}j<(iAu5!4w?5|e3i>E7{fbN`RQ${9Glf!gd(pWr?)Fuwzc6KwAK@~zK z?Y=v8<&jS9PLX@37O}5np1)83M?V2@dL9I*u9*QJlVJMco%f(}`adj&Cc_v#8ke78 z9RKy!o)?{b8q_@$JAUnmwKr7WN?C&-PQdUzxOZK_g_&dH`nfAJEI3y)Z+3!IqoBNZ zSTp`|U{QY3uws5#%10EbyT0P2)|gE=>GH#Zp36Bq-&s30X-^$oG485C<~Tsy%%6N? zymw}}X4C6&*VC`LYrmIQ zlBGMPamZC-6(!QIlgO@DQt^uHUyNVdI!)K&0q6i-R+UNoi;(CPZN8L;$iYeggK#wR zH9Jz-nw5x^F!z$_zr|Tc7Ac9_efQCN>3iy;#omjx<@s}{n?QNf;?gt=wXN>&)}Flf za{B~SgAN1xc&NA;;+0=DCe>@x*{KovPb=Y9h|%CL><^*X}llKiBb z9j_(rC@(IOTU%?mZMQ9>IAT8HDxgx~>^RPKTcu2>T^L)lN7W zaWsl_Qi<0e5;46*&(&^dzDBx}wo>Kb$zxpk;NJ*u$<|QJ;oqBd>&Xw>QtaCaOki?Q zkvd{ib>`;5%?i!s zQS+`uNA#Uq#n}`O2rsUb!u*cPak^a0C6~+=$)rU;)6WpPE`+In_kjj*JuxefDY2cA zq`#98**tf)fGvA~30d!qlrL45YHs)}$|q*KfWjgfGZ?9r5zJMeOqGSy(Xvd}jhV@_ zZNUy(appt>Chv@qUD)|1@W)8SCG z))(w~!W8myM8`mkBjpO)aWtfNiS;p3vc`g}kGt-rKD!S0LWjeUf7=w85Vq_}{1teqK#R1bWPwnz=H*$;$v)kDWtuqAY zi*1|N#o|MS_fl?(EF7isz{w51xKLnW|-6-XX}`vPsQbarttyS2rHD2-#j zjcBy;T$f_$7rz6ZesJX3GM<3f(6ifKw^x<)`+<8``6wEI&(vX6M-#SU7&l2`W6PehTc9xLC5@LF!ZDIZY_J^s_f-?}&^?CyP+k00sd zW$m(#u?mG&!|-qUlG_l(?fQ8J+fSP@7UY!P0w`(l9P|WrRy6OLo)i7<83wJTpl?T2 zg$*mtR*Hq^ErnHSBfuxf;`*C7BuuEi3g4HJcDk^eVN?iUsG`ogdEz1k-S5c0KD}pI zH^1Ax_R0D0v%~}%oxY!Br$++dtHsS!Ap)^}GyOnx!9s7j-VIUZn}-u+C_B>1EF~$N zmk_r_H}tM)!3e{<;zXM$+g){|l;dREKo0iTGE~-mn8{B(x)XME4&hVNye7Gr5&P`= zV{GR>UVl?#2x6u2$C;Gpn`A3CaXr-|Y^G1LA}1A@2Op+H!)m>cBi$1IF`?uuUbz2c zy@9jv(4s%ynTw&Nzl5f#F${U0w-AXV4JiqPbf&59nGy(yy3frJ7VR)F_QsdL>ORy~ zytDTG33bLh6Dw;1!HEy~=~;>iZ&^sZNItpNz+2(;vw8ze7gx$;;pN zSg4uIjaByjX3UF)I+BNmKw^z)^M_{Syp^xvEqi9?jry>#qnXayZhQ;l*~0;hvjL#O z%k8EpiSTW+iO;B<l087t9I<){_PP&0V3|;{wd2^{y~fQPd&skqoDfgrDceY zVhq_EDQh)|FZapCkRmM+lH^@=$tivmYP-54P8o4eskyWV%UTN{8j{Kg4p%uKVHLo}NuU&Ud zCr3Ht;4BDYn=5IIUCv4t)b`D1Sn9-Y%{cp^yg}|- z@Oe@SKIl$sywxZC*Fnv;&>7>>8nkwgdn*Dn|t z`nN0=U@^^K663cOfk-F>g&+7a@nCUa+o9ZFBCzneiWl*Ydnz%(8`{07p*oAL{mP`E~FP6@-vN_+v zR#zjYD*d&FGRi3bj?&OKyQ5^gn}Z9^{^qC)%q61Nvi8snDd*{|Fy@xe4?a-!Sc% zuc)*v*wir%!F^AXe`2(KORT?CFobb@G+lLqKypogMNcv_sAPM>k02ji+L|H`qD!ef zs5TXhE0*ZmYCK&Ptt>TVzZweIMV_8fNikH=NP{`JPtc!UvTsh`?tkZQLa2;jn~BZ+ zogy179PDo$r5FE52eKvCV{f+Qt-b}ypXhTSc|sU7xZm(%bd~SJrNVc z_EDXYi1}gQ-}ca$L$?q~*uxyVtePU%g{AZH&T_NEtyqEDwh5mCwvkc3YLrRjYZ~xx z3N$&O_%TRz=Vx{mJ>1Fm6F<|LXx`A5MyDr+^9!`=TsJi9+jYa!Y2gsx%{C|I%`E2( z3mj@-MSPj+p88=>;U3W0HP@0;Q^&~l0fmP35Oo=kxVGRlHOa(AKD4s&_X=?}V%u&h ztsE1_L@~&p2A+eowP&<6#yt~*A;{Ehl+#uY7JRs$>^HaJszXG7G#fW&_U|Oxo(0;k z{j0#E?AAZsDP;^rf(>fElyiKEKe0X*30fa2eO;I@6Q~iiVVGMt#Bki{ZnWzIEH)c% z!#LzuoGE20<+_f!%N#puQm7TH_tq0xbuJ{&QnZY){0DbJM02Ay5GlJaATb}Wc&jo+ zn2}+@LbRJ9ov95U5J_1N-z&nznYoJ=ImQ?uUE!30b%NfO-4SpYUBKzU=e3}*Z=x@g zuc`LsUJiXPCtWXHreF{%M$1k|}zD29q{jQC+TSM5~C8lvS%P2#!aGXh8D@OB* ziW4hAq0!$GzhT+))+we+cJ9w1_BmL!d^)IHlYAn!s~9W}hrt!!rceB=r8#mneJ<#v zV0&vujM<*I_V^=uxwrS!2UZzv!ebBnP_oqzTU1I7$4mUiCq5+^vdq&uC#FOG?Ccm` zXg}H2c0MNa5mUn?p1VpG=lsWq^4Pv2+(Ce`e`N<@VE?OnmM2slaU>)u3^19wa^j)ycQAv=0&@%|ywRMK}G zdL;_VSVW3}D4QwcgCgV?uUq|Yub8-?&?(_3*cq7EUoU@IA-0LnMZQ;_lSDJj)~t;+ zBmTp*8Le{bjzL!9d*9^<#iZ3pqDNVIh%Qkf?P2Ecl_&W2NUL_{KQITb@+s(d*_3k} zEw~6;4`Tu7H?-Mrn1@WGV&@!*#ugI*p0(-Rj4sRTUmT`!9Xty7p0N1qnij8;n?gy6 z#tY}rzaYNg@xlLeGa-k#t?)I`L7&Mt>g6m3HXgAXWy(dC6`~M9$ab=Fu@!LI)Jt;c zu-znd-#lJE^C`)uE>zBC@yoSpA(qWE&~zJRVz;b%AH7gD@o}+?cBN<20@NuJ`Uqj| z(Sb&K5uUvZsL4@p%4c=O~< zC+ORA%fS}y7LJK1eOBN0{5-BS$Ga^sET7b_vU0eR~t2$*I+-ixqODe2e<&!n0|P= zO2~&4l;RXt*oofnh8492NoVl)RC;_7&4C|TnEcGwlXaU>A?K1Q9q;h_PF2_#+XV}& z0T%AksDuu&itF>YvJnE>SkRpWz(ET@VPCCOX8gJZ5B2h{4T~9xVgCnY+kHXdf*WeyFZs6-_zm`J zd#prSGn5F_ydF~mpi)BjTH?$5QQ8tOgfu((KAH!ft^(O#7={k(8yP`x)lf)TblQ5}n&%mw#Y(?j z#~9U+;aG75i3&DyN61#rOJJlWdmK+3e}G(^8Qg{)IoqaC+R`T8+JFrYtvHvAQj%s zoKOn#=8_yVBtYO@a1F7l?BuWs-N6rZ@efTa=W&|h0#bfsM}z9!tgjE8?P%} zb%PFl=$%AMc9D*4!gbojXIihIzL;toJZuL0$}M>x_enj43$2_E10_+A-cW^;`a;PO zqp3pFZkejX_?QW@e)xw}u!i@;Kp~6OM(gBj z(WA5aI&v|!J>K`-;#MJNgietqH#l0u>{8?=6NS(cSu!%y~8df=}hnSzbwD6bpba z^1j#{Nyi?^LTI|MMKtv^{^>SRnoYdaGJ?14T;oiT{q+s}h7VA6NO0DH$##5e`6S5p zhO0JFd?!?@RMY3kbq_g)@9UI1e zfHi^axw6xxiN6GI%1H;5&)Adfl@P5c_3yld6~zXbmic6yaL4ZW8ytX@A7`_0@s$B%lW-CJ`$ z!@ijq*(7PW60Ow1_i+~7EI;?RZQrrg+Y-vt>Q!yzuZ(rdQ00Q(E^OE8SCeE0roFox zKJT34(HhY$$>D2f4^Vf)L_Xz<{K{(z{H>q{xW{)anaS_OyKnkz`ZT{0Qn#^VG1P{^ z+ga0l|4YA(Mt0W$7!YAhK#pD!X$6j@M&z3doe5TkyZj$dz5*X`*?Gn&7~3(RHu`p( zOyWfQ_TCtZhfRa3ee8&ERaJu(X z#};+Iz-O)?_NJat(Ia`3Gp!=^n9I?0{n%x^i@9UH#f<=LE?p`7N6b5i`u~-td`g!c zm`Y{+`~6gb79g;3<`)D42S0+E zqSV0X=QMy-5T&jSP4$$4{MnG zo)+1<_GuZ;FKus4boI(!_$&3?%ih?&H4VLPJa~68gafEWTGR{73GCiFSmo~#L%h9M zSH-xe`I+|!f0@iND`(PZ&!UF<+p0gB5|7ig&G1dkw*W~ccj4%oX}4?;d9yvd&@Cfz zIbQIC&pR@Bb8o|st>Ea2AVLYIj&bN0HTXpLKd$4g(_;cVZwtt4lA?}x&Q7&#jV=5h za_VhkYzs~lU;@KuxWA^F1gFS>e%Jnt!we(+!2pe$5->UI&8zRkz!K3K7Cyp|m(}?g z^D8^NVfqAlM?-?bovOuWH(|^F_~RS=_z2WP1%7&!_EMJ*@A_L(eKJ(}J)$(N-i3UE zo+BrhitcfN5S9q&v?ZkEG>NCu>Qe8(O1_fz*^d!jO6R~?auTn)RYx$ zbQD?1Nz<95C@^;%nSJQ$6Eifj;FOlF(=XL}naBf6S#|yk0VWHHf~IXEaAor@6MhiE zoBI95xR}dv+(DINIl4IpOPp4<s$D7OoN zUijSwe^N?OyqPN7doImp9PZLPQI$gZAF~-pc|I?aJMeulEGPhNP#QSjkh3XHad1<| zg{p-76SZg&y?1@e2i6%jVwhbDqmICGjA?g?56kjc$7ei&PtVAirf+Cj=7*XUZn@TK zeZHmR*#GdwfG7nL!1QS{0!G||j&EyJsTdPc-ee+Rfe7}3W!D-s%&Kp@Qt(V++&cu0 z32_>gLf>H2R5;7~&@s1O+lP3!Li%{3AY^W;v#9XW)m1Bk!ScM3mxzJDm1Q94t~y}9 z7zS_?2FuwZmz}%8 zL`-=L{5E&SgbpJx5f#$?wS#GxJ!TGz zVxuNwP;#N#tdkY!OwLpPUy5hHNMWKF+dKQ0VM!_J`s2P1UNEkiS6_O8oV6SU5o$ai z*!4#bS5?5p=Z#vV_lz${qg1o4w8=YQ%#o(g* z)Mu)OK4|j9+wYp?F;eg`Ncbu3$$8~oLv3YwxpqyP+t%D1ktXM+KUEd_Spe*f*&>m! zqJJtDyf`+Vi)Rs&R6)^lUWivhU|UtRyj%6@ur2Ia^T|JRv0 z-Y?{TXjpq7&?p*3_%HC@^7cv6g~NTD3TZ!Nh(dAw6G-#K=Y&ywbs)fO8h1!LQVl!u zaG5%)J6$WNkrXW!rT3VJy^teeCPmEVtT#f85?#&7uKk_3b8H^c^7=CCwmj->EoB7q{UP ziy|dBZ-9u;QZyxdaS(0m-Dkh6j;z~7(@UF52I5}AJv{ZrIF>lF2)>kRo|+}*JhysX zDT7glxBv0Zac>#3mYuRA&yL##c$xoMYMuo97jcevZRw+iq$zz8sawY*jxJ3@XaDdZ zFiLcGlaM2!H|(cIr8BTxW%O}D#XY&>Q}H(rR-+yZJ`>pa`t*-L|t3Nwog=it01@9+!<=+tJx_d1brXL}Q#wMPoqgF;t#58<5Jz|`#hEV7(|(-|HR42 z68o$3Zi#xOa<#UH8~ezqy!&|rA}5#-^__#JZFa534fg<$$<<-ZBWKQsIkQUoNYsJ5 zZQRFXq`s7FZak?iFK`2K4fC=p`XDvv?w}683w;y2w%;+qIFPyM`Dmp8rZn7KZyRL+ zzv6z)JRKq3^X7gjvm%^`05XR5{H{p4{n*c-l?p``eJJ$Y50p}M?2rEIZHrIiplNQO zM}2>&eeB6+TxN^@reUa#73!n=^|u>xSIiHB`*jMDgn?2ZR={l(NTVrx<1!QB3QBup zl5u6D`(RKebBu?4gcdiL_jpnJ#a!esa$C$rK=`&5ymWz)`T8=E-e;gKCKv$dU&7pj z5)|%x`8C-(UAxukZ*!LgTr*Rqy`DBw<}Erc4>P+dB@GqeOM?tLn%Pz z`t%X^DCm54PcFmNq@>HJ02&|{-$15DXMylb4)HG9w8sy2v>#T`kUd%c1?TjzU3X9P zqrWWPa>FK96L_Z2Dc-7NV!E^$15;b6~m-}yl2RP{pIf|W_xGeaI1B+m4nF*bz^0Rbf z|19d4k{1jMtrp_{eRR+b5eL ztL83-F2B$Bnzq;u$^t&n3c~pcoPIjZXFgb`_F+1d&yZ$7-?VUG42h4{*q;r(>crdd zxWXoWQWFNc>l@-<7W|V>dLZD$SEA<#%Z<1qa7DLM%u~_Ij9)|7RDV!xd#;Q_;gUlH zfwz}ZruX>n3)9mSpK`MrVIej|i;Y3jTV0~HOnAMHi!0b{G04;0yw8e%5k9bHs&&M% zHn{kthScaF7CX##=Wpnla3=au7VhVSmhZf*v#6YigI)!A2YQZ9^xL@eH^MOiQ?LNLXm0lqUG%+3TS(<|EhyZbvCAjNWi?p3Sgw->P(QMe z&s4L=CEc2`M@a(t4Ex1P<%sKui;Rl8yEI}=Xp8gUn|E^T2RHZ{*l(NUM;+TPRXoYb ztn|XaabjvERwOjz)Ekz$``%SyGrbE0OSEBZ7{np_ab}i}T})B=Spj-}i|TYP>`XdO zCfwG0t-B%n6GRsGm~mESa-S|Odvc9b-L-+W#Ki$<(&VC@bt-u4ygP<5L}1*S=_NM8 z=xaH$&oe_2-Y&0I1Q50xzl+pZTZm!O6K)U}CS5%xlMvQ&ag`hi?bqOJHMiO3!bk{%=q-LUt1Z`p<3&jc-p!w{ zz6a}-JGH=WzA5c4n-qZN*`wzSEr5l{(3l1=dKG$E%&Xu`QD+FVj?<)L`}s46Tw&`Z zGg8A}%UM8w@YENY%hEHk?x$pxq3+VC`pX8l4>Vm%FPyg=E1lytT_E!_NG*!G@IVSk z{n@<;dLj&2IOIoJx%XG^z2{C?8mBOPPX}kRx)t4jp)jtNKiOu)W^tOuSCT5tmw&Dd zo15mo2a3l%(_qKme27ne;tI;d4Sd#-Y*)b?Lu^HWkFucYOSf~MA$ zH9Fe2R70Jbee_u}&#K6QpOCJF#!v!>dd5>{jE+z$SUV-sB+isxhcOus1SY2v%S0@P zxF`@@z%HtaOyG(^Ept^70~}2B92$kxH=TO<9)wjAASZH?GXv1fphwj?hTRYEHZB&` zvhf7fI#UXrNOv+as4qAzJ|11fcWy^UD>|9pz4zkO8BMp(fdjGx+IylauOkh05S%aX zgkQl*gzKXbAedZec|Vh_QWO42;*%jdLMm|hV?w0q9rpNk_O}tHSj2|90yQ`rpi2nF|3q%W0HJp08tg%Tp7u z8xiA>(Bn?KVB(wXHXk=jLXQ2i#sO)qqRA$M2o=H`wh}&3P0#uoKxzk2M06VK8wC{HHqj%Jem zuZn5>LcyPGE$PU+5>y1nj>VGTv-rY0B;j4>RJbgM20Oc9))6v}bkxiQQ;mK-&zeCC_!jc#TdvPPsZ0g9 zR?7L-z>5SE13+;^C>m>q{gsZmn`sb9UKeI2W;#u)=RX;v%2we21#_H@N}%exC6yUp z9=$g^?iwn5r!otgo_XEeaUbTW7QQd8zGtVef7E5n%RGivHK~=r=X>SrFzqQ3S7D)q zlE!?y2~8*uo80r_Yx<<~yK07tgmk)da3+;FaTacTMy+x`b)GQiF%rW6uEt!%Wxdjn!Xu>O}zm&=)um zpE%Z+Lb3q&^T)t{=9|g?i(-inTUhW|KYKt>PdM+SYx7-1#dsQ5o#l^C~C@~q3k z$gM=8a#9ubauK}xJ76yRY!U*6n9>oGd=~{6gq}{|M4VT)_E$QKJ;@&r2f*BpCJtK+ zBJ=^M#F$Z6?uDcZ*K9IU;kBKoe!m=l^W&8I!I|`_{}cER4vV-{QLW<0V*EtcplY-S zp@UPQ^6{7E;fTge+n)-f-!K`Xq&WuQ_p1i*OjGS70M6 zd%7Y&Ln9+h2i1*3^IzJ9>OGAOW~|8n0wnL3f8}NTs@T6jvv;JzbkmJ#tY!{|$-96S zQ;N$2sG3D?e8Zv56)Iy#TG0Fp?SS3`ettBe zVi0a8pLph|H3?#pajlAGT*i`bttC@$$88M*XTT@K=d0n{ldy{gn!pT07_GOYef z>7E-~_LIp5T|tTO^CLY7oe?^&fe5N?w4L3VjXW%3mgKZ{wCa{j^ybQOCE_5Ari?4R z<@)Zrs#!!MQYyXjzBSO)CItUa*5r-vd;9vkANu%_HfY>|K}|8%BY&VoEV6+Aqv1-Su*xd*APT;>>@av-euR zwJTuS_vG260sRrSJj_gKK2!9r?u*ITnzjYi4;7zHXdgaw9=4mla*D|?Wy~2ZvMb!z z>({dttIYOt!8^a{Ce3k2tBvhN!A*D|9})K+cR<4lr>@Z!*Xpuk=~IJ9^8 z|11D{paxC7j#f`8fzYlBf6RkDyIMt~mT2d{ZeK1Opiw_GRRk0Bk2e(%B9F6amPa}K zbH2YaxRRgw!ua(;5P~veAG;}bWjn`Oykx;%`Hq^LKJVSfOw4P4`zp8?SNv259Xgo# zS7~e*ejUE1iANEed7;unW!X6RA@=gIElj`d8L-w!^!Vtxzn9cY!k5=hT+E3l<%j`? zN5XvZRAuT>i^R!Kq-r{_-=36FBAfIhMvE+kV*Sm?N1%T1&&XPf9w439NIwddYwt+t zVVP4pU%nI-qW^w5KSkhJfG%*pS+2P`V53NM&D>Y&^`a|HDy5~5=FID0cKu}bar5~J zl~2e^XM(x=BT}htLjY6amANGON#^a@yYcl&4zrmJ=CoMab7eI6WB(l1J*LE^uG`w) zQF$})Z;I=f9nX3Hyu*${tdVneWyPO3Hk@r`>YqO?{ht#<#~pKaOXuK`9~Cit9RvaZ z@@o|a6E@bFgzrz5-@lpYp7=LkgPl*8dGEX)14u1fWPB?zrtAKm%EKR3{4nA(Cc#CT zj|2#-i%vkvmWn-g>2_^xbPsw3ysvh0_m-6fnF+SDoAT~w=%B*>;*qk`4a3e-i6H$p2KOg?X(UX~r^ySf3+h>=gf2dz{U``a0`{`)V#XTKK=A4FX~U)~me-W83)U z^gV5fn+U6+{eafbc5b528@a{>UV!?qAz4=96Gnz|gi=1pM z&8-1svws%`wGmM>b4NK+l{mQ&a_V|e`D+H>k@^cAJ-05~I?0HR7QzYUf#D{YD^V~J zF%@iiEZAzdhuSs5TCXavUU#NW3&TILny3E1bHz;%;?QdAtZg!SdS0PVNZ3>CW%ukP znE|P4XD+$0zdM-X-fal(He;Co97Xu2mSV1)nC_yv>38;LBm@^qNd|@iuSn&rM9-1T z86@PN0MP_(HzV11FvygD1Z^3eJYy()I^*nLE4=UB?q41R!OX@Tx3esGb_^Xn)VMLZ zpRg1nl}Z8Ycju8Gx4x#8u#^7Y-YZXC}(Z zt6Ec86*cVhV^__}-7hxtn6Xv+mnu(tt65smw>!Q2+7Cid8g;MaP(r9N`xW`3`q6P@ zqL=!;eB!5fWT#64f9`Rx3{4t6Oyc<*JYJXERF7mcx1hqn^-K(fW0R;q?)X?RsYfk6 z>;sDB&Q(OXeBz^0KfW_RO=r*rLX$t_OS0XNr)?sQaLYhos=|%uw;FoG`JZtT`7`76 zXM+A;toaOL3`iHCg0a;hlUXn-=<Xl(4-dZ&*O&kCZGxzju@}jMCIAtp z*LFqF%q8%9Ve*z+(z(#!&!P&u(hsYTJnzGEDOAd6KXsL{SAY<&&n?|ol%k%%o{~ji zDiXpTB!z90>uh(4sOBilGZx&_&V2wZUGtKh3mqEsgnQh3KmIB(@ZE5eSi!L3G@NP) zK81x4NSlqT*1yYL*g%VsXgAj=q~>O?Qlg3=jN;dG&6jEV4?akyJCk z%`E>BssNoQK_4EXgK_yF;C!w=T1aMA*ci6o`l0x4@1%g90iW>Rv{tLtzmuF45|)U2hCdw~9vjsPh^aGE|&{+NBGxs;k zDqXYbp7HW%_=8JIpQe|^N|B6JZ_}bdJs8gs3}BBEZ4>Tc18aLIPph4@v=<9`K13bHqE&WOCi*3Y4)vucdJC1b# zxJ2UgT{r+F1ky|S!bCZOuca6WE-5KAhqJ`l1{CT(pSzOonTXZ%#3m87YgM9RfS>lw=SL{sOwy8e*yM5jgl?#2SP z;?5=A+13_>1$g$VxOe%`R59AbY-6onsnT@fQiCRMvoy!p2sB1}+t)kp86zt|lP0%K z`U>w5fH}hdN(BNQz8n4Th!*mg05H z=REW{ZwY}komfxc`li?zwxE>fRAD}XLUrSX$?zjwLzz@OQo^H{72(BE?~=x|Nm_SU zOWaTGIKYN-^@l>DO&MCrDfov-OY+MRQP*$DLq$JYXIXw0w?fv(CA`h8cpBn}QvdaE zvm=`Rjgo#GY%b{Zi8T=GSokg~_z87KD%&Wx`HqfzsN5GKlz+Wl|87L1E9y9QlBhVP zm=Y@C)FvXH#Hk_Q@PL%t_1jiaaOc{H;MMh9yDFD)?o{$XTr{Jvoamru=!9|SR}%s7 zZI-#dTU<%%>iWT)g^$KE!U^0k78PW`RM4Taa|~#H#*LcDU{M{~CYHgU)4ju>Rywjp z_Wk-0D#oFQv+N6AA5xMGOdLJ)RBY&R42eBVWlz_pwz-g5x74erqPBP1GWuQp%jR$D zMiR*8-?^0=QhJl3r{Gs|knkVk;qMn@=E2Ihi;rDn#bj1IKK9hCvxh1wA$U#51r$cN>Q!ApQMpu3s|~J;mRsoHceoznPbkb zhfi@Zgf}ie_pDr+oH3YpgG-m%geQVI`%Sf^-R!0s7PV&AZt0hG%QMghtn2Vnm4GGR zMxZ0I-9U^orb~p3b;r8xs1qK?@>&a}H@Ik&54G5;y_{NLM<4pE+$+^z^9LHrO~A)b zqrLX+ypr3G=}T^&SexcOx>~4jXSv#7qG#z@qL1jFTjJl3gPTUn1+@)P=^*$fS*rQw zW5-pP^}vI2*qk=V_u)*$1M`TgEsspdX4I+PMu4b(=7Y21lb+Rd{Pzj-s;LYLXtfGA zo7(qWe#!e%!)>LWZ%5KiM&v@q-&2b}>i8|VP zYvbH;BNOygxQVf7ljU7vRg~0S?62uA*TNXa$MG`*Ds`&2M#fvEzSMSV6Io z3qu~IxU(`lW2*&+?@OK&H zcR{p|ms?1hkM_}>%{#D2t{I7(ygsaC$&$lMsdDrn;Dtg&Vk-O~usMaHrZQ|^u^|F)qFSlYQX&Gn%DS!(OIZxN)( z+i?nq1-__w*x`0#|MZ{8_vdZ1!v-C(nAJ$bJsymTrp0Kf>^tAcqR$SVg zfrsB8N{F6b=7Uv<8%|zqZn(s1tf5bbekx)zkB3bdm8)joPHlBZ;l=g5K6R+gI4#tM zYjO#SIOkGuxgl8IuG%&}y~Bn}Ns23x=~&5IGN{YOL|(g!cdO!~i`9>16(xQxaupYn zx>q`#W(}O++O*T6T`l~<YoWR<~^%)V&OVkvD1m*_6Pq_!kNP7KJ*NtqZeV@5@~p47K~6`I{ae5fDYSDg$}-h zmGi%?iwzG*{}02hlAQ);za!oSEk4qqqC&$p^cG|Cqn$v!roETIvy zVN4`iEqexU{ot~;o$&f?+@$w-%~Z=+wv{?2tZJEnDF?>PN8fsA{kr zZLwwk;vGOKF=8h^<)ZPg_vjAO$kfoRMetdMsuX(VC1=A}}wTPl)kLVUmSX7T6uniXQ)l6)TE zXuS&;wy=sZ3DhtpWG8ogz&PqM;MZKJlR(fxhYyD(4A+$>P&Yav0ZHwqa45=^ zpi8ipF8M#@JW^ZfMNN5@SUa;Dp)4@19l=$CmmHxIK zn-wLaeMOG!bwf5CCHaz4g8$Ntr8G+sivyVT0|xW{+IQV|pzp`)gAn9YhS761n}h4! z>kq9)n6n??H>8>#G*=J9Jjj)ES`a>xD(Q7eoMD3naI79}>EvB=!N05wt55qZBx zl{jTp79|WcWN@|~&NiPMG745~B~0dIrssD-AfL`~ zK!OvFxm_c)%wvb++m7nCIiYGVdW+IU<;-nGPw`}kNu^%L6O}x)lsvNBDI=!6X|cnc z5P%|bm<(dc-Fx68rjk1?#3tnS3K-z5Is1C>X!^VO*QrA5gZ*Z~kcAUFcGO;K<(1WD|!aVDcP2IP15E=jds<(5%L9T=(DpNN7U9B!$$wl$jJlryA%|#FR){ z_JiD99<0F(`t}v-Xtu-VugB!Z{vz97XjVw~#l|#5u0gEcT2`A8^}j@tm+e!Z%H1|I zD+c#${~f*>fiV>o)1*i4nsEDL|%f zA2>u}y5{-2dvAh>8#-%XziJ9pJdZ^p^6O5oZYKEAgi|bA{rTbTu-53jU`PR!x2d=6 zP1U$0XoRbQk&o~4MFf!P7DfK3k(+^&Z4FfK7t>l17muS$ej@)0kAYBBE3!^k?LKSc zvQeG4RK5{kIh^}8ZG-_H@P^xnJUqXxc8EF^25|_9z-^vpR}NjAjK|}8kX;U`cMZqT z@dZomdvI|bq`8X_#T0t49wB+7*5JcKgWt2Hp_~s%m>CVvFxNaj({O0<)uwZ%sn7UW zR<<>P(XT2TqVw-QsCZ0uyP9>Fdo7f&sFg7217#;uS58dcNsmvbA>|eE5Qw?{&^0_^Ud%)z`@zJZEufA12{PE1x@L9b;JJI}bLX+CNBwdQ^+eaK z)_c9XT+?(yc8Pd=sE55E#qWnh^-@7b?V@H0aL6PnaxQ3m*WCM~-;%voNkmKHNZ9b5 zdAvM2AA2*z))A~`&sTg5=F4z2+2&0>NEJ47^W4=RuY|O3?x}9DswRN?vuh^^6P{y0rqaC)Lh9lY9FOC2NjHJv8YhE(lI^+0_g~0}_hi9DhF&jI2z+kHe)PTr#nws~v zvU9QaAkwCSpZ{k<|5y-a;2S$St3B2W{V)shMlOXzpqpt&AiwZ_;|o zM%Rf|M~UnVAESX{Ix`qAPwe#Uhg*0zNJt(2X6IeIiuJ1ye=G zD7>A6UN9ys{dFxdJOAe8Y3}E-pzgQ2i`0U`8EU1LG~K!fk(hU?q_B-^#@41eUodm)BVqgz|t;?>ttW;K5LOyz)`Ji7i{veh}FzS}n1^vUP0t(r?F z$Kds>ZtdG!!zJ*11YLA~Eb@BOevdI6PXbDvP@E}wOv*T+ij?x!2&cUXD%9Bpc!V0^U-1E5;*A|pItj4 z(kIU0FCzCvGpy6Qh1JM$(yY+d=r3iqFYgmWQS)drUJ5@?i>Rnw%$7N6xfysRx+k5U z(|>nJ{pVDhfWY4I9iRY{3(uMTD3y_i2EOsQim-h0N zkpJlPvqnM4vN+k_(7xy64jZY!L@7_gLxIg+UmpqdpxTT>UU4e@7C-N|Pbd}AKA}4b_vF8CLBW|8i9(s~ zy6X$)&|iW4tr%V<#>UbgtHaIeH|IEKq;`yPo8I#xR(kJ;K)=#!!hKAIwVcR(ft^7@ z%{v3adRO=JX121kJc3=DIklKDuA7j-bovN~88riF?cp zyT6dXd`)`KVdHax&A)c4KN^T25)uGnkr())r$EkunU(dCo9q!Q%65Snj4a1f_C%N`O|mrZtNiHRw7MxV(+wb;>ssjdWsNK|p0_x_Tz++{+NfBz(% zeA8}*pK<8_IOKU0Vy|$o^!C3Wsy`q2ffE-cC`i0`qGo&4N&R)|4BzbaWxyu*Jp$Wf z`fJMu%0M#IJG8?;&CBbxbM;RP9E`5@G9ho{>sg4a^Gh9dF_vX+6yPVY*I#xou4ZB5 z2_{1X71bUI5my;{%R;Q)#8YNz0H8j675U5lCXj(! zpP~l)c@6|^072T`?_r-NPgnn;H5d{v=>sx1nOFr8B`m= z2DU~!+P%UCt8t&u>@djAE5cYfkt?c)_<&!r@VMqOuXF@rcJZ{;5G#1`3@GfiAG4RA z&B-tk-R{PhK7{@{itDtlrC}_a7}Ov%j%arkI!$Sm2Q`A!h3)gQ%~eCE2nCF;gYf$8ec0`)h|C+4uDnV(4diTc{}2+S7wOZo4EGdnl$ zT5)=-vrLn)k(i%Fzh0CEGnQ(m@q+R{XE>6cQa#ZoKmU7GH4y{T@P9cNaC@q@>lW3g z*km5aL3kxO{L=m?1=$zbXZ%g9rp?Py!g`{98(L@~0nJvlOKHE47@X5PDUWgvtq6<|EIi>N@`Mr8xTvo*uHY~Gj;p};hbLSoM*eHE&-451jkM>(;x1~rS?`Ba zZ@!x z?``2(ZY#M&tnF&D$QK=Vww6xtG4y#N^<2BYeO*Ub#svO$?t)dY&GuT>CZS)_Gw`Lv z>~E9(g%{tc(#WkUuZSQsn8>eei4xLW+{jh&-bRDfiN{ag!#Fd$k(jx+ z7QptOBo}mUI*F#*Yu7$rpiWvEg$SL;NQ4I`h$4}HdPAF-2!Sjq)el;o;cv256{=s| z;F{57YZ<1Ac+@oH9a*;>ws$`z+`sxGGaiycBRC}oU#?b=0&miZ9}-Z&CBva>fka=g%cNnIgsl@s^?`8C^ivEDB$@Qf>*`ye zsnacZ*NU~tcb`H?Lo`@-tR>HYaB;K5M2X;Ce_U70%b4o?@`gj4ya(Bi~iuI>{{nb0%`GmMA*u7WnRj=G5^WdQ`P9-|ItBjdvupHYpdzs-yTBU zI#Fw1L#Bx|vrH(CIRHSeUlP<;w6r1uBzSi2rtJx^+Rm^|4R8xVtSMC^OaTl4%Q!UvY)9%Ec#y=OX}mu+Ia zO7{ZzlrMKGKVWX^y0{_ny3^jbM{9LGHVg4xt2Hb`*f$;q%E%B(V+oRvX|^|53^6?r zGI)3XMAI!MB!Dg9?R8+#MGG$yf{jUR9N*GkYbq#~hl)+d;$E5D7e*SC)1zj%Akuj| z7Vr5|gUlaC<7-FPuPIQk0iC-X{VR(Pg04TC zhLO9y8mp~Ve;q5POBYODxeH)!Oiz74=jdrG9jAH8;|HYLTu=NBlF3l85Xvw!qNyUm ztO6M(reSiQvF%x6)wp!>T0SpjK)z?WQUvP59(@I=;g|FKfuHjOsU#0`KXYy#Iscx? zXB!U6ZvzI7@YTL*7)chEM&Qy*>Wg^i!<+tFbYrOi}uctXhr?k#~mO4OM6j@pR1uctxYdF%_&70v5XGA^Qz<_=4T| zzAVK-26qE4S0|0(PZ+iSMQEP53>!Qb)wQ9scCx5_HC;F`=(^a}iULc3IkGDMs@kZ# zbnL1h9QC|J7$H#7qmTvVqrD-o|~&113F6AeC$j`TKAm)&Mzwcd~dAE9ddUi3GNA_hrI2T z0K(_3FuL}PlZ)H@$zg_1geV^cnmv8)H5|s?pawzR(T%nzb;jHJ z3$9i)1`JNhSRxhi*tv&p2y{nYTf;Z{$mB^xb(9S`?;cm0){{&#@f7Pz@%B$aAlX z)tY?Nq8F9g zm$%n}#JfNy3P0SzO{ePttAEtLqH53 zFE1lrZijw`4j*2CDiXS7s}TDDTESu313$G3|SEcJd8f{vI-M zBJ>j??#gD;r}LPL3Tz_2jed;hd~`cCxl5HEv-8-lO)=_UpTd%;1ds}|Gj%5D6vL%# zxhMM_fbJtaQDhC9kY8|O(Z$YifdJn6`1MwN+Vw29ZtNA}d1bX7WJ{sduQMG(Z?`O^!)OT)ea2}+OTPPDx*NRL(d*%y0 zvHQ;AzIL+VQIf1%dc1zl)BG>q^UdHULk9NbVPsdhd{VKsti;{1r?CWR6`nrx6Ec6G z2w=lzibTsloC+A(D4)sx^%f2MX1LeoXIlIAHm%EoOC|ClKm>_ie|D4mEfAv z^V?pF-7xZ3?9OBN1P}pOoH80kH(81GUO-|RwE^aRJjbRojB=7ygrPkwUl7jE3jdLF z3RwbQ81wAcUBYA3kH;JHa$Me)dg8aI{$R;sw9W&}1K=^v*P)Nj8HzP2Bi?{PWCe$k ziLo%xCQ3$%Ao36U^}?71rqvWq+YZ~&>i2N4uBpMa8?IqV(B16h%M7RL&qkaWO z*CNUuA(~*HIbEz+<%pu6{zoL%KF<=;X4)TGpU~B5FBPN@*R&l)$ke~ODn(4Llt@gm z96&|~rqnp4&)6hBAHvsSxa=34ca1~s&f|eML(r?vpiJ~WsvX?? z|CVMR2*ja;lAIm?P{%_|JMB@c@De*S#7*6MrF>!O4UICXwl-Gl+iAc5@9$fMbyvBq zS1&C3ssmRtG}H=`JqhqpC};T;9&0pthsUfIaO-#a5Dnt9kJ@s^Y6$!_%9vFNqv9hIB>R-6UC32c6D*f-C{c9Oe9und8xb6dP0E|9sAGEIy3B@^%Z%Wk$=H1 zo+M3kd*~seWXfl-;t_P=wDoeibqA_GWIyn)%E|--^s7hMtm0;=c!J)X)8}85Umm=j zcRTUnYXSpsrj&n#IsO z&K_yNub2RM6+(y29!Eqy7=7R7Y|Q?Xb-{D_8j{dfl)|bpmY|RVUrKmNg_`vOKV%y0 z5O7YgDn2HD%roA&cdPFzy}0HGVtH@W6VDXFXN0MQU1U3jXqXA**WUX}ik!v-ZJ2f( zH;LpB&Mb4(HR*$v?Mx=@(7Y=NIh~h@WY9X`s_tGL!qwF75c&+4rE}W;SqqzSMvQEI z@3A}D`#W-P%}?EL`X~Mb$$b*H%DcB0NJ-jQS-tFXG18%AhuI@V8^u3Zeyf$2&R}>N zB&2~~x&j}ux)5Gan)ld0o)SJ>{?X~kX+<^b^^3*gXTDwK?Q#Hh2JuLv1-P*zB1hsG zL{hLa$Q$s#1YmHX8d!7wwG_ro$^X@Lvbx$TsBMnlCl^?s211%i)MgAsFiaosdx#O4 zopkMn_w6eNpur3Vd&e`Jd5n|$`({WGJjmRB7?R>*Oz1?C^QIEOuk6Af^}$c{p~@V= z_=k{rEAQxU=IY|NtXj4;xV_hJd!4f_%6gTw7TlpP;=+`9F`_@_fF_I?Zx3MGNHC_u zTDbW|c-7jupNW;HpH|6&F3^PZxOCb)piEb#9bJr~(SDs+=n0pRk-*Bro)`;n&!PPu zF66l%KI4lwGhcncU^hCxFrls-8GFuN5g72HdFK=tUN!f6B+uP6@4jnaY`XXOedkeq;dsZJze{C3BO?KzYQ^h<`)JJ z*cV-pmG&q8z~D))XS^yv1Vts5+C}tvl~I9%3lf~fK%LW`+xM{|Ar%^tkKx2?wy2uG zMsxW;CYK!;=f9Pn0-5owc&NM-Fy;Lrc8%GG>M}0r=(4))?={K zDit_*VUBzq;#i@1OJ|9~l~_F{znkMPZ#AYLsk)+eg@t+$PouNImCR0toyc+3P1^B# zQr7+7-PE5$%LO==&@B2oY^>NU|40S`><+u$3)qtP<~jfRaFS+a%by*Bnn*qPV!CqU z(S)5h&OBhP%TpvroNO)rJ*29WhW(uol1T8+^_YCXGDrX2j~k81C|bDh(oEB^Naq5w z@;*BtMK96~DN*vnmWQ3w9eUhq%@_Ld-$ws&tq6#wFF1KsE&RK^7teL|EF%bHkd1~n zapRlTWJ);)^N5Ln@cJ9-+T*$SRDQpiuO2zRf$EnG;}<@7ib9&*i#TV?`i;F0DfYdL z*qn9!@&4Ha511}~GQj|d)sy@ka`i|xcq|cRYh4;u9>W~pExR3#@&OyfEFcbzM~&iu z!T+Eu40swE=O#s^MDpG49w+f|L#M7;1kHrC=Q4s(uH{IC{JN96^#gk#C5R4H$mIJx zj0)ELvLIjez9&TCIW|0YISeQVLhl8n9Y-Ae+}@wybnk)pRW1}?t@$_!?0CR+j_u+#sW(?ru)*_pNO&I}EOtYZQh;M2}sWPiaO)d-!;Q zWG|V9!5-*`sTvNrYs+fhV)r^H-<;*;Xx)|Kg5Im;BGMHO@3}t|pd4i56xaR5f$`$P8jT78#JFE+NG>P)!ew|KJck1&fGjpvwuaE+gN#=xr}5~z zj5#j2oK8Kfm`j$s7Q)SZCZ1h+wn{t$bAX>Y3hi}ha#@$`x@B)SbUy?z*rbe3Ny3`` zrm8A3#VIMY2f|QCz*)@&VFEc^2X)!%@eDWxb&Oh)`iV-TDAhv=;XAzKkg!vrrdP*;nmI?{$$+#64m^cxZlP3gO@RXq+xyF#z$)8RfH%k1X zMT8P!ugkWs<-*)RK!dZ7J*2{O%%dtZJZs%`6bMLmXV{#<5U@t8_*fZmVU|DFA9x;L z#fQnUTN4O}zfMck$d~;yFf+SC=}N`yV4-u%(?Ja;r&7()5-|43ZSsjL-%}l zMkiH*Qs@U2nIHKOQm=2XT}0NDIJnk7+>#ja+x+*JploP$vUVa@rw;RQt>!jDW|DGX zU#Q8Ijp$>cHzF%AG>nJHfwMPw-?J|K5Wxvz@x#3ixYrp)>)oeO8PwP47VH|L7AcFy z=snb${>j3ozM{vX)UUuraN=lv5iMe;DKs7g5krn~4fW`nyVOhL{+#;MB$YoiGDN+*oC;lFAsOZ|~rNn=Lva z*>iBG0vDM(P&WQC`sA&D14RBfBbuI|xO}aMOqqVZAkkaBR}UMXr!{_5>$4`IrN zAl#GY-hSEH?1mAk+2}PV7EaWif*||;il#}Zgvr3HBED*!)!pzjuf{W}JP^A2uIVK2 zC*NLx!uJQOYQ|X-`|AmOS81nmvHp&7sN;-aPIxCzye2jx46MB$Jxwo+3Kz@1aae@iG`CORyDO{a%=A;v%q zJIsJrlHpASt^RHHcTsHUov0w|-71Hv^o^c&P*CVOlmdUZyqA!kk}4G`yo&g3;2=YuCzvf;9QG~^F1i*T4Xkm zjBhnK`~y8oM9BeGZ?PlyUgtZ!P|dH3n}rTvL=^#*fd$ApcL@DT)d=5w{4i^#|l|1*`e{a{Wd(hq&TqAC7&Z@w{kvXX!gjn9j&RnrR(r4FP6?1Ov5aVvU>cD&fx11{Bj0Q3=kQ)? z=|xg$BVDa9Q%l_<^Ztlt^7qxjsrFoa6 zdnuvm;?4g|r|^jD$xb^)>p43U$-pLn|L+8A7_<2^2*O5$gJt|)BAD5+1reV=MWO*n z9fT4nPCE%Kw-5povx2_SA6cTf#f5K;f9O5z;K8KQ^Z(37D_gn*nQQr2ew0M3&BHEN zHW&91|F451n=Qzz_x?mFqVwmR?^R2&Z8$zCYA`s&&Y;}af?t7zYn39im;ch9HIsq~ z7l`SB#X4x)NFxuV-cRQhBr=SrO+Q=^BHw#YY09c6h}*PsCiEA{M*vD`JGf zN?#l5SxuTHGeY>Xnis>c1W%7ypArf&WEq?%;SGA}kYmNY-+#Kg75^SL5@XuwxS5&K z!y7|tbTcTvB0U3rgva#!Bd7gvWBXK&2^-~DK;jJx>;|EGDrtF!AUlP?lo===Fb7R6 z7ke)ztg}DAo@8petTZQzQ8j&9i#w=DZ7|*?dwnh5VL33A`6z9#>A<0${h{dFfMTtb z)1(+D93~f_2W@KG1@Xs-p8U~h_=U&l#GO`@Z`z4M*L+CbMlKPe%h&sA^z*~sVtW8) z%8Z}!?t$y`+F$^gI}|+tkCsBgpjS~vvjm#5@}6Xw0WAQwVAro=n@`0w#I7jUJmbe9 zU<|Xj+hjrFv2E#(eCva>&UNe}wUroXk?7-WOMRVrRU_*$A+_)~-Vt?n2?!87raKnN zmh`OhFLB8IEh+J8u+9@r=8>t*ZN}9f6F`B%)|f!C(vp;}CXoA2V*}~(r!RhkCoPPA zYNCMeJ^t?{Bb3W-n}a6|r|Ban$V5iLSy%x+hG_at{ZcAh9cQWwqvUs!1oEd(0xxyj z(-Yli+n&v)jWk6&h^}ftcUSk3Mg_Y?j!l$W^+m@-@dm^vcl%e@q3H+gtXWQw$ug63 zz&8*(?E0<7p{AwPZa0GWZq1=mhquvLnfG1J;!3iTuNunV@-HK#=Fc8ppubh#oiV2v zE3Dc%8NkfINwr=4A&rBP((fEwtR69kROKH+C=t37^wrO9so(nC}A)b?Nv`-ema;SR1? z@RQBmw=d}NOD|0i{Gi+eTm8Y>9aOgnQ9YlL{E|^q(`p!H){{Q}?H97Y+`YEG%nsk} zjEaD7dTz`-kg)9R(LhGJTW{b9Mh@peb6$fxm|^Ik^{hw-OY+%R=`ql4FtP<6X>mv| zv!h~>N^VcT!aHJmEV`vi@_%Qo2t45#gR20_y`G-_GSb1%OixcIH6Fj^DVAgM8s^t} z#yf_~+#&A~GEwLJ_t(Jy_N^kQAEn=2d)0!)?$c`?e%9lw5HRylEzi7h{K1BDepY^z z2xSHGtjZe5ZLBVDn4C>LC<#&>hAF3Y1isCD$IeItH{TWc;x&y7`93-ZMU+D;Fe9my~1^Q}x&%&F#MsJ`XqTQIpVotx$eesA%) zhe$4Ti^1+;k$^T2CDP%_hg&Ks()-!K*Sjui>=tYC<7Eq=D^3ZN*XvdNPf%KG%o873 z4jRY(DQ7ty`tdgU#>qZiUvnro%-!yZz>*Uwe?Se>oD=Cpmc;y*p3~R!y{X~`9rU+i zG&ZETY*?BeRPN(Viy)iWRVjXVQdFD);DV(u4}7?ut-cP)a`foxI;_t=+IoKCfxI8G zx$fzl8!|_4jr6oMyOBaIs6M(od_){__s%W@_4+8Lw;j)& zH}EB+EW=q}zV*;$tGAYSM%}8C*h4tI;q<4a*C395j4y~1>}P;uIzKl19lX?fs`R2w zQ!RJPF)qoJ1=Ed&lxa*hL6^h@mo-gbMRleHl$P^vAzazJ5%)mK!0|&&UVUuGCSlNH zuV)Qm0O7$Pu}hEz{sw2OPL+@pCfA!EmMjUTR3xCE>g4-PvR5{!5NsAUJQ(sKzJ24w zw0@VA-YMSvR~S7Krs-i*Wll?ZAw2(A)|CfBxqt6>m@H-2O|nLs+a*HTnUPBFU@C1A zqh!1GonaWMaI@4!vQCTTDjAb4%P=DQ8W|Z|mdIcbh8Z({Q}p|mJAb`@%sF#D&w0*s z&ilUeeqJ{&5W>!?Vob!jW4Lp7=-KOqU?7U;^%b%1e*t zKOz2Prmya=3)=Tc3cp-kTR+)iXUw2^UKI+oyJ<0f&MXzJn9CDo z*|n^sS1zL^Sb2t?7h^2onh;7_nhU$nnE5Sy6{woY$-gkEYWd0n0p*tVRFjw;$&S!Q)uYjQJT)1)Vgf0FP)mZitj${ZVVLC5_lmWV;B6k zdSFeKrs$IWOlDY6;C5eqVYxu^Lv5;D>nvCPV;etOP%c+o>H{aR9I+3tcpvuTttzPV!k(IX)xjlSXg zNWh23rGEL3qc1$)MGI*XX2nPllv@uHX5?|6=U}0G_B-4?{wdF*?vJowEHMG?lJfr2 zID#_qisN)Kg1aaq(a(!q!atdjXTtj}A%P%{>ng#7Hbs!djr{Ul*V1-!D<7cKzN?BF zLIp>OMMzZ;CZEGc$er@*dq8A?1b?znQ}n~fI!smV4`(v@%#+-bH3tjb9bYDa4;9A2 zI>`0?lN$;+u;YxWl&IacRxF>UGg z+Ukl%tE2V1ORRCpC*|}&ZH+tHp+1umsqUxY>m^s9FS4)idMo=+&2pAF7h;LSNctkID$7SP>6MPL1OYM)miuOHw$()Ag4w> z!WiTak%BS>255S3HNA5sJ!L7V3`(NaUl%NzwbT6ev*9@rUk*vZLq|-O=u(t`;xhH4 z-_1oH%RO+}LrTlaoh@yC34d=ASX(-R=x)}y3FfInBEokKG%TLHg0xs zFFgVY5z_(oUB=ecL1+$c$G___h&Np#yoR-cL*U-g(8g;%@uJ+CG>|2#GW!cb8)(q{ z1KmjS^SVSD8sqQrJR;y{y7{qcscm zJ081Q?@IxLqg{BV*+W5=O9FN}BO^lDuDfG`zB`i*&x94oH>af;4kJA-7L7?*MM4d;3s1gGes(26|LTSaTL03jqyyid^hi_^C`=V#6y<~)Jo=qu&T70ycIy$%6Cvna0 z&9Z!`OX`r0u8he*#oJ8&ul$jVmuy2Uo9ThYGL8a-7rlE4=|-P;g(%J^et$J_u)b;&ldD@E3-UEW$Fj<_KL`Or2 zqxQ12Og-pC*Gx5$a~BAplt1J?&O^;QC-tEF#BObu@u9mAV_%K|PM zsPN6Ve{S&!mTCzofsY?;#p7hSv7oM1|5}+U1>!DA45%+m-^;M)a?&rg^^F>?X0mcn z#Mku}DEmq50m{Xe=SXKgij~JS>>h*)z!o@9WQt01==XDa;VrjH8Uxl48a>mnjenpU z*b_L__WV4RN=@S&t&0?de(4oU;m7hBbj{X0~DO%tGh z>TExGvqfknje}|;R9IKXaf?G8bfHgeLw>uq=Ep>Uc~D7V*rO*QqxutWTb9S68B}4*U+iyYNf^0G7{{g1Um? z9FJ1~r9f+6z}4uy#1Bp6{e6_y+S9ky2K0E?+M#hC3tfa3KeA|ic4{5W=K!K zw8DEkA)voF3lW}_w+Um?S6u#%{UPGp?SUO0w*rRC{xV7unC=bPgW)gAv>y~+ikGrk zmH;et$wvDlZW6F+s*^`S8tR-mEjgu*ncq9=_QJNp&;~!d^qjrX6}I$j*!og-`-Q36 z6FNzH(l&NsyDL^sBSDWj_;{WOad@@3TTA=-=am)cZ`JP>OSff4KiscE{n}nLxQ;p} z3Xk=5W%wg?(7xP&Zk52PB~e7}Q>DV(miC1I@K7%jI8a1N@kvcA#m95XlAjIdRN#a2 z)(%Mm%#L{u?k>}pvh|fGD`bxK@o#metz3TxA>55u&)8!1CKh$an*Gl}H2K~9gd|Wo z3m$_C05juY_8D-P(Gz?6_V}?)-EXFa3ZVKBFuM5j#SdD0qPm}X@znFeSUGeHw|QOa zv;YRv7Prg1PxBop#tiUyU1qvf)IT{mW-L3Ve^Z)Zq60M=pnqyD6ml8#&*>E$jho=rz;E?#leG02ke+Fs3no- zM$b=+_FTqYVw57)(AF6ni(YiNJE8PM*}8PUvNfDB?%y{_ea*i$x%`wA;uld^y?lKm z{Xyn);pVWwz&G@zNjN!0P{yFxc~c8$+FV<-YmLurOJL>4JMtVK7p1F*9HrjTDW(?O zvK4>Kx0@^rjVPhI4g7~{>4(FePN5?It*NQ;7&x}B#Ur$&)GVJ#Cx)~jd=O#tAG(pC zKwev(u=-G_6G45{QR(x~MEyoLVz%(~$`pGS)Pm|z=77I&H}(jo@Oxh^2U4?(Pp3vmeu3OaN7wM6(#v-+!dGG8(hc1LI60SP4XOrj|6@*zRpF??uD zwP|o(z|7*i8jc5svHjHCz;ya(KlFzH{zzQE3<#`yJ2Q9l4*P1zOB!{g%-3dDljvsD zh89N?c6WcqefiNbN8lD_|M7HCJ=ae2zzi^Z?Rp8fFzI~%pRwZ-4RO7M)HTv^!n~6 zVturz!yYD?;dVOQaR3+JB7%6t_J5kOJ>HRwfb;Rnw{G0if-gN0>Xu2XPlip;Is&ru z48s}1i3#8ck|uv!QXJ-!YR z2r(Cd?eKA2?WNpL10DPPk2t`7wbgz`)MhIl*kOzPXIK%TA~)0IaIrH3NdI!_|IF)0HzZX?cnm}hOR zid9S6-N?GXRo?dmVz_VDwy0g|o0^nuCT6w}`vrGWV(lS7e?{_1{3jX0Ogz2kLW9m2 zHl7|!Id3442M>wz!BV!QGpZW@1B4(x>6(&hN(O7GEF55;$cmJ7FvEbRZB#H;h4#CB_Q=U3{Vgp>MY{ zFf9X6u>@U3FhF=yiSP&>BnkE*R3{$U9B1k=kf0`k(}l)sj!Y(lrkWCiho99^UC;88 z6PllAUsz?#mHFE;Cso4A>EA?y7QYksDn5|!$GJJT9%n2xEL4O}qtT!nZAdB*n39>n zx~%NLMcg}M&7F?&;#iiJtAa(bOjQofx8~Aq|06E5@xXyu_7L)_)?=hv-&w8Xquw|> z_ZUxVGP^`$_sT8X_2Lpb3==g{ZeSMJy5_Wqt6`UHF*f&LxbA1o zV|xQrq|>RFm1lkf?j4lV_sUuD&^?tW7Mznb3QT7JS^C72O;>+4Cf?wA()s$6{o)8_1BZ%?)0?QytouU>uBNK5>5VV}AM(`X~mxG;l%{6*D0O3$lTc{XgEA$f7&X0u^WS$nwC57Qq*K{!(+YR&PC zzrkuF_a+b1$kO+~X4 zAJ@?Qcc&|?=0+r)|p=JVI zfkpqe>&R`gSgaW~ha)4HpFVw>SzRqXnq`MTzYDATB=bvwj3xt=Rv&HNF7;$;>cIc4?kumHxuJY~@x zyun3Of8#YOEJC{^yo?SNu#p5NXxzFKrQT19kNWEk=4ceAzv+(VuVv5CeY*R2zB*^> zFdHta^R%|^!l2%I`%nQZaNr!{6k)%Xl_ShMi5!F3sk88(xf%8(A#tM zOrqB)4e?cYz2AGmQ3LQRY!3ikrM7P0QuyC|q9w+`jOb#0n)10D;(K|_=i{cuTP zRZGo>+Y^}?p`n`AK>=kYU>{d$3DNbIoRjZvcv-eY=e9I$-JSS4Ay4r$h<)ZcURSRSPmRY`vOg6yHDRgRm?>q*)EhI>4xNtSHU09if1(+x z5p+5z0X-v*i->Gu4$FilGjHhWMT+=1S4xF}* zT1bu#Kx?7@omHuMx^Wv$F}^8Y3cU*nHjqt%o1qKt1698u;K>E<;_coY&2Uf9 z>=Wviwpc}5_v9jA+{8Vx!Voj_$Mwt{Qc^;^C}tM~7HXWJvGDf1`7|W~>sIg8<6%dbTwKKBp2oD_*`?3(Ou_Cet5E({qnJ!7X)KZ9+)eUZz7%9tjEwFAyBx3|H@-b%Shs^V{8X@}j z;}|pS2uX(ApzOD#$nnuU)J&FQw+MCjXhw}BE6iQJ@^hn0Hnk-MFAaK7Bls)ASKl8- zg@@YT81k%Ut5nr!|KzPNh#Xe~d&`l%c5sP$G$H+8XYAvEn1#>wH}oMYUISmsNM#Ys ze;!n4#a2_B)qgH7qKiBctxB8baX&fVU6je#sQ;vH)5-K7>wk5hK}YKhU{Kux^}PM7 z8qJypDr}m@9kXFZH$)HMI{h459%;OuxYZ5?njtyLaO9)-z;p2%=@a-AA7CM#m_sb% z;;~>3U+h%-xs_a(1I?HD2%6C;B;1^II%A1Fw&XGv2P@;pj~pJXoMNHV81Ali$*VnQ z=#TtL#nSTJ(gJMQE0qkY@*dMKlgK0O33zWw7kyM}8Q&P^JG&Nnm}1d`&Lrc^R$U>? z;aiS7NC41234hF5Kc=~7tVV1g%Z?^O>tdGPfZ9Of89{YHqHAF}rXGrC3U4X_?2pN5 L^HT*UZEyb{wxd?^ literal 0 HcmV?d00001 diff --git a/dist/img/logo.png b/dist/img/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..1ad08f9f2a497f154ebae2b8eae350aee31e9f83 GIT binary patch literal 39451 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 z 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 ZfWQ37KnYIJ0kkDY3siyF`8YY>|JiV4y<`9Y literal 0 HcmV?d00001 diff --git a/dist/index.html b/dist/index.html new file mode 100644 index 0000000..2380868 --- /dev/null +++ b/dist/index.html @@ -0,0 +1 @@ +Web IM

\ No newline at end of file diff --git a/dist/js/app.26bc1008.js b/dist/js/app.26bc1008.js new file mode 100644 index 0000000..f3d622e --- /dev/null +++ b/dist/js/app.26bc1008.js @@ -0,0 +1,3213 @@ +/******/ (function() { // webpackBootstrap +/******/ "use strict"; +/******/ var __webpack_modules__ = ({ + +/***/ 4677: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6768); +/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(144); +/* harmony import */ var _components_LoginView_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3727); +/* harmony import */ var _components_DocumentedShell_vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8409); +/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(926); + + + + + +/* harmony default export */ __webpack_exports__.A = ({ + __name: 'App', + setup(__props) { + const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_4__/* .useSessionStore */ .B)(); + (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .onMounted */ .sV)(() => { + session.restore(); + }); + return (_ctx, _cache) => { + return !(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .unref */ .R1)(session).isAuthenticated ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createBlock */ .Wv)(_components_LoginView_vue__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A, { + key: 0 + })) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createBlock */ .Wv)(_components_DocumentedShell_vue__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A, { + key: 1 + })); + }; + } +}); + +/***/ }), + +/***/ 865: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5130); +/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6768); +/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(144); +/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5187); +/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(926); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(2169); + +const _hoisted_1 = { + class: "documented-shell" +}; +const _hoisted_2 = { + class: "documented-rail" +}; +const _hoisted_3 = { + class: "documented-avatar" +}; +const _hoisted_4 = ["src"]; +const _hoisted_5 = { + key: 1 +}; +const _hoisted_6 = { + class: "documented-rail-copy" +}; +const _hoisted_7 = { + class: "documented-main" +}; +const _hoisted_8 = { + class: "documented-header" +}; +const _hoisted_9 = { + class: "documented-status" +}; +const _hoisted_10 = { + class: "documented-card" +}; +const _hoisted_11 = { + class: "documented-meta" +}; +const _hoisted_12 = { + key: 0, + class: "form-error" +}; +const _hoisted_13 = { + key: 1, + class: "form-info" +}; +const _hoisted_14 = { + class: "modal-actions" +}; +const _hoisted_15 = ["disabled"]; +const _hoisted_16 = ["disabled"]; + + + +/* harmony default export */ __webpack_exports__.A = ({ + __name: 'DocumentedShell', + setup(__props) { + const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_4__/* .useSessionStore */ .B)(); + const passwordDialogOpen = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .ref */ .KR)(false); + const passwordSaving = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .ref */ .KR)(false); + const passwordError = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .ref */ .KR)(''); + const passwordNotice = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .ref */ .KR)(''); + const passwordDraft = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .reactive */ .Kh)({ + oldPassword: '', + newPassword: '', + confirmPassword: '' + }); + const initials = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .computed */ .EW)(() => String(session.displayName || session.userId || 'U').slice(0, 1).toUpperCase()); + function resetPasswordDraft() { + passwordDraft.oldPassword = ''; + passwordDraft.newPassword = ''; + passwordDraft.confirmPassword = ''; + } + function openPasswordDialog() { + passwordError.value = ''; + passwordNotice.value = ''; + resetPasswordDraft(); + passwordDialogOpen.value = true; + } + function closePasswordDialog() { + if (passwordSaving.value) { + return; + } + passwordDialogOpen.value = false; + passwordError.value = ''; + passwordNotice.value = ''; + resetPasswordDraft(); + } + async function savePassword() { + passwordError.value = ''; + passwordNotice.value = ''; + if (!passwordDraft.oldPassword || !passwordDraft.newPassword || !passwordDraft.confirmPassword) { + passwordError.value = '请填写完整密码'; + return; + } + if (passwordDraft.newPassword !== passwordDraft.confirmPassword) { + passwordError.value = '两次输入的新密码不一致'; + return; + } + if (passwordDraft.oldPassword === passwordDraft.newPassword) { + passwordError.value = '新密码不能与当前密码相同'; + return; + } + passwordSaving.value = true; + try { + await session.changePassword({ + oldPassword: passwordDraft.oldPassword, + newPassword: passwordDraft.newPassword + }); + passwordNotice.value = '密码已修改,当前登录态会按文档要求失效。'; + } catch (error) { + passwordError.value = error.message || '密码修改失败'; + } finally { + passwordSaving.value = false; + } + } + async function logout() { + await session.logout(); + } + return (_ctx, _cache) => { + return (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("main", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("aside", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(session).portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("img", { + key: 0, + src: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(session).portrait, + alt: "" + }, null, 8, _hoisted_4)) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("span", _hoisted_5, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(initials.value), 1))]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", _hoisted_6, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(session).displayName || (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(session).userId), 1), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(session).userId), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("button", { + class: "documented-rail-button", + type: "button", + onClick: openPasswordDialog + }, "修改密码"), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("button", { + class: "documented-rail-button ghost", + type: "button", + onClick: logout + }, "退出登录")]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("section", _hoisted_7, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("header", _hoisted_8, [_cache[4] || (_cache[4] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", null, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("h1", null, "文档对接模式"), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("p", null, "当前界面只保留这两份文档已经明确提供的能力。")], -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", _hoisted_9, [_cache[3] || (_cache[3] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("span", null, "连接状态", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(session).connectionStatusText || '已登录'), 1)])]), _cache[11] || (_cache[11] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createStaticVNode */ .Fv)("

已按文档接入

  • `/auth/login_pwd` 密码登录
  • `/auth/register` 注册并返回 `imToken`、`accessToken`、`refreshToken`
  • `/auth/sendEmailCode` 邮箱验证码
  • `/auth/refreshToken` 过期自动刷新
  • `/auth/changePassword` 修改密码
  • `/auth/logout` 退出登录
  • 扫码登录兼容接口:`/pc_session` 与 `/session_login/{token}`
  • AES-128-CBC 请求加密、响应解密、`X-Timestamp`、排除路径规则

当前按 1 比 1 已停用

下面这些旧页面功能已经不再走本地 PHP 或旧接口,因为你给的文档里没有对应定义。

  • 会话列表与消息列表
  • 发送文字、图片、文件消息
  • 联系人列表、添加联系人、备注
  • 群详情、群成员、群管理
  • 个人资料编辑与头像上传
", 2)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("section", _hoisted_10, [_cache[10] || (_cache[10] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("h2", null, "当前登录态", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dl", _hoisted_11, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", null, [_cache[5] || (_cache[5] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dt", null, "用户 ID", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(session).userId || '-'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", null, [_cache[6] || (_cache[6] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dt", null, "显示名", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(session).displayName || '-'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", null, [_cache[7] || (_cache[7] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dt", null, "IM Token", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(session).token ? '已保存' : '未保存'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", null, [_cache[8] || (_cache[8] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dt", null, "App Server", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(_config__WEBPACK_IMPORTED_MODULE_5__/* .appConfig */ .U).appServer), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", null, [_cache[9] || (_cache[9] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dt", null, "扫码服务", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(_config__WEBPACK_IMPORTED_MODULE_5__/* .appConfig */ .U).qrAppServer), 1)])])])]), passwordDialogOpen.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("div", { + key: 0, + class: "modal-backdrop", + onClick: (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .withModifiers */ .D$)(closePasswordDialog, ["self"]) + }, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("form", { + class: "modal-panel documented-password-panel", + onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .withModifiers */ .D$)(savePassword, ["prevent"]) + }, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("header", null, [_cache[12] || (_cache[12] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("strong", null, "修改密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("button", { + type: "button", + class: "icon-button", + title: "关闭", + onClick: closePasswordDialog + }, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("label", null, [_cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("span", null, "当前密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("input", { + "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => passwordDraft.oldPassword = $event), + type: "password", + autocomplete: "current-password" + }, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_0__/* .vModelText */ .Jo, passwordDraft.oldPassword]])]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("label", null, [_cache[14] || (_cache[14] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("span", null, "新密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("input", { + "onUpdate:modelValue": _cache[1] || (_cache[1] = $event => passwordDraft.newPassword = $event), + type: "password", + autocomplete: "new-password" + }, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_0__/* .vModelText */ .Jo, passwordDraft.newPassword]])]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("label", null, [_cache[15] || (_cache[15] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("span", null, "确认新密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("input", { + "onUpdate:modelValue": _cache[2] || (_cache[2] = $event => passwordDraft.confirmPassword = $event), + type: "password", + autocomplete: "new-password" + }, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_0__/* .vModelText */ .Jo, passwordDraft.confirmPassword]])]), passwordError.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("p", _hoisted_12, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(passwordError.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createCommentVNode */ .Q3)("", true), passwordNotice.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("p", _hoisted_13, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(passwordNotice.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", _hoisted_14, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("button", { + type: "button", + class: "ghost-inline-action", + disabled: passwordSaving.value, + onClick: closePasswordDialog + }, "取消", 8, _hoisted_15), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("button", { + class: "primary-inline-action", + disabled: passwordSaving.value + }, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(passwordSaving.value ? '保存中...' : '保存'), 9, _hoisted_16)])], 32)])) : (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createCommentVNode */ .Q3)("", true)]); + }; + } +}); + +/***/ }), + +/***/ 8607: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423); +/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5130); +/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6768); +/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(144); +/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(5187); +/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(2387); +/* harmony import */ var jr_qrcode__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(2789); +/* harmony import */ var jr_qrcode__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(jr_qrcode__WEBPACK_IMPORTED_MODULE_6__); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(2169); +/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(926); +/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(5051); + + +const _hoisted_1 = { + class: "login-page" +}; +const _hoisted_2 = { + class: "login-panel" +}; +const _hoisted_3 = { + class: "brand-lockup" +}; +const _hoisted_4 = ["src", "alt"]; +const _hoisted_5 = { + class: "login-tabs register-tabs", + style: { + gridTemplateColumns: 'repeat(3, minmax(0, 1fr))' + } +}; +const _hoisted_6 = ["disabled"]; +const _hoisted_7 = ["src"]; +const _hoisted_8 = { + key: 1 +}; +const _hoisted_9 = { + key: 0, + class: "qr-scan-user" +}; +const _hoisted_10 = ["src"]; +const _hoisted_11 = { + key: 1 +}; +const _hoisted_12 = { + class: "qr-login-status" +}; +const _hoisted_13 = ["disabled"]; +const _hoisted_14 = ["autocomplete", "inputmode", "placeholder"]; +const _hoisted_15 = ["disabled"]; +const _hoisted_16 = { + key: 2, + class: "form-error" +}; +const _hoisted_17 = { + key: 3, + class: "form-info" +}; +const _hoisted_18 = { + class: "login-tabs register-tabs", + style: { + gridTemplateColumns: 'repeat(2, minmax(0, 1fr))' + } +}; +const _hoisted_19 = ["autocomplete", "inputmode", "placeholder"]; +const _hoisted_20 = { + key: 0 +}; +const _hoisted_21 = { + class: "code-row" +}; +const _hoisted_22 = ["disabled"]; +const _hoisted_23 = ["disabled"]; +const _hoisted_24 = { + key: 1, + class: "form-error" +}; +const _hoisted_25 = { + key: 2, + class: "form-info" +}; + + + + + + +const QR_CODE_PREFIX_PC_SESSION = 'wildfirechat://pcsession/'; +const defaultPlatformLogo = '/favicon.ico'; +/* harmony default export */ __webpack_exports__.A = ({ + __name: 'LoginView', + setup(__props) { + const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_8__/* .useSessionStore */ .B)(); + const view = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('login'); + const loginMode = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('phone'); + const loginAccount = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(''); + const loginPassword = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(''); + const registerType = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(1); + const registerForm = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .reactive */ .Kh)({ + number: '', + code: '', + password: '', + confirmPassword: '', + invitationCode: '' + }); + const sendingCode = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(false); + const info = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(''); + const qrStatus = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('idle'); + const qrCodeImage = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(''); + const qrSessionToken = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(''); + const qrUserName = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(''); + const qrUserPortrait = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(''); + let qrGeneration = 0; + let qrExpireTimer = null; + const defaultPlatformName = _config__WEBPACK_IMPORTED_MODULE_7__/* .appConfig */ .U.appName; + const platformName = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(defaultPlatformName); + const platformLogo = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(defaultPlatformLogo); + const canSubmitLogin = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => loginAccount.value.length >= 3 && loginPassword.value.length >= 1); + const canRequestEmailCode = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => registerType.value === 2 && /\S+@\S+\.\S+/.test(registerForm.number)); + const canSubmitRegister = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => { + if (registerForm.password.length < 1 || registerForm.password !== registerForm.confirmPassword) { + return false; + } + if (registerType.value === 2) { + return canRequestEmailCode.value && registerForm.code.length >= 1; + } + return registerForm.number.length >= 5; + }); + const qrUserInitial = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => String(qrUserName.value || 'U').slice(0, 1).toUpperCase()); + const qrStatusTitle = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => { + if (session.connecting || qrStatus.value === 'confirmed') { + return '正在进入'; + } + if (qrStatus.value === 'loading') { + return '正在生成二维码'; + } + if (qrStatus.value === 'scanned') { + return qrUserName.value ? `${qrUserName.value} 已扫码` : '已扫码,待确认'; + } + if (qrStatus.value === 'expired') { + return '二维码已过期'; + } + if (qrStatus.value === 'error') { + return '二维码加载失败'; + } + return '扫码登录'; + }); + const qrStatusText = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => { + if (session.connecting || qrStatus.value === 'confirmed') { + return '登录信息已确认,正在建立连接'; + } + if (qrStatus.value === 'loading') { + return '正在创建扫码登录会话'; + } + if (qrStatus.value === 'scanned') { + return '请在手机 App 上确认登录'; + } + if (qrStatus.value === 'expired') { + return '请刷新二维码后重新扫码'; + } + if (qrStatus.value === 'error') { + return '请稍后重试'; + } + return '使用已登录的手机 App 扫描二维码'; + }); + const qrRefreshText = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => { + if (qrStatus.value === 'loading') { + return '生成中...'; + } + if (qrStatus.value === 'expired' || qrStatus.value === 'error') { + return '重新生成二维码'; + } + return '刷新二维码'; + }); + (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .onMounted */ .sV)(() => { + loadPlatformConfig(); + }); + (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .onBeforeUnmount */ .xo)(() => { + stopQrLogin(); + }); + function clearFormMessage() { + session.error = ''; + info.value = ''; + } + function setLoginMode(mode) { + loginMode.value = mode; + loginAccount.value = ''; + loginPassword.value = ''; + clearFormMessage(); + if (mode === 'qr') { + startQrLogin(); + return; + } + stopQrLogin(); + } + async function submitLogin() { + clearFormMessage(); + const type = loginMode.value === 'email' ? 2 : 1; + await session.loginWithPassword(loginAccount.value, loginPassword.value, type); + } + function switchRegisterType(type) { + registerType.value = type; + registerForm.number = ''; + registerForm.code = ''; + registerForm.password = ''; + registerForm.confirmPassword = ''; + registerForm.invitationCode = ''; + clearFormMessage(); + } + async function requestEmailCode() { + clearFormMessage(); + sendingCode.value = true; + try { + await _services_imClient__WEBPACK_IMPORTED_MODULE_9__/* .imClient */ .wD.requestAuthCode(registerForm.number); + info.value = '邮箱验证码已发送,请在当前注册表单中填写后继续。'; + } catch (error) { + session.error = error.message || '验证码发送失败'; + } finally { + sendingCode.value = false; + } + } + async function submitRegister() { + clearFormMessage(); + if (registerForm.password !== registerForm.confirmPassword) { + session.error = '两次输入的密码不一致'; + return; + } + const result = await session.register({ + type: registerType.value, + number: registerForm.number, + code: registerType.value === 2 ? registerForm.code : '', + password: registerForm.password, + invitationCode: registerForm.invitationCode + }); + if (result) { + info.value = '注册成功,正在进入系统。'; + } + } + function openRegister() { + clearFormMessage(); + stopQrLogin(); + view.value = 'register'; + } + function backToLogin() { + clearFormMessage(); + loginMode.value = 'phone'; + stopQrLogin(); + view.value = 'login'; + } + function resetQrState() { + qrStatus.value = 'idle'; + qrCodeImage.value = ''; + qrSessionToken.value = ''; + qrUserName.value = ''; + qrUserPortrait.value = ''; + } + function clearQrExpireTimer() { + if (qrExpireTimer) { + window.clearTimeout(qrExpireTimer); + qrExpireTimer = null; + } + } + function stopQrLogin() { + qrGeneration += 1; + clearQrExpireTimer(); + resetQrState(); + } + function refreshQrLogin() { + startQrLogin(true); + } + async function startQrLogin(force = false) { + if (loginMode.value !== 'qr') { + return; + } + if (!force && qrSessionToken.value && qrCodeImage.value && !['expired', 'error'].includes(qrStatus.value)) { + return; + } + qrGeneration += 1; + const generation = qrGeneration; + clearQrExpireTimer(); + clearFormMessage(); + qrStatus.value = 'loading'; + qrCodeImage.value = ''; + qrSessionToken.value = ''; + qrUserName.value = ''; + qrUserPortrait.value = ''; + try { + const pcSession = await _services_imClient__WEBPACK_IMPORTED_MODULE_9__/* .imClient */ .wD.createPcSession(); + if (generation !== qrGeneration || loginMode.value !== 'qr') { + return; + } + const token = String(pcSession.token || ''); + if (!token) { + throw new Error('服务端没有返回扫码 token'); + } + qrSessionToken.value = token; + qrCodeImage.value = jr_qrcode__WEBPACK_IMPORTED_MODULE_6___default().getQrBase64(QR_CODE_PREFIX_PC_SESSION + token); + qrStatus.value = 'waiting'; + const expireMs = Math.max(30000, Math.min(Number(pcSession.expired || 300000), 300000)); + qrExpireTimer = window.setTimeout(() => { + if (generation === qrGeneration && qrStatus.value !== 'confirmed' && !session.isAuthenticated) { + qrStatus.value = 'expired'; + } + }, expireMs); + pollQrLogin(generation, token); + } catch (error) { + if (generation !== qrGeneration) { + return; + } + qrStatus.value = 'error'; + session.error = error.message || '二维码加载失败'; + } + } + async function pollQrLogin(generation, token) { + try { + while (generation === qrGeneration && loginMode.value === 'qr' && !session.isAuthenticated) { + const payload = await _services_imClient__WEBPACK_IMPORTED_MODULE_9__/* .imClient */ .wD.loginWithPcSession(token); + if (generation !== qrGeneration || loginMode.value !== 'qr') { + return; + } + const code = Number(payload.code); + const data = payload.data || payload.result || {}; + const status = Number(data.status); + if (code === 0 && data.imToken) { + qrStatus.value = 'confirmed'; + clearQrExpireTimer(); + await session.completePcSessionLogin(data); + return; + } + if (code === 20042 || status === 1 || status === 3) { + qrStatus.value = 'scanned'; + qrUserName.value = data.userName || data.displayName || qrUserName.value; + qrUserPortrait.value = data.portrait || qrUserPortrait.value; + await delay(1000); + continue; + } + if (status === 0 || code === 13) { + qrStatus.value = 'waiting'; + await delay(1000); + continue; + } + if (status === 4) { + qrStatus.value = 'expired'; + session.error = payload.message || '扫码登录已取消'; + return; + } + if (payload.message) { + throw new Error(payload.message); + } + await delay(1000); + } + } catch (error) { + if (generation === qrGeneration && loginMode.value === 'qr' && !session.isAuthenticated) { + qrStatus.value = 'error'; + session.error = error.message || '扫码登录失败'; + } + } + } + function delay(ms) { + return new Promise(resolve => window.setTimeout(resolve, ms)); + } + async function loadPlatformConfig() { + try { + const response = await axios__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A.get(_config__WEBPACK_IMPORTED_MODULE_7__/* .appConfig */ .U.platformConfigApi, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '平台配置加载失败'); + } + const config = response.data?.result || {}; + const name = String(config.platformName || '').trim(); + const logo = String(config.logoUrl || config.logo || '').trim(); + const version = String(config.version || '').trim(); + platformName.value = name || defaultPlatformName; + platformLogo.value = resolveBrandLogo(logo, version); + } catch (error) { + platformName.value = defaultPlatformName; + platformLogo.value = defaultPlatformLogo; + } + applyDocumentBrand(); + } + function resolveBrandLogo(value, version = '') { + const logo = String(value || '').trim(); + if (!logo) { + return defaultPlatformLogo; + } + if (/^(https?:|data:|blob:)/i.test(logo)) { + return appendBrandVersion(logo, version); + } + if (logo.startsWith('//')) { + return appendBrandVersion(`${window.location.protocol}${logo}`, version); + } + const base = logo.startsWith('/') ? _config__WEBPACK_IMPORTED_MODULE_7__/* .appConfig */ .U.adminServer : `${_config__WEBPACK_IMPORTED_MODULE_7__/* .appConfig */ .U.adminServer}/`; + return appendBrandVersion(new URL(logo, base).toString(), version); + } + function appendBrandVersion(url, version) { + if (!version || /^(data:|blob:)/i.test(url)) { + return url; + } + const parsed = new URL(url, window.location.href); + parsed.searchParams.set('v', version); + return parsed.toString(); + } + function applyDocumentBrand() { + if (typeof document === 'undefined') { + return; + } + document.title = platformName.value || defaultPlatformName; + let icon = document.querySelector('link[rel="icon"]'); + if (!icon) { + icon = document.createElement('link'); + icon.setAttribute('rel', 'icon'); + document.head.appendChild(icon); + } + icon.setAttribute('href', platformLogo.value || defaultPlatformLogo); + } + function handleBrandLogoError() { + if (platformLogo.value !== defaultPlatformLogo) { + platformLogo.value = defaultPlatformLogo; + applyDocumentBrand(); + } + } + return (_ctx, _cache) => { + return (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("main", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("section", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("img", { + class: "brand-mark", + src: platformLogo.value, + alt: `${platformName.value} logo`, + onError: handleBrandLogoError + }, null, 40, _hoisted_4), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", null, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("h1", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(platformName.value), 1)])]), view.value === 'login' ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("form", { + key: 0, + class: "login-form", + onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .withModifiers */ .D$)(submitLogin, ["prevent"]) + }, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_5, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", { + type: "button", + class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)({ + active: loginMode.value === 'qr' + }), + onClick: _cache[0] || (_cache[0] = $event => setLoginMode('qr')) + }, "扫码登录", 2), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", { + type: "button", + class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)({ + active: loginMode.value === 'phone' + }), + onClick: _cache[1] || (_cache[1] = $event => setLoginMode('phone')) + }, "手机号", 2), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", { + type: "button", + class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)({ + active: loginMode.value === 'email' + }), + onClick: _cache[2] || (_cache[2] = $event => setLoginMode('email')) + }, "邮箱", 2)]), loginMode.value === 'qr' ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_2__/* .Fragment */ .FK, { + key: 0 + }, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", { + class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)(["qr-login-card", { + scanned: qrStatus.value === 'scanned', + expired: qrStatus.value === 'expired', + error: qrStatus.value === 'error' + }]) + }, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", { + type: "button", + class: "qr-code-button", + disabled: qrStatus.value === 'loading' || (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting, + onClick: refreshQrLogin + }, [qrCodeImage.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("img", { + key: 0, + src: qrCodeImage.value, + alt: "扫码登录二维码" + }, null, 8, _hoisted_7)) : ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("span", _hoisted_8, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(qrStatus.value === 'loading' ? '生成中' : '点击刷新'), 1))], 8, _hoisted_6), qrStatus.value === 'scanned' ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("div", _hoisted_9, [qrUserPortrait.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("img", { + key: 0, + src: qrUserPortrait.value, + alt: "" + }, null, 8, _hoisted_10)) : ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("span", _hoisted_11, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(qrUserInitial.value), 1))])) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true)], 2), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_12, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(qrStatusTitle.value), 1), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(qrStatusText.value), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", { + type: "button", + class: "primary-action", + disabled: qrStatus.value === 'loading' || (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting, + onClick: refreshQrLogin + }, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(qrRefreshText.value), 9, _hoisted_13)], 64)) : ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_2__/* .Fragment */ .FK, { + key: 1 + }, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(loginMode.value === 'phone' ? '手机号' : '邮箱'), 1), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", { + "onUpdate:modelValue": _cache[3] || (_cache[3] = $event => loginAccount.value = $event), + autocomplete: loginMode.value === 'phone' ? 'username' : 'email', + inputmode: loginMode.value === 'phone' ? 'tel' : 'email', + placeholder: loginMode.value === 'phone' ? '请输入手机号' : '请输入邮箱' + }, null, 8, _hoisted_14), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, loginAccount.value, void 0, { + trim: true + }]])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [_cache[12] || (_cache[12] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, "密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", { + "onUpdate:modelValue": _cache[4] || (_cache[4] = $event => loginPassword.value = $event), + autocomplete: "current-password", + type: "password", + placeholder: "请输入密码" + }, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, loginPassword.value]])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", { + class: "primary-action", + disabled: (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting || !canSubmitLogin.value + }, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting ? '登录中...' : '登录'), 9, _hoisted_15)], 64)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).error ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("p", _hoisted_16, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).error), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true), info.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("p", _hoisted_17, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(info.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true)], 32)) : ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("form", { + key: 1, + class: "login-form", + onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .withModifiers */ .D$)(submitRegister, ["prevent"]) + }, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_18, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", { + type: "button", + class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)({ + active: registerType.value === 1 + }), + onClick: _cache[5] || (_cache[5] = $event => switchRegisterType(1)) + }, "手机号注册", 2), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", { + type: "button", + class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)({ + active: registerType.value === 2 + }), + onClick: _cache[6] || (_cache[6] = $event => switchRegisterType(2)) + }, "邮箱注册", 2)]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(registerType.value === 1 ? '手机号' : '邮箱'), 1), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", { + "onUpdate:modelValue": _cache[7] || (_cache[7] = $event => registerForm.number = $event), + autocomplete: registerType.value === 1 ? 'tel' : 'email', + inputmode: registerType.value === 1 ? 'tel' : 'email', + placeholder: registerType.value === 1 ? '请输入手机号' : '请输入邮箱' + }, null, 8, _hoisted_19), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, registerForm.number, void 0, { + trim: true + }]])]), registerType.value === 2 ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("label", _hoisted_20, [_cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, "邮箱验证码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_21, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", { + "onUpdate:modelValue": _cache[8] || (_cache[8] = $event => registerForm.code = $event), + autocomplete: "one-time-code", + inputmode: "numeric", + placeholder: "请输入邮箱验证码" + }, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, registerForm.code, void 0, { + trim: true + }]]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", { + type: "button", + class: "code-action", + disabled: sendingCode.value || !canRequestEmailCode.value, + onClick: requestEmailCode + }, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(sendingCode.value ? '发送中' : '发送验证码'), 9, _hoisted_22)])])) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [_cache[14] || (_cache[14] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, "密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", { + "onUpdate:modelValue": _cache[9] || (_cache[9] = $event => registerForm.password = $event), + autocomplete: "new-password", + type: "password", + placeholder: "请输入密码" + }, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, registerForm.password]])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [_cache[15] || (_cache[15] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, "确认密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", { + "onUpdate:modelValue": _cache[10] || (_cache[10] = $event => registerForm.confirmPassword = $event), + autocomplete: "new-password", + type: "password", + placeholder: "请再次输入密码" + }, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, registerForm.confirmPassword]])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [_cache[16] || (_cache[16] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, "邀请码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", { + "onUpdate:modelValue": _cache[11] || (_cache[11] = $event => registerForm.invitationCode = $event), + autocomplete: "off", + placeholder: "没有可留空" + }, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, registerForm.invitationCode, void 0, { + trim: true + }]])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", { + class: "primary-action", + disabled: (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting || !canSubmitRegister.value + }, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting ? '注册中...' : '注册并登录'), 9, _hoisted_23), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).error ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("p", _hoisted_24, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).error), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true), info.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("p", _hoisted_25, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(info.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true)], 32)), view.value === 'login' ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("button", { + key: 2, + class: "ghost-action", + type: "button", + onClick: openRegister + }, " 新用户注册 ")) : ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("button", { + key: 3, + class: "ghost-action", + type: "button", + onClick: backToLogin + }, " 返回登录 "))])]); + }; + } +}); + +/***/ }), + +/***/ 2169: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +const currentHost = window.location.hostname || '127.0.0.1'; +const runtimeConfig = window.JC_WEB_IM_CONFIG || {}; +const appServerOrigin = `${window.location.protocol}//${currentHost}:8888`; +const qrAppServerOrigin = `${window.location.protocol}//${currentHost}:18888`; +const adminServerOrigin = `${window.location.protocol}//${currentHost}:8024`; +const appConfig = { + appName: 'Web IM', + adminServer: runtimeConfig.adminServer || undefined || adminServerOrigin, + appServer: runtimeConfig.appServer || undefined || appServerOrigin, + qrAppServer: runtimeConfig.qrAppServer || undefined || qrAppServerOrigin, + platformConfigApi: runtimeConfig.platformConfigApi || undefined || ( false ? 0 : '/api/platform_config.php'), + registerConfigApi: runtimeConfig.registerConfigApi || undefined || `${adminServerOrigin}/api/register-config`, + registerPhoneExistsApi: runtimeConfig.registerPhoneExistsApi || undefined || `${adminServerOrigin}/api/register-phone-exists`, + contactsApi: runtimeConfig.contactsApi || undefined || ( false ? 0 : '/api/contacts.php'), + updateAliasApi: runtimeConfig.updateAliasApi || undefined || ( false ? 0 : '/api/update_alias.php'), + addContactApi: runtimeConfig.addContactApi || undefined || ( false ? 0 : '/api/add_contact.php'), + conversationActionsApi: runtimeConfig.conversationActionsApi || undefined || ( false ? 0 : '/api/conversation_actions.php'), + sendMessageApi: runtimeConfig.sendMessageApi || undefined || ( false ? 0 : '/api/send_message.php'), + messageActionApi: runtimeConfig.messageActionApi || undefined || ( false ? 0 : '/api/message_action.php'), + messageDetailApi: runtimeConfig.messageDetailApi || undefined || ( false ? 0 : '/api/message_detail.php'), + messagesApi: runtimeConfig.messagesApi || undefined || ( false ? 0 : '/api/messages.php'), + profileApi: runtimeConfig.profileApi || undefined || ( false ? 0 : '/api/profile.php'), + changePasswordApi: runtimeConfig.changePasswordApi || undefined || `${appServerOrigin}/auth/changePassword`, + logoutApi: runtimeConfig.logoutApi || undefined || `${appServerOrigin}/auth/logout`, + imServerHost: runtimeConfig.imServerHost || undefined || currentHost, + imRoutePort: Number(runtimeConfig.imRoutePort || undefined || 18000), + useWss: runtimeConfig.useWss ?? undefined === 'true', + wsPath: runtimeConfig.wsPath || undefined || '/ws', + wsUrl: runtimeConfig.wsUrl || undefined || '', + sdkMode: runtimeConfig.sdkMode || undefined || 'http', + syncIntervalMs: Number(runtimeConfig.syncIntervalMs || undefined || 300), + platform: 5, + clientIdStorageKey: 'qmt-web-im-client-id', + authTokenStoragePrefix: 'qmt-web-im-auth-token-' +}; +/* harmony export */ __webpack_require__.d(__webpack_exports__, [ +/* harmony export */ "U", 0, /* binding */ appConfig +/* harmony export */ ]); + + +/***/ }), + +/***/ 1406: +/***/ (function(__unused_webpack_module, __unused_webpack___webpack_exports__, __webpack_require__) { + +/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5130); +/* harmony import */ var pinia__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2261); +/* harmony import */ var _App_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7067); + + + + +(0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createApp */ .Ef)(_App_vue__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A).use((0,pinia__WEBPACK_IMPORTED_MODULE_1__/* .createPinia */ .Ey)()).mount('#app'); + +/***/ }), + +/***/ 9311: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Ln: function() { return /* binding */ appServerPost; }, +/* harmony export */ Pd: function() { return /* binding */ getStoredAppAuth; }, +/* harmony export */ eG: function() { return /* binding */ persistAppAuth; }, +/* harmony export */ u$: function() { return /* binding */ clearStoredAppAuth; } +/* harmony export */ }); +/* unused harmony exports appServerRequest, appServerGet */ +/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8111); +/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7588); +/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var core_js_modules_es_typed_array_with_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(9577); +/* harmony import */ var core_js_modules_es_typed_array_with_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_with_js__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var core_js_modules_es_uint8_array_set_from_base64_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6632); +/* harmony import */ var core_js_modules_es_uint8_array_set_from_base64_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_uint8_array_set_from_base64_js__WEBPACK_IMPORTED_MODULE_3__); +/* harmony import */ var core_js_modules_es_uint8_array_set_from_hex_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4226); +/* harmony import */ var core_js_modules_es_uint8_array_set_from_hex_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_uint8_array_set_from_hex_js__WEBPACK_IMPORTED_MODULE_4__); +/* harmony import */ var core_js_modules_es_uint8_array_to_base64_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(9486); +/* harmony import */ var core_js_modules_es_uint8_array_to_base64_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_uint8_array_to_base64_js__WEBPACK_IMPORTED_MODULE_5__); +/* harmony import */ var core_js_modules_es_uint8_array_to_hex_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(456); +/* harmony import */ var core_js_modules_es_uint8_array_to_hex_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_uint8_array_to_hex_js__WEBPACK_IMPORTED_MODULE_6__); +/* harmony import */ var core_js_modules_web_dom_exception_stack_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(4979); +/* harmony import */ var core_js_modules_web_dom_exception_stack_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_web_dom_exception_stack_js__WEBPACK_IMPORTED_MODULE_7__); +/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(2387); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(2169); + + + + + + + + + + +const AES_KEY = 'xczx2026!@#secKe'; +const ENCRYPTION_EXCLUDE_PATHS = ['/avatar/', '/f/', '/amr2mp3', '/appVersion/check']; +const AUTH_STORAGE_KEY = 'qmt-web-im-app-auth-v1'; +const AUTH_ERROR_CODE = 13; +const REFRESH_ERROR_CODE = 20045; +let importedCryptoKeyPromise = null; +let refreshPromise = null; +function storageScope() { + return _config__WEBPACK_IMPORTED_MODULE_9__/* .appConfig */ .U.appServer || ''; +} +function readAuthStore() { + try { + return JSON.parse(localStorage.getItem(AUTH_STORAGE_KEY) || '{}'); + } catch (error) { + return {}; + } +} +function writeAuthStore(store) { + localStorage.setItem(AUTH_STORAGE_KEY, JSON.stringify(store)); +} +function normalizeAuthBundle(bundle = {}) { + const accessToken = String(bundle.accessToken || '').trim(); + const refreshToken = String(bundle.refreshToken || '').trim(); + if (!accessToken || !refreshToken) { + return null; + } + return { + accessToken, + refreshToken, + tokenType: String(bundle.tokenType || 'Bearer').trim() || 'Bearer', + accessTokenExpireIn: Number(bundle.accessTokenExpireIn || 0) || 0, + accessTokenExpireAt: Number(bundle.accessTokenExpireAt || 0) || 0, + refreshTokenExpireIn: Number(bundle.refreshTokenExpireIn || 0) || 0, + refreshTokenExpireAt: Number(bundle.refreshTokenExpireAt || 0) || 0 + }; +} +function getStoredAppAuth() { + const store = readAuthStore(); + return normalizeAuthBundle(store[storageScope()]); +} +function persistAppAuth(bundle) { + const normalized = normalizeAuthBundle(bundle); + const store = readAuthStore(); + if (!normalized) { + delete store[storageScope()]; + writeAuthStore(store); + return null; + } + store[storageScope()] = normalized; + writeAuthStore(store); + return normalized; +} +function clearStoredAppAuth() { + persistAppAuth(null); +} +function hasFormData(value) { + return typeof FormData !== 'undefined' && value instanceof FormData; +} +function absoluteUrl(url) { + return new URL(url, window.location.origin); +} +function shouldEncrypt(url) { + const pathname = absoluteUrl(url).pathname; + return !ENCRYPTION_EXCLUDE_PATHS.some(path => pathname === path || pathname.startsWith(path)); +} +function shouldAttachAuth(config) { + return !config.skipAuth; +} +function textEncoder() { + return new TextEncoder(); +} +function textDecoder() { + return new TextDecoder(); +} +function bytesToBase64(bytes) { + let binary = ''; + bytes.forEach(byte => { + binary += String.fromCharCode(byte); + }); + return btoa(binary); +} +function base64ToBytes(base64) { + const binary = atob(base64); + const bytes = new Uint8Array(binary.length); + for (let index = 0; index < binary.length; index += 1) { + bytes[index] = binary.charCodeAt(index); + } + return bytes; +} +async function getCryptoKey() { + if (!importedCryptoKeyPromise) { + importedCryptoKeyPromise = window.crypto.subtle.importKey('raw', textEncoder().encode(AES_KEY), { + name: 'AES-CBC' + }, false, ['encrypt', 'decrypt']); + } + return importedCryptoKeyPromise; +} +async function encryptPayload(plainText) { + const iv = window.crypto.getRandomValues(new Uint8Array(16)); + const key = await getCryptoKey(); + const encrypted = await window.crypto.subtle.encrypt({ + name: 'AES-CBC', + iv + }, key, textEncoder().encode(plainText)); + return `${bytesToBase64(iv)}:${bytesToBase64(new Uint8Array(encrypted))}`; +} +async function decryptPayload(cipherText) { + const [ivBase64, encryptedBase64] = String(cipherText || '').split(':', 2); + if (!ivBase64 || !encryptedBase64) { + throw new Error('Encrypted payload format is invalid'); + } + const key = await getCryptoKey(); + const decrypted = await window.crypto.subtle.decrypt({ + name: 'AES-CBC', + iv: base64ToBytes(ivBase64) + }, key, base64ToBytes(encryptedBase64)); + return textDecoder().decode(decrypted); +} +function normalizeBusinessResponse(payload) { + if (payload && typeof payload === 'object' && !Array.isArray(payload)) { + return payload; + } + return { + code: 0, + message: 'success', + data: payload + }; +} +async function decodeResponsePayload(response) { + const encrypted = String(response.headers?.['x-encrypted'] || '').toLowerCase() === 'true'; + if (encrypted && typeof response.data === 'string') { + const plainText = await decryptPayload(response.data); + response.data = normalizeBusinessResponse(JSON.parse(plainText)); + return response; + } + response.data = normalizeBusinessResponse(response.data); + return response; +} +const client = axios__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A.create({ + withCredentials: false +}); +client.interceptors.request.use(async config => { + const nextConfig = { + ...config + }; + const url = absoluteUrl(nextConfig.url || '').toString(); + if (shouldAttachAuth(nextConfig)) { + const auth = getStoredAppAuth(); + if (auth?.accessToken) { + nextConfig.headers = { + ...(nextConfig.headers || {}), + Authorization: `${auth.tokenType || 'Bearer'} ${auth.accessToken}` + }; + } + } + if (!hasFormData(nextConfig.data) && nextConfig.method?.toLowerCase() !== 'get' && shouldEncrypt(url)) { + const plainBody = JSON.stringify(nextConfig.data ?? {}); + nextConfig.data = await encryptPayload(plainBody); + nextConfig.headers = { + ...(nextConfig.headers || {}), + 'Content-Type': 'text/plain;charset=UTF-8', + 'X-Timestamp': `${Math.floor(Date.now() / 1000)}` + }; + } + return nextConfig; +}); +client.interceptors.response.use(async response => decodeResponsePayload(response)); +async function refreshAccessToken() { + if (refreshPromise) { + return refreshPromise; + } + const auth = getStoredAppAuth(); + if (!auth?.refreshToken) { + clearStoredAppAuth(); + throw new Error('登录状态已失效,请重新登录'); + } + refreshPromise = client.post(`${_config__WEBPACK_IMPORTED_MODULE_9__/* .appConfig */ .U.appServer}/auth/refreshToken`, { + refreshToken: auth.refreshToken + }, { + skipAuth: true + }).then(response => { + const payload = response.data || {}; + if (Number(payload.code) !== 0 || !payload.data) { + if (Number(payload.code) === REFRESH_ERROR_CODE) { + clearStoredAppAuth(); + } + throw new Error(payload.message || '刷新登录状态失败'); + } + persistAppAuth(payload.data); + return payload.data; + }).finally(() => { + refreshPromise = null; + }); + return refreshPromise; +} +async function request(config) { + const response = await client.request(config); + const payload = response.data || {}; + if (Number(payload.code) === AUTH_ERROR_CODE && shouldAttachAuth(config) && !config._retriedAfterRefresh) { + await refreshAccessToken(); + return request({ + ...config, + _retriedAfterRefresh: true + }); + } + return response; +} +async function appServerRequest(config) { + return request(config); +} +async function appServerGet(url, config = {}) { + return request({ + ...config, + method: 'get', + url + }); +} +async function appServerPost(url, data = {}, config = {}) { + return request({ + ...config, + method: 'post', + url, + data + }); +} + +/***/ }), + +/***/ 4355: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ u: function() { return /* binding */ DocumentedHttpImClient; } +/* harmony export */ }); +/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423); +/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2169); +/* harmony import */ var _httpImClient__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5099); +/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2387); +/* harmony import */ var _appServerClient__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(9311); + + + + + +function inferAccountType(account) { + return String(account || '').includes('@') ? 2 : 1; +} +function unwrapData(response) { + return response.data?.data ?? response.data?.result ?? null; +} +function unwrapMessage(response, fallback) { + return response.data?.message || response.data?.msg || fallback; +} +class DocumentedHttpImClient extends _httpImClient__WEBPACK_IMPORTED_MODULE_2__/* .HttpImClient */ .Y { + unsupported(feature) { + throw new Error(`当前对接文档未提供“${feature}”接口,已禁用旧本地代理链路`); + } + async loginWithPassword(account, password, type = inferAccountType(account)) { + const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .appServerPost */ .Ln)(`${_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.appServer}/auth/login_pwd`, { + type, + number: account, + password, + platform: _config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.platform, + clientId: this.getClientId() + }, { + skipAuth: true + }); + if (response.data?.code !== 0) { + throw new Error(unwrapMessage(response, '登录失败')); + } + (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .persistAppAuth */ .eG)(unwrapData(response)); + return unwrapData(response); + } + async requestAuthCode(email) { + const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .appServerPost */ .Ln)(`${_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.appServer}/auth/sendEmailCode`, { + email + }, { + skipAuth: true + }); + if (response.data?.code !== 0) { + throw new Error(unwrapMessage(response, '验证码发送失败')); + } + return unwrapData(response); + } + async loginWithCode(account, code) { + void account; + void code; + throw new Error('接口文档未提供验证码登录接口,请使用密码登录'); + } + async register({ + type, + number, + code = '', + password, + invitationCode = '' + }) { + const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .appServerPost */ .Ln)(`${_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.appServer}/auth/register`, { + type, + number, + code, + password, + clientId: this.getClientId(), + platform: _config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.platform, + invitationCode + }, { + skipAuth: true + }); + if (response.data?.code !== 0) { + throw new Error(unwrapMessage(response, '注册失败')); + } + (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .persistAppAuth */ .eG)(unwrapData(response)); + return unwrapData(response); + } + async createPcSession(userId = '') { + const response = await axios__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.post(`${_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.qrAppServer}/pc_session`, { + flag: 1, + device_name: 'Web IM', + userId, + clientId: this.getClientId(), + platform: _config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.platform + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(unwrapMessage(response, '二维码登录会话创建失败')); + } + return unwrapData(response) || {}; + } + async loginWithPcSession(token) { + const url = `${_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.qrAppServer}/session_login/${encodeURIComponent(token)}`; + let response; + try { + response = await axios__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.post(url, null, { + withCredentials: false + }); + } catch (postError) { + response = await axios__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.get(url, { + withCredentials: false + }); + } + this.persistAppToken(url, response); + const payload = response.data || {}; + const result = payload.result ?? payload.data ?? null; + if (Number(payload.code) === 0 && result) { + (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .persistAppAuth */ .eG)(result); + } + if ([0, 8, 9, 10, 13, 18, 20042].includes(Number(payload.code))) { + return { + ...payload, + data: result + }; + } + throw new Error(payload.message || '扫码登录失败'); + } + async changePassword({ + oldPassword, + newPassword + }) { + const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .appServerPost */ .Ln)(_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.changePasswordApi, { + oldPassword, + newPassword + }); + if (response.data?.code !== 0) { + throw new Error(unwrapMessage(response, '密码修改失败')); + } + return true; + } + async resetPasswordWithCode({ + mobile, + resetCode, + newPassword + }) { + void mobile; + void resetCode; + void newPassword; + throw new Error('接口文档未提供重置密码接口,请联系服务端确认流程'); + } + async logout() { + const auth = (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .getStoredAppAuth */ .Pd)(); + if (!auth?.refreshToken) { + (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .clearStoredAppAuth */ .u$)(); + return true; + } + try { + const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .appServerPost */ .Ln)(_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.logoutApi, { + refreshToken: auth.refreshToken + }); + if (response.data?.code !== 0) { + throw new Error(unwrapMessage(response, '退出登录失败')); + } + } finally { + (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .clearStoredAppAuth */ .u$)(); + } + return true; + } + async fetchRemoteConversations() { + return []; + } + async fetchRemoteMessages() { + return []; + } + async getServerContactList() { + return []; + } + async getProfile() { + return null; + } + async sendTextMessage() { + this.unsupported('发送消息'); + } + async sendAttachmentMessage() { + this.unsupported('发送附件消息'); + } + async addContact() { + this.unsupported('添加联系人'); + } + async updateContactAlias() { + this.unsupported('联系人备注'); + } + async createGroup() { + this.unsupported('创建群组'); + } + async joinGroup() { + this.unsupported('加入群组'); + } + async broadcastMessage() { + this.unsupported('群发消息'); + } + async getGroupDetail() { + this.unsupported('群详情'); + } + async getGroupMembers() { + this.unsupported('群成员'); + } + async updateGroupAlias() { + this.unsupported('群备注'); + } + async leaveGroup() { + this.unsupported('退出群组'); + } + async dismissGroup() { + this.unsupported('解散群组'); + } + async transferGroup() { + this.unsupported('转让群组'); + } + async setGroupAdmins() { + this.unsupported('设置群管理员'); + } + async updateGroupProfile() { + this.unsupported('更新群资料'); + } + async kickGroupMembers() { + this.unsupported('移除群成员'); + } + async updateGroupMuteSetting() { + this.unsupported('群禁言设置'); + } + async updateProfile() { + this.unsupported('更新个人资料'); + } + async recallMessage() { + this.unsupported('撤回消息'); + } + async editMessage() { + this.unsupported('编辑消息'); + } + async getMessageDetail() { + this.unsupported('消息详情'); + } +} + +/***/ }), + +/***/ 5099: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Y: function() { return /* binding */ HttpImClient; } +/* harmony export */ }); +/* unused harmony export imClient */ +/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423); +/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4114); +/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8111); +/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2489); +/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3__); +/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(116); +/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4__); +/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7588); +/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_5__); +/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(1701); +/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_6__); +/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(3579); +/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_7__); +/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(5367); +/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_8__); +/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(2731); +/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_9__); +/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(7642); +/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_10__); +/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(8004); +/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_11__); +/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(3853); +/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_12__); +/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(5876); +/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_13__); +/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(2475); +/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_14___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_14__); +/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(5024); +/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_15__); +/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(1698); +/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_16___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_16__); +/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(2387); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(2169); +/* harmony import */ var _services_appServerClient__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(9311); + + + + + + + + + + + + + + + + + + + + +const LOCAL_MESSAGE_STORAGE_KEY = 'qmt-web-im-local-messages-v2'; +const LOCAL_HIDDEN_MESSAGE_STORAGE_KEY = 'qmt-web-im-hidden-messages-v1'; +const LOCAL_RECALLED_MESSAGE_STORAGE_KEY = 'qmt-web-im-recalled-messages-v1'; +function scopedStorageKey(baseKey, userId = '') { + const scope = `${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer || ''}:${userId || 'anonymous'}`; + return `${baseKey}:${encodeURIComponent(scope)}`; +} +function randomId() { + if (window.crypto && window.crypto.randomUUID) { + return window.crypto.randomUUID().replaceAll('-', ''); + } + return `${Date.now()}${Math.random().toString(16).slice(2)}`; +} +function readLocalMessages(userId) { + try { + return JSON.parse(localStorage.getItem(scopedStorageKey(LOCAL_MESSAGE_STORAGE_KEY, userId)) || '{}'); + } catch (error) { + return {}; + } +} +function readMessageSet(storageKey, userId) { + try { + return JSON.parse(localStorage.getItem(scopedStorageKey(storageKey, userId)) || '{}'); + } catch (error) { + return {}; + } +} +function writeMessageSet(storageKey, messagesByConversation, userId) { + localStorage.setItem(scopedStorageKey(storageKey, userId), JSON.stringify(messagesByConversation)); +} +function messageKeys(message) { + return [message?.id, message?.messageUid].filter(Boolean).map(value => String(value)); +} +function hasStoredMessage(storageKey, conversationId, message, userId) { + const stored = readMessageSet(storageKey, userId); + const ids = new Set(stored[conversationId] || []); + return messageKeys(message).some(id => ids.has(id)); +} +function storeMessageKeys(storageKey, conversationId, messages, userId) { + const stored = readMessageSet(storageKey, userId); + const ids = new Set(stored[conversationId] || []); + messages.forEach(message => { + messageKeys(message).forEach(id => ids.add(id)); + }); + stored[conversationId] = Array.from(ids); + writeMessageSet(storageKey, stored, userId); +} +function withRecalledState(message) { + return { + ...message, + status: 'recalled', + deliveryStatus: '', + recalled: true, + recallStatus: '已撤回' + }; +} +function applyLocalMessageState(conversationId, messages, userId) { + return messages.filter(message => !hasStoredMessage(LOCAL_HIDDEN_MESSAGE_STORAGE_KEY, conversationId, message, userId)).map(message => { + const isRecalled = Boolean(message.recalled) || message.status === 'recalled' || hasStoredMessage(LOCAL_RECALLED_MESSAGE_STORAGE_KEY, conversationId, message, userId); + if (!isRecalled) { + return message; + } + return withRecalledState(message); + }); +} +function writeLocalMessages(messagesByConversation, userId) { + localStorage.setItem(scopedStorageKey(LOCAL_MESSAGE_STORAGE_KEY, userId), JSON.stringify(messagesByConversation)); +} +function saveLocalMessage(message, userId) { + const messagesByConversation = readLocalMessages(userId); + messagesByConversation[message.conversationId] = messagesByConversation[message.conversationId] || []; + const index = messagesByConversation[message.conversationId].findIndex(item => item.id === message.id); + if (index >= 0) { + messagesByConversation[message.conversationId].splice(index, 1, message); + } else { + messagesByConversation[message.conversationId].push(message); + } + writeLocalMessages(messagesByConversation, userId); +} +function mergeSyncedMessages(localMessages, remoteMessages, conversationId, userId) { + const visibleLocalMessages = applyLocalMessageState(conversationId, localMessages, userId); + const localByKey = new Map(); + visibleLocalMessages.forEach(message => { + messageKeys(message).forEach(key => { + if (!localByKey.has(key)) { + localByKey.set(key, message); + } + }); + }); + const visibleRemoteMessages = applyLocalMessageState(conversationId, remoteMessages, userId).map(remoteMessage => { + if (!remoteMessage.recalled || String(remoteMessage.text || '').trim()) { + return remoteMessage; + } + const localMessage = messageKeys(remoteMessage).map(key => localByKey.get(key)).find(message => message?.text && message.text !== '你撤回了一条消息'); + return localMessage ? { + ...remoteMessage, + text: localMessage.text + } : remoteMessage; + }); + const remoteKeys = new Set(); + visibleRemoteMessages.forEach(message => { + messageKeys(message).forEach(key => remoteKeys.add(key)); + }); + const now = Date.now(); + function hasRemoteMatch(localMessage) { + if (localMessage.messageUid && remoteKeys.has(localMessage.messageUid)) { + return true; + } + return visibleRemoteMessages.some(remoteMessage => { + return remoteMessage.direction === localMessage.direction && remoteMessage.text === localMessage.text && Math.abs(Number(remoteMessage.timestamp || 0) - Number(localMessage.timestamp || 0)) < 15000; + }); + } + const pendingLocalMessages = visibleLocalMessages.filter(message => { + if (message.status === 'recalled' || message.recalled) { + return message.direction === 'out' && !hasRemoteMatch(message); + } + if (message.direction !== 'out') { + return false; + } + if (message.status === 'sent' && message.messageUid) { + return !hasRemoteMatch(message); + } + if (message.status === 'sent') { + return !hasRemoteMatch(message) && now - Number(message.timestamp || 0) < 30000; + } + return message.status === 'sending' || message.status === 'failed'; + }); + return [...visibleRemoteMessages, ...pendingLocalMessages].sort((a, b) => { + return Number(a.displayTimestamp || a.timestamp || 0) - Number(b.displayTimestamp || b.timestamp || 0); + }); +} +function getTitle(value, fallback) { + return value || fallback || ''; +} +function getUniqueEquipment(mobile, fallback) { + const allowedDevices = { + '18301902119': '67072d37062c4f31b1165073552933ba', + '18301902116': '1777479418113eeea8e236edce', + '18301902118': 'de89fb2f2a61480a8c381f6c16e28bd8', + '18301902117': 'd117f480faa64145b6162107b1b49617' + }; + return allowedDevices[mobile] || localStorage.getItem('uniqueEquipment') || fallback; +} +function canUseLocalLoginFallback(response) { + const message = response.data?.message || ''; + return false && 0; +} +class HttpImClient { + constructor() { + this.listeners = new Map(); + this.connected = false; + this.currentUser = null; + } + getClientId() { + let clientId = localStorage.getItem(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.clientIdStorageKey); + if (!clientId) { + clientId = randomId(); + localStorage.setItem(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.clientIdStorageKey, clientId); + } + return clientId; + } + restoreClientId(clientId) { + if (clientId) { + localStorage.setItem(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.clientIdStorageKey, clientId); + } + } + getSdkVersion() { + return 'HTTP'; + } + async ensureSdk() { + return true; + } + async loginWithPassword(mobile, password) { + const url = `${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/login_pwd`; + const deviceId = getUniqueEquipment(mobile, this.getClientId()); + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(url, { + mobile, + password, + platform: _config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.platform, + clientId: deviceId, + uniqueEquipment: deviceId + }, { + withCredentials: false + }); + this.persistAppToken(url, response); + if (response.data?.code !== 0) { + if (canUseLocalLoginFallback(response)) { + return { + userId: mobile, + token: `local-device-pending-${Date.now()}`, + displayName: mobile, + localOnly: true + }; + } + throw new Error(response.data?.message || '登录失败'); + } + return response.data.result; + } + async requestAuthCode(mobile) { + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(`${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/send_code`, { + mobile + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '验证码发送失败'); + } + return response.data.result; + } + async loginWithCode(mobile, code) { + const url = `${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/login`; + const deviceId = getUniqueEquipment(mobile, this.getClientId()); + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(url, { + mobile, + code, + platform: _config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.platform, + clientId: deviceId, + uniqueEquipment: deviceId + }, { + withCredentials: false + }); + this.persistAppToken(url, response); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '登录失败'); + } + return response.data.result; + } + async createPcSession(userId = '') { + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(`${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/pc_session`, { + flag: 1, + device_name: 'Web IM', + userId, + clientId: this.getClientId(), + platform: _config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.platform + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '二维码登录会话创建失败'); + } + return response.data.result || {}; + } + async loginWithPcSession(token) { + const url = `${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/session_login/${encodeURIComponent(token)}`; + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(url, null, { + withCredentials: false + }); + this.persistAppToken(url, response); + const data = response.data || {}; + if ([0, 8, 9, 10, 18].includes(Number(data.code))) { + return data; + } + throw new Error(data.message || '扫码登录失败'); + } + async registerWithPhone(mobile, code) { + const url = `${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/register`; + const deviceId = getUniqueEquipment(mobile, this.getClientId()); + try { + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(url, { + mobile, + code, + platform: _config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.platform, + clientId: deviceId, + uniqueEquipment: deviceId + }, { + withCredentials: false + }); + this.persistAppToken(url, response); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '注册失败'); + } + return response.data.result; + } catch (error) { + const status = error.response?.status; + if (status === 404 || status === 405) { + return this.loginWithCode(mobile, code); + } + throw error; + } + } + connect(userId, token) { + this.currentUser = { + userId, + token + }; + this.connected = true; + this.emit('connectionStatusChanged', { + connected: true, + statusText: '已连接' + }); + this.refreshConversationList(); + } + disconnect() { + this.connected = false; + this.currentUser = null; + this.emit('connectionStatusChanged', { + connected: false, + statusText: '未连接' + }); + } + getConversationList() { + return []; + } + refreshConversationList() { + const conversations = this.getConversationList(); + if (conversations.length) { + this.emit('conversationsChanged', conversations); + } + if (this.currentUser?.userId) { + this.fetchRemoteConversations().then(remoteConversations => { + this.emit('conversationsChanged', remoteConversations); + }).catch(() => {}); + } + return conversations; + } + async fetchRemoteConversations(limit = 50) { + if (!this.currentUser?.userId) { + return []; + } + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.messagesApi, { + userId: this.currentUser.userId, + limit + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '会话同步失败'); + } + return (response.data?.result?.conversations || []).map(conversation => ({ + ...conversation, + updatedAt: Number(conversation.updatedAt || Date.now()), + avatarText: conversation.avatarText || String(conversation.title || conversation.target || '?').slice(0, 1).toUpperCase(), + raw: conversation.raw || { + type: 'single', + target: conversation.target, + line: 0 + } + })); + } + getMessages(conversation) { + if (!conversation?.id) { + return []; + } + const userId = this.currentUser?.userId || ''; + return applyLocalMessageState(conversation.id, readLocalMessages(userId)[conversation.id] || [], userId); + } + async fetchRemoteMessages(conversation, limit = 50, options = {}) { + if (!conversation?.id || !this.currentUser?.userId) { + return []; + } + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.messagesApi, { + userId: this.currentUser.userId, + target: conversation.target || conversation.raw?.target || conversation.id.replace(/^single-/, ''), + limit, + conversationType: conversation.type || conversation.raw?.type || 0, + markRead: Boolean(options.markRead) + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '消息同步失败'); + } + const messages = (response.data?.result?.messages || []).map(message => ({ + ...message, + displayTimestamp: message.displayTimestamp || message.timestamp, + conversationId: conversation.id + })); + const userId = this.currentUser?.userId || ''; + const messagesByConversation = readLocalMessages(userId); + messagesByConversation[conversation.id] = mergeSyncedMessages(messagesByConversation[conversation.id] || [], messages, conversation.id, userId); + writeLocalMessages(messagesByConversation, userId); + return messagesByConversation[conversation.id]; + } + hideMessages(conversation, messages) { + const items = Array.isArray(messages) ? messages : [messages]; + if (!conversation?.id || !items.length) { + return; + } + const userId = this.currentUser?.userId || ''; + storeMessageKeys(LOCAL_HIDDEN_MESSAGE_STORAGE_KEY, conversation.id, items, userId); + const messagesByConversation = readLocalMessages(userId); + messagesByConversation[conversation.id] = applyLocalMessageState(conversation.id, messagesByConversation[conversation.id] || [], userId); + writeLocalMessages(messagesByConversation, userId); + } + markMessagesRecalled(conversation, messages) { + const items = Array.isArray(messages) ? messages : [messages]; + if (!conversation?.id || !items.length) { + return; + } + const userId = this.currentUser?.userId || ''; + storeMessageKeys(LOCAL_RECALLED_MESSAGE_STORAGE_KEY, conversation.id, items, userId); + const messagesByConversation = readLocalMessages(userId); + messagesByConversation[conversation.id] = applyLocalMessageState(conversation.id, messagesByConversation[conversation.id] || [], userId); + writeLocalMessages(messagesByConversation, userId); + } + async recallMessage(conversation, message) { + const messageUid = String(message?.messageUid || message?.id || '').trim(); + if (!/^\d+$/.test(messageUid)) { + throw new Error('缺少可撤回的消息ID'); + } + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.messageActionApi, { + action: 'recall', + userId: this.currentUser?.userId || message.from || '', + messageUid + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '撤回失败'); + } + this.markMessagesRecalled(conversation, [message]); + return response.data.result; + } + async editMessage(conversation, message, text) { + const messageUid = String(message?.messageUid || message?.id || '').trim(); + if (!/^\d+$/.test(messageUid)) { + throw new Error('缺少可编辑的消息ID'); + } + const nextText = String(text || '').trim(); + if (!nextText) { + throw new Error('编辑内容不能为空'); + } + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.messageActionApi, { + action: 'edit', + userId: this.currentUser?.userId || message.from || '', + messageUid, + text: nextText + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '编辑失败'); + } + const result = response.data?.result?.message || {}; + const editedMessage = { + ...message, + text: result.text || nextText, + status: 'delivered', + deliveryStatus: 'delivered', + editedAt: Number(result.editedAt || Date.now()), + activityTimestamp: Number(result.editedAt || Date.now()) + }; + saveLocalMessage(editedMessage, this.currentUser?.userId || ''); + this.emit('messageStatusChanged', editedMessage); + return editedMessage; + } + async getMessageDetail(conversation, message) { + const messageUid = String(message?.messageUid || message?.id || '').trim(); + if (!messageUid) { + throw new Error('缺少消息ID'); + } + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.messageDetailApi, { + userId: this.currentUser?.userId || '', + target: conversation?.target || conversation?.raw?.target || conversation?.id?.replace(/^single-/, '') || '', + conversationType: conversation?.type || conversation?.raw?.type || 'single', + messageUid + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '消息详情加载失败'); + } + return response.data?.result?.detail || null; + } + async sendTextMessage(conversation, text, initialMessage = null) { + const senderRole = conversation?.role || conversation?.raw?.role || ''; + const message = initialMessage || { + id: randomId(), + conversationId: conversation.id, + from: this.currentUser?.userId || 'me', + senderRole, + direction: 'out', + type: 'text', + text, + status: 'sending', + deliveryStatus: 'sending', + timestamp: Date.now() + }; + saveLocalMessage(message, this.currentUser?.userId || ''); + if (!initialMessage) { + this.emit('messageSent', message); + } + try { + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.sendMessageApi, { + sender: this.currentUser?.userId || '', + target: conversation.target || conversation.raw?.target || conversation.id.replace(/^single-/, ''), + conversationType: conversation.type || conversation.raw?.type || 0, + text + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '发送失败'); + } + const sentMessage = { + ...message, + status: 'sent', + deliveryStatus: 'sent', + messageUid: response.data?.result?.messageUid ? String(response.data.result.messageUid) : '', + senderRole: response.data?.result?.senderRole || message.senderRole || '', + serverTimestamp: Number(response.data?.result?.timestamp || 0) || null, + timestamp: message.timestamp, + displayTimestamp: message.displayTimestamp || message.timestamp + }; + saveLocalMessage(sentMessage, this.currentUser?.userId || ''); + this.emit('messageStatusChanged', sentMessage); + return sentMessage; + } catch (error) { + const failedMessage = { + ...message, + status: 'failed', + deliveryStatus: '', + error: error.response?.data?.message || error.message || '发送失败' + }; + saveLocalMessage(failedMessage, this.currentUser?.userId || ''); + this.emit('messageStatusChanged', failedMessage); + return failedMessage; + } + } + async sendAttachmentMessage(conversation, { + type, + file, + text = '' + }, initialMessage = null) { + const senderRole = conversation?.role || conversation?.raw?.role || ''; + const message = initialMessage || { + id: randomId(), + conversationId: conversation.id, + from: this.currentUser?.userId || 'me', + senderRole, + direction: 'out', + type, + text, + attachment: { + type, + name: file?.name || (type === 'image' ? '图片' : '文件'), + mime: file?.type || '', + size: file?.size || 0, + url: type === 'image' && file ? URL.createObjectURL(file) : '' + }, + status: 'sending', + deliveryStatus: 'sending', + timestamp: Date.now() + }; + saveLocalMessage(message, this.currentUser?.userId || ''); + if (!initialMessage) { + this.emit('messageSent', message); + } + try { + const formData = new FormData(); + formData.append('sender', this.currentUser?.userId || ''); + formData.append('target', conversation.target || conversation.raw?.target || conversation.id.replace(/^single-/, '')); + formData.append('conversationType', conversation.type || conversation.raw?.type || 0); + formData.append('messageType', type); + formData.append('text', text || ''); + formData.append('attachment', file); + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.sendMessageApi, formData, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '发送失败'); + } + const sentMessage = { + ...message, + status: 'sent', + deliveryStatus: 'sent', + messageUid: response.data?.result?.messageUid ? String(response.data.result.messageUid) : '', + senderRole: response.data?.result?.senderRole || message.senderRole || '', + attachment: response.data?.result?.attachment || message.attachment, + serverTimestamp: Number(response.data?.result?.timestamp || 0) || null, + timestamp: message.timestamp, + displayTimestamp: message.displayTimestamp || message.timestamp + }; + saveLocalMessage(sentMessage, this.currentUser?.userId || ''); + this.emit('messageStatusChanged', sentMessage); + return sentMessage; + } catch (error) { + const failedMessage = { + ...message, + status: 'failed', + deliveryStatus: '', + error: error.response?.data?.message || error.message || '发送失败' + }; + saveLocalMessage(failedMessage, this.currentUser?.userId || ''); + this.emit('messageStatusChanged', failedMessage); + return failedMessage; + } + } + getContactList() { + return []; + } + async getServerContactList(userId) { + if (!userId) { + return []; + } + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.contactsApi, { + userId + }, { + withCredentials: false, + headers: this.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.contactsApi) + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '联系人加载失败'); + } + return (response.data?.result?.contacts || []).map(item => { + return this.mapContact(item.uid, { + alias: item.alias + }, { + uid: item.uid, + displayName: item.displayName, + name: item.name, + mobile: item.mobile, + portrait: item.portrait, + address: item.address, + friendAlias: item.alias + }); + }).sort((a, b) => a.title.localeCompare(b.title, 'zh-CN')); + } + async addContact(userId, keyword, reason = '') { + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.addContactApi, { + userId, + keyword, + reason + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '添加联系人失败'); + } + const item = response.data?.result?.contact; + if (!item?.uid) { + return null; + } + return this.mapContact(item.uid, { + alias: item.alias + }, { + uid: item.uid, + displayName: item.displayName, + name: item.name, + mobile: item.mobile, + portrait: item.portrait, + address: item.address, + friendAlias: item.alias + }); + } + normalizeConversation(conversation) { + const title = getTitle(conversation?.title, conversation?.target || ''); + return { + ...conversation, + id: conversation?.id || `${conversation?.type === 'single' ? 'single' : 'group'}-${conversation?.target}`, + target: conversation?.target || conversation?.raw?.target || '', + title, + subtitle: conversation?.subtitle || '', + unread: Number(conversation?.unread || 0), + portrait: conversation?.portrait || '', + avatarText: conversation?.avatarText || title.slice(0, 1).toUpperCase(), + updatedAt: Number(conversation?.updatedAt || Date.now()), + raw: conversation?.raw || { + type: conversation?.type === 'single' ? 'single' : 'group', + target: conversation?.target || '', + line: 0 + } + }; + } + async createGroup(userId, { + name, + memberIds = [], + announcement = '', + welcomeText = '', + channel = false + }) { + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, { + action: channel ? 'create_channel' : 'create_group', + userId, + name, + memberIds, + announcement, + welcomeText + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || (channel ? '创建公告群失败' : '创建群组失败')); + } + return this.normalizeConversation(response.data?.result?.conversation || {}); + } + async joinGroup(userId, groupKey) { + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, { + action: 'join_group', + userId, + groupKey + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '加入群组失败'); + } + return this.normalizeConversation(response.data?.result?.conversation || {}); + } + async broadcastMessage(userId, targetIds, text) { + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, { + action: 'broadcast', + userId, + targetIds, + text + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '群发失败'); + } + return response.data?.result || {}; + } + async getGroupDetail(userId, groupId) { + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, { + action: 'group_detail', + userId, + groupId + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '群资料加载失败'); + } + return response.data?.result?.group || null; + } + async getGroupMembers(userId, groupId) { + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, { + action: 'group_members', + userId, + groupId + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '群员加载失败'); + } + return response.data?.result?.members || []; + } + async updateGroupAlias(userId, groupId, alias) { + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, { + action: 'update_group_alias', + userId, + groupId, + alias + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '本群昵称保存失败'); + } + return response.data?.result?.alias || ''; + } + async leaveGroup(userId, groupId) { + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, { + action: 'leave_group', + userId, + groupId + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '退出群组失败'); + } + return response.data?.result || {}; + } + async dismissGroup(userId, groupId) { + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, { + action: 'dismiss_group', + userId, + groupId + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '解散群组失败'); + } + return response.data?.result || {}; + } + async transferGroup(userId, groupId, targetUserId) { + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, { + action: 'transfer_group', + userId, + groupId, + targetUserId + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '转让群组失败'); + } + return response.data?.result || {}; + } + async setGroupAdmins(userId, groupId, adminIds) { + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, { + action: 'set_group_admins', + userId, + groupId, + adminIds + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '管理员设置失败'); + } + return response.data?.result || {}; + } + async updateGroupProfile(userId, groupId, { + name, + announcement, + welcomeText + }) { + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, { + action: 'update_group_profile', + userId, + groupId, + name, + announcement, + welcomeText + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '群资料保存失败'); + } + return response.data?.result || {}; + } + async kickGroupMembers(userId, groupId, targetIds) { + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, { + action: 'kick_group_members', + userId, + groupId, + targetIds + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '踢人失败'); + } + return response.data?.result || {}; + } + async updateGroupMuteSetting(userId, groupId, setting) { + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, { + action: 'update_mute_setting', + userId, + groupId, + ...setting + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '禁言设置保存失败'); + } + return response.data?.result?.muteSetting || null; + } + async updateContactAlias(userId, targetId, alias) { + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.updateAliasApi, { + userId, + targetId, + alias + }, { + withCredentials: false, + headers: this.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.updateAliasApi) + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '备注名修改失败'); + } + return response.data?.result?.contact?.alias || ''; + } + async getProfile(userId) { + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.profileApi, { + action: 'get', + userId + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '用户资料加载失败'); + } + return response.data?.result?.profile || null; + } + async updateProfile(userId, { + displayName, + portraitFile + }) { + const formData = new FormData(); + formData.append('action', 'update'); + formData.append('userId', userId); + formData.append('displayName', displayName); + if (portraitFile) { + formData.append('portraitFile', portraitFile); + } + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.profileApi, formData, { + withCredentials: false, + headers: this.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer) + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '用户资料保存失败'); + } + return response.data?.result?.profile || null; + } + async changePassword({ + oldPassword, + newPassword + }) { + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.changePasswordApi, { + oldPassword, + newPassword + }, { + withCredentials: false, + headers: this.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.changePasswordApi) + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || response.data?.msg || '密码修改失败'); + } + return true; + } + async resetPasswordWithCode({ + mobile, + resetCode, + newPassword + }) { + const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.resetPasswordApi, { + mobile, + resetCode, + newPassword + }, { + withCredentials: false + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || response.data?.msg || '密码设置失败'); + } + return true; + } + refreshContactList() { + const contacts = this.getContactList(); + this.emit('contactsChanged', contacts); + return contacts; + } + createSingleConversation(userId, userInfo = null) { + const title = getTitle(userInfo?.title || userInfo?.displayName || userInfo?.name, userId); + return { + id: `single-${userId}`, + type: 'single', + target: userId, + title, + subtitle: '', + unread: 0, + portrait: userInfo?.portrait || '', + avatarText: title.slice(0, 1).toUpperCase(), + updatedAt: Date.now(), + raw: { + type: 'single', + target: userId, + line: 0 + } + }; + } + mapContact(userId, friend, userInfo) { + const title = getTitle(userInfo?.friendAlias || friend?.alias || userInfo?.displayName || userInfo?.name, userId); + return { + id: userId, + uid: userId, + title, + subtitle: userInfo?.mobile || userInfo?.name || userId, + portrait: userInfo?.portrait || '', + address: userInfo?.address || '', + avatarText: title.slice(0, 1).toUpperCase(), + alias: friend?.alias || userInfo?.friendAlias || '', + rawFriend: friend, + rawUser: userInfo + }; + } + on(eventName, handler) { + if (!this.listeners.has(eventName)) { + this.listeners.set(eventName, new Set()); + } + this.listeners.get(eventName).add(handler); + return () => this.off(eventName, handler); + } + off(eventName, handler) { + this.listeners.get(eventName)?.delete(handler); + } + emit(eventName, payload) { + this.listeners.get(eventName)?.forEach(handler => handler(payload)); + } + persistAppToken(url, response) { + const appToken = response.headers?.authtoken || response.headers?.authToken; + if (appToken) { + localStorage.setItem(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.authTokenStoragePrefix + this.getUrlHost(url), appToken); + } + } + getAppAuthHeaders(url) { + const host = this.getUrlHost(url); + if (!host) { + return {}; + } + const token = localStorage.getItem(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.authTokenStoragePrefix + host); + return token ? { + authToken: token + } : {}; + } + getUrlHost(url) { + try { + return new URL(url, window.location.origin).host; + } catch (error) { + return ''; + } + } +} +const imClient = new HttpImClient(); + +/***/ }), + +/***/ 5051: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +/* unused harmony export WildfireImClient */ +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2169); +/* harmony import */ var _httpImClient__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5099); +/* harmony import */ var _longConnectionImClient__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3909); +/* harmony import */ var _documentedHttpImClient__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4355); + + + + +class UnsupportedWildfireImClient { + constructor() { + throw new Error('当前本地社区版 Web 客户端未启用 WildFire Web SDK'); + } +} +const imClient = _config__WEBPACK_IMPORTED_MODULE_0__/* .appConfig */ .U.sdkMode === 'wildfire' ? new UnsupportedWildfireImClient() : _config__WEBPACK_IMPORTED_MODULE_0__/* .appConfig */ .U.sdkMode === 'custom-ws' || _config__WEBPACK_IMPORTED_MODULE_0__/* .appConfig */ .U.sdkMode === 'long' ? new _longConnectionImClient__WEBPACK_IMPORTED_MODULE_2__/* .LongConnectionImClient */ .E() : new _documentedHttpImClient__WEBPACK_IMPORTED_MODULE_3__/* .DocumentedHttpImClient */ .u(); + +/* harmony export */ __webpack_require__.d(__webpack_exports__, [ +/* harmony export */ "wD", 0, /* binding */ imClient +/* harmony export */ ]); + + +/***/ }), + +/***/ 3909: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ E: function() { return /* binding */ LongConnectionImClient; } +/* harmony export */ }); +/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8111); +/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2489); +/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7588); +/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1701); +/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_3__); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(2169); +/* harmony import */ var _httpImClient__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(5099); + + + + + + +const HEARTBEAT_INTERVAL_MS = 25000; +const RECONNECT_MIN_MS = 1000; +const RECONNECT_MAX_MS = 15000; +function buildWsUrl() { + if (_config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.wsUrl) { + return _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.wsUrl; + } + const protocol = _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.useWss ? 'wss' : 'ws'; + const host = _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.imServerHost || window.location.hostname; + const port = _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.imRoutePort ? `:${_config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.imRoutePort}` : ''; + const path = _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.wsPath?.startsWith('/') ? _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.wsPath : `/${_config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.wsPath || 'ws'}`; + return `${protocol}://${host}${port}${path}`; +} +function normalizeConversationId(payload) { + const target = payload.target || payload.to || payload.receiver || payload.conversationTarget || payload.from || payload.sender; + return payload.conversationId || (target ? `single-${target}` : ''); +} +function normalizeIncomingMessage(payload, currentUserId) { + const item = payload.message || payload; + const from = item.from || item.sender || item.fromUser || ''; + const target = item.target || item.to || item.receiver || ''; + const direction = from && String(from) === String(currentUserId) ? 'out' : 'in'; + const conversationId = item.conversationId || normalizeConversationId({ + ...item, + target: direction === 'out' ? target : from + }); + if (!conversationId) { + return null; + } + const status = item.status || item.deliveryStatus || 'sent'; + return { + id: item.id || item.messageId || item.messageUid || `${Date.now()}${Math.random().toString(16).slice(2)}`, + messageUid: item.messageUid || item.uid || item.messageId || '', + conversationId, + from, + target, + direction, + type: item.type || 'text', + text: item.text || item.content || item.searchableContent || '', + status, + deliveryStatus: item.deliveryStatus || (direction === 'out' ? status : ''), + timestamp: Number(item.timestamp || item.serverTimestamp || Date.now()), + displayTimestamp: Number(item.displayTimestamp || item.timestamp || item.serverTimestamp || Date.now()), + raw: item + }; +} +class LongConnectionImClient extends _httpImClient__WEBPACK_IMPORTED_MODULE_5__/* .HttpImClient */ .Y { + constructor() { + super(); + this.socket = null; + this.wsUrl = buildWsUrl(); + this.heartbeatTimer = null; + this.reconnectTimer = null; + this.reconnectAttempts = 0; + this.manualClose = false; + } + getSdkVersion() { + return 'JC-LC/0.1'; + } + shouldUseMessagePolling() { + return !this.connected; + } + async ensureSdk() { + if (typeof WebSocket === 'undefined') { + throw new Error('当前浏览器不支持 WebSocket 长连接'); + } + return true; + } + connect(userId, token) { + this.currentUser = { + userId, + token + }; + this.manualClose = false; + this.openSocket(); + } + disconnect() { + this.manualClose = true; + this.clearReconnectTimer(); + this.clearHeartbeatTimer(); + if (this.socket) { + this.socket.close(); + this.socket = null; + } + super.disconnect(); + } + openSocket() { + if (this.socket?.readyState === WebSocket.OPEN) { + this.sendAuthFrame(); + return; + } + if (this.socket?.readyState === WebSocket.CONNECTING) { + return; + } + this.emit('connectionStatusChanged', { + connected: false, + statusText: '长连接连接中' + }); + try { + this.socket = new WebSocket(this.wsUrl); + this.socket.binaryType = 'arraybuffer'; + } catch (error) { + this.emit('connectionStatusChanged', { + connected: false, + statusText: '长连接创建失败,使用HTTP补偿' + }); + this.scheduleReconnect(); + return; + } + this.socket.onopen = () => { + this.connected = true; + this.reconnectAttempts = 0; + this.emit('connectionStatusChanged', { + connected: true, + statusText: '长连接已连接' + }); + this.sendAuthFrame(); + this.startHeartbeat(); + this.refreshConversationList(); + }; + this.socket.onmessage = event => { + this.handleFrame(event.data); + }; + this.socket.onerror = () => { + this.emit('connectionStatusChanged', { + connected: false, + statusText: '长连接异常,使用HTTP补偿' + }); + }; + this.socket.onclose = () => { + this.connected = false; + this.clearHeartbeatTimer(); + this.socket = null; + if (this.manualClose) { + return; + } + this.emit('connectionStatusChanged', { + connected: false, + statusText: '长连接重连中' + }); + this.scheduleReconnect(); + }; + } + sendAuthFrame() { + this.sendFrame({ + type: 'auth', + userId: this.currentUser?.userId || '', + token: this.currentUser?.token || '', + clientId: this.getClientId(), + platform: _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.platform, + timestamp: Date.now() + }); + } + sendFrame(frame) { + if (this.socket?.readyState !== WebSocket.OPEN) { + return false; + } + this.socket.send(JSON.stringify(frame)); + return true; + } + handleFrame(rawData) { + if (rawData instanceof ArrayBuffer) { + this.emit('rawFrameReceived', rawData); + return; + } + let payload; + try { + payload = typeof rawData === 'string' ? JSON.parse(rawData) : rawData; + } catch (error) { + return; + } + const type = payload.type || payload.event || payload.cmd || ''; + if (type === 'pong' || type === 'auth_ok' || type === 'connected') { + return; + } + if (type === 'contactsChanged') { + this.emit('contactsChanged', payload.contacts || []); + return; + } + if (type === 'conversationsChanged') { + this.emit('conversationsChanged', payload.conversations || []); + return; + } + if (type === 'messages' && Array.isArray(payload.messages)) { + payload.messages.map(message => normalizeIncomingMessage(message, this.currentUser?.userId)).filter(Boolean).forEach(message => this.emit('messageReceived', message)); + return; + } + const message = normalizeIncomingMessage(payload, this.currentUser?.userId); + if (message) { + this.emit(message.direction === 'out' ? 'messageStatusChanged' : 'messageReceived', message); + } + } + startHeartbeat() { + this.clearHeartbeatTimer(); + this.heartbeatTimer = window.setInterval(() => { + this.sendFrame({ + type: 'ping', + timestamp: Date.now() + }); + }, HEARTBEAT_INTERVAL_MS); + } + clearHeartbeatTimer() { + if (this.heartbeatTimer) { + window.clearInterval(this.heartbeatTimer); + this.heartbeatTimer = null; + } + } + scheduleReconnect() { + this.clearReconnectTimer(); + const delay = Math.min(RECONNECT_MAX_MS, RECONNECT_MIN_MS * 2 ** this.reconnectAttempts); + this.reconnectAttempts += 1; + this.reconnectTimer = window.setTimeout(() => { + this.openSocket(); + }, delay); + } + clearReconnectTimer() { + if (this.reconnectTimer) { + window.clearTimeout(this.reconnectTimer); + this.reconnectTimer = null; + } + } +} + +/***/ }), + +/***/ 926: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423); +/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var pinia__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2261); +/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5051); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2169); + + + + +const STORAGE_KEY = 'qmt-web-im-session'; +function normalizeStoredPortrait(portrait) { + return portrait || ''; +} +function nextProfilePortrait(profilePortrait, currentPortrait) { + return normalizeStoredPortrait(profilePortrait) || normalizeStoredPortrait(currentPortrait); +} +function inferAccountType(account) { + return String(account || '').includes('@') ? 2 : 1; +} +const useSessionStore = (0,pinia__WEBPACK_IMPORTED_MODULE_1__/* .defineStore */ .nY)('session', { + state: () => ({ + isAuthenticated: false, + connecting: false, + connected: false, + connectionStatusText: '未连接', + userId: '', + token: '', + displayName: '', + portrait: '', + error: '', + sdkVersion: '', + eventsBound: false + }), + actions: { + restore() { + const raw = localStorage.getItem(STORAGE_KEY); + if (!raw) { + return; + } + try { + const session = JSON.parse(raw); + if (session.appServer !== _config__WEBPACK_IMPORTED_MODULE_3__/* .appConfig */ .U.appServer) { + localStorage.removeItem(STORAGE_KEY); + return; + } + if (session.userId && session.token) { + if (!session.clientId) { + localStorage.removeItem(STORAGE_KEY); + return; + } + this.userId = session.userId; + this.token = session.token; + this.displayName = session.displayName || session.userId; + this.portrait = normalizeStoredPortrait(session.portrait); + this.isAuthenticated = true; + _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.restoreClientId(session.clientId); + this.connect(); + this.refreshProfile(); + } + } catch (error) { + localStorage.removeItem(STORAGE_KEY); + } + }, + async loginWithPassword(account, password, type = inferAccountType(account)) { + this.error = ''; + this.connecting = true; + try { + const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.loginWithPassword(account, password, type); + this.applyLoginResult(result); + await this.connect(); + } catch (error) { + this.error = error.message || '登录失败'; + } finally { + this.connecting = false; + } + }, + async loginWithCode(account, code) { + this.error = ''; + this.connecting = true; + try { + const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.loginWithCode(account, code); + this.applyLoginResult(result); + await this.connect(); + } catch (error) { + this.error = error.message || '登录失败'; + } finally { + this.connecting = false; + } + }, + async completePcSessionLogin(result) { + this.error = ''; + this.connecting = true; + try { + this.applyLoginResult(result); + await this.connect(); + } catch (error) { + this.error = error.message || '扫码登录失败'; + } finally { + this.connecting = false; + } + }, + async register(payload) { + this.error = ''; + this.connecting = true; + try { + const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.register(payload); + this.applyLoginResult(result); + await this.connect(); + return result; + } catch (error) { + this.error = error.message || '注册失败'; + return null; + } finally { + this.connecting = false; + } + }, + applyLoginResult(result) { + this.userId = result.userId || result.uid || result.id || ''; + this.token = result.token || result.imToken || ''; + this.displayName = result.displayName || result.userName || result.name || this.userId; + this.portrait = normalizeStoredPortrait(result.portrait); + this.isAuthenticated = Boolean(this.userId && this.token); + this.persistSession(); + }, + persistSession() { + localStorage.setItem(STORAGE_KEY, JSON.stringify({ + userId: this.userId, + token: this.token, + displayName: this.displayName, + portrait: this.portrait, + clientId: _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.getClientId(), + appServer: _config__WEBPACK_IMPORTED_MODULE_3__/* .appConfig */ .U.appServer + })); + }, + applyProfile(profile) { + if (!profile) { + return; + } + this.userId = profile.userId || profile.uid || this.userId; + this.displayName = profile.displayName || profile.name || this.displayName || this.userId; + this.portrait = nextProfilePortrait(profile.portrait, this.portrait); + this.persistSession(); + }, + async refreshProfile() { + if (!this.userId) { + return null; + } + try { + const profile = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.getProfile(this.userId); + this.applyProfile(profile); + return profile; + } catch (error) { + return null; + } + }, + async saveProfile({ + displayName, + portraitFile + }) { + if (!this.userId) { + throw new Error('请先登录'); + } + const profile = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.updateProfile(this.userId, { + displayName, + portraitFile + }); + this.applyProfile(profile); + return profile; + }, + async changePassword({ + oldPassword, + newPassword + }) { + if (!this.userId) { + throw new Error('请先登录'); + } + await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.changePassword({ + oldPassword, + newPassword + }); + await this.logout(); + return true; + }, + async resetPasswordWithCode({ + mobile, + resetCode, + newPassword + }) { + await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.resetPasswordWithCode({ + mobile, + resetCode, + newPassword + }); + return true; + }, + async connect() { + if (!this.userId || !this.token) { + return; + } + await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.ensureSdk(); + this.sdkVersion = _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.getSdkVersion(); + this.bindImEvents(); + await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.connect(this.userId, this.token); + }, + bindImEvents() { + if (this.eventsBound) { + return; + } + this.eventsBound = true; + _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.on('connectionStatusChanged', status => { + this.connected = status.connected; + this.connectionStatusText = status.statusText || (status.connected ? '已连接' : '未连接'); + }); + }, + async logout() { + try { + await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.logout?.(); + } catch (error) { + this.error = error.message || '退出登录失败'; + } finally { + _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.disconnect(); + localStorage.removeItem(STORAGE_KEY); + this.$reset(); + } + } + } +}); +/* harmony export */ __webpack_require__.d(__webpack_exports__, [ +/* harmony export */ "B", 0, /* binding */ useSessionStore +/* harmony export */ ]); + + +/***/ }), + +/***/ 7067: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +/* harmony import */ var _App_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4208); + + + +const __exports__ = _App_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A; + +/* harmony default export */ __webpack_exports__.A = (__exports__); + +/***/ }), + +/***/ 8409: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +/* harmony import */ var _DocumentedShell_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1106); + + + +const __exports__ = _DocumentedShell_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A; + +/* harmony default export */ __webpack_exports__.A = (__exports__); + +/***/ }), + +/***/ 3727: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +/* harmony import */ var _LoginView_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4524); + + + +const __exports__ = _LoginView_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A; + +/* harmony default export */ __webpack_exports__.A = (__exports__); + +/***/ }), + +/***/ 4208: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_App_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; } +/* harmony export */ }); +/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_App_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4677); + + +/***/ }), + +/***/ 1106: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_DocumentedShell_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; } +/* harmony export */ }); +/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_DocumentedShell_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(865); + + +/***/ }), + +/***/ 4524: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_LoginView_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; } +/* harmony export */ }); +/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_LoginView_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8607); + + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = __webpack_modules__; +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/chunk loaded */ +/******/ !function() { +/******/ var deferred = []; +/******/ __webpack_require__.O = function(result, chunkIds, fn, priority) { +/******/ if(chunkIds) { +/******/ priority = priority || 0; +/******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1]; +/******/ deferred[i] = [chunkIds, fn, priority]; +/******/ return; +/******/ } +/******/ var notFulfilled = Infinity; +/******/ for (var i = 0; i < deferred.length; i++) { +/******/ var chunkIds = deferred[i][0]; +/******/ var fn = deferred[i][1]; +/******/ var priority = deferred[i][2]; +/******/ var fulfilled = true; +/******/ for (var j = 0; j < chunkIds.length; j++) { +/******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) { +/******/ chunkIds.splice(j--, 1); +/******/ } else { +/******/ fulfilled = false; +/******/ if(priority < notFulfilled) notFulfilled = priority; +/******/ } +/******/ } +/******/ if(fulfilled) { +/******/ deferred.splice(i--, 1) +/******/ var r = fn(); +/******/ if (r !== undefined) result = r; +/******/ } +/******/ } +/******/ return result; +/******/ }; +/******/ }(); +/******/ +/******/ /* webpack/runtime/compat get default export */ +/******/ !function() { +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function() { return module['default']; } : +/******/ function() { return module; }; +/******/ __webpack_require__.d(getter, { a: getter }); +/******/ return getter; +/******/ }; +/******/ }(); +/******/ +/******/ /* webpack/runtime/define property getters */ +/******/ !function() { +/******/ // define getter/value functions for harmony exports +/******/ __webpack_require__.d = function(exports, definition) { +/******/ if(Array.isArray(definition)) { +/******/ var i = 0; +/******/ while(i < definition.length) { +/******/ var key = definition[i++]; +/******/ var binding = definition[i++]; +/******/ if(!__webpack_require__.o(exports, key)) { +/******/ if(binding === 0) { +/******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] }); +/******/ } else { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: binding }); +/******/ } +/******/ } else if(binding === 0) { i++; } +/******/ } +/******/ } else { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ } +/******/ }; +/******/ }(); +/******/ +/******/ /* webpack/runtime/global */ +/******/ !function() { +/******/ __webpack_require__.g = (function() { +/******/ if (typeof globalThis === 'object') return globalThis; +/******/ try { +/******/ return this || new Function('return this')(); +/******/ } catch (e) { +/******/ if (typeof window === 'object') return window; +/******/ } +/******/ })(); +/******/ }(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ !function() { +/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } +/******/ }(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ !function() { +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ }(); +/******/ +/******/ /* webpack/runtime/set anonymous default export name */ +/******/ !function() { +/******/ // set .name for anonymous default exports per ES spec +/******/ __webpack_require__.dn = function(x) { +/******/ (Object.getOwnPropertyDescriptor(x, "name") || {}).writable || Object.defineProperty(x, "name", { value: "default", configurable: true }); +/******/ }; +/******/ }(); +/******/ +/******/ /* webpack/runtime/jsonp chunk loading */ +/******/ !function() { +/******/ // no baseURI +/******/ +/******/ // object to store loaded and loading chunks +/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded +/******/ var installedChunks = { +/******/ 524: 0 +/******/ }; +/******/ +/******/ // no chunk on demand loading +/******/ +/******/ // no prefetching +/******/ +/******/ // no preloaded +/******/ +/******/ // no HMR +/******/ +/******/ // no HMR manifest +/******/ +/******/ __webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; }; +/******/ +/******/ // install a JSONP callback for chunk loading +/******/ var webpackJsonpCallback = function(parentChunkLoadingFunction, data) { +/******/ var chunkIds = data[0]; +/******/ var moreModules = data[1]; +/******/ var runtime = data[2]; +/******/ // add "moreModules" to the modules object, +/******/ // then flag all "chunkIds" as loaded and fire callback +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); +/******/ for(;i < chunkIds.length; i++) { +/******/ chunkId = chunkIds[i]; +/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { +/******/ installedChunks[chunkId][0](); +/******/ } +/******/ installedChunks[chunkId] = 0; +/******/ } +/******/ return __webpack_require__.O(result); +/******/ } +/******/ +/******/ var chunkLoadingGlobal = self["webpackChunkjc_web_im"] = self["webpackChunkjc_web_im"] || []; +/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); +/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); +/******/ }(); +/******/ +/************************************************************************/ +/******/ +/******/ // startup +/******/ // Load entry module and return exports +/******/ // This entry module depends on other loaded chunks and execution need to be delayed +/******/ var __webpack_exports__ = __webpack_require__.O(undefined, [504], function() { return __webpack_require__(1406); }) +/******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__); +/******/ +/******/ })() +; +//# sourceMappingURL=app.26bc1008.js.map \ No newline at end of file diff --git a/dist/js/app.26bc1008.js.map b/dist/js/app.26bc1008.js.map new file mode 100644 index 0000000..09c03b5 --- /dev/null +++ b/dist/js/app.26bc1008.js.map @@ -0,0 +1 @@ +{"version":3,"file":"js/app.26bc1008.js","mappings":"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K,kEAAQ,CAACka,UAAU,CAAC,CAAC;QACrB9N,YAAY,CAACmX,UAAU,CAACV,WAAW,CAAC;QACpC,IAAI,CAACiB,MAAM,CAAC,CAAC;MACf;IACF;EACF;AACF,CAAC,CAAC,C;;;;;;;;;;;;AChO+D;AACL;;AAE5D,oBAAoB,4FAAM;;AAE1B,sDAAe,W;;;;;;;;ACL8D;AACL;;AAExE,oBAAoB,wGAAM;;AAE1B,sDAAe,W;;;;;;;;ACLwD;AACL;;AAElE,oBAAoB,kGAAM;;AAE1B,sDAAe,W;;;;;;;;;;;ACLmO,C;;;;;;;;;;;ACAqB,C;;;;;;;;;;;ACAN,C;;;;;;UCAjQ;UACA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;;UAEA;UACA;;UAEA;UACA;UACA;;UAEA;UACA;;;;;WCzBA;WACA;WACA;WACA;WACA,+BAA+B,wCAAwC;WACvE;WACA;WACA;WACA;WACA,iBAAiB,qBAAqB;WACtC;WACA;WACA;WACA;WACA,kBAAkB,qBAAqB;WACvC,oHAAoH,iDAAiD;WACrK;WACA,KAAK;WACL;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA,E;;;;;WC7BA;WACA;WACA;WACA,eAAe,4BAA4B;WAC3C,eAAe;WACf,iCAAiC,WAAW;WAC5C;WACA,E;;;;;WCPA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA,2CAA2C,0CAA0C;WACrF,MAAM;WACN,2CAA2C,gCAAgC;WAC3E;WACA,KAAK,yBAAyB;WAC9B;WACA,GAAG;WACH;WACA;WACA,0CAA0C,wCAAwC;WAClF;WACA;WACA;WACA,E;;;;;WCtBA;WACA;WACA;WACA;WACA,GAAG;WACH;WACA;WACA,CAAC,I;;;;;WCPD,8CAA8C,yD;;;;;WCA9C;WACA;WACA;WACA,uDAAuD,iBAAiB;WACxE;WACA,gDAAgD,aAAa;WAC7D,E;;;;;WCNA;WACA;WACA,kDAAkD,iDAAiD,sCAAsC;WACzI,E;;;;;WCHA;;WAEA;WACA;WACA;WACA;WACA;WACA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA,8CAA8C;;WAE9C;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA,iCAAiC,mCAAmC;WACpE;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA,MAAM,qBAAqB;WAC3B;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;WAEA;WACA;WACA,4G;;;;;UElDA;UACA;UACA;UACA,+EAA+E,mCAAmC;UAClH","sources":["webpack://jc-web-im/./src/App.vue","webpack://jc-web-im/./src/components/DocumentedShell.vue","webpack://jc-web-im/./src/components/LoginView.vue","webpack://jc-web-im/./src/config.js","webpack://jc-web-im/./src/main.js","webpack://jc-web-im/./src/services/appServerClient.js","webpack://jc-web-im/./src/services/documentedHttpImClient.js","webpack://jc-web-im/./src/services/httpImClient.js","webpack://jc-web-im/./src/services/imClient.js","webpack://jc-web-im/./src/services/longConnectionImClient.js","webpack://jc-web-im/./src/stores/session.js","webpack://jc-web-im/./src/App.vue?7ccd","webpack://jc-web-im/./src/components/DocumentedShell.vue?4923","webpack://jc-web-im/./src/components/LoginView.vue?3311","webpack://jc-web-im/./src/App.vue?455b","webpack://jc-web-im/./src/components/DocumentedShell.vue?08ea","webpack://jc-web-im/./src/components/LoginView.vue?f595","webpack://jc-web-im/webpack/bootstrap","webpack://jc-web-im/webpack/runtime/chunk loaded","webpack://jc-web-im/webpack/runtime/compat get default export","webpack://jc-web-im/webpack/runtime/define property getters","webpack://jc-web-im/webpack/runtime/global","webpack://jc-web-im/webpack/runtime/hasOwnProperty shorthand","webpack://jc-web-im/webpack/runtime/make namespace object","webpack://jc-web-im/webpack/runtime/set anonymous default export name","webpack://jc-web-im/webpack/runtime/jsonp chunk loading","webpack://jc-web-im/webpack/before-startup","webpack://jc-web-im/webpack/startup","webpack://jc-web-im/webpack/after-startup"],"sourcesContent":["\n\n\n","\n\n\n","\n\n\n","const currentHost = window.location.hostname || '127.0.0.1';\nconst runtimeConfig = window.JC_WEB_IM_CONFIG || {};\nconst appServerOrigin = `${window.location.protocol}//${currentHost}:8888`;\nconst qrAppServerOrigin = `${window.location.protocol}//${currentHost}:18888`;\nconst adminServerOrigin = `${window.location.protocol}//${currentHost}:8024`;\n\r\nexport const appConfig = {\r\n appName: 'Web IM',\r\n adminServer: runtimeConfig.adminServer || process.env.VUE_APP_ADMIN_SERVER || adminServerOrigin,\n appServer: runtimeConfig.appServer || process.env.VUE_APP_APP_SERVER || appServerOrigin,\n qrAppServer: runtimeConfig.qrAppServer || process.env.VUE_APP_QR_APP_SERVER || qrAppServerOrigin,\n platformConfigApi: runtimeConfig.platformConfigApi || process.env.VUE_APP_PLATFORM_CONFIG_API || (process.env.NODE_ENV === 'development' ? '/local-api/platform_config.php' : '/api/platform_config.php'),\n registerConfigApi: runtimeConfig.registerConfigApi || process.env.VUE_APP_REGISTER_CONFIG_API || `${adminServerOrigin}/api/register-config`,\r\n registerPhoneExistsApi: runtimeConfig.registerPhoneExistsApi || process.env.VUE_APP_REGISTER_PHONE_EXISTS_API || `${adminServerOrigin}/api/register-phone-exists`,\r\n contactsApi: runtimeConfig.contactsApi || process.env.VUE_APP_CONTACTS_API || (process.env.NODE_ENV === 'development' ? '/local-api/contacts.php' : '/api/contacts.php'),\r\n updateAliasApi: runtimeConfig.updateAliasApi || process.env.VUE_APP_UPDATE_ALIAS_API || (process.env.NODE_ENV === 'development' ? '/local-api/update_alias.php' : '/api/update_alias.php'),\r\n addContactApi: runtimeConfig.addContactApi || process.env.VUE_APP_ADD_CONTACT_API || (process.env.NODE_ENV === 'development' ? '/local-api/add_contact.php' : '/api/add_contact.php'),\r\n conversationActionsApi: runtimeConfig.conversationActionsApi || process.env.VUE_APP_CONVERSATION_ACTIONS_API || (process.env.NODE_ENV === 'development' ? '/local-api/conversation_actions.php' : '/api/conversation_actions.php'),\r\n sendMessageApi: runtimeConfig.sendMessageApi || process.env.VUE_APP_SEND_MESSAGE_API || (process.env.NODE_ENV === 'development' ? '/local-api/send_message.php' : '/api/send_message.php'),\r\n messageActionApi: runtimeConfig.messageActionApi || process.env.VUE_APP_MESSAGE_ACTION_API || (process.env.NODE_ENV === 'development' ? '/local-api/message_action.php' : '/api/message_action.php'),\r\n messageDetailApi: runtimeConfig.messageDetailApi || process.env.VUE_APP_MESSAGE_DETAIL_API || (process.env.NODE_ENV === 'development' ? '/local-api/message_detail.php' : '/api/message_detail.php'),\r\n messagesApi: runtimeConfig.messagesApi || process.env.VUE_APP_MESSAGES_API || (process.env.NODE_ENV === 'development' ? '/local-api/messages.php' : '/api/messages.php'),\r\n profileApi: runtimeConfig.profileApi || process.env.VUE_APP_PROFILE_API || (process.env.NODE_ENV === 'development' ? '/local-api/profile.php' : '/api/profile.php'),\r\n changePasswordApi: runtimeConfig.changePasswordApi || process.env.VUE_APP_CHANGE_PASSWORD_API || `${appServerOrigin}/auth/changePassword`,\n logoutApi: runtimeConfig.logoutApi || process.env.VUE_APP_LOGOUT_API || `${appServerOrigin}/auth/logout`,\n imServerHost: runtimeConfig.imServerHost || process.env.VUE_APP_IM_SERVER_HOST || currentHost,\n imRoutePort: Number(runtimeConfig.imRoutePort || process.env.VUE_APP_IM_ROUTE_PORT || 18000),\r\n useWss: runtimeConfig.useWss ?? process.env.VUE_APP_USE_WSS === 'true',\n wsPath: runtimeConfig.wsPath || process.env.VUE_APP_WS_PATH || '/ws',\n wsUrl: runtimeConfig.wsUrl || process.env.VUE_APP_WS_URL || '',\n sdkMode: runtimeConfig.sdkMode || process.env.VUE_APP_IM_MODE || 'http',\n syncIntervalMs: Number(runtimeConfig.syncIntervalMs || process.env.VUE_APP_SYNC_INTERVAL_MS || 300),\n platform: 5,\n clientIdStorageKey: 'qmt-web-im-client-id',\n authTokenStoragePrefix: 'qmt-web-im-auth-token-'\n};\n","import { createApp } from 'vue';\r\nimport { createPinia } from 'pinia';\r\nimport App from './App.vue';\r\nimport './styles/base.css';\r\n\r\ncreateApp(App).use(createPinia()).mount('#app');\r\n","import axios from 'axios';\nimport { appConfig } from '@/config';\n\nconst AES_KEY = 'xczx2026!@#secKe';\nconst ENCRYPTION_EXCLUDE_PATHS = ['/avatar/', '/f/', '/amr2mp3', '/appVersion/check'];\nconst AUTH_STORAGE_KEY = 'qmt-web-im-app-auth-v1';\nconst AUTH_ERROR_CODE = 13;\nconst REFRESH_ERROR_CODE = 20045;\n\nlet importedCryptoKeyPromise = null;\nlet refreshPromise = null;\n\nfunction storageScope() {\n return appConfig.appServer || '';\n}\n\nfunction readAuthStore() {\n try {\n return JSON.parse(localStorage.getItem(AUTH_STORAGE_KEY) || '{}');\n } catch (error) {\n return {};\n }\n}\n\nfunction writeAuthStore(store) {\n localStorage.setItem(AUTH_STORAGE_KEY, JSON.stringify(store));\n}\n\nfunction normalizeAuthBundle(bundle = {}) {\n const accessToken = String(bundle.accessToken || '').trim();\n const refreshToken = String(bundle.refreshToken || '').trim();\n if (!accessToken || !refreshToken) {\n return null;\n }\n return {\n accessToken,\n refreshToken,\n tokenType: String(bundle.tokenType || 'Bearer').trim() || 'Bearer',\n accessTokenExpireIn: Number(bundle.accessTokenExpireIn || 0) || 0,\n accessTokenExpireAt: Number(bundle.accessTokenExpireAt || 0) || 0,\n refreshTokenExpireIn: Number(bundle.refreshTokenExpireIn || 0) || 0,\n refreshTokenExpireAt: Number(bundle.refreshTokenExpireAt || 0) || 0\n };\n}\n\nexport function getStoredAppAuth() {\n const store = readAuthStore();\n return normalizeAuthBundle(store[storageScope()]);\n}\n\nexport function persistAppAuth(bundle) {\n const normalized = normalizeAuthBundle(bundle);\n const store = readAuthStore();\n if (!normalized) {\n delete store[storageScope()];\n writeAuthStore(store);\n return null;\n }\n store[storageScope()] = normalized;\n writeAuthStore(store);\n return normalized;\n}\n\nexport function clearStoredAppAuth() {\n persistAppAuth(null);\n}\n\nfunction hasFormData(value) {\n return typeof FormData !== 'undefined' && value instanceof FormData;\n}\n\nfunction absoluteUrl(url) {\n return new URL(url, window.location.origin);\n}\n\nfunction shouldEncrypt(url) {\n const pathname = absoluteUrl(url).pathname;\n return !ENCRYPTION_EXCLUDE_PATHS.some(path => pathname === path || pathname.startsWith(path));\n}\n\nfunction shouldAttachAuth(config) {\n return !config.skipAuth;\n}\n\nfunction textEncoder() {\n return new TextEncoder();\n}\n\nfunction textDecoder() {\n return new TextDecoder();\n}\n\nfunction bytesToBase64(bytes) {\n let binary = '';\n bytes.forEach(byte => {\n binary += String.fromCharCode(byte);\n });\n return btoa(binary);\n}\n\nfunction base64ToBytes(base64) {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index);\n }\n return bytes;\n}\n\nasync function getCryptoKey() {\n if (!importedCryptoKeyPromise) {\n importedCryptoKeyPromise = window.crypto.subtle.importKey(\n 'raw',\n textEncoder().encode(AES_KEY),\n { name: 'AES-CBC' },\n false,\n ['encrypt', 'decrypt']\n );\n }\n return importedCryptoKeyPromise;\n}\n\nasync function encryptPayload(plainText) {\n const iv = window.crypto.getRandomValues(new Uint8Array(16));\n const key = await getCryptoKey();\n const encrypted = await window.crypto.subtle.encrypt(\n { name: 'AES-CBC', iv },\n key,\n textEncoder().encode(plainText)\n );\n return `${bytesToBase64(iv)}:${bytesToBase64(new Uint8Array(encrypted))}`;\n}\n\nasync function decryptPayload(cipherText) {\n const [ivBase64, encryptedBase64] = String(cipherText || '').split(':', 2);\n if (!ivBase64 || !encryptedBase64) {\n throw new Error('Encrypted payload format is invalid');\n }\n const key = await getCryptoKey();\n const decrypted = await window.crypto.subtle.decrypt(\n { name: 'AES-CBC', iv: base64ToBytes(ivBase64) },\n key,\n base64ToBytes(encryptedBase64)\n );\n return textDecoder().decode(decrypted);\n}\n\nfunction normalizeBusinessResponse(payload) {\n if (payload && typeof payload === 'object' && !Array.isArray(payload)) {\n return payload;\n }\n return {\n code: 0,\n message: 'success',\n data: payload\n };\n}\n\nasync function decodeResponsePayload(response) {\n const encrypted = String(response.headers?.['x-encrypted'] || '').toLowerCase() === 'true';\n if (encrypted && typeof response.data === 'string') {\n const plainText = await decryptPayload(response.data);\n response.data = normalizeBusinessResponse(JSON.parse(plainText));\n return response;\n }\n response.data = normalizeBusinessResponse(response.data);\n return response;\n}\n\nconst client = axios.create({\n withCredentials: false\n});\n\nclient.interceptors.request.use(async config => {\n const nextConfig = { ...config };\n const url = absoluteUrl(nextConfig.url || '').toString();\n\n if (shouldAttachAuth(nextConfig)) {\n const auth = getStoredAppAuth();\n if (auth?.accessToken) {\n nextConfig.headers = {\n ...(nextConfig.headers || {}),\n Authorization: `${auth.tokenType || 'Bearer'} ${auth.accessToken}`\n };\n }\n }\n\n if (!hasFormData(nextConfig.data) && nextConfig.method?.toLowerCase() !== 'get' && shouldEncrypt(url)) {\n const plainBody = JSON.stringify(nextConfig.data ?? {});\n nextConfig.data = await encryptPayload(plainBody);\n nextConfig.headers = {\n ...(nextConfig.headers || {}),\n 'Content-Type': 'text/plain;charset=UTF-8',\n 'X-Timestamp': `${Math.floor(Date.now() / 1000)}`\n };\n }\n\n return nextConfig;\n});\n\nclient.interceptors.response.use(async response => decodeResponsePayload(response));\n\nasync function refreshAccessToken() {\n if (refreshPromise) {\n return refreshPromise;\n }\n const auth = getStoredAppAuth();\n if (!auth?.refreshToken) {\n clearStoredAppAuth();\n throw new Error('登录状态已失效,请重新登录');\n }\n\n refreshPromise = client.post(`${appConfig.appServer}/auth/refreshToken`, {\n refreshToken: auth.refreshToken\n }, {\n skipAuth: true\n }).then(response => {\n const payload = response.data || {};\n if (Number(payload.code) !== 0 || !payload.data) {\n if (Number(payload.code) === REFRESH_ERROR_CODE) {\n clearStoredAppAuth();\n }\n throw new Error(payload.message || '刷新登录状态失败');\n }\n persistAppAuth(payload.data);\n return payload.data;\n }).finally(() => {\n refreshPromise = null;\n });\n\n return refreshPromise;\n}\n\nasync function request(config) {\n const response = await client.request(config);\n const payload = response.data || {};\n if (Number(payload.code) === AUTH_ERROR_CODE && shouldAttachAuth(config) && !config._retriedAfterRefresh) {\n await refreshAccessToken();\n return request({\n ...config,\n _retriedAfterRefresh: true\n });\n }\n return response;\n}\n\nexport async function appServerRequest(config) {\n return request(config);\n}\n\nexport async function appServerGet(url, config = {}) {\n return request({\n ...config,\n method: 'get',\n url\n });\n}\n\nexport async function appServerPost(url, data = {}, config = {}) {\n return request({\n ...config,\n method: 'post',\n url,\n data\n });\n}\n","import { appConfig } from '@/config';\nimport { HttpImClient } from './httpImClient';\nimport axios from 'axios';\nimport {\n appServerGet,\n appServerPost,\n clearStoredAppAuth,\n getStoredAppAuth,\n persistAppAuth\n} from './appServerClient';\n\nfunction inferAccountType(account) {\n return String(account || '').includes('@') ? 2 : 1;\n}\n\nfunction unwrapData(response) {\n return response.data?.data ?? response.data?.result ?? null;\n}\n\nfunction unwrapMessage(response, fallback) {\n return response.data?.message || response.data?.msg || fallback;\n}\n\nexport class DocumentedHttpImClient extends HttpImClient {\n unsupported(feature) {\n throw new Error(`当前对接文档未提供“${feature}”接口,已禁用旧本地代理链路`);\n }\n\n async loginWithPassword(account, password, type = inferAccountType(account)) {\n const response = await appServerPost(`${appConfig.appServer}/auth/login_pwd`, {\n type,\n number: account,\n password,\n platform: appConfig.platform,\n clientId: this.getClientId()\n }, {\n skipAuth: true\n });\n\n if (response.data?.code !== 0) {\n throw new Error(unwrapMessage(response, '登录失败'));\n }\n\n persistAppAuth(unwrapData(response));\n return unwrapData(response);\n }\n\n async requestAuthCode(email) {\n const response = await appServerPost(`${appConfig.appServer}/auth/sendEmailCode`, {\n email\n }, {\n skipAuth: true\n });\n\n if (response.data?.code !== 0) {\n throw new Error(unwrapMessage(response, '验证码发送失败'));\n }\n\n return unwrapData(response);\n }\n\n async loginWithCode(account, code) {\n void account;\n void code;\n throw new Error('接口文档未提供验证码登录接口,请使用密码登录');\n }\n\n async register({ type, number, code = '', password, invitationCode = '' }) {\n const response = await appServerPost(`${appConfig.appServer}/auth/register`, {\n type,\n number,\n code,\n password,\n clientId: this.getClientId(),\n platform: appConfig.platform,\n invitationCode\n }, {\n skipAuth: true\n });\n\n if (response.data?.code !== 0) {\n throw new Error(unwrapMessage(response, '注册失败'));\n }\n\n persistAppAuth(unwrapData(response));\n return unwrapData(response);\n }\n\n async createPcSession(userId = '') {\n const response = await axios.post(`${appConfig.qrAppServer}/pc_session`, {\n flag: 1,\n device_name: 'Web IM',\n userId,\n clientId: this.getClientId(),\n platform: appConfig.platform\n }, { withCredentials: false });\n\n if (response.data?.code !== 0) {\n throw new Error(unwrapMessage(response, '二维码登录会话创建失败'));\n }\n\n return unwrapData(response) || {};\n }\n\n async loginWithPcSession(token) {\n const url = `${appConfig.qrAppServer}/session_login/${encodeURIComponent(token)}`;\n let response;\n try {\n response = await axios.post(url, null, { withCredentials: false });\n } catch (postError) {\n response = await axios.get(url, { withCredentials: false });\n }\n\n this.persistAppToken(url, response);\n\n const payload = response.data || {};\n const result = payload.result ?? payload.data ?? null;\n\n if (Number(payload.code) === 0 && result) {\n persistAppAuth(result);\n }\n\n if ([0, 8, 9, 10, 13, 18, 20042].includes(Number(payload.code))) {\n return {\n ...payload,\n data: result\n };\n }\n\n throw new Error(payload.message || '扫码登录失败');\n }\n\n async changePassword({ oldPassword, newPassword }) {\n const response = await appServerPost(appConfig.changePasswordApi, {\n oldPassword,\n newPassword\n });\n\n if (response.data?.code !== 0) {\n throw new Error(unwrapMessage(response, '密码修改失败'));\n }\n\n return true;\n }\n\n async resetPasswordWithCode({ mobile, resetCode, newPassword }) {\n void mobile;\n void resetCode;\n void newPassword;\n throw new Error('接口文档未提供重置密码接口,请联系服务端确认流程');\n }\n\n async logout() {\n const auth = getStoredAppAuth();\n if (!auth?.refreshToken) {\n clearStoredAppAuth();\n return true;\n }\n\n try {\n const response = await appServerPost(appConfig.logoutApi, {\n refreshToken: auth.refreshToken\n });\n if (response.data?.code !== 0) {\n throw new Error(unwrapMessage(response, '退出登录失败'));\n }\n } finally {\n clearStoredAppAuth();\n }\n\n return true;\n }\n\n async fetchRemoteConversations() {\n return [];\n }\n\n async fetchRemoteMessages() {\n return [];\n }\n\n async getServerContactList() {\n return [];\n }\n\n async getProfile() {\n return null;\n }\n\n async sendTextMessage() {\n this.unsupported('发送消息');\n }\n\n async sendAttachmentMessage() {\n this.unsupported('发送附件消息');\n }\n\n async addContact() {\n this.unsupported('添加联系人');\n }\n\n async updateContactAlias() {\n this.unsupported('联系人备注');\n }\n\n async createGroup() {\n this.unsupported('创建群组');\n }\n\n async joinGroup() {\n this.unsupported('加入群组');\n }\n\n async broadcastMessage() {\n this.unsupported('群发消息');\n }\n\n async getGroupDetail() {\n this.unsupported('群详情');\n }\n\n async getGroupMembers() {\n this.unsupported('群成员');\n }\n\n async updateGroupAlias() {\n this.unsupported('群备注');\n }\n\n async leaveGroup() {\n this.unsupported('退出群组');\n }\n\n async dismissGroup() {\n this.unsupported('解散群组');\n }\n\n async transferGroup() {\n this.unsupported('转让群组');\n }\n\n async setGroupAdmins() {\n this.unsupported('设置群管理员');\n }\n\n async updateGroupProfile() {\n this.unsupported('更新群资料');\n }\n\n async kickGroupMembers() {\n this.unsupported('移除群成员');\n }\n\n async updateGroupMuteSetting() {\n this.unsupported('群禁言设置');\n }\n\n async updateProfile() {\n this.unsupported('更新个人资料');\n }\n\n async recallMessage() {\n this.unsupported('撤回消息');\n }\n\n async editMessage() {\n this.unsupported('编辑消息');\n }\n\n async getMessageDetail() {\n this.unsupported('消息详情');\n }\n}\n","import axios from 'axios';\nimport { appConfig } from '@/config';\nimport {\n appServerGet,\n appServerPost,\n clearStoredAppAuth,\n getStoredAppAuth,\n persistAppAuth\n} from '@/services/appServerClient';\n\r\nconst LOCAL_MESSAGE_STORAGE_KEY = 'qmt-web-im-local-messages-v2';\r\nconst LOCAL_HIDDEN_MESSAGE_STORAGE_KEY = 'qmt-web-im-hidden-messages-v1';\r\nconst LOCAL_RECALLED_MESSAGE_STORAGE_KEY = 'qmt-web-im-recalled-messages-v1';\r\n\r\nfunction scopedStorageKey(baseKey, userId = '') {\r\n const scope = `${appConfig.appServer || ''}:${userId || 'anonymous'}`;\r\n return `${baseKey}:${encodeURIComponent(scope)}`;\r\n}\r\n\r\nfunction randomId() {\r\n if (window.crypto && window.crypto.randomUUID) {\r\n return window.crypto.randomUUID().replaceAll('-', '');\r\n }\r\n return `${Date.now()}${Math.random().toString(16).slice(2)}`;\r\n}\r\n\r\nfunction readLocalMessages(userId) {\r\n try {\r\n return JSON.parse(localStorage.getItem(scopedStorageKey(LOCAL_MESSAGE_STORAGE_KEY, userId)) || '{}');\r\n } catch (error) {\r\n return {};\r\n }\r\n}\r\n\r\nfunction readMessageSet(storageKey, userId) {\r\n try {\r\n return JSON.parse(localStorage.getItem(scopedStorageKey(storageKey, userId)) || '{}');\r\n } catch (error) {\r\n return {};\r\n }\r\n}\r\n\r\nfunction writeMessageSet(storageKey, messagesByConversation, userId) {\r\n localStorage.setItem(scopedStorageKey(storageKey, userId), JSON.stringify(messagesByConversation));\r\n}\r\n\r\nfunction messageKeys(message) {\r\n return [message?.id, message?.messageUid]\r\n .filter(Boolean)\r\n .map(value => String(value));\r\n}\r\n\r\nfunction hasStoredMessage(storageKey, conversationId, message, userId) {\r\n const stored = readMessageSet(storageKey, userId);\r\n const ids = new Set(stored[conversationId] || []);\r\n return messageKeys(message).some(id => ids.has(id));\r\n}\r\n\r\nfunction storeMessageKeys(storageKey, conversationId, messages, userId) {\r\n const stored = readMessageSet(storageKey, userId);\r\n const ids = new Set(stored[conversationId] || []);\r\n messages.forEach(message => {\r\n messageKeys(message).forEach(id => ids.add(id));\r\n });\r\n stored[conversationId] = Array.from(ids);\r\n writeMessageSet(storageKey, stored, userId);\r\n}\r\n\r\nfunction withRecalledState(message) {\r\n return {\r\n ...message,\r\n status: 'recalled',\r\n deliveryStatus: '',\r\n recalled: true,\r\n recallStatus: '已撤回'\r\n };\r\n}\r\n\r\nfunction applyLocalMessageState(conversationId, messages, userId) {\r\n return messages\r\n .filter(message => !hasStoredMessage(LOCAL_HIDDEN_MESSAGE_STORAGE_KEY, conversationId, message, userId))\r\n .map(message => {\r\n const isRecalled = Boolean(message.recalled)\r\n || message.status === 'recalled'\r\n || hasStoredMessage(LOCAL_RECALLED_MESSAGE_STORAGE_KEY, conversationId, message, userId);\r\n if (!isRecalled) {\r\n return message;\r\n }\r\n return withRecalledState(message);\r\n });\r\n}\r\n\r\nfunction writeLocalMessages(messagesByConversation, userId) {\r\n localStorage.setItem(scopedStorageKey(LOCAL_MESSAGE_STORAGE_KEY, userId), JSON.stringify(messagesByConversation));\r\n}\r\n\r\nfunction saveLocalMessage(message, userId) {\r\n const messagesByConversation = readLocalMessages(userId);\r\n messagesByConversation[message.conversationId] = messagesByConversation[message.conversationId] || [];\r\n const index = messagesByConversation[message.conversationId].findIndex(item => item.id === message.id);\r\n if (index >= 0) {\r\n messagesByConversation[message.conversationId].splice(index, 1, message);\r\n } else {\r\n messagesByConversation[message.conversationId].push(message);\r\n }\r\n writeLocalMessages(messagesByConversation, userId);\r\n}\r\n\r\nfunction mergeSyncedMessages(localMessages, remoteMessages, conversationId, userId) {\r\n const visibleLocalMessages = applyLocalMessageState(conversationId, localMessages, userId);\r\n const localByKey = new Map();\r\n visibleLocalMessages.forEach(message => {\r\n messageKeys(message).forEach(key => {\r\n if (!localByKey.has(key)) {\r\n localByKey.set(key, message);\r\n }\r\n });\r\n });\r\n\r\n const visibleRemoteMessages = applyLocalMessageState(conversationId, remoteMessages, userId).map(remoteMessage => {\r\n if (!remoteMessage.recalled || String(remoteMessage.text || '').trim()) {\r\n return remoteMessage;\r\n }\r\n const localMessage = messageKeys(remoteMessage)\r\n .map(key => localByKey.get(key))\r\n .find(message => message?.text && message.text !== '你撤回了一条消息');\r\n return localMessage ? { ...remoteMessage, text: localMessage.text } : remoteMessage;\r\n });\r\n const remoteKeys = new Set();\r\n visibleRemoteMessages.forEach(message => {\r\n messageKeys(message).forEach(key => remoteKeys.add(key));\r\n });\r\n const now = Date.now();\r\n\r\n function hasRemoteMatch(localMessage) {\r\n if (localMessage.messageUid && remoteKeys.has(localMessage.messageUid)) {\r\n return true;\r\n }\r\n return visibleRemoteMessages.some(remoteMessage => {\r\n return remoteMessage.direction === localMessage.direction\r\n && remoteMessage.text === localMessage.text\r\n && Math.abs(Number(remoteMessage.timestamp || 0) - Number(localMessage.timestamp || 0)) < 15000;\r\n });\r\n }\r\n\r\n const pendingLocalMessages = visibleLocalMessages.filter(message => {\r\n if (message.status === 'recalled' || message.recalled) {\r\n return message.direction === 'out' && !hasRemoteMatch(message);\r\n }\r\n if (message.direction !== 'out') {\r\n return false;\r\n }\r\n if (message.status === 'sent' && message.messageUid) {\r\n return !hasRemoteMatch(message);\r\n }\r\n if (message.status === 'sent') {\r\n return !hasRemoteMatch(message) && now - Number(message.timestamp || 0) < 30000;\r\n }\r\n return message.status === 'sending' || message.status === 'failed';\r\n });\r\n\r\n return [...visibleRemoteMessages, ...pendingLocalMessages].sort((a, b) => {\r\n return Number(a.displayTimestamp || a.timestamp || 0) - Number(b.displayTimestamp || b.timestamp || 0);\r\n });\r\n}\r\n\r\nfunction getTitle(value, fallback) {\r\n return value || fallback || '';\r\n}\r\n\r\nfunction getUniqueEquipment(mobile, fallback) {\r\n const allowedDevices = {\r\n '18301902119': '67072d37062c4f31b1165073552933ba',\r\n '18301902116': '1777479418113eeea8e236edce',\r\n '18301902118': 'de89fb2f2a61480a8c381f6c16e28bd8',\r\n '18301902117': 'd117f480faa64145b6162107b1b49617'\r\n };\r\n return allowedDevices[mobile] || localStorage.getItem('uniqueEquipment') || fallback;\r\n}\r\n\r\nfunction canUseLocalLoginFallback(response) {\r\n const message = response.data?.message || '';\r\n return process.env.NODE_ENV === 'development' && message.includes('允许此设备登录');\r\n}\r\n\r\nexport class HttpImClient {\r\n constructor() {\r\n this.listeners = new Map();\r\n this.connected = false;\r\n this.currentUser = null;\r\n }\r\n\r\n getClientId() {\r\n let clientId = localStorage.getItem(appConfig.clientIdStorageKey);\r\n if (!clientId) {\r\n clientId = randomId();\r\n localStorage.setItem(appConfig.clientIdStorageKey, clientId);\r\n }\r\n return clientId;\r\n }\r\n\r\n restoreClientId(clientId) {\r\n if (clientId) {\r\n localStorage.setItem(appConfig.clientIdStorageKey, clientId);\r\n }\r\n }\r\n\r\n getSdkVersion() {\r\n return 'HTTP';\r\n }\r\n\r\n async ensureSdk() {\r\n return true;\r\n }\r\n\r\n async loginWithPassword(mobile, password) {\r\n const url = `${appConfig.appServer}/login_pwd`;\r\n const deviceId = getUniqueEquipment(mobile, this.getClientId());\r\n const response = await axios.post(url, {\r\n mobile,\r\n password,\r\n platform: appConfig.platform,\r\n clientId: deviceId,\r\n uniqueEquipment: deviceId\r\n }, { withCredentials: false });\r\n\r\n this.persistAppToken(url, response);\r\n if (response.data?.code !== 0) {\r\n if (canUseLocalLoginFallback(response)) {\r\n return {\r\n userId: mobile,\r\n token: `local-device-pending-${Date.now()}`,\r\n displayName: mobile,\r\n localOnly: true\r\n };\r\n }\r\n throw new Error(response.data?.message || '登录失败');\r\n }\r\n return response.data.result;\r\n }\r\n\r\n async requestAuthCode(mobile) {\r\n const response = await axios.post(`${appConfig.appServer}/send_code`, { mobile }, { withCredentials: false });\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '验证码发送失败');\r\n }\r\n return response.data.result;\r\n }\r\n\r\n async loginWithCode(mobile, code) {\r\n const url = `${appConfig.appServer}/login`;\r\n const deviceId = getUniqueEquipment(mobile, this.getClientId());\r\n const response = await axios.post(url, {\r\n mobile,\r\n code,\r\n platform: appConfig.platform,\r\n clientId: deviceId,\r\n uniqueEquipment: deviceId\r\n }, { withCredentials: false });\r\n\r\n this.persistAppToken(url, response);\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '登录失败');\r\n }\r\n return response.data.result;\r\n }\r\n\r\n async createPcSession(userId = '') {\r\n const response = await axios.post(`${appConfig.appServer}/pc_session`, {\r\n flag: 1,\r\n device_name: 'Web IM',\r\n userId,\r\n clientId: this.getClientId(),\r\n platform: appConfig.platform\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '二维码登录会话创建失败');\r\n }\r\n return response.data.result || {};\r\n }\r\n\r\n async loginWithPcSession(token) {\r\n const url = `${appConfig.appServer}/session_login/${encodeURIComponent(token)}`;\r\n const response = await axios.post(url, null, { withCredentials: false });\r\n this.persistAppToken(url, response);\r\n const data = response.data || {};\r\n if ([0, 8, 9, 10, 18].includes(Number(data.code))) {\r\n return data;\r\n }\r\n throw new Error(data.message || '扫码登录失败');\r\n }\r\n\r\n async registerWithPhone(mobile, code) {\r\n const url = `${appConfig.appServer}/register`;\r\n const deviceId = getUniqueEquipment(mobile, this.getClientId());\r\n\r\n try {\r\n const response = await axios.post(url, {\r\n mobile,\r\n code,\r\n platform: appConfig.platform,\r\n clientId: deviceId,\r\n uniqueEquipment: deviceId\r\n }, { withCredentials: false });\r\n\r\n this.persistAppToken(url, response);\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '注册失败');\r\n }\r\n return response.data.result;\r\n } catch (error) {\r\n const status = error.response?.status;\r\n if (status === 404 || status === 405) {\r\n return this.loginWithCode(mobile, code);\r\n }\r\n throw error;\r\n }\r\n }\r\n\r\n connect(userId, token) {\r\n this.currentUser = { userId, token };\r\n this.connected = true;\r\n this.emit('connectionStatusChanged', { connected: true, statusText: '已连接' });\r\n this.refreshConversationList();\r\n }\r\n\r\n disconnect() {\r\n this.connected = false;\r\n this.currentUser = null;\r\n this.emit('connectionStatusChanged', { connected: false, statusText: '未连接' });\r\n }\r\n\r\n getConversationList() {\r\n return [];\r\n }\r\n\r\n refreshConversationList() {\r\n const conversations = this.getConversationList();\r\n if (conversations.length) {\r\n this.emit('conversationsChanged', conversations);\r\n }\r\n if (this.currentUser?.userId) {\r\n this.fetchRemoteConversations().then(remoteConversations => {\r\n this.emit('conversationsChanged', remoteConversations);\r\n }).catch(() => {});\r\n }\r\n return conversations;\r\n }\r\n\r\n async fetchRemoteConversations(limit = 50) {\r\n if (!this.currentUser?.userId) {\r\n return [];\r\n }\r\n const response = await axios.post(appConfig.messagesApi, {\r\n userId: this.currentUser.userId,\r\n limit\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '会话同步失败');\r\n }\r\n\r\n return (response.data?.result?.conversations || []).map(conversation => ({\r\n ...conversation,\r\n updatedAt: Number(conversation.updatedAt || Date.now()),\r\n avatarText: conversation.avatarText || String(conversation.title || conversation.target || '?').slice(0, 1).toUpperCase(),\r\n raw: conversation.raw || { type: 'single', target: conversation.target, line: 0 }\r\n }));\r\n }\r\n\r\n getMessages(conversation) {\r\n if (!conversation?.id) {\r\n return [];\r\n }\r\n const userId = this.currentUser?.userId || '';\r\n return applyLocalMessageState(conversation.id, readLocalMessages(userId)[conversation.id] || [], userId);\r\n }\r\n\r\n async fetchRemoteMessages(conversation, limit = 50, options = {}) {\r\n if (!conversation?.id || !this.currentUser?.userId) {\r\n return [];\r\n }\r\n const response = await axios.post(appConfig.messagesApi, {\r\n userId: this.currentUser.userId,\r\n target: conversation.target || conversation.raw?.target || conversation.id.replace(/^single-/, ''),\r\n limit,\r\n conversationType: conversation.type || conversation.raw?.type || 0,\r\n markRead: Boolean(options.markRead)\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '消息同步失败');\r\n }\r\n\r\n const messages = (response.data?.result?.messages || []).map(message => ({\r\n ...message,\r\n displayTimestamp: message.displayTimestamp || message.timestamp,\r\n conversationId: conversation.id\r\n }));\r\n const userId = this.currentUser?.userId || '';\r\n const messagesByConversation = readLocalMessages(userId);\r\n messagesByConversation[conversation.id] = mergeSyncedMessages(messagesByConversation[conversation.id] || [], messages, conversation.id, userId);\r\n writeLocalMessages(messagesByConversation, userId);\r\n return messagesByConversation[conversation.id];\r\n }\r\n\r\n hideMessages(conversation, messages) {\r\n const items = Array.isArray(messages) ? messages : [messages];\r\n if (!conversation?.id || !items.length) {\r\n return;\r\n }\r\n const userId = this.currentUser?.userId || '';\r\n storeMessageKeys(LOCAL_HIDDEN_MESSAGE_STORAGE_KEY, conversation.id, items, userId);\r\n const messagesByConversation = readLocalMessages(userId);\r\n messagesByConversation[conversation.id] = applyLocalMessageState(\r\n conversation.id,\r\n messagesByConversation[conversation.id] || [],\r\n userId\r\n );\r\n writeLocalMessages(messagesByConversation, userId);\r\n }\r\n\r\n markMessagesRecalled(conversation, messages) {\r\n const items = Array.isArray(messages) ? messages : [messages];\r\n if (!conversation?.id || !items.length) {\r\n return;\r\n }\r\n const userId = this.currentUser?.userId || '';\r\n storeMessageKeys(LOCAL_RECALLED_MESSAGE_STORAGE_KEY, conversation.id, items, userId);\r\n const messagesByConversation = readLocalMessages(userId);\r\n messagesByConversation[conversation.id] = applyLocalMessageState(\r\n conversation.id,\r\n messagesByConversation[conversation.id] || [],\r\n userId\r\n );\r\n writeLocalMessages(messagesByConversation, userId);\r\n }\r\n\r\n async recallMessage(conversation, message) {\r\n const messageUid = String(message?.messageUid || message?.id || '').trim();\r\n if (!/^\\d+$/.test(messageUid)) {\r\n throw new Error('缺少可撤回的消息ID');\r\n }\r\n\r\n const response = await axios.post(appConfig.messageActionApi, {\r\n action: 'recall',\r\n userId: this.currentUser?.userId || message.from || '',\r\n messageUid\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '撤回失败');\r\n }\r\n this.markMessagesRecalled(conversation, [message]);\r\n return response.data.result;\r\n }\r\n\r\n async editMessage(conversation, message, text) {\r\n const messageUid = String(message?.messageUid || message?.id || '').trim();\r\n if (!/^\\d+$/.test(messageUid)) {\r\n throw new Error('缺少可编辑的消息ID');\r\n }\r\n const nextText = String(text || '').trim();\r\n if (!nextText) {\r\n throw new Error('编辑内容不能为空');\r\n }\r\n\r\n const response = await axios.post(appConfig.messageActionApi, {\r\n action: 'edit',\r\n userId: this.currentUser?.userId || message.from || '',\r\n messageUid,\r\n text: nextText\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '编辑失败');\r\n }\r\n\r\n const result = response.data?.result?.message || {};\r\n const editedMessage = {\r\n ...message,\r\n text: result.text || nextText,\r\n status: 'delivered',\r\n deliveryStatus: 'delivered',\r\n editedAt: Number(result.editedAt || Date.now()),\r\n activityTimestamp: Number(result.editedAt || Date.now())\r\n };\r\n saveLocalMessage(editedMessage, this.currentUser?.userId || '');\r\n this.emit('messageStatusChanged', editedMessage);\r\n return editedMessage;\r\n }\r\n\r\n async getMessageDetail(conversation, message) {\r\n const messageUid = String(message?.messageUid || message?.id || '').trim();\r\n if (!messageUid) {\r\n throw new Error('缺少消息ID');\r\n }\r\n const response = await axios.post(appConfig.messageDetailApi, {\r\n userId: this.currentUser?.userId || '',\r\n target: conversation?.target || conversation?.raw?.target || conversation?.id?.replace(/^single-/, '') || '',\r\n conversationType: conversation?.type || conversation?.raw?.type || 'single',\r\n messageUid\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '消息详情加载失败');\r\n }\r\n\r\n return response.data?.result?.detail || null;\r\n }\r\n\r\n async sendTextMessage(conversation, text, initialMessage = null) {\r\n const senderRole = conversation?.role || conversation?.raw?.role || '';\r\n const message = initialMessage || {\r\n id: randomId(),\r\n conversationId: conversation.id,\r\n from: this.currentUser?.userId || 'me',\r\n senderRole,\r\n direction: 'out',\r\n type: 'text',\r\n text,\r\n status: 'sending',\r\n deliveryStatus: 'sending',\r\n timestamp: Date.now()\r\n };\r\n saveLocalMessage(message, this.currentUser?.userId || '');\r\n if (!initialMessage) {\r\n this.emit('messageSent', message);\r\n }\r\n\r\n try {\r\n const response = await axios.post(appConfig.sendMessageApi, {\r\n sender: this.currentUser?.userId || '',\r\n target: conversation.target || conversation.raw?.target || conversation.id.replace(/^single-/, ''),\r\n conversationType: conversation.type || conversation.raw?.type || 0,\r\n text\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '发送失败');\r\n }\r\n\r\n const sentMessage = {\r\n ...message,\r\n status: 'sent',\r\n deliveryStatus: 'sent',\r\n messageUid: response.data?.result?.messageUid ? String(response.data.result.messageUid) : '',\r\n senderRole: response.data?.result?.senderRole || message.senderRole || '',\r\n serverTimestamp: Number(response.data?.result?.timestamp || 0) || null,\r\n timestamp: message.timestamp,\r\n displayTimestamp: message.displayTimestamp || message.timestamp\r\n };\r\n saveLocalMessage(sentMessage, this.currentUser?.userId || '');\r\n this.emit('messageStatusChanged', sentMessage);\r\n return sentMessage;\r\n } catch (error) {\r\n const failedMessage = {\r\n ...message,\r\n status: 'failed',\r\n deliveryStatus: '',\r\n error: error.response?.data?.message || error.message || '发送失败'\r\n };\r\n saveLocalMessage(failedMessage, this.currentUser?.userId || '');\r\n this.emit('messageStatusChanged', failedMessage);\r\n return failedMessage;\r\n }\r\n }\r\n\r\n async sendAttachmentMessage(conversation, { type, file, text = '' }, initialMessage = null) {\r\n const senderRole = conversation?.role || conversation?.raw?.role || '';\r\n const message = initialMessage || {\r\n id: randomId(),\r\n conversationId: conversation.id,\r\n from: this.currentUser?.userId || 'me',\r\n senderRole,\r\n direction: 'out',\r\n type,\r\n text,\r\n attachment: {\r\n type,\r\n name: file?.name || (type === 'image' ? '图片' : '文件'),\r\n mime: file?.type || '',\r\n size: file?.size || 0,\r\n url: type === 'image' && file ? URL.createObjectURL(file) : ''\r\n },\r\n status: 'sending',\r\n deliveryStatus: 'sending',\r\n timestamp: Date.now()\r\n };\r\n saveLocalMessage(message, this.currentUser?.userId || '');\r\n if (!initialMessage) {\r\n this.emit('messageSent', message);\r\n }\r\n\r\n try {\r\n const formData = new FormData();\r\n formData.append('sender', this.currentUser?.userId || '');\r\n formData.append('target', conversation.target || conversation.raw?.target || conversation.id.replace(/^single-/, ''));\r\n formData.append('conversationType', conversation.type || conversation.raw?.type || 0);\r\n formData.append('messageType', type);\r\n formData.append('text', text || '');\r\n formData.append('attachment', file);\r\n\r\n const response = await axios.post(appConfig.sendMessageApi, formData, {\r\n withCredentials: false\r\n });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '发送失败');\r\n }\r\n\r\n const sentMessage = {\r\n ...message,\r\n status: 'sent',\r\n deliveryStatus: 'sent',\r\n messageUid: response.data?.result?.messageUid ? String(response.data.result.messageUid) : '',\r\n senderRole: response.data?.result?.senderRole || message.senderRole || '',\r\n attachment: response.data?.result?.attachment || message.attachment,\r\n serverTimestamp: Number(response.data?.result?.timestamp || 0) || null,\r\n timestamp: message.timestamp,\r\n displayTimestamp: message.displayTimestamp || message.timestamp\r\n };\r\n saveLocalMessage(sentMessage, this.currentUser?.userId || '');\r\n this.emit('messageStatusChanged', sentMessage);\r\n return sentMessage;\r\n } catch (error) {\r\n const failedMessage = {\r\n ...message,\r\n status: 'failed',\r\n deliveryStatus: '',\r\n error: error.response?.data?.message || error.message || '发送失败'\r\n };\r\n saveLocalMessage(failedMessage, this.currentUser?.userId || '');\r\n this.emit('messageStatusChanged', failedMessage);\r\n return failedMessage;\r\n }\r\n }\r\n\r\n getContactList() {\r\n return [];\r\n }\r\n\r\n async getServerContactList(userId) {\r\n if (!userId) {\r\n return [];\r\n }\r\n const response = await axios.post(appConfig.contactsApi, { userId }, {\r\n withCredentials: false,\r\n headers: this.getAppAuthHeaders(appConfig.contactsApi)\r\n });\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '联系人加载失败');\r\n }\r\n return (response.data?.result?.contacts || []).map(item => {\r\n return this.mapContact(item.uid, { alias: item.alias }, {\r\n uid: item.uid,\r\n displayName: item.displayName,\r\n name: item.name,\r\n mobile: item.mobile,\r\n portrait: item.portrait,\r\n address: item.address,\r\n friendAlias: item.alias\r\n });\r\n }).sort((a, b) => a.title.localeCompare(b.title, 'zh-CN'));\r\n }\r\n\r\n async addContact(userId, keyword, reason = '') {\r\n const response = await axios.post(appConfig.addContactApi, {\r\n userId,\r\n keyword,\r\n reason\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '添加联系人失败');\r\n }\r\n\r\n const item = response.data?.result?.contact;\r\n if (!item?.uid) {\r\n return null;\r\n }\r\n\r\n return this.mapContact(item.uid, { alias: item.alias }, {\r\n uid: item.uid,\r\n displayName: item.displayName,\r\n name: item.name,\r\n mobile: item.mobile,\r\n portrait: item.portrait,\r\n address: item.address,\r\n friendAlias: item.alias\r\n });\r\n }\r\n\r\n normalizeConversation(conversation) {\r\n const title = getTitle(conversation?.title, conversation?.target || '');\r\n return {\r\n ...conversation,\r\n id: conversation?.id || `${conversation?.type === 'single' ? 'single' : 'group'}-${conversation?.target}`,\r\n target: conversation?.target || conversation?.raw?.target || '',\r\n title,\r\n subtitle: conversation?.subtitle || '',\r\n unread: Number(conversation?.unread || 0),\r\n portrait: conversation?.portrait || '',\r\n avatarText: conversation?.avatarText || title.slice(0, 1).toUpperCase(),\r\n updatedAt: Number(conversation?.updatedAt || Date.now()),\r\n raw: conversation?.raw || {\r\n type: conversation?.type === 'single' ? 'single' : 'group',\r\n target: conversation?.target || '',\r\n line: 0\r\n }\r\n };\r\n }\r\n\r\n async createGroup(userId, { name, memberIds = [], announcement = '', welcomeText = '', channel = false }) {\r\n const response = await axios.post(appConfig.conversationActionsApi, {\r\n action: channel ? 'create_channel' : 'create_group',\r\n userId,\r\n name,\r\n memberIds,\r\n announcement,\r\n welcomeText\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || (channel ? '创建公告群失败' : '创建群组失败'));\r\n }\r\n\r\n return this.normalizeConversation(response.data?.result?.conversation || {});\r\n }\r\n\r\n async joinGroup(userId, groupKey) {\r\n const response = await axios.post(appConfig.conversationActionsApi, {\r\n action: 'join_group',\r\n userId,\r\n groupKey\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '加入群组失败');\r\n }\r\n\r\n return this.normalizeConversation(response.data?.result?.conversation || {});\r\n }\r\n\r\n async broadcastMessage(userId, targetIds, text) {\r\n const response = await axios.post(appConfig.conversationActionsApi, {\r\n action: 'broadcast',\r\n userId,\r\n targetIds,\r\n text\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '群发失败');\r\n }\r\n\r\n return response.data?.result || {};\r\n }\r\n\r\n async getGroupDetail(userId, groupId) {\r\n const response = await axios.post(appConfig.conversationActionsApi, {\r\n action: 'group_detail',\r\n userId,\r\n groupId\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '群资料加载失败');\r\n }\r\n\r\n return response.data?.result?.group || null;\r\n }\r\n\r\n async getGroupMembers(userId, groupId) {\r\n const response = await axios.post(appConfig.conversationActionsApi, {\r\n action: 'group_members',\r\n userId,\r\n groupId\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '群员加载失败');\r\n }\r\n\r\n return response.data?.result?.members || [];\r\n }\r\n\r\n async updateGroupAlias(userId, groupId, alias) {\r\n const response = await axios.post(appConfig.conversationActionsApi, {\r\n action: 'update_group_alias',\r\n userId,\r\n groupId,\r\n alias\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '本群昵称保存失败');\r\n }\r\n\r\n return response.data?.result?.alias || '';\r\n }\r\n\r\n async leaveGroup(userId, groupId) {\r\n const response = await axios.post(appConfig.conversationActionsApi, {\r\n action: 'leave_group',\r\n userId,\r\n groupId\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '退出群组失败');\r\n }\r\n\r\n return response.data?.result || {};\r\n }\r\n\r\n async dismissGroup(userId, groupId) {\r\n const response = await axios.post(appConfig.conversationActionsApi, {\r\n action: 'dismiss_group',\r\n userId,\r\n groupId\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '解散群组失败');\r\n }\r\n\r\n return response.data?.result || {};\r\n }\r\n\r\n async transferGroup(userId, groupId, targetUserId) {\r\n const response = await axios.post(appConfig.conversationActionsApi, {\r\n action: 'transfer_group',\r\n userId,\r\n groupId,\r\n targetUserId\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '转让群组失败');\r\n }\r\n\r\n return response.data?.result || {};\r\n }\r\n\r\n async setGroupAdmins(userId, groupId, adminIds) {\r\n const response = await axios.post(appConfig.conversationActionsApi, {\r\n action: 'set_group_admins',\r\n userId,\r\n groupId,\r\n adminIds\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '管理员设置失败');\r\n }\r\n\r\n return response.data?.result || {};\r\n }\r\n\r\n async updateGroupProfile(userId, groupId, { name, announcement, welcomeText }) {\r\n const response = await axios.post(appConfig.conversationActionsApi, {\r\n action: 'update_group_profile',\r\n userId,\r\n groupId,\r\n name,\r\n announcement,\r\n welcomeText\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '群资料保存失败');\r\n }\r\n\r\n return response.data?.result || {};\r\n }\r\n\r\n async kickGroupMembers(userId, groupId, targetIds) {\r\n const response = await axios.post(appConfig.conversationActionsApi, {\r\n action: 'kick_group_members',\r\n userId,\r\n groupId,\r\n targetIds\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '踢人失败');\r\n }\r\n\r\n return response.data?.result || {};\r\n }\r\n\r\n async updateGroupMuteSetting(userId, groupId, setting) {\r\n const response = await axios.post(appConfig.conversationActionsApi, {\r\n action: 'update_mute_setting',\r\n userId,\r\n groupId,\r\n ...setting\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '禁言设置保存失败');\r\n }\r\n\r\n return response.data?.result?.muteSetting || null;\r\n }\r\n\r\n async updateContactAlias(userId, targetId, alias) {\r\n const response = await axios.post(appConfig.updateAliasApi, {\r\n userId,\r\n targetId,\r\n alias\r\n }, {\r\n withCredentials: false,\r\n headers: this.getAppAuthHeaders(appConfig.updateAliasApi)\r\n });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '备注名修改失败');\r\n }\r\n\r\n return response.data?.result?.contact?.alias || '';\r\n }\r\n\r\n async getProfile(userId) {\r\n const response = await axios.post(appConfig.profileApi, {\r\n action: 'get',\r\n userId\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '用户资料加载失败');\r\n }\r\n\r\n return response.data?.result?.profile || null;\r\n }\r\n\r\n async updateProfile(userId, { displayName, portraitFile }) {\r\n const formData = new FormData();\r\n formData.append('action', 'update');\r\n formData.append('userId', userId);\r\n formData.append('displayName', displayName);\r\n if (portraitFile) {\r\n formData.append('portraitFile', portraitFile);\r\n }\r\n\r\n const response = await axios.post(appConfig.profileApi, formData, {\r\n withCredentials: false,\r\n headers: this.getAppAuthHeaders(appConfig.appServer)\r\n });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || '用户资料保存失败');\r\n }\r\n\r\n return response.data?.result?.profile || null;\r\n }\r\n\r\n async changePassword({ oldPassword, newPassword }) {\r\n const response = await axios.post(appConfig.changePasswordApi, {\r\n oldPassword,\r\n newPassword\r\n }, {\r\n withCredentials: false,\r\n headers: this.getAppAuthHeaders(appConfig.changePasswordApi)\r\n });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || response.data?.msg || '密码修改失败');\r\n }\r\n\r\n return true;\r\n }\r\n\r\n async resetPasswordWithCode({ mobile, resetCode, newPassword }) {\r\n const response = await axios.post(appConfig.resetPasswordApi, {\r\n mobile,\r\n resetCode,\r\n newPassword\r\n }, { withCredentials: false });\r\n\r\n if (response.data?.code !== 0) {\r\n throw new Error(response.data?.message || response.data?.msg || '密码设置失败');\r\n }\r\n\r\n return true;\r\n }\r\n\r\n refreshContactList() {\r\n const contacts = this.getContactList();\r\n this.emit('contactsChanged', contacts);\r\n return contacts;\r\n }\r\n\r\n createSingleConversation(userId, userInfo = null) {\r\n const title = getTitle(userInfo?.title || userInfo?.displayName || userInfo?.name, userId);\r\n return {\r\n id: `single-${userId}`,\r\n type: 'single',\r\n target: userId,\r\n title,\r\n subtitle: '',\r\n unread: 0,\r\n portrait: userInfo?.portrait || '',\r\n avatarText: title.slice(0, 1).toUpperCase(),\r\n updatedAt: Date.now(),\r\n raw: { type: 'single', target: userId, line: 0 }\r\n };\r\n }\r\n\r\n mapContact(userId, friend, userInfo) {\r\n const title = getTitle(userInfo?.friendAlias || friend?.alias || userInfo?.displayName || userInfo?.name, userId);\r\n return {\r\n id: userId,\r\n uid: userId,\r\n title,\r\n subtitle: userInfo?.mobile || userInfo?.name || userId,\r\n portrait: userInfo?.portrait || '',\r\n address: userInfo?.address || '',\r\n avatarText: title.slice(0, 1).toUpperCase(),\r\n alias: friend?.alias || userInfo?.friendAlias || '',\r\n rawFriend: friend,\r\n rawUser: userInfo\r\n };\r\n }\r\n\r\n on(eventName, handler) {\r\n if (!this.listeners.has(eventName)) {\r\n this.listeners.set(eventName, new Set());\r\n }\r\n this.listeners.get(eventName).add(handler);\r\n return () => this.off(eventName, handler);\r\n }\r\n\r\n off(eventName, handler) {\r\n this.listeners.get(eventName)?.delete(handler);\r\n }\r\n\r\n emit(eventName, payload) {\r\n this.listeners.get(eventName)?.forEach(handler => handler(payload));\r\n }\r\n\r\n persistAppToken(url, response) {\r\n const appToken = response.headers?.authtoken || response.headers?.authToken;\r\n if (appToken) {\r\n localStorage.setItem(appConfig.authTokenStoragePrefix + this.getUrlHost(url), appToken);\r\n }\r\n }\r\n\r\n getAppAuthHeaders(url) {\r\n const host = this.getUrlHost(url);\r\n if (!host) {\r\n return {};\r\n }\r\n const token = localStorage.getItem(appConfig.authTokenStoragePrefix + host);\r\n return token ? { authToken: token } : {};\r\n }\r\n\r\n getUrlHost(url) {\r\n try {\r\n return new URL(url, window.location.origin).host;\r\n } catch (error) {\r\n return '';\r\n }\r\n }\r\n}\r\n\r\nexport const imClient = new HttpImClient();\r\n","import { appConfig } from '@/config';\nimport { HttpImClient } from './httpImClient';\nimport { LongConnectionImClient } from './longConnectionImClient';\nimport { DocumentedHttpImClient } from './documentedHttpImClient';\n\r\nclass UnsupportedWildfireImClient {\r\n constructor() {\r\n throw new Error('当前本地社区版 Web 客户端未启用 WildFire Web SDK');\r\n }\r\n}\r\n\r\nexport const imClient = appConfig.sdkMode === 'wildfire'\n ? new UnsupportedWildfireImClient()\n : appConfig.sdkMode === 'custom-ws' || appConfig.sdkMode === 'long'\n ? new LongConnectionImClient()\n : new DocumentedHttpImClient();\n\nexport {\n DocumentedHttpImClient,\n HttpImClient,\n LongConnectionImClient,\n UnsupportedWildfireImClient as WildfireImClient\n};\n","import { appConfig } from '@/config';\r\nimport { HttpImClient } from './httpImClient';\r\n\r\nconst HEARTBEAT_INTERVAL_MS = 25000;\r\nconst RECONNECT_MIN_MS = 1000;\r\nconst RECONNECT_MAX_MS = 15000;\r\n\r\nfunction buildWsUrl() {\r\n if (appConfig.wsUrl) {\r\n return appConfig.wsUrl;\r\n }\r\n const protocol = appConfig.useWss ? 'wss' : 'ws';\r\n const host = appConfig.imServerHost || window.location.hostname;\r\n const port = appConfig.imRoutePort ? `:${appConfig.imRoutePort}` : '';\r\n const path = appConfig.wsPath?.startsWith('/') ? appConfig.wsPath : `/${appConfig.wsPath || 'ws'}`;\r\n return `${protocol}://${host}${port}${path}`;\r\n}\r\n\r\nfunction normalizeConversationId(payload) {\r\n const target = payload.target || payload.to || payload.receiver || payload.conversationTarget || payload.from || payload.sender;\r\n return payload.conversationId || (target ? `single-${target}` : '');\r\n}\r\n\r\nfunction normalizeIncomingMessage(payload, currentUserId) {\r\n const item = payload.message || payload;\r\n const from = item.from || item.sender || item.fromUser || '';\r\n const target = item.target || item.to || item.receiver || '';\r\n const direction = from && String(from) === String(currentUserId) ? 'out' : 'in';\r\n const conversationId = item.conversationId || normalizeConversationId({\r\n ...item,\r\n target: direction === 'out' ? target : from\r\n });\r\n\r\n if (!conversationId) {\r\n return null;\r\n }\r\n\r\n const status = item.status || item.deliveryStatus || 'sent';\r\n\r\n return {\r\n id: item.id || item.messageId || item.messageUid || `${Date.now()}${Math.random().toString(16).slice(2)}`,\r\n messageUid: item.messageUid || item.uid || item.messageId || '',\r\n conversationId,\r\n from,\r\n target,\r\n direction,\r\n type: item.type || 'text',\r\n text: item.text || item.content || item.searchableContent || '',\r\n status,\r\n deliveryStatus: item.deliveryStatus || (direction === 'out' ? status : ''),\r\n timestamp: Number(item.timestamp || item.serverTimestamp || Date.now()),\r\n displayTimestamp: Number(item.displayTimestamp || item.timestamp || item.serverTimestamp || Date.now()),\r\n raw: item\r\n };\r\n}\r\n\r\nexport class LongConnectionImClient extends HttpImClient {\r\n constructor() {\r\n super();\r\n this.socket = null;\r\n this.wsUrl = buildWsUrl();\r\n this.heartbeatTimer = null;\r\n this.reconnectTimer = null;\r\n this.reconnectAttempts = 0;\r\n this.manualClose = false;\r\n }\r\n\r\n getSdkVersion() {\r\n return 'JC-LC/0.1';\r\n }\r\n\r\n shouldUseMessagePolling() {\r\n return !this.connected;\r\n }\r\n\r\n async ensureSdk() {\r\n if (typeof WebSocket === 'undefined') {\r\n throw new Error('当前浏览器不支持 WebSocket 长连接');\r\n }\r\n return true;\r\n }\r\n\r\n connect(userId, token) {\r\n this.currentUser = { userId, token };\r\n this.manualClose = false;\r\n this.openSocket();\r\n }\r\n\r\n disconnect() {\r\n this.manualClose = true;\r\n this.clearReconnectTimer();\r\n this.clearHeartbeatTimer();\r\n if (this.socket) {\r\n this.socket.close();\r\n this.socket = null;\r\n }\r\n super.disconnect();\r\n }\r\n\r\n openSocket() {\r\n if (this.socket?.readyState === WebSocket.OPEN) {\r\n this.sendAuthFrame();\r\n return;\r\n }\r\n if (this.socket?.readyState === WebSocket.CONNECTING) {\r\n return;\r\n }\r\n\r\n this.emit('connectionStatusChanged', { connected: false, statusText: '长连接连接中' });\r\n\r\n try {\r\n this.socket = new WebSocket(this.wsUrl);\r\n this.socket.binaryType = 'arraybuffer';\r\n } catch (error) {\r\n this.emit('connectionStatusChanged', { connected: false, statusText: '长连接创建失败,使用HTTP补偿' });\r\n this.scheduleReconnect();\r\n return;\r\n }\r\n\r\n this.socket.onopen = () => {\r\n this.connected = true;\r\n this.reconnectAttempts = 0;\r\n this.emit('connectionStatusChanged', { connected: true, statusText: '长连接已连接' });\r\n this.sendAuthFrame();\r\n this.startHeartbeat();\r\n this.refreshConversationList();\r\n };\r\n\r\n this.socket.onmessage = event => {\r\n this.handleFrame(event.data);\r\n };\r\n\r\n this.socket.onerror = () => {\r\n this.emit('connectionStatusChanged', { connected: false, statusText: '长连接异常,使用HTTP补偿' });\r\n };\r\n\r\n this.socket.onclose = () => {\r\n this.connected = false;\r\n this.clearHeartbeatTimer();\r\n this.socket = null;\r\n if (this.manualClose) {\r\n return;\r\n }\r\n this.emit('connectionStatusChanged', { connected: false, statusText: '长连接重连中' });\r\n this.scheduleReconnect();\r\n };\r\n }\r\n\r\n sendAuthFrame() {\r\n this.sendFrame({\r\n type: 'auth',\r\n userId: this.currentUser?.userId || '',\r\n token: this.currentUser?.token || '',\r\n clientId: this.getClientId(),\r\n platform: appConfig.platform,\r\n timestamp: Date.now()\r\n });\r\n }\r\n\r\n sendFrame(frame) {\r\n if (this.socket?.readyState !== WebSocket.OPEN) {\r\n return false;\r\n }\r\n this.socket.send(JSON.stringify(frame));\r\n return true;\r\n }\r\n\r\n handleFrame(rawData) {\r\n if (rawData instanceof ArrayBuffer) {\r\n this.emit('rawFrameReceived', rawData);\r\n return;\r\n }\r\n\r\n let payload;\r\n try {\r\n payload = typeof rawData === 'string' ? JSON.parse(rawData) : rawData;\r\n } catch (error) {\r\n return;\r\n }\r\n\r\n const type = payload.type || payload.event || payload.cmd || '';\r\n if (type === 'pong' || type === 'auth_ok' || type === 'connected') {\r\n return;\r\n }\r\n if (type === 'contactsChanged') {\r\n this.emit('contactsChanged', payload.contacts || []);\r\n return;\r\n }\r\n if (type === 'conversationsChanged') {\r\n this.emit('conversationsChanged', payload.conversations || []);\r\n return;\r\n }\r\n if (type === 'messages' && Array.isArray(payload.messages)) {\r\n payload.messages\r\n .map(message => normalizeIncomingMessage(message, this.currentUser?.userId))\r\n .filter(Boolean)\r\n .forEach(message => this.emit('messageReceived', message));\r\n return;\r\n }\r\n\r\n const message = normalizeIncomingMessage(payload, this.currentUser?.userId);\r\n if (message) {\r\n this.emit(message.direction === 'out' ? 'messageStatusChanged' : 'messageReceived', message);\r\n }\r\n }\r\n\r\n startHeartbeat() {\r\n this.clearHeartbeatTimer();\r\n this.heartbeatTimer = window.setInterval(() => {\r\n this.sendFrame({ type: 'ping', timestamp: Date.now() });\r\n }, HEARTBEAT_INTERVAL_MS);\r\n }\r\n\r\n clearHeartbeatTimer() {\r\n if (this.heartbeatTimer) {\r\n window.clearInterval(this.heartbeatTimer);\r\n this.heartbeatTimer = null;\r\n }\r\n }\r\n\r\n scheduleReconnect() {\r\n this.clearReconnectTimer();\r\n const delay = Math.min(RECONNECT_MAX_MS, RECONNECT_MIN_MS * 2 ** this.reconnectAttempts);\r\n this.reconnectAttempts += 1;\r\n this.reconnectTimer = window.setTimeout(() => {\r\n this.openSocket();\r\n }, delay);\r\n }\r\n\r\n clearReconnectTimer() {\r\n if (this.reconnectTimer) {\r\n window.clearTimeout(this.reconnectTimer);\r\n this.reconnectTimer = null;\r\n }\r\n }\r\n}\r\n","import { defineStore } from 'pinia';\nimport { imClient } from '@/services/imClient';\nimport { appConfig } from '@/config';\n\nconst STORAGE_KEY = 'qmt-web-im-session';\n\nfunction normalizeStoredPortrait(portrait) {\n return portrait || '';\n}\n\nfunction nextProfilePortrait(profilePortrait, currentPortrait) {\n return normalizeStoredPortrait(profilePortrait) || normalizeStoredPortrait(currentPortrait);\n}\n\nfunction inferAccountType(account) {\n return String(account || '').includes('@') ? 2 : 1;\n}\n\nexport const useSessionStore = defineStore('session', {\n state: () => ({\n isAuthenticated: false,\n connecting: false,\n connected: false,\n connectionStatusText: '未连接',\n userId: '',\n token: '',\n displayName: '',\n portrait: '',\n error: '',\n sdkVersion: '',\n eventsBound: false\n }),\n actions: {\n restore() {\n const raw = localStorage.getItem(STORAGE_KEY);\n if (!raw) {\n return;\n }\n\n try {\n const session = JSON.parse(raw);\n if (session.appServer !== appConfig.appServer) {\n localStorage.removeItem(STORAGE_KEY);\n return;\n }\n\n if (session.userId && session.token) {\n if (!session.clientId) {\n localStorage.removeItem(STORAGE_KEY);\n return;\n }\n this.userId = session.userId;\n this.token = session.token;\n this.displayName = session.displayName || session.userId;\n this.portrait = normalizeStoredPortrait(session.portrait);\n this.isAuthenticated = true;\n imClient.restoreClientId(session.clientId);\n this.connect();\n this.refreshProfile();\n }\n } catch (error) {\n localStorage.removeItem(STORAGE_KEY);\n }\n },\n\n async loginWithPassword(account, password, type = inferAccountType(account)) {\n this.error = '';\n this.connecting = true;\n try {\n const result = await imClient.loginWithPassword(account, password, type);\n this.applyLoginResult(result);\n await this.connect();\n } catch (error) {\n this.error = error.message || '登录失败';\n } finally {\n this.connecting = false;\n }\n },\n\n async loginWithCode(account, code) {\n this.error = '';\n this.connecting = true;\n try {\n const result = await imClient.loginWithCode(account, code);\n this.applyLoginResult(result);\n await this.connect();\n } catch (error) {\n this.error = error.message || '登录失败';\n } finally {\n this.connecting = false;\n }\n },\n\n async completePcSessionLogin(result) {\n this.error = '';\n this.connecting = true;\n try {\n this.applyLoginResult(result);\n await this.connect();\n } catch (error) {\n this.error = error.message || '扫码登录失败';\n } finally {\n this.connecting = false;\n }\n },\n\n async register(payload) {\n this.error = '';\n this.connecting = true;\n try {\n const result = await imClient.register(payload);\n this.applyLoginResult(result);\n await this.connect();\n return result;\n } catch (error) {\n this.error = error.message || '注册失败';\n return null;\n } finally {\n this.connecting = false;\n }\n },\n\n applyLoginResult(result) {\n this.userId = result.userId || result.uid || result.id || '';\n this.token = result.token || result.imToken || '';\n this.displayName = result.displayName || result.userName || result.name || this.userId;\n this.portrait = normalizeStoredPortrait(result.portrait);\n this.isAuthenticated = Boolean(this.userId && this.token);\n this.persistSession();\n },\n\n persistSession() {\n localStorage.setItem(STORAGE_KEY, JSON.stringify({\n userId: this.userId,\n token: this.token,\n displayName: this.displayName,\n portrait: this.portrait,\n clientId: imClient.getClientId(),\n appServer: appConfig.appServer\n }));\n },\n\n applyProfile(profile) {\n if (!profile) {\n return;\n }\n this.userId = profile.userId || profile.uid || this.userId;\n this.displayName = profile.displayName || profile.name || this.displayName || this.userId;\n this.portrait = nextProfilePortrait(profile.portrait, this.portrait);\n this.persistSession();\n },\n\n async refreshProfile() {\n if (!this.userId) {\n return null;\n }\n try {\n const profile = await imClient.getProfile(this.userId);\n this.applyProfile(profile);\n return profile;\n } catch (error) {\n return null;\n }\n },\n\n async saveProfile({ displayName, portraitFile }) {\n if (!this.userId) {\n throw new Error('请先登录');\n }\n const profile = await imClient.updateProfile(this.userId, {\n displayName,\n portraitFile\n });\n this.applyProfile(profile);\n return profile;\n },\n\n async changePassword({ oldPassword, newPassword }) {\n if (!this.userId) {\n throw new Error('请先登录');\n }\n await imClient.changePassword({ oldPassword, newPassword });\n await this.logout();\n return true;\n },\n\n async resetPasswordWithCode({ mobile, resetCode, newPassword }) {\n await imClient.resetPasswordWithCode({ mobile, resetCode, newPassword });\n return true;\n },\n\n async connect() {\n if (!this.userId || !this.token) {\n return;\n }\n await imClient.ensureSdk();\n this.sdkVersion = imClient.getSdkVersion();\n this.bindImEvents();\n await imClient.connect(this.userId, this.token);\n },\n\n bindImEvents() {\n if (this.eventsBound) {\n return;\n }\n this.eventsBound = true;\n imClient.on('connectionStatusChanged', status => {\n this.connected = status.connected;\n this.connectionStatusText = status.statusText || (status.connected ? '已连接' : '未连接');\n });\n },\n\n async logout() {\n try {\n await imClient.logout?.();\n } catch (error) {\n this.error = error.message || '退出登录失败';\n } finally {\n imClient.disconnect();\n localStorage.removeItem(STORAGE_KEY);\n this.$reset();\n }\n }\n }\n});\n","import script from \"./App.vue?vue&type=script&setup=true&lang=js\"\nexport * from \"./App.vue?vue&type=script&setup=true&lang=js\"\n\nconst __exports__ = script;\n\nexport default __exports__","import script from \"./DocumentedShell.vue?vue&type=script&setup=true&lang=js\"\nexport * from \"./DocumentedShell.vue?vue&type=script&setup=true&lang=js\"\n\nconst __exports__ = script;\n\nexport default __exports__","import script from \"./LoginView.vue?vue&type=script&setup=true&lang=js\"\nexport * from \"./LoginView.vue?vue&type=script&setup=true&lang=js\"\n\nconst __exports__ = script;\n\nexport default __exports__","export { default } from \"-!../node_modules/thread-loader/dist/cjs.js!../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./App.vue?vue&type=script&setup=true&lang=js\"; export * from \"-!../node_modules/thread-loader/dist/cjs.js!../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./App.vue?vue&type=script&setup=true&lang=js\"","export { default } from \"-!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./DocumentedShell.vue?vue&type=script&setup=true&lang=js\"; export * from \"-!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./DocumentedShell.vue?vue&type=script&setup=true&lang=js\"","export { default } from \"-!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./LoginView.vue?vue&type=script&setup=true&lang=js\"; export * from \"-!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./LoginView.vue?vue&type=script&setup=true&lang=js\"","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","var deferred = [];\n__webpack_require__.O = function(result, chunkIds, fn, priority) {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar chunkIds = deferred[i][0];\n\t\tvar fn = deferred[i][1];\n\t\tvar priority = deferred[i][2];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = function(module) {\n\tvar getter = module && module.__esModule ?\n\t\tfunction() { return module['default']; } :\n\t\tfunction() { return module; };\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter/value functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tif(Array.isArray(definition)) {\n\t\tvar i = 0;\n\t\twhile(i < definition.length) {\n\t\t\tvar key = definition[i++];\n\t\t\tvar binding = definition[i++];\n\t\t\tif(!__webpack_require__.o(exports, key)) {\n\t\t\t\tif(binding === 0) {\n\t\t\t\t\tObject.defineProperty(exports, key, { enumerable: true, value: definition[i++] });\n\t\t\t\t} else {\n\t\t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: binding });\n\t\t\t\t}\n\t\t\t} else if(binding === 0) { i++; }\n\t\t}\n\t} else {\n\t\tfor(var key in definition) {\n\t\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t\t}\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","// set .name for anonymous default exports per ES spec\n__webpack_require__.dn = function(x) {\n\t(Object.getOwnPropertyDescriptor(x, \"name\") || {}).writable || Object.defineProperty(x, \"name\", { value: \"default\", configurable: true });\n};","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t524: 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; };\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = function(parentChunkLoadingFunction, data) {\n\tvar chunkIds = data[0];\n\tvar moreModules = data[1];\n\tvar runtime = data[2];\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunkjc_web_im\"] = self[\"webpackChunkjc_web_im\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [504], function() { return __webpack_require__(1406); })\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n",""],"names":["onMounted","LoginView","DocumentedShell","useSessionStore","session","restore","computed","reactive","ref","appConfig","passwordDialogOpen","passwordSaving","passwordError","passwordNotice","passwordDraft","oldPassword","newPassword","confirmPassword","initials","String","displayName","userId","slice","toUpperCase","resetPasswordDraft","openPasswordDialog","value","closePasswordDialog","savePassword","changePassword","error","message","logout","axios","jrQRCode","onBeforeUnmount","imClient","QR_CODE_PREFIX_PC_SESSION","defaultPlatformLogo","view","loginMode","loginAccount","loginPassword","registerType","registerForm","number","code","password","invitationCode","sendingCode","info","qrStatus","qrCodeImage","qrSessionToken","qrUserName","qrUserPortrait","qrGeneration","qrExpireTimer","defaultPlatformName","appName","platformName","platformLogo","canSubmitLogin","length","canRequestEmailCode","test","canSubmitRegister","qrUserInitial","qrStatusTitle","connecting","qrStatusText","qrRefreshText","loadPlatformConfig","stopQrLogin","clearFormMessage","setLoginMode","mode","startQrLogin","submitLogin","type","loginWithPassword","switchRegisterType","requestEmailCode","requestAuthCode","submitRegister","result","register","openRegister","backToLogin","resetQrState","clearQrExpireTimer","window","clearTimeout","refreshQrLogin","force","includes","generation","pcSession","createPcSession","token","Error","getQrBase64","expireMs","Math","max","min","Number","expired","setTimeout","isAuthenticated","pollQrLogin","payload","loginWithPcSession","data","status","imToken","completePcSessionLogin","userName","portrait","delay","ms","Promise","resolve","response","get","platformConfigApi","withCredentials","config","name","trim","logo","logoUrl","version","resolveBrandLogo","applyDocumentBrand","appendBrandVersion","startsWith","location","protocol","base","adminServer","URL","toString","url","parsed","href","searchParams","set","document","title","icon","querySelector","createElement","setAttribute","head","appendChild","handleBrandLogoError","currentHost","hostname","runtimeConfig","JC_WEB_IM_CONFIG","appServerOrigin","qrAppServerOrigin","adminServerOrigin","process","env","VUE_APP_ADMIN_SERVER","appServer","VUE_APP_APP_SERVER","qrAppServer","VUE_APP_QR_APP_SERVER","VUE_APP_PLATFORM_CONFIG_API","NODE_ENV","registerConfigApi","VUE_APP_REGISTER_CONFIG_API","registerPhoneExistsApi","VUE_APP_REGISTER_PHONE_EXISTS_API","contactsApi","VUE_APP_CONTACTS_API","updateAliasApi","VUE_APP_UPDATE_ALIAS_API","addContactApi","VUE_APP_ADD_CONTACT_API","conversationActionsApi","VUE_APP_CONVERSATION_ACTIONS_API","sendMessageApi","VUE_APP_SEND_MESSAGE_API","messageActionApi","VUE_APP_MESSAGE_ACTION_API","messageDetailApi","VUE_APP_MESSAGE_DETAIL_API","messagesApi","VUE_APP_MESSAGES_API","profileApi","VUE_APP_PROFILE_API","changePasswordApi","VUE_APP_CHANGE_PASSWORD_API","logoutApi","VUE_APP_LOGOUT_API","imServerHost","VUE_APP_IM_SERVER_HOST","imRoutePort","VUE_APP_IM_ROUTE_PORT","useWss","VUE_APP_USE_WSS","wsPath","VUE_APP_WS_PATH","wsUrl","VUE_APP_WS_URL","sdkMode","VUE_APP_IM_MODE","syncIntervalMs","VUE_APP_SYNC_INTERVAL_MS","platform","clientIdStorageKey","authTokenStoragePrefix","createApp","createPinia","App","use","mount","AES_KEY","ENCRYPTION_EXCLUDE_PATHS","AUTH_STORAGE_KEY","AUTH_ERROR_CODE","REFRESH_ERROR_CODE","importedCryptoKeyPromise","refreshPromise","storageScope","readAuthStore","JSON","parse","localStorage","getItem","writeAuthStore","store","setItem","stringify","normalizeAuthBundle","bundle","accessToken","refreshToken","tokenType","accessTokenExpireIn","accessTokenExpireAt","refreshTokenExpireIn","refreshTokenExpireAt","getStoredAppAuth","persistAppAuth","normalized","clearStoredAppAuth","hasFormData","FormData","absoluteUrl","origin","shouldEncrypt","pathname","some","path","shouldAttachAuth","skipAuth","textEncoder","TextEncoder","textDecoder","TextDecoder","bytesToBase64","bytes","binary","forEach","byte","fromCharCode","btoa","base64ToBytes","base64","atob","Uint8Array","index","charCodeAt","getCryptoKey","crypto","subtle","importKey","encode","encryptPayload","plainText","iv","getRandomValues","key","encrypted","encrypt","decryptPayload","cipherText","ivBase64","encryptedBase64","split","decrypted","decrypt","decode","normalizeBusinessResponse","Array","isArray","decodeResponsePayload","headers","toLowerCase","client","create","interceptors","request","nextConfig","auth","Authorization","method","plainBody","floor","Date","now","refreshAccessToken","post","then","finally","_retriedAfterRefresh","appServerRequest","appServerGet","appServerPost","HttpImClient","inferAccountType","account","unwrapData","unwrapMessage","fallback","msg","DocumentedHttpImClient","unsupported","feature","clientId","getClientId","email","loginWithCode","flag","device_name","encodeURIComponent","postError","persistAppToken","resetPasswordWithCode","mobile","resetCode","fetchRemoteConversations","fetchRemoteMessages","getServerContactList","getProfile","sendTextMessage","sendAttachmentMessage","addContact","updateContactAlias","createGroup","joinGroup","broadcastMessage","getGroupDetail","getGroupMembers","updateGroupAlias","leaveGroup","dismissGroup","transferGroup","setGroupAdmins","updateGroupProfile","kickGroupMembers","updateGroupMuteSetting","updateProfile","recallMessage","editMessage","getMessageDetail","LOCAL_MESSAGE_STORAGE_KEY","LOCAL_HIDDEN_MESSAGE_STORAGE_KEY","LOCAL_RECALLED_MESSAGE_STORAGE_KEY","scopedStorageKey","baseKey","scope","randomId","randomUUID","replaceAll","random","readLocalMessages","readMessageSet","storageKey","writeMessageSet","messagesByConversation","messageKeys","id","messageUid","filter","Boolean","map","hasStoredMessage","conversationId","stored","ids","Set","has","storeMessageKeys","messages","add","from","withRecalledState","deliveryStatus","recalled","recallStatus","applyLocalMessageState","isRecalled","writeLocalMessages","saveLocalMessage","findIndex","item","splice","push","mergeSyncedMessages","localMessages","remoteMessages","visibleLocalMessages","localByKey","Map","visibleRemoteMessages","remoteMessage","text","localMessage","find","remoteKeys","hasRemoteMatch","direction","abs","timestamp","pendingLocalMessages","sort","a","b","displayTimestamp","getTitle","getUniqueEquipment","allowedDevices","canUseLocalLoginFallback","constructor","listeners","connected","currentUser","restoreClientId","getSdkVersion","ensureSdk","deviceId","uniqueEquipment","localOnly","registerWithPhone","connect","emit","statusText","refreshConversationList","disconnect","getConversationList","conversations","remoteConversations","catch","limit","conversation","updatedAt","avatarText","target","raw","line","getMessages","options","replace","conversationType","markRead","hideMessages","items","markMessagesRecalled","action","nextText","editedMessage","editedAt","activityTimestamp","detail","initialMessage","senderRole","role","sender","sentMessage","serverTimestamp","failedMessage","file","attachment","mime","size","createObjectURL","formData","append","getContactList","getAppAuthHeaders","contacts","mapContact","uid","alias","address","friendAlias","localeCompare","keyword","reason","contact","normalizeConversation","subtitle","unread","memberIds","announcement","welcomeText","channel","groupKey","targetIds","groupId","group","members","targetUserId","adminIds","setting","muteSetting","targetId","profile","portraitFile","resetPasswordApi","refreshContactList","createSingleConversation","userInfo","friend","rawFriend","rawUser","on","eventName","handler","off","delete","appToken","authtoken","authToken","getUrlHost","host","LongConnectionImClient","UnsupportedWildfireImClient","WildfireImClient","HEARTBEAT_INTERVAL_MS","RECONNECT_MIN_MS","RECONNECT_MAX_MS","buildWsUrl","port","normalizeConversationId","to","receiver","conversationTarget","normalizeIncomingMessage","currentUserId","fromUser","messageId","content","searchableContent","socket","heartbeatTimer","reconnectTimer","reconnectAttempts","manualClose","shouldUseMessagePolling","WebSocket","openSocket","clearReconnectTimer","clearHeartbeatTimer","close","readyState","OPEN","sendAuthFrame","CONNECTING","binaryType","scheduleReconnect","onopen","startHeartbeat","onmessage","event","handleFrame","onerror","onclose","sendFrame","frame","send","rawData","ArrayBuffer","cmd","setInterval","clearInterval","defineStore","STORAGE_KEY","normalizeStoredPortrait","nextProfilePortrait","profilePortrait","currentPortrait","state","connectionStatusText","sdkVersion","eventsBound","actions","removeItem","refreshProfile","applyLoginResult","persistSession","applyProfile","saveProfile","bindImEvents","$reset"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/js/chunk-vendors.cd0faf68.js b/dist/js/chunk-vendors.cd0faf68.js new file mode 100644 index 0000000..7888f04 --- /dev/null +++ b/dist/js/chunk-vendors.cd0faf68.js @@ -0,0 +1,24967 @@ +(self["webpackChunkjc_web_im"] = self["webpackChunkjc_web_im"] || []).push([[504],{ + +/***/ 144: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ C4: function() { return /* binding */ pauseTracking; }, +/* harmony export */ EW: function() { return /* binding */ computed; }, +/* harmony export */ Gc: function() { return /* binding */ shallowReactive; }, +/* harmony export */ IG: function() { return /* binding */ markRaw; }, +/* harmony export */ KR: function() { return /* binding */ ref; }, +/* harmony export */ Kh: function() { return /* binding */ reactive; }, +/* harmony export */ Pr: function() { return /* binding */ proxyRefs; }, +/* harmony export */ QW: function() { return /* binding */ toRefs; }, +/* harmony export */ R1: function() { return /* binding */ unref; }, +/* harmony export */ X2: function() { return /* binding */ ReactiveEffect; }, +/* harmony export */ bl: function() { return /* binding */ resetTracking; }, +/* harmony export */ g8: function() { return /* binding */ isReactive; }, +/* harmony export */ hV: function() { return /* binding */ traverse; }, +/* harmony export */ hZ: function() { return /* binding */ trigger; }, +/* harmony export */ i9: function() { return /* binding */ isRef; }, +/* harmony export */ jr: function() { return /* binding */ onScopeDispose; }, +/* harmony export */ ju: function() { return /* binding */ isProxy; }, +/* harmony export */ o5: function() { return /* binding */ getCurrentScope; }, +/* harmony export */ u4: function() { return /* binding */ track; }, +/* harmony export */ uY: function() { return /* binding */ effectScope; }, +/* harmony export */ ux: function() { return /* binding */ toRaw; }, +/* harmony export */ wB: function() { return /* binding */ watch; }, +/* harmony export */ yC: function() { return /* binding */ EffectScope; } +/* harmony export */ }); +/* unused harmony exports ARRAY_ITERATE_KEY, EffectFlags, ITERATE_KEY, MAP_KEY_ITERATE_KEY, ReactiveFlags, TrackOpTypes, TriggerOpTypes, WatchErrorCodes, customRef, effect, enableTracking, getCurrentWatcher, isReadonly, isShallow, onEffectCleanup, onWatcherCleanup, reactiveReadArray, readonly, shallowReadArray, shallowReadonly, shallowRef, stop, toReactive, toReadonly, toRef, toValue, triggerRef */ +/* unused harmony import specifier */ var extend; +/* unused harmony import specifier */ var toRawType; +/* unused harmony import specifier */ var isFunction; +/* unused harmony import specifier */ var isObject; +/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4114); +/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8111); +/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2489); +/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7588); +/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_3__); +/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(1701); +/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_4__); +/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(3579); +/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_5__); +/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(5367); +/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_6__); +/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(2731); +/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_7__); +/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(7642); +/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_8__); +/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(8004); +/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_9__); +/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(3853); +/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_10__); +/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(5876); +/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_11__); +/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(2475); +/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_12__); +/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(5024); +/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_13__); +/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(1698); +/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_14___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_14__); +/* harmony import */ var core_js_modules_es_weak_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(8454); +/* harmony import */ var core_js_modules_es_weak_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_weak_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_15__); +/* harmony import */ var core_js_modules_es_weak_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(9452); +/* harmony import */ var core_js_modules_es_weak_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_16___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_weak_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_16__); +/* harmony import */ var _vue_shared__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(6107); + + + + + + + + + + + + + + + + + +/** +* @vue/reactivity v3.5.13 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/ + +function warn(msg, ...args) { + console.warn(`[Vue warn] ${msg}`, ...args); +} +let activeEffectScope; +class EffectScope { + constructor(detached = false) { + this.detached = detached; + /** + * @internal + */ + this._active = true; + /** + * @internal + */ + this.effects = []; + /** + * @internal + */ + this.cleanups = []; + this._isPaused = false; + this.parent = activeEffectScope; + if (!detached && activeEffectScope) { + this.index = (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(this) - 1; + } + } + get active() { + return this._active; + } + pause() { + if (this._active) { + this._isPaused = true; + let i, l; + if (this.scopes) { + for (i = 0, l = this.scopes.length; i < l; i++) { + this.scopes[i].pause(); + } + } + for (i = 0, l = this.effects.length; i < l; i++) { + this.effects[i].pause(); + } + } + } + /** + * Resumes the effect scope, including all child scopes and effects. + */ + resume() { + if (this._active) { + if (this._isPaused) { + this._isPaused = false; + let i, l; + if (this.scopes) { + for (i = 0, l = this.scopes.length; i < l; i++) { + this.scopes[i].resume(); + } + } + for (i = 0, l = this.effects.length; i < l; i++) { + this.effects[i].resume(); + } + } + } + } + run(fn) { + if (this._active) { + const currentEffectScope = activeEffectScope; + try { + activeEffectScope = this; + return fn(); + } finally { + activeEffectScope = currentEffectScope; + } + } else if (false) // removed by dead control flow +{} + } + /** + * This should only be called on non-detached scopes + * @internal + */ + on() { + activeEffectScope = this; + } + /** + * This should only be called on non-detached scopes + * @internal + */ + off() { + activeEffectScope = this.parent; + } + stop(fromParent) { + if (this._active) { + this._active = false; + let i, l; + for (i = 0, l = this.effects.length; i < l; i++) { + this.effects[i].stop(); + } + this.effects.length = 0; + for (i = 0, l = this.cleanups.length; i < l; i++) { + this.cleanups[i](); + } + this.cleanups.length = 0; + if (this.scopes) { + for (i = 0, l = this.scopes.length; i < l; i++) { + this.scopes[i].stop(true); + } + this.scopes.length = 0; + } + if (!this.detached && this.parent && !fromParent) { + const last = this.parent.scopes.pop(); + if (last && last !== this) { + this.parent.scopes[this.index] = last; + last.index = this.index; + } + } + this.parent = void 0; + } + } +} +function effectScope(detached) { + return new EffectScope(detached); +} +function getCurrentScope() { + return activeEffectScope; +} +function onScopeDispose(fn, failSilently = false) { + if (activeEffectScope) { + activeEffectScope.cleanups.push(fn); + } else if (false) // removed by dead control flow +{} +} +let activeSub; +const EffectFlags = (/* unused pure expression or super */ null && ({ + "ACTIVE": 1, + "1": "ACTIVE", + "RUNNING": 2, + "2": "RUNNING", + "TRACKING": 4, + "4": "TRACKING", + "NOTIFIED": 8, + "8": "NOTIFIED", + "DIRTY": 16, + "16": "DIRTY", + "ALLOW_RECURSE": 32, + "32": "ALLOW_RECURSE", + "PAUSED": 64, + "64": "PAUSED" +})); +const pausedQueueEffects = /* @__PURE__ */new WeakSet(); +class ReactiveEffect { + constructor(fn) { + this.fn = fn; + /** + * @internal + */ + this.deps = void 0; + /** + * @internal + */ + this.depsTail = void 0; + /** + * @internal + */ + this.flags = 1 | 4; + /** + * @internal + */ + this.next = void 0; + /** + * @internal + */ + this.cleanup = void 0; + this.scheduler = void 0; + if (activeEffectScope && activeEffectScope.active) { + activeEffectScope.effects.push(this); + } + } + pause() { + this.flags |= 64; + } + resume() { + if (this.flags & 64) { + this.flags &= ~64; + if (pausedQueueEffects.has(this)) { + pausedQueueEffects.delete(this); + this.trigger(); + } + } + } + /** + * @internal + */ + notify() { + if (this.flags & 2 && !(this.flags & 32)) { + return; + } + if (!(this.flags & 8)) { + batch(this); + } + } + run() { + if (!(this.flags & 1)) { + return this.fn(); + } + this.flags |= 2; + cleanupEffect(this); + prepareDeps(this); + const prevEffect = activeSub; + const prevShouldTrack = shouldTrack; + activeSub = this; + shouldTrack = true; + try { + return this.fn(); + } finally { + if (false) // removed by dead control flow +{} + cleanupDeps(this); + activeSub = prevEffect; + shouldTrack = prevShouldTrack; + this.flags &= ~2; + } + } + stop() { + if (this.flags & 1) { + for (let link = this.deps; link; link = link.nextDep) { + removeSub(link); + } + this.deps = this.depsTail = void 0; + cleanupEffect(this); + this.onStop && this.onStop(); + this.flags &= ~1; + } + } + trigger() { + if (this.flags & 64) { + pausedQueueEffects.add(this); + } else if (this.scheduler) { + this.scheduler(); + } else { + this.runIfDirty(); + } + } + /** + * @internal + */ + runIfDirty() { + if (isDirty(this)) { + this.run(); + } + } + get dirty() { + return isDirty(this); + } +} +let batchDepth = 0; +let batchedSub; +let batchedComputed; +function batch(sub, isComputed = false) { + sub.flags |= 8; + if (isComputed) { + sub.next = batchedComputed; + batchedComputed = sub; + return; + } + sub.next = batchedSub; + batchedSub = sub; +} +function startBatch() { + batchDepth++; +} +function endBatch() { + if (--batchDepth > 0) { + return; + } + if (batchedComputed) { + let e = batchedComputed; + batchedComputed = void 0; + while (e) { + const next = e.next; + e.next = void 0; + e.flags &= ~8; + e = next; + } + } + let error; + while (batchedSub) { + let e = batchedSub; + batchedSub = void 0; + while (e) { + const next = e.next; + e.next = void 0; + e.flags &= ~8; + if (e.flags & 1) { + try { + ; + e.trigger(); + } catch (err) { + if (!error) error = err; + } + } + e = next; + } + } + if (error) throw error; +} +function prepareDeps(sub) { + for (let link = sub.deps; link; link = link.nextDep) { + link.version = -1; + link.prevActiveLink = link.dep.activeLink; + link.dep.activeLink = link; + } +} +function cleanupDeps(sub) { + let head; + let tail = sub.depsTail; + let link = tail; + while (link) { + const prev = link.prevDep; + if (link.version === -1) { + if (link === tail) tail = prev; + removeSub(link); + removeDep(link); + } else { + head = link; + } + link.dep.activeLink = link.prevActiveLink; + link.prevActiveLink = void 0; + link = prev; + } + sub.deps = head; + sub.depsTail = tail; +} +function isDirty(sub) { + for (let link = sub.deps; link; link = link.nextDep) { + if (link.dep.version !== link.version || link.dep.computed && (refreshComputed(link.dep.computed) || link.dep.version !== link.version)) { + return true; + } + } + if (sub._dirty) { + return true; + } + return false; +} +function refreshComputed(computed) { + if (computed.flags & 4 && !(computed.flags & 16)) { + return; + } + computed.flags &= ~16; + if (computed.globalVersion === globalVersion) { + return; + } + computed.globalVersion = globalVersion; + const dep = computed.dep; + computed.flags |= 2; + if (dep.version > 0 && !computed.isSSR && computed.deps && !isDirty(computed)) { + computed.flags &= ~2; + return; + } + const prevSub = activeSub; + const prevShouldTrack = shouldTrack; + activeSub = computed; + shouldTrack = true; + try { + prepareDeps(computed); + const value = computed.fn(computed._value); + if (dep.version === 0 || (0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .hasChanged */ .$H)(value, computed._value)) { + computed._value = value; + dep.version++; + } + } catch (err) { + dep.version++; + throw err; + } finally { + activeSub = prevSub; + shouldTrack = prevShouldTrack; + cleanupDeps(computed); + computed.flags &= ~2; + } +} +function removeSub(link, soft = false) { + const { + dep, + prevSub, + nextSub + } = link; + if (prevSub) { + prevSub.nextSub = nextSub; + link.prevSub = void 0; + } + if (nextSub) { + nextSub.prevSub = prevSub; + link.nextSub = void 0; + } + if (false) // removed by dead control flow +{} + if (dep.subs === link) { + dep.subs = prevSub; + if (!prevSub && dep.computed) { + dep.computed.flags &= ~4; + for (let l = dep.computed.deps; l; l = l.nextDep) { + removeSub(l, true); + } + } + } + if (!soft && ! --dep.sc && dep.map) { + dep.map.delete(dep.key); + } +} +function removeDep(link) { + const { + prevDep, + nextDep + } = link; + if (prevDep) { + prevDep.nextDep = nextDep; + link.prevDep = void 0; + } + if (nextDep) { + nextDep.prevDep = prevDep; + link.nextDep = void 0; + } +} +function effect(fn, options) { + if (fn.effect instanceof ReactiveEffect) { + fn = fn.effect.fn; + } + const e = new ReactiveEffect(fn); + if (options) { + extend(e, options); + } + try { + e.run(); + } catch (err) { + e.stop(); + throw err; + } + const runner = e.run.bind(e); + runner.effect = e; + return runner; +} +function stop(runner) { + runner.effect.stop(); +} +let shouldTrack = true; +const trackStack = []; +function pauseTracking() { + trackStack.push(shouldTrack); + shouldTrack = false; +} +function enableTracking() { + trackStack.push(shouldTrack); + shouldTrack = true; +} +function resetTracking() { + const last = trackStack.pop(); + shouldTrack = last === void 0 ? true : last; +} +function onEffectCleanup(fn, failSilently = false) { + if (activeSub instanceof ReactiveEffect) { + activeSub.cleanup = fn; + } else if (false) // removed by dead control flow +{} +} +function cleanupEffect(e) { + const { + cleanup + } = e; + e.cleanup = void 0; + if (cleanup) { + const prevSub = activeSub; + activeSub = void 0; + try { + cleanup(); + } finally { + activeSub = prevSub; + } + } +} +let globalVersion = 0; +class Link { + constructor(sub, dep) { + this.sub = sub; + this.dep = dep; + this.version = dep.version; + this.nextDep = this.prevDep = this.nextSub = this.prevSub = this.prevActiveLink = void 0; + } +} +class Dep { + constructor(computed) { + this.computed = computed; + this.version = 0; + /** + * Link between this dep and the current active effect + */ + this.activeLink = void 0; + /** + * Doubly linked list representing the subscribing effects (tail) + */ + this.subs = void 0; + /** + * For object property deps cleanup + */ + this.map = void 0; + this.key = void 0; + /** + * Subscriber counter + */ + this.sc = 0; + if (false) // removed by dead control flow +{} + } + track(debugInfo) { + if (!activeSub || !shouldTrack || activeSub === this.computed) { + return; + } + let link = this.activeLink; + if (link === void 0 || link.sub !== activeSub) { + link = this.activeLink = new Link(activeSub, this); + if (!activeSub.deps) { + activeSub.deps = activeSub.depsTail = link; + } else { + link.prevDep = activeSub.depsTail; + activeSub.depsTail.nextDep = link; + activeSub.depsTail = link; + } + addSub(link); + } else if (link.version === -1) { + link.version = this.version; + if (link.nextDep) { + const next = link.nextDep; + next.prevDep = link.prevDep; + if (link.prevDep) { + link.prevDep.nextDep = next; + } + link.prevDep = activeSub.depsTail; + link.nextDep = void 0; + activeSub.depsTail.nextDep = link; + activeSub.depsTail = link; + if (activeSub.deps === link) { + activeSub.deps = next; + } + } + } + if (false) // removed by dead control flow +{} + return link; + } + trigger(debugInfo) { + this.version++; + globalVersion++; + this.notify(debugInfo); + } + notify(debugInfo) { + startBatch(); + try { + if (false) // removed by dead control flow +{} + for (let link = this.subs; link; link = link.prevSub) { + if (link.sub.notify()) { + ; + link.sub.dep.notify(); + } + } + } finally { + endBatch(); + } + } +} +function addSub(link) { + link.dep.sc++; + if (link.sub.flags & 4) { + const computed = link.dep.computed; + if (computed && !link.dep.subs) { + computed.flags |= 4 | 16; + for (let l = computed.deps; l; l = l.nextDep) { + addSub(l); + } + } + const currentTail = link.dep.subs; + if (currentTail !== link) { + link.prevSub = currentTail; + if (currentTail) currentTail.nextSub = link; + } + if (false) // removed by dead control flow +{} + link.dep.subs = link; + } +} +const targetMap = /* @__PURE__ */new WeakMap(); +const ITERATE_KEY = Symbol( false ? 0 : ""); +const MAP_KEY_ITERATE_KEY = Symbol( false ? 0 : ""); +const ARRAY_ITERATE_KEY = Symbol( false ? 0 : ""); +function track(target, type, key) { + if (shouldTrack && activeSub) { + let depsMap = targetMap.get(target); + if (!depsMap) { + targetMap.set(target, depsMap = /* @__PURE__ */new Map()); + } + let dep = depsMap.get(key); + if (!dep) { + depsMap.set(key, dep = new Dep()); + dep.map = depsMap; + dep.key = key; + } + if (false) // removed by dead control flow +{} else { + dep.track(); + } + } +} +function trigger(target, type, key, newValue, oldValue, oldTarget) { + const depsMap = targetMap.get(target); + if (!depsMap) { + globalVersion++; + return; + } + const run = dep => { + if (dep) { + if (false) // removed by dead control flow +{} else { + dep.trigger(); + } + } + }; + startBatch(); + if (type === "clear") { + depsMap.forEach(run); + } else { + const targetIsArray = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isArray */ .cy)(target); + const isArrayIndex = targetIsArray && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isIntegerKey */ .yI)(key); + if (targetIsArray && key === "length") { + const newLength = Number(newValue); + depsMap.forEach((dep, key2) => { + if (key2 === "length" || key2 === ARRAY_ITERATE_KEY || !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isSymbol */ .Bm)(key2) && key2 >= newLength) { + run(dep); + } + }); + } else { + if (key !== void 0 || depsMap.has(void 0)) { + run(depsMap.get(key)); + } + if (isArrayIndex) { + run(depsMap.get(ARRAY_ITERATE_KEY)); + } + switch (type) { + case "add": + if (!targetIsArray) { + run(depsMap.get(ITERATE_KEY)); + if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isMap */ .CE)(target)) { + run(depsMap.get(MAP_KEY_ITERATE_KEY)); + } + } else if (isArrayIndex) { + run(depsMap.get("length")); + } + break; + case "delete": + if (!targetIsArray) { + run(depsMap.get(ITERATE_KEY)); + if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isMap */ .CE)(target)) { + run(depsMap.get(MAP_KEY_ITERATE_KEY)); + } + } + break; + case "set": + if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isMap */ .CE)(target)) { + run(depsMap.get(ITERATE_KEY)); + } + break; + } + } + } + endBatch(); +} +function getDepFromReactive(object, key) { + const depMap = targetMap.get(object); + return depMap && depMap.get(key); +} +function reactiveReadArray(array) { + const raw = toRaw(array); + if (raw === array) return raw; + track(raw, "iterate", ARRAY_ITERATE_KEY); + return isShallow(array) ? raw : raw.map(toReactive); +} +function shallowReadArray(arr) { + track(arr = toRaw(arr), "iterate", ARRAY_ITERATE_KEY); + return arr; +} +const arrayInstrumentations = { + __proto__: null, + [Symbol.iterator]() { + return iterator(this, Symbol.iterator, toReactive); + }, + concat(...args) { + return reactiveReadArray(this).concat(...args.map(x => (0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isArray */ .cy)(x) ? reactiveReadArray(x) : x)); + }, + entries() { + return iterator(this, "entries", value => { + value[1] = toReactive(value[1]); + return value; + }); + }, + every(fn, thisArg) { + return apply(this, "every", fn, thisArg, void 0, arguments); + }, + filter(fn, thisArg) { + return apply(this, "filter", fn, thisArg, v => v.map(toReactive), arguments); + }, + find(fn, thisArg) { + return apply(this, "find", fn, thisArg, toReactive, arguments); + }, + findIndex(fn, thisArg) { + return apply(this, "findIndex", fn, thisArg, void 0, arguments); + }, + findLast(fn, thisArg) { + return apply(this, "findLast", fn, thisArg, toReactive, arguments); + }, + findLastIndex(fn, thisArg) { + return apply(this, "findLastIndex", fn, thisArg, void 0, arguments); + }, + // flat, flatMap could benefit from ARRAY_ITERATE but are not straight-forward to implement + forEach(fn, thisArg) { + return apply(this, "forEach", fn, thisArg, void 0, arguments); + }, + includes(...args) { + return searchProxy(this, "includes", args); + }, + indexOf(...args) { + return searchProxy(this, "indexOf", args); + }, + join(separator) { + return reactiveReadArray(this).join(separator); + }, + // keys() iterator only reads `length`, no optimisation required + lastIndexOf(...args) { + return searchProxy(this, "lastIndexOf", args); + }, + map(fn, thisArg) { + return apply(this, "map", fn, thisArg, void 0, arguments); + }, + pop() { + return noTracking(this, "pop"); + }, + push(...args) { + return noTracking(this, "push", args); + }, + reduce(fn, ...args) { + return reduce(this, "reduce", fn, args); + }, + reduceRight(fn, ...args) { + return reduce(this, "reduceRight", fn, args); + }, + shift() { + return noTracking(this, "shift"); + }, + // slice could use ARRAY_ITERATE but also seems to beg for range tracking + some(fn, thisArg) { + return apply(this, "some", fn, thisArg, void 0, arguments); + }, + splice(...args) { + return noTracking(this, "splice", args); + }, + toReversed() { + return reactiveReadArray(this).toReversed(); + }, + toSorted(comparer) { + return reactiveReadArray(this).toSorted(comparer); + }, + toSpliced(...args) { + return reactiveReadArray(this).toSpliced(...args); + }, + unshift(...args) { + return noTracking(this, "unshift", args); + }, + values() { + return iterator(this, "values", toReactive); + } +}; +function iterator(self, method, wrapValue) { + const arr = shallowReadArray(self); + const iter = arr[method](); + if (arr !== self && !isShallow(self)) { + iter._next = iter.next; + iter.next = () => { + const result = iter._next(); + if (result.value) { + result.value = wrapValue(result.value); + } + return result; + }; + } + return iter; +} +const arrayProto = Array.prototype; +function apply(self, method, fn, thisArg, wrappedRetFn, args) { + const arr = shallowReadArray(self); + const needsWrap = arr !== self && !isShallow(self); + const methodFn = arr[method]; + if (methodFn !== arrayProto[method]) { + const result2 = methodFn.apply(self, args); + return needsWrap ? toReactive(result2) : result2; + } + let wrappedFn = fn; + if (arr !== self) { + if (needsWrap) { + wrappedFn = function (item, index) { + return fn.call(this, toReactive(item), index, self); + }; + } else if (fn.length > 2) { + wrappedFn = function (item, index) { + return fn.call(this, item, index, self); + }; + } + } + const result = methodFn.call(arr, wrappedFn, thisArg); + return needsWrap && wrappedRetFn ? wrappedRetFn(result) : result; +} +function reduce(self, method, fn, args) { + const arr = shallowReadArray(self); + let wrappedFn = fn; + if (arr !== self) { + if (!isShallow(self)) { + wrappedFn = function (acc, item, index) { + return fn.call(this, acc, toReactive(item), index, self); + }; + } else if (fn.length > 3) { + wrappedFn = function (acc, item, index) { + return fn.call(this, acc, item, index, self); + }; + } + } + return arr[method](wrappedFn, ...args); +} +function searchProxy(self, method, args) { + const arr = toRaw(self); + track(arr, "iterate", ARRAY_ITERATE_KEY); + const res = arr[method](...args); + if ((res === -1 || res === false) && isProxy(args[0])) { + args[0] = toRaw(args[0]); + return arr[method](...args); + } + return res; +} +function noTracking(self, method, args = []) { + pauseTracking(); + startBatch(); + const res = toRaw(self)[method].apply(self, args); + endBatch(); + resetTracking(); + return res; +} +const isNonTrackableKeys = /* @__PURE__ */(0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .makeMap */ .pD)(`__proto__,__v_isRef,__isVue`); +const builtInSymbols = new Set(/* @__PURE__ */Object.getOwnPropertyNames(Symbol).filter(key => key !== "arguments" && key !== "caller").map(key => Symbol[key]).filter(_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isSymbol */ .Bm)); +function hasOwnProperty(key) { + if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isSymbol */ .Bm)(key)) key = String(key); + const obj = toRaw(this); + track(obj, "has", key); + return obj.hasOwnProperty(key); +} +class BaseReactiveHandler { + constructor(_isReadonly = false, _isShallow = false) { + this._isReadonly = _isReadonly; + this._isShallow = _isShallow; + } + get(target, key, receiver) { + if (key === "__v_skip") return target["__v_skip"]; + const isReadonly2 = this._isReadonly, + isShallow2 = this._isShallow; + if (key === "__v_isReactive") { + return !isReadonly2; + } else if (key === "__v_isReadonly") { + return isReadonly2; + } else if (key === "__v_isShallow") { + return isShallow2; + } else if (key === "__v_raw") { + if (receiver === (isReadonly2 ? isShallow2 ? shallowReadonlyMap : readonlyMap : isShallow2 ? shallowReactiveMap : reactiveMap).get(target) || + // receiver is not the reactive proxy, but has the same prototype + // this means the receiver is a user proxy of the reactive proxy + Object.getPrototypeOf(target) === Object.getPrototypeOf(receiver)) { + return target; + } + return; + } + const targetIsArray = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isArray */ .cy)(target); + if (!isReadonly2) { + let fn; + if (targetIsArray && (fn = arrayInstrumentations[key])) { + return fn; + } + if (key === "hasOwnProperty") { + return hasOwnProperty; + } + } + const res = Reflect.get(target, key, + // if this is a proxy wrapping a ref, return methods using the raw ref + // as receiver so that we don't have to call `toRaw` on the ref in all + // its class methods + isRef(target) ? target : receiver); + if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isSymbol */ .Bm)(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) { + return res; + } + if (!isReadonly2) { + track(target, "get", key); + } + if (isShallow2) { + return res; + } + if (isRef(res)) { + return targetIsArray && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isIntegerKey */ .yI)(key) ? res : res.value; + } + if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isObject */ .Gv)(res)) { + return isReadonly2 ? readonly(res) : reactive(res); + } + return res; + } +} +class MutableReactiveHandler extends BaseReactiveHandler { + constructor(isShallow2 = false) { + super(false, isShallow2); + } + set(target, key, value, receiver) { + let oldValue = target[key]; + if (!this._isShallow) { + const isOldValueReadonly = isReadonly(oldValue); + if (!isShallow(value) && !isReadonly(value)) { + oldValue = toRaw(oldValue); + value = toRaw(value); + } + if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isArray */ .cy)(target) && isRef(oldValue) && !isRef(value)) { + if (isOldValueReadonly) { + return false; + } else { + oldValue.value = value; + return true; + } + } + } + const hadKey = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isArray */ .cy)(target) && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isIntegerKey */ .yI)(key) ? Number(key) < target.length : (0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .hasOwn */ .$3)(target, key); + const result = Reflect.set(target, key, value, isRef(target) ? target : receiver); + if (target === toRaw(receiver)) { + if (!hadKey) { + trigger(target, "add", key, value); + } else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .hasChanged */ .$H)(value, oldValue)) { + trigger(target, "set", key, value, oldValue); + } + } + return result; + } + deleteProperty(target, key) { + const hadKey = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .hasOwn */ .$3)(target, key); + const oldValue = target[key]; + const result = Reflect.deleteProperty(target, key); + if (result && hadKey) { + trigger(target, "delete", key, void 0, oldValue); + } + return result; + } + has(target, key) { + const result = Reflect.has(target, key); + if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isSymbol */ .Bm)(key) || !builtInSymbols.has(key)) { + track(target, "has", key); + } + return result; + } + ownKeys(target) { + track(target, "iterate", (0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isArray */ .cy)(target) ? "length" : ITERATE_KEY); + return Reflect.ownKeys(target); + } +} +class ReadonlyReactiveHandler extends BaseReactiveHandler { + constructor(isShallow2 = false) { + super(true, isShallow2); + } + set(target, key) { + if (false) // removed by dead control flow +{} + return true; + } + deleteProperty(target, key) { + if (false) // removed by dead control flow +{} + return true; + } +} +const mutableHandlers = /* @__PURE__ */new MutableReactiveHandler(); +const readonlyHandlers = /* @__PURE__ */new ReadonlyReactiveHandler(); +const shallowReactiveHandlers = /* @__PURE__ */new MutableReactiveHandler(true); +const shallowReadonlyHandlers = /* @__PURE__ */(/* unused pure expression or super */ null && (new ReadonlyReactiveHandler(true))); +const toShallow = value => value; +const getProto = v => Reflect.getPrototypeOf(v); +function createIterableMethod(method, isReadonly2, isShallow2) { + return function (...args) { + const target = this["__v_raw"]; + const rawTarget = toRaw(target); + const targetIsMap = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isMap */ .CE)(rawTarget); + const isPair = method === "entries" || method === Symbol.iterator && targetIsMap; + const isKeyOnly = method === "keys" && targetIsMap; + const innerIterator = target[method](...args); + const wrap = isShallow2 ? toShallow : isReadonly2 ? toReadonly : toReactive; + !isReadonly2 && track(rawTarget, "iterate", isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY); + return { + // iterator protocol + next() { + const { + value, + done + } = innerIterator.next(); + return done ? { + value, + done + } : { + value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value), + done + }; + }, + // iterable protocol + [Symbol.iterator]() { + return this; + } + }; + }; +} +function createReadonlyMethod(type) { + return function (...args) { + if (false) // removed by dead control flow +{} + return type === "delete" ? false : type === "clear" ? void 0 : this; + }; +} +function createInstrumentations(readonly, shallow) { + const instrumentations = { + get(key) { + const target = this["__v_raw"]; + const rawTarget = toRaw(target); + const rawKey = toRaw(key); + if (!readonly) { + if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .hasChanged */ .$H)(key, rawKey)) { + track(rawTarget, "get", key); + } + track(rawTarget, "get", rawKey); + } + const { + has + } = getProto(rawTarget); + const wrap = shallow ? toShallow : readonly ? toReadonly : toReactive; + if (has.call(rawTarget, key)) { + return wrap(target.get(key)); + } else if (has.call(rawTarget, rawKey)) { + return wrap(target.get(rawKey)); + } else if (target !== rawTarget) { + target.get(key); + } + }, + get size() { + const target = this["__v_raw"]; + !readonly && track(toRaw(target), "iterate", ITERATE_KEY); + return Reflect.get(target, "size", target); + }, + has(key) { + const target = this["__v_raw"]; + const rawTarget = toRaw(target); + const rawKey = toRaw(key); + if (!readonly) { + if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .hasChanged */ .$H)(key, rawKey)) { + track(rawTarget, "has", key); + } + track(rawTarget, "has", rawKey); + } + return key === rawKey ? target.has(key) : target.has(key) || target.has(rawKey); + }, + forEach(callback, thisArg) { + const observed = this; + const target = observed["__v_raw"]; + const rawTarget = toRaw(target); + const wrap = shallow ? toShallow : readonly ? toReadonly : toReactive; + !readonly && track(rawTarget, "iterate", ITERATE_KEY); + return target.forEach((value, key) => { + return callback.call(thisArg, wrap(value), wrap(key), observed); + }); + } + }; + (0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .extend */ .X$)(instrumentations, readonly ? { + add: createReadonlyMethod("add"), + set: createReadonlyMethod("set"), + delete: createReadonlyMethod("delete"), + clear: createReadonlyMethod("clear") + } : { + add(value) { + if (!shallow && !isShallow(value) && !isReadonly(value)) { + value = toRaw(value); + } + const target = toRaw(this); + const proto = getProto(target); + const hadKey = proto.has.call(target, value); + if (!hadKey) { + target.add(value); + trigger(target, "add", value, value); + } + return this; + }, + set(key, value) { + if (!shallow && !isShallow(value) && !isReadonly(value)) { + value = toRaw(value); + } + const target = toRaw(this); + const { + has, + get + } = getProto(target); + let hadKey = has.call(target, key); + if (!hadKey) { + key = toRaw(key); + hadKey = has.call(target, key); + } else if (false) // removed by dead control flow +{} + const oldValue = get.call(target, key); + target.set(key, value); + if (!hadKey) { + trigger(target, "add", key, value); + } else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .hasChanged */ .$H)(value, oldValue)) { + trigger(target, "set", key, value, oldValue); + } + return this; + }, + delete(key) { + const target = toRaw(this); + const { + has, + get + } = getProto(target); + let hadKey = has.call(target, key); + if (!hadKey) { + key = toRaw(key); + hadKey = has.call(target, key); + } else if (false) // removed by dead control flow +{} + const oldValue = get ? get.call(target, key) : void 0; + const result = target.delete(key); + if (hadKey) { + trigger(target, "delete", key, void 0, oldValue); + } + return result; + }, + clear() { + const target = toRaw(this); + const hadItems = target.size !== 0; + const oldTarget = false ? 0 : void 0; + const result = target.clear(); + if (hadItems) { + trigger(target, "clear", void 0, void 0, oldTarget); + } + return result; + } + }); + const iteratorMethods = ["keys", "values", "entries", Symbol.iterator]; + iteratorMethods.forEach(method => { + instrumentations[method] = createIterableMethod(method, readonly, shallow); + }); + return instrumentations; +} +function createInstrumentationGetter(isReadonly2, shallow) { + const instrumentations = createInstrumentations(isReadonly2, shallow); + return (target, key, receiver) => { + if (key === "__v_isReactive") { + return !isReadonly2; + } else if (key === "__v_isReadonly") { + return isReadonly2; + } else if (key === "__v_raw") { + return target; + } + return Reflect.get((0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .hasOwn */ .$3)(instrumentations, key) && key in target ? instrumentations : target, key, receiver); + }; +} +const mutableCollectionHandlers = { + get: /* @__PURE__ */createInstrumentationGetter(false, false) +}; +const shallowCollectionHandlers = { + get: /* @__PURE__ */createInstrumentationGetter(false, true) +}; +const readonlyCollectionHandlers = { + get: /* @__PURE__ */createInstrumentationGetter(true, false) +}; +const shallowReadonlyCollectionHandlers = (/* unused pure expression or super */ null && ({ + get: /* @__PURE__ */createInstrumentationGetter(true, true) +})); +function checkIdentityKeys(target, has, key) { + const rawKey = toRaw(key); + if (rawKey !== key && has.call(target, rawKey)) { + const type = toRawType(target); + warn(`Reactive ${type} contains both the raw and reactive versions of the same object${type === `Map` ? ` as keys` : ``}, which can lead to inconsistencies. Avoid differentiating between the raw and reactive versions of an object and only use the reactive version if possible.`); + } +} +const reactiveMap = /* @__PURE__ */new WeakMap(); +const shallowReactiveMap = /* @__PURE__ */new WeakMap(); +const readonlyMap = /* @__PURE__ */new WeakMap(); +const shallowReadonlyMap = /* @__PURE__ */new WeakMap(); +function targetTypeMap(rawType) { + switch (rawType) { + case "Object": + case "Array": + return 1 /* COMMON */; + case "Map": + case "Set": + case "WeakMap": + case "WeakSet": + return 2 /* COLLECTION */; + default: + return 0 /* INVALID */; + } +} +function getTargetType(value) { + return value["__v_skip"] || !Object.isExtensible(value) ? 0 /* INVALID */ : targetTypeMap((0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .toRawType */ .Zf)(value)); +} +function reactive(target) { + if (isReadonly(target)) { + return target; + } + return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap); +} +function shallowReactive(target) { + return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers, shallowReactiveMap); +} +function readonly(target) { + return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap); +} +function shallowReadonly(target) { + return createReactiveObject(target, true, shallowReadonlyHandlers, shallowReadonlyCollectionHandlers, shallowReadonlyMap); +} +function createReactiveObject(target, isReadonly2, baseHandlers, collectionHandlers, proxyMap) { + if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isObject */ .Gv)(target)) { + if (false) // removed by dead control flow +{} + return target; + } + if (target["__v_raw"] && !(isReadonly2 && target["__v_isReactive"])) { + return target; + } + const existingProxy = proxyMap.get(target); + if (existingProxy) { + return existingProxy; + } + const targetType = getTargetType(target); + if (targetType === 0 /* INVALID */) { + return target; + } + const proxy = new Proxy(target, targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers); + proxyMap.set(target, proxy); + return proxy; +} +function isReactive(value) { + if (isReadonly(value)) { + return isReactive(value["__v_raw"]); + } + return !!(value && value["__v_isReactive"]); +} +function isReadonly(value) { + return !!(value && value["__v_isReadonly"]); +} +function isShallow(value) { + return !!(value && value["__v_isShallow"]); +} +function isProxy(value) { + return value ? !!value["__v_raw"] : false; +} +function toRaw(observed) { + const raw = observed && observed["__v_raw"]; + return raw ? toRaw(raw) : observed; +} +function markRaw(value) { + if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .hasOwn */ .$3)(value, "__v_skip") && Object.isExtensible(value)) { + (0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .def */ .yQ)(value, "__v_skip", true); + } + return value; +} +const toReactive = value => (0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isObject */ .Gv)(value) ? reactive(value) : value; +const toReadonly = value => (0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isObject */ .Gv)(value) ? readonly(value) : value; +function isRef(r) { + return r ? r["__v_isRef"] === true : false; +} +function ref(value) { + return createRef(value, false); +} +function shallowRef(value) { + return createRef(value, true); +} +function createRef(rawValue, shallow) { + if (isRef(rawValue)) { + return rawValue; + } + return new RefImpl(rawValue, shallow); +} +class RefImpl { + constructor(value, isShallow2) { + this.dep = new Dep(); + this["__v_isRef"] = true; + this["__v_isShallow"] = false; + this._rawValue = isShallow2 ? value : toRaw(value); + this._value = isShallow2 ? value : toReactive(value); + this["__v_isShallow"] = isShallow2; + } + get value() { + if (false) // removed by dead control flow +{} else { + this.dep.track(); + } + return this._value; + } + set value(newValue) { + const oldValue = this._rawValue; + const useDirectValue = this["__v_isShallow"] || isShallow(newValue) || isReadonly(newValue); + newValue = useDirectValue ? newValue : toRaw(newValue); + if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .hasChanged */ .$H)(newValue, oldValue)) { + this._rawValue = newValue; + this._value = useDirectValue ? newValue : toReactive(newValue); + if (false) // removed by dead control flow +{} else { + this.dep.trigger(); + } + } + } +} +function triggerRef(ref2) { + if (ref2.dep) { + if (false) // removed by dead control flow +{} else { + ref2.dep.trigger(); + } + } +} +function unref(ref2) { + return isRef(ref2) ? ref2.value : ref2; +} +function toValue(source) { + return isFunction(source) ? source() : unref(source); +} +const shallowUnwrapHandlers = { + get: (target, key, receiver) => key === "__v_raw" ? target : unref(Reflect.get(target, key, receiver)), + set: (target, key, value, receiver) => { + const oldValue = target[key]; + if (isRef(oldValue) && !isRef(value)) { + oldValue.value = value; + return true; + } else { + return Reflect.set(target, key, value, receiver); + } + } +}; +function proxyRefs(objectWithRefs) { + return isReactive(objectWithRefs) ? objectWithRefs : new Proxy(objectWithRefs, shallowUnwrapHandlers); +} +class CustomRefImpl { + constructor(factory) { + this["__v_isRef"] = true; + this._value = void 0; + const dep = this.dep = new Dep(); + const { + get, + set + } = factory(dep.track.bind(dep), dep.trigger.bind(dep)); + this._get = get; + this._set = set; + } + get value() { + return this._value = this._get(); + } + set value(newVal) { + this._set(newVal); + } +} +function customRef(factory) { + return new CustomRefImpl(factory); +} +function toRefs(object) { + if (false) // removed by dead control flow +{} + const ret = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isArray */ .cy)(object) ? new Array(object.length) : {}; + for (const key in object) { + ret[key] = propertyToRef(object, key); + } + return ret; +} +class ObjectRefImpl { + constructor(_object, _key, _defaultValue) { + this._object = _object; + this._key = _key; + this._defaultValue = _defaultValue; + this["__v_isRef"] = true; + this._value = void 0; + } + get value() { + const val = this._object[this._key]; + return this._value = val === void 0 ? this._defaultValue : val; + } + set value(newVal) { + this._object[this._key] = newVal; + } + get dep() { + return getDepFromReactive(toRaw(this._object), this._key); + } +} +class GetterRefImpl { + constructor(_getter) { + this._getter = _getter; + this["__v_isRef"] = true; + this["__v_isReadonly"] = true; + this._value = void 0; + } + get value() { + return this._value = this._getter(); + } +} +function toRef(source, key, defaultValue) { + if (isRef(source)) { + return source; + } else if (isFunction(source)) { + return new GetterRefImpl(source); + } else if (isObject(source) && arguments.length > 1) { + return propertyToRef(source, key, defaultValue); + } else { + return ref(source); + } +} +function propertyToRef(source, key, defaultValue) { + const val = source[key]; + return isRef(val) ? val : new ObjectRefImpl(source, key, defaultValue); +} +class ComputedRefImpl { + constructor(fn, setter, isSSR) { + this.fn = fn; + this.setter = setter; + /** + * @internal + */ + this._value = void 0; + /** + * @internal + */ + this.dep = new Dep(this); + /** + * @internal + */ + this.__v_isRef = true; + // TODO isolatedDeclarations "__v_isReadonly" + // A computed is also a subscriber that tracks other deps + /** + * @internal + */ + this.deps = void 0; + /** + * @internal + */ + this.depsTail = void 0; + /** + * @internal + */ + this.flags = 16; + /** + * @internal + */ + this.globalVersion = globalVersion - 1; + /** + * @internal + */ + this.next = void 0; + // for backwards compat + this.effect = this; + this["__v_isReadonly"] = !setter; + this.isSSR = isSSR; + } + /** + * @internal + */ + notify() { + this.flags |= 16; + if (!(this.flags & 8) && + // avoid infinite self recursion + activeSub !== this) { + batch(this, true); + return true; + } else if (false) // removed by dead control flow +{} + } + get value() { + const link = false ? 0 : this.dep.track(); + refreshComputed(this); + if (link) { + link.version = this.dep.version; + } + return this._value; + } + set value(newValue) { + if (this.setter) { + this.setter(newValue); + } else if (false) // removed by dead control flow +{} + } +} +function computed(getterOrOptions, debugOptions, isSSR = false) { + let getter; + let setter; + if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isFunction */ .Tn)(getterOrOptions)) { + getter = getterOrOptions; + } else { + getter = getterOrOptions.get; + setter = getterOrOptions.set; + } + const cRef = new ComputedRefImpl(getter, setter, isSSR); + if (false) // removed by dead control flow +{} + return cRef; +} +const TrackOpTypes = (/* unused pure expression or super */ null && ({ + "GET": "get", + "HAS": "has", + "ITERATE": "iterate" +})); +const TriggerOpTypes = (/* unused pure expression or super */ null && ({ + "SET": "set", + "ADD": "add", + "DELETE": "delete", + "CLEAR": "clear" +})); +const ReactiveFlags = (/* unused pure expression or super */ null && ({ + "SKIP": "__v_skip", + "IS_REACTIVE": "__v_isReactive", + "IS_READONLY": "__v_isReadonly", + "IS_SHALLOW": "__v_isShallow", + "RAW": "__v_raw", + "IS_REF": "__v_isRef" +})); +const WatchErrorCodes = (/* unused pure expression or super */ null && ({ + "WATCH_GETTER": 2, + "2": "WATCH_GETTER", + "WATCH_CALLBACK": 3, + "3": "WATCH_CALLBACK", + "WATCH_CLEANUP": 4, + "4": "WATCH_CLEANUP" +})); +const INITIAL_WATCHER_VALUE = {}; +const cleanupMap = /* @__PURE__ */new WeakMap(); +let activeWatcher = void 0; +function getCurrentWatcher() { + return activeWatcher; +} +function onWatcherCleanup(cleanupFn, failSilently = false, owner = activeWatcher) { + if (owner) { + let cleanups = cleanupMap.get(owner); + if (!cleanups) cleanupMap.set(owner, cleanups = []); + cleanups.push(cleanupFn); + } else if (false) // removed by dead control flow +{} +} +function watch(source, cb, options = _vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .EMPTY_OBJ */ .MZ) { + const { + immediate, + deep, + once, + scheduler, + augmentJob, + call + } = options; + const warnInvalidSource = s => { + (options.onWarn || warn)(`Invalid watch source: `, s, `A watch source can only be a getter/effect function, a ref, a reactive object, or an array of these types.`); + }; + const reactiveGetter = source2 => { + if (deep) return source2; + if (isShallow(source2) || deep === false || deep === 0) return traverse(source2, 1); + return traverse(source2); + }; + let effect; + let getter; + let cleanup; + let boundCleanup; + let forceTrigger = false; + let isMultiSource = false; + if (isRef(source)) { + getter = () => source.value; + forceTrigger = isShallow(source); + } else if (isReactive(source)) { + getter = () => reactiveGetter(source); + forceTrigger = true; + } else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isArray */ .cy)(source)) { + isMultiSource = true; + forceTrigger = source.some(s => isReactive(s) || isShallow(s)); + getter = () => source.map(s => { + if (isRef(s)) { + return s.value; + } else if (isReactive(s)) { + return reactiveGetter(s); + } else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isFunction */ .Tn)(s)) { + return call ? call(s, 2) : s(); + } else { + false && 0; + } + }); + } else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isFunction */ .Tn)(source)) { + if (cb) { + getter = call ? () => call(source, 2) : source; + } else { + getter = () => { + if (cleanup) { + pauseTracking(); + try { + cleanup(); + } finally { + resetTracking(); + } + } + const currentEffect = activeWatcher; + activeWatcher = effect; + try { + return call ? call(source, 3, [boundCleanup]) : source(boundCleanup); + } finally { + activeWatcher = currentEffect; + } + }; + } + } else { + getter = _vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .NOOP */ .tE; + false && 0; + } + if (cb && deep) { + const baseGetter = getter; + const depth = deep === true ? Infinity : deep; + getter = () => traverse(baseGetter(), depth); + } + const scope = getCurrentScope(); + const watchHandle = () => { + effect.stop(); + if (scope && scope.active) { + (0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .remove */ .TF)(scope.effects, effect); + } + }; + if (once && cb) { + const _cb = cb; + cb = (...args) => { + _cb(...args); + watchHandle(); + }; + } + let oldValue = isMultiSource ? new Array(source.length).fill(INITIAL_WATCHER_VALUE) : INITIAL_WATCHER_VALUE; + const job = immediateFirstRun => { + if (!(effect.flags & 1) || !effect.dirty && !immediateFirstRun) { + return; + } + if (cb) { + const newValue = effect.run(); + if (deep || forceTrigger || (isMultiSource ? newValue.some((v, i) => (0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .hasChanged */ .$H)(v, oldValue[i])) : (0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .hasChanged */ .$H)(newValue, oldValue))) { + if (cleanup) { + cleanup(); + } + const currentWatcher = activeWatcher; + activeWatcher = effect; + try { + const args = [newValue, + // pass undefined as the old value when it's changed for the first time + oldValue === INITIAL_WATCHER_VALUE ? void 0 : isMultiSource && oldValue[0] === INITIAL_WATCHER_VALUE ? [] : oldValue, boundCleanup]; + call ? call(cb, 3, args) : + // @ts-expect-error + cb(...args); + oldValue = newValue; + } finally { + activeWatcher = currentWatcher; + } + } + } else { + effect.run(); + } + }; + if (augmentJob) { + augmentJob(job); + } + effect = new ReactiveEffect(getter); + effect.scheduler = scheduler ? () => scheduler(job, false) : job; + boundCleanup = fn => onWatcherCleanup(fn, false, effect); + cleanup = effect.onStop = () => { + const cleanups = cleanupMap.get(effect); + if (cleanups) { + if (call) { + call(cleanups, 4); + } else { + for (const cleanup2 of cleanups) cleanup2(); + } + cleanupMap.delete(effect); + } + }; + if (false) // removed by dead control flow +{} + if (cb) { + if (immediate) { + job(true); + } else { + oldValue = effect.run(); + } + } else if (scheduler) { + scheduler(job.bind(null, true), true); + } else { + effect.run(); + } + watchHandle.pause = effect.pause.bind(effect); + watchHandle.resume = effect.resume.bind(effect); + watchHandle.stop = watchHandle; + return watchHandle; +} +function traverse(value, depth = Infinity, seen) { + if (depth <= 0 || !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isObject */ .Gv)(value) || value["__v_skip"]) { + return value; + } + seen = seen || /* @__PURE__ */new Set(); + if (seen.has(value)) { + return value; + } + seen.add(value); + depth--; + if (isRef(value)) { + traverse(value.value, depth, seen); + } else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isArray */ .cy)(value)) { + for (let i = 0; i < value.length; i++) { + traverse(value[i], depth, seen); + } + } else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isSet */ .vM)(value) || (0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isMap */ .CE)(value)) { + value.forEach(v => { + traverse(v, depth, seen); + }); + } else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_17__/* .isPlainObject */ .Qd)(value)) { + for (const key in value) { + traverse(value[key], depth, seen); + } + for (const key of Object.getOwnPropertySymbols(value)) { + if (Object.prototype.propertyIsEnumerable.call(value, key)) { + traverse(value[key], depth, seen); + } + } + } + return value; +} + + +/***/ }), + +/***/ 6107: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ pD: function() { return /* binding */ makeMap; } +/* harmony export */ }); +/* unused harmony exports EMPTY_ARR, NO, PatchFlagNames, PatchFlags, ShapeFlags, SlotFlags, camelize, capitalize, cssVarNameEscapeSymbolsRE, escapeHtml, escapeHtmlComment, genCacheKey, genPropsAccessExp, generateCodeFrame, getEscapedCssVarName, getGlobalThis, hyphenate, includeBooleanAttr, invokeArrayFns, isBooleanAttr, isBuiltInDirective, isDate, isGloballyAllowed, isGloballyWhitelisted, isHTMLTag, isKnownHtmlAttr, isKnownMathMLAttr, isKnownSvgAttr, isMathMLTag, isModelListener, isOn, isPromise, isRegExp, isRenderableAttrValue, isReservedProp, isSSRSafeAttrName, isSVGTag, isSpecialBooleanAttr, isString, isVoidTag, looseEqual, looseIndexOf, looseToNumber, normalizeClass, normalizeProps, normalizeStyle, objectToString, parseStringStyle, propsToAttrMap, slotFlagsText, stringifyStyle, toDisplayString, toHandlerKey, toNumber, toTypeString */ +/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4114); +/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8111); +/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2489); +/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7588); +/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_3__); + + + + +/** +* @vue/shared v3.5.13 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/ +/*! #__NO_SIDE_EFFECTS__ */ +// @__NO_SIDE_EFFECTS__ +function makeMap(str) { + const map = /* @__PURE__ */Object.create(null); + for (const key of str.split(",")) map[key] = 1; + return val => val in map; +} +const EMPTY_OBJ = false ? 0 : {}; +const EMPTY_ARR = false ? 0 : []; +const NOOP = () => {}; +const NO = () => false; +const isOn = key => key.charCodeAt(0) === 111 && key.charCodeAt(1) === 110 && ( +// uppercase letter +key.charCodeAt(2) > 122 || key.charCodeAt(2) < 97); +const isModelListener = key => key.startsWith("onUpdate:"); +const extend = Object.assign; +const remove = (arr, el) => { + const i = arr.indexOf(el); + if (i > -1) { + arr.splice(i, 1); + } +}; +const hasOwnProperty = Object.prototype.hasOwnProperty; +const hasOwn = (val, key) => hasOwnProperty.call(val, key); +const isArray = Array.isArray; +const isMap = val => toTypeString(val) === "[object Map]"; +const isSet = val => toTypeString(val) === "[object Set]"; +const isDate = val => toTypeString(val) === "[object Date]"; +const isRegExp = val => toTypeString(val) === "[object RegExp]"; +const isFunction = val => typeof val === "function"; +const isString = val => typeof val === "string"; +const isSymbol = val => typeof val === "symbol"; +const isObject = val => val !== null && typeof val === "object"; +const isPromise = val => { + return (isObject(val) || isFunction(val)) && isFunction(val.then) && isFunction(val.catch); +}; +const objectToString = Object.prototype.toString; +const toTypeString = value => objectToString.call(value); +const toRawType = value => { + return toTypeString(value).slice(8, -1); +}; +const isPlainObject = val => toTypeString(val) === "[object Object]"; +const isIntegerKey = key => isString(key) && key !== "NaN" && key[0] !== "-" && "" + parseInt(key, 10) === key; +const isReservedProp = /* @__PURE__ */(/* unused pure expression or super */ null && (makeMap( +// the leading comma is intentional so empty string "" is also included +",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"))); +const isBuiltInDirective = /* @__PURE__ */(/* unused pure expression or super */ null && (makeMap("bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo"))); +const cacheStringFunction = fn => { + const cache = /* @__PURE__ */Object.create(null); + return str => { + const hit = cache[str]; + return hit || (cache[str] = fn(str)); + }; +}; +const camelizeRE = /-(\w)/g; +const camelize = cacheStringFunction(str => { + return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : ""); +}); +const hyphenateRE = /\B([A-Z])/g; +const hyphenate = cacheStringFunction(str => str.replace(hyphenateRE, "-$1").toLowerCase()); +const capitalize = cacheStringFunction(str => { + return str.charAt(0).toUpperCase() + str.slice(1); +}); +const toHandlerKey = cacheStringFunction(str => { + const s = str ? `on${capitalize(str)}` : ``; + return s; +}); +const hasChanged = (value, oldValue) => !Object.is(value, oldValue); +const invokeArrayFns = (fns, ...arg) => { + for (let i = 0; i < fns.length; i++) { + fns[i](...arg); + } +}; +const def = (obj, key, value, writable = false) => { + Object.defineProperty(obj, key, { + configurable: true, + enumerable: false, + writable, + value + }); +}; +const looseToNumber = val => { + const n = parseFloat(val); + return isNaN(n) ? val : n; +}; +const toNumber = val => { + const n = isString(val) ? Number(val) : NaN; + return isNaN(n) ? val : n; +}; +let _globalThis; +const getGlobalThis = () => { + return _globalThis || (_globalThis = typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : typeof __webpack_require__.g !== "undefined" ? __webpack_require__.g : {}); +}; +const identRE = /^[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*$/; +function genPropsAccessExp(name) { + return identRE.test(name) ? `__props.${name}` : `__props[${JSON.stringify(name)}]`; +} +function genCacheKey(source, options) { + return source + JSON.stringify(options, (_, val) => typeof val === "function" ? val.toString() : val); +} +const PatchFlags = (/* unused pure expression or super */ null && ({ + "TEXT": 1, + "1": "TEXT", + "CLASS": 2, + "2": "CLASS", + "STYLE": 4, + "4": "STYLE", + "PROPS": 8, + "8": "PROPS", + "FULL_PROPS": 16, + "16": "FULL_PROPS", + "NEED_HYDRATION": 32, + "32": "NEED_HYDRATION", + "STABLE_FRAGMENT": 64, + "64": "STABLE_FRAGMENT", + "KEYED_FRAGMENT": 128, + "128": "KEYED_FRAGMENT", + "UNKEYED_FRAGMENT": 256, + "256": "UNKEYED_FRAGMENT", + "NEED_PATCH": 512, + "512": "NEED_PATCH", + "DYNAMIC_SLOTS": 1024, + "1024": "DYNAMIC_SLOTS", + "DEV_ROOT_FRAGMENT": 2048, + "2048": "DEV_ROOT_FRAGMENT", + "CACHED": -1, + "-1": "CACHED", + "BAIL": -2, + "-2": "BAIL" +})); +const PatchFlagNames = (/* unused pure expression or super */ null && ({ + [1]: `TEXT`, + [2]: `CLASS`, + [4]: `STYLE`, + [8]: `PROPS`, + [16]: `FULL_PROPS`, + [32]: `NEED_HYDRATION`, + [64]: `STABLE_FRAGMENT`, + [128]: `KEYED_FRAGMENT`, + [256]: `UNKEYED_FRAGMENT`, + [512]: `NEED_PATCH`, + [1024]: `DYNAMIC_SLOTS`, + [2048]: `DEV_ROOT_FRAGMENT`, + [-1]: `HOISTED`, + [-2]: `BAIL` +})); +const ShapeFlags = (/* unused pure expression or super */ null && ({ + "ELEMENT": 1, + "1": "ELEMENT", + "FUNCTIONAL_COMPONENT": 2, + "2": "FUNCTIONAL_COMPONENT", + "STATEFUL_COMPONENT": 4, + "4": "STATEFUL_COMPONENT", + "TEXT_CHILDREN": 8, + "8": "TEXT_CHILDREN", + "ARRAY_CHILDREN": 16, + "16": "ARRAY_CHILDREN", + "SLOTS_CHILDREN": 32, + "32": "SLOTS_CHILDREN", + "TELEPORT": 64, + "64": "TELEPORT", + "SUSPENSE": 128, + "128": "SUSPENSE", + "COMPONENT_SHOULD_KEEP_ALIVE": 256, + "256": "COMPONENT_SHOULD_KEEP_ALIVE", + "COMPONENT_KEPT_ALIVE": 512, + "512": "COMPONENT_KEPT_ALIVE", + "COMPONENT": 6, + "6": "COMPONENT" +})); +const SlotFlags = (/* unused pure expression or super */ null && ({ + "STABLE": 1, + "1": "STABLE", + "DYNAMIC": 2, + "2": "DYNAMIC", + "FORWARDED": 3, + "3": "FORWARDED" +})); +const slotFlagsText = (/* unused pure expression or super */ null && ({ + [1]: "STABLE", + [2]: "DYNAMIC", + [3]: "FORWARDED" +})); +const GLOBALS_ALLOWED = "Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt,console,Error,Symbol"; +const isGloballyAllowed = /* @__PURE__ */(/* unused pure expression or super */ null && (makeMap(GLOBALS_ALLOWED))); +const isGloballyWhitelisted = (/* unused pure expression or super */ null && (isGloballyAllowed)); +const range = 2; +function generateCodeFrame(source, start = 0, end = source.length) { + start = Math.max(0, Math.min(start, source.length)); + end = Math.max(0, Math.min(end, source.length)); + if (start > end) return ""; + let lines = source.split(/(\r?\n)/); + const newlineSequences = lines.filter((_, idx) => idx % 2 === 1); + lines = lines.filter((_, idx) => idx % 2 === 0); + let count = 0; + const res = []; + for (let i = 0; i < lines.length; i++) { + count += lines[i].length + (newlineSequences[i] && newlineSequences[i].length || 0); + if (count >= start) { + for (let j = i - range; j <= i + range || end > count; j++) { + if (j < 0 || j >= lines.length) continue; + const line = j + 1; + res.push(`${line}${" ".repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`); + const lineLength = lines[j].length; + const newLineSeqLength = newlineSequences[j] && newlineSequences[j].length || 0; + if (j === i) { + const pad = start - (count - (lineLength + newLineSeqLength)); + const length = Math.max(1, end > count ? lineLength - pad : end - start); + res.push(` | ` + " ".repeat(pad) + "^".repeat(length)); + } else if (j > i) { + if (end > count) { + const length = Math.max(Math.min(end - count, lineLength), 1); + res.push(` | ` + "^".repeat(length)); + } + count += lineLength + newLineSeqLength; + } + } + break; + } + } + return res.join("\n"); +} +function normalizeStyle(value) { + if (isArray(value)) { + const res = {}; + for (let i = 0; i < value.length; i++) { + const item = value[i]; + const normalized = isString(item) ? parseStringStyle(item) : normalizeStyle(item); + if (normalized) { + for (const key in normalized) { + res[key] = normalized[key]; + } + } + } + return res; + } else if (isString(value) || isObject(value)) { + return value; + } +} +const listDelimiterRE = /;(?![^(]*\))/g; +const propertyDelimiterRE = /:([^]+)/; +const styleCommentRE = /\/\*[^]*?\*\//g; +function parseStringStyle(cssText) { + const ret = {}; + cssText.replace(styleCommentRE, "").split(listDelimiterRE).forEach(item => { + if (item) { + const tmp = item.split(propertyDelimiterRE); + tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim()); + } + }); + return ret; +} +function stringifyStyle(styles) { + if (!styles) return ""; + if (isString(styles)) return styles; + let ret = ""; + for (const key in styles) { + const value = styles[key]; + if (isString(value) || typeof value === "number") { + const normalizedKey = key.startsWith(`--`) ? key : hyphenate(key); + ret += `${normalizedKey}:${value};`; + } + } + return ret; +} +function normalizeClass(value) { + let res = ""; + if (isString(value)) { + res = value; + } else if (isArray(value)) { + for (let i = 0; i < value.length; i++) { + const normalized = normalizeClass(value[i]); + if (normalized) { + res += normalized + " "; + } + } + } else if (isObject(value)) { + for (const name in value) { + if (value[name]) { + res += name + " "; + } + } + } + return res.trim(); +} +function normalizeProps(props) { + if (!props) return null; + let { + class: klass, + style + } = props; + if (klass && !isString(klass)) { + props.class = normalizeClass(klass); + } + if (style) { + props.style = normalizeStyle(style); + } + return props; +} +const HTML_TAGS = "html,body,base,head,link,meta,style,title,address,article,aside,footer,header,hgroup,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,summary,template,blockquote,iframe,tfoot"; +const SVG_TAGS = "svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,feDistantLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,text,textPath,title,tspan,unknown,use,view"; +const MATH_TAGS = "annotation,annotation-xml,maction,maligngroup,malignmark,math,menclose,merror,mfenced,mfrac,mfraction,mglyph,mi,mlabeledtr,mlongdiv,mmultiscripts,mn,mo,mover,mpadded,mphantom,mprescripts,mroot,mrow,ms,mscarries,mscarry,msgroup,msline,mspace,msqrt,msrow,mstack,mstyle,msub,msubsup,msup,mtable,mtd,mtext,mtr,munder,munderover,none,semantics"; +const VOID_TAGS = "area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr"; +const isHTMLTag = /* @__PURE__ */(/* unused pure expression or super */ null && (makeMap(HTML_TAGS))); +const isSVGTag = /* @__PURE__ */(/* unused pure expression or super */ null && (makeMap(SVG_TAGS))); +const isMathMLTag = /* @__PURE__ */(/* unused pure expression or super */ null && (makeMap(MATH_TAGS))); +const isVoidTag = /* @__PURE__ */(/* unused pure expression or super */ null && (makeMap(VOID_TAGS))); +const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`; +const isSpecialBooleanAttr = /* @__PURE__ */(/* unused pure expression or super */ null && (makeMap(specialBooleanAttrs))); +const isBooleanAttr = /* @__PURE__ */makeMap(specialBooleanAttrs + `,async,autofocus,autoplay,controls,default,defer,disabled,hidden,inert,loop,open,required,reversed,scoped,seamless,checked,muted,multiple,selected`); +function includeBooleanAttr(value) { + return !!value || value === ""; +} +const unsafeAttrCharRE = /[>/="'\u0009\u000a\u000c\u0020]/; +const attrValidationCache = (/* unused pure expression or super */ null && ({})); +function isSSRSafeAttrName(name) { + if (attrValidationCache.hasOwnProperty(name)) { + return attrValidationCache[name]; + } + const isUnsafe = unsafeAttrCharRE.test(name); + if (isUnsafe) { + console.error(`unsafe attribute name: ${name}`); + } + return attrValidationCache[name] = !isUnsafe; +} +const propsToAttrMap = (/* unused pure expression or super */ null && ({ + acceptCharset: "accept-charset", + className: "class", + htmlFor: "for", + httpEquiv: "http-equiv" +})); +const isKnownHtmlAttr = /* @__PURE__ */(/* unused pure expression or super */ null && (makeMap(`accept,accept-charset,accesskey,action,align,allow,alt,async,autocapitalize,autocomplete,autofocus,autoplay,background,bgcolor,border,buffered,capture,challenge,charset,checked,cite,class,code,codebase,color,cols,colspan,content,contenteditable,contextmenu,controls,coords,crossorigin,csp,data,datetime,decoding,default,defer,dir,dirname,disabled,download,draggable,dropzone,enctype,enterkeyhint,for,form,formaction,formenctype,formmethod,formnovalidate,formtarget,headers,height,hidden,high,href,hreflang,http-equiv,icon,id,importance,inert,integrity,ismap,itemprop,keytype,kind,label,lang,language,loading,list,loop,low,manifest,max,maxlength,minlength,media,min,multiple,muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,preload,radiogroup,readonly,referrerpolicy,rel,required,reversed,rows,rowspan,sandbox,scope,scoped,selected,shape,size,sizes,slot,span,spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,target,title,translate,type,usemap,value,width,wrap`))); +const isKnownSvgAttr = /* @__PURE__ */(/* unused pure expression or super */ null && (makeMap(`xmlns,accent-height,accumulate,additive,alignment-baseline,alphabetic,amplitude,arabic-form,ascent,attributeName,attributeType,azimuth,baseFrequency,baseline-shift,baseProfile,bbox,begin,bias,by,calcMode,cap-height,class,clip,clipPathUnits,clip-path,clip-rule,color,color-interpolation,color-interpolation-filters,color-profile,color-rendering,contentScriptType,contentStyleType,crossorigin,cursor,cx,cy,d,decelerate,descent,diffuseConstant,direction,display,divisor,dominant-baseline,dur,dx,dy,edgeMode,elevation,enable-background,end,exponent,fill,fill-opacity,fill-rule,filter,filterRes,filterUnits,flood-color,flood-opacity,font-family,font-size,font-size-adjust,font-stretch,font-style,font-variant,font-weight,format,from,fr,fx,fy,g1,g2,glyph-name,glyph-orientation-horizontal,glyph-orientation-vertical,glyphRef,gradientTransform,gradientUnits,hanging,height,href,hreflang,horiz-adv-x,horiz-origin-x,id,ideographic,image-rendering,in,in2,intercept,k,k1,k2,k3,k4,kernelMatrix,kernelUnitLength,kerning,keyPoints,keySplines,keyTimes,lang,lengthAdjust,letter-spacing,lighting-color,limitingConeAngle,local,marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,mask,maskContentUnits,maskUnits,mathematical,max,media,method,min,mode,name,numOctaves,offset,opacity,operator,order,orient,orientation,origin,overflow,overline-position,overline-thickness,panose-1,paint-order,path,pathLength,patternContentUnits,patternTransform,patternUnits,ping,pointer-events,points,pointsAtX,pointsAtY,pointsAtZ,preserveAlpha,preserveAspectRatio,primitiveUnits,r,radius,referrerPolicy,refX,refY,rel,rendering-intent,repeatCount,repeatDur,requiredExtensions,requiredFeatures,restart,result,rotate,rx,ry,scale,seed,shape-rendering,slope,spacing,specularConstant,specularExponent,speed,spreadMethod,startOffset,stdDeviation,stemh,stemv,stitchTiles,stop-color,stop-opacity,strikethrough-position,strikethrough-thickness,string,stroke,stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,stroke-width,style,surfaceScale,systemLanguage,tabindex,tableValues,target,targetX,targetY,text-anchor,text-decoration,text-rendering,textLength,to,transform,transform-origin,type,u1,u2,underline-position,underline-thickness,unicode,unicode-bidi,unicode-range,units-per-em,v-alphabetic,v-hanging,v-ideographic,v-mathematical,values,vector-effect,version,vert-adv-y,vert-origin-x,vert-origin-y,viewBox,viewTarget,visibility,width,widths,word-spacing,writing-mode,x,x-height,x1,x2,xChannelSelector,xlink:actuate,xlink:arcrole,xlink:href,xlink:role,xlink:show,xlink:title,xlink:type,xmlns:xlink,xml:base,xml:lang,xml:space,y,y1,y2,yChannelSelector,z,zoomAndPan`))); +const isKnownMathMLAttr = /* @__PURE__ */(/* unused pure expression or super */ null && (makeMap(`accent,accentunder,actiontype,align,alignmentscope,altimg,altimg-height,altimg-valign,altimg-width,alttext,bevelled,close,columnsalign,columnlines,columnspan,denomalign,depth,dir,display,displaystyle,encoding,equalcolumns,equalrows,fence,fontstyle,fontweight,form,frame,framespacing,groupalign,height,href,id,indentalign,indentalignfirst,indentalignlast,indentshift,indentshiftfirst,indentshiftlast,indextype,justify,largetop,largeop,lquote,lspace,mathbackground,mathcolor,mathsize,mathvariant,maxsize,minlabelspacing,mode,other,overflow,position,rowalign,rowlines,rowspan,rquote,rspace,scriptlevel,scriptminsize,scriptsizemultiplier,selection,separator,separators,shift,side,src,stackalign,stretchy,subscriptshift,superscriptshift,symmetric,voffset,width,widths,xlink:href,xlink:show,xlink:type,xmlns`))); +function isRenderableAttrValue(value) { + if (value == null) { + return false; + } + const type = typeof value; + return type === "string" || type === "number" || type === "boolean"; +} +const escapeRE = /["'&<>]/; +function escapeHtml(string) { + const str = "" + string; + const match = escapeRE.exec(str); + if (!match) { + return str; + } + let html = ""; + let escaped; + let index; + let lastIndex = 0; + for (index = match.index; index < str.length; index++) { + switch (str.charCodeAt(index)) { + case 34: + escaped = """; + break; + case 38: + escaped = "&"; + break; + case 39: + escaped = "'"; + break; + case 60: + escaped = "<"; + break; + case 62: + escaped = ">"; + break; + default: + continue; + } + if (lastIndex !== index) { + html += str.slice(lastIndex, index); + } + lastIndex = index + 1; + html += escaped; + } + return lastIndex !== index ? html + str.slice(lastIndex, index) : html; +} +const commentStripRE = /^-?>||--!>|?@[\\\]^`{|}~]/g; +function getEscapedCssVarName(key, doubleEscape) { + return key.replace(cssVarNameEscapeSymbolsRE, s => doubleEscape ? s === '"' ? '\\\\\\"' : `\\\\${s}` : `\\${s}`); +} +function looseCompareArrays(a, b) { + if (a.length !== b.length) return false; + let equal = true; + for (let i = 0; equal && i < a.length; i++) { + equal = looseEqual(a[i], b[i]); + } + return equal; +} +function looseEqual(a, b) { + if (a === b) return true; + let aValidType = isDate(a); + let bValidType = isDate(b); + if (aValidType || bValidType) { + return aValidType && bValidType ? a.getTime() === b.getTime() : false; + } + aValidType = isSymbol(a); + bValidType = isSymbol(b); + if (aValidType || bValidType) { + return a === b; + } + aValidType = isArray(a); + bValidType = isArray(b); + if (aValidType || bValidType) { + return aValidType && bValidType ? looseCompareArrays(a, b) : false; + } + aValidType = isObject(a); + bValidType = isObject(b); + if (aValidType || bValidType) { + if (!aValidType || !bValidType) { + return false; + } + const aKeysCount = Object.keys(a).length; + const bKeysCount = Object.keys(b).length; + if (aKeysCount !== bKeysCount) { + return false; + } + for (const key in a) { + const aHasKey = a.hasOwnProperty(key); + const bHasKey = b.hasOwnProperty(key); + if (aHasKey && !bHasKey || !aHasKey && bHasKey || !looseEqual(a[key], b[key])) { + return false; + } + } + } + return String(a) === String(b); +} +function looseIndexOf(arr, val) { + return arr.findIndex(item => looseEqual(item, val)); +} +const isRef = val => { + return !!(val && val["__v_isRef"] === true); +}; +const toDisplayString = val => { + return isString(val) ? val : val == null ? "" : isArray(val) || isObject(val) && (val.toString === objectToString || !isFunction(val.toString)) ? isRef(val) ? toDisplayString(val.value) : JSON.stringify(val, replacer, 2) : String(val); +}; +const replacer = (_key, val) => { + if (isRef(val)) { + return replacer(_key, val.value); + } else if (isMap(val)) { + return { + [`Map(${val.size})`]: [...val.entries()].reduce((entries, [key, val2], i) => { + entries[stringifySymbol(key, i) + " =>"] = val2; + return entries; + }, {}) + }; + } else if (isSet(val)) { + return { + [`Set(${val.size})`]: [...val.values()].map(v => stringifySymbol(v)) + }; + } else if (isSymbol(val)) { + return stringifySymbol(val); + } else if (isObject(val) && !isArray(val) && !isPlainObject(val)) { + return String(val); + } + return val; +}; +const stringifySymbol = (v, i = "") => { + var _a; + return ( + // Symbol.description in es2019+ so we need to cast here to pass + // the lib: es2016 check + isSymbol(v) ? `Symbol(${(_a = v.description) != null ? _a : i})` : v + ); +}; + +/* harmony export */ __webpack_require__.d(__webpack_exports__, [ +/* harmony export */ "$3", 0, /* binding */ hasOwn, +/* harmony export */ "$H", 0, /* binding */ hasChanged, +/* harmony export */ "Bm", 0, /* binding */ isSymbol, +/* harmony export */ "CE", 0, /* binding */ isMap, +/* harmony export */ "Gv", 0, /* binding */ isObject, +/* harmony export */ "MZ", 0, /* binding */ EMPTY_OBJ, +/* harmony export */ "Qd", 0, /* binding */ isPlainObject, +/* harmony export */ "TF", 0, /* binding */ remove, +/* harmony export */ "Tn", 0, /* binding */ isFunction, +/* harmony export */ "X$", 0, /* binding */ extend, +/* harmony export */ "Zf", 0, /* binding */ toRawType, +/* harmony export */ "cy", 0, /* binding */ isArray, +/* harmony export */ "tE", 0, /* binding */ NOOP, +/* harmony export */ "vM", 0, /* binding */ isSet, +/* harmony export */ "yI", 0, /* binding */ isIntegerKey, +/* harmony export */ "yQ", 0, /* binding */ def +/* harmony export */ ]); + + +/***/ }), + +/***/ 6768: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ CE: function() { return /* binding */ createElementBlock; }, +/* harmony export */ Fv: function() { return /* binding */ createStaticVNode; }, +/* harmony export */ K9: function() { return /* binding */ createRenderer; }, +/* harmony export */ Lk: function() { return /* binding */ createBaseVNode; }, +/* harmony export */ PS: function() { return /* binding */ hasInjectionContext; }, +/* harmony export */ Q3: function() { return /* binding */ createCommentVNode; }, +/* harmony export */ WQ: function() { return /* binding */ inject; }, +/* harmony export */ Wv: function() { return /* binding */ createBlock; }, +/* harmony export */ bo: function() { return /* binding */ withDirectives; }, +/* harmony export */ dY: function() { return /* binding */ nextTick; }, +/* harmony export */ qL: function() { return /* binding */ callWithAsyncErrorHandling; }, +/* harmony export */ uX: function() { return /* binding */ openBlock; }, +/* harmony export */ wB: function() { return /* binding */ watch; } +/* harmony export */ }); +/* unused harmony exports BaseTransition, BaseTransitionPropsValidators, Comment, DeprecationTypes, ErrorCodes, ErrorTypeStrings, KeepAlive, Static, Suspense, Teleport, Text, assertNumber, callWithErrorHandling, cloneVNode, compatUtils, createHydrationRenderer, createPropsRestProxy, createSlots, createTextVNode, defineAsyncComponent, defineComponent, defineEmits, defineExpose, defineModel, defineOptions, defineProps, defineSlots, devtools, getCurrentInstance, getTransitionRawChildren, guardReactiveProps, h, handleError, hydrateOnIdle, hydrateOnInteraction, hydrateOnMediaQuery, hydrateOnVisible, initCustomFormatter, isMemoSame, isRuntimeOnly, isVNode, mergeDefaults, mergeModels, mergeProps, onActivated, onBeforeMount, onBeforeUpdate, onDeactivated, onErrorCaptured, onRenderTracked, onRenderTriggered, onServerPrefetch, onUnmounted, onUpdated, popScopeId, provide, pushScopeId, queuePostFlushCb, registerRuntimeCompiler, renderList, renderSlot, resolveComponent, resolveDirective, resolveDynamicComponent, resolveFilter, resolveTransitionHooks, setBlockTracking, setDevtoolsHook, setTransitionHooks, ssrContextKey, ssrUtils, toHandlers, transformVNodeArgs, useAttrs, useId, useModel, useSSRContext, useSlots, useTemplateRef, useTransitionState, version, warn, watchEffect, watchPostEffect, watchSyncEffect, withAsyncContext, withCtx, withDefaults, withMemo, withScopeId */ +/* unused harmony import specifier */ var pauseTracking; +/* unused harmony import specifier */ var resetTracking; +/* unused harmony import specifier */ var isRef; +/* unused harmony import specifier */ var toRaw; +/* unused harmony import specifier */ var shallowRef; +/* unused harmony import specifier */ var isReactive; +/* unused harmony import specifier */ var ref; +/* unused harmony import specifier */ var isShallow; +/* unused harmony import specifier */ var shallowReadArray; +/* unused harmony import specifier */ var toReactive; +/* unused harmony import specifier */ var customRef; +/* unused harmony import specifier */ var track; +/* unused harmony import specifier */ var isString; +/* unused harmony import specifier */ var isFunction; +/* unused harmony import specifier */ var extend; +/* unused harmony import specifier */ var isBuiltInDirective; +/* unused harmony import specifier */ var isArray; +/* unused harmony import specifier */ var EMPTY_OBJ; +/* unused harmony import specifier */ var isOn; +/* unused harmony import specifier */ var isReservedProp; +/* unused harmony import specifier */ var normalizeClass; +/* unused harmony import specifier */ var stringifyStyle; +/* unused harmony import specifier */ var normalizeStyle; +/* unused harmony import specifier */ var isKnownSvgAttr; +/* unused harmony import specifier */ var isBooleanAttr; +/* unused harmony import specifier */ var isKnownHtmlAttr; +/* unused harmony import specifier */ var includeBooleanAttr; +/* unused harmony import specifier */ var isRenderableAttrValue; +/* unused harmony import specifier */ var getEscapedCssVarName; +/* unused harmony import specifier */ var invokeArrayFns; +/* unused harmony import specifier */ var isRegExp; +/* unused harmony import specifier */ var camelize; +/* unused harmony import specifier */ var capitalize; +/* unused harmony import specifier */ var isObject; +/* unused harmony import specifier */ var isSymbol; +/* unused harmony import specifier */ var toHandlerKey; +/* unused harmony import specifier */ var isGloballyAllowed; +/* unused harmony import specifier */ var NOOP; +/* unused harmony import specifier */ var isPromise; +/* unused harmony import specifier */ var makeMap; +/* unused harmony import specifier */ var toRawType; +/* unused harmony import specifier */ var hyphenate; +/* unused harmony import specifier */ var hasChanged; +/* unused harmony import specifier */ var toNumber; +/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423); +/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4114); +/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8111); +/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var core_js_modules_es_iterator_every_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1148); +/* harmony import */ var core_js_modules_es_iterator_every_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_every_js__WEBPACK_IMPORTED_MODULE_3__); +/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(2489); +/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_4__); +/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7588); +/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_5__); +/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(1701); +/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_6__); +/* harmony import */ var core_js_modules_es_iterator_reduce_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(8237); +/* harmony import */ var core_js_modules_es_iterator_reduce_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_reduce_js__WEBPACK_IMPORTED_MODULE_7__); +/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(3579); +/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_8__); +/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(5367); +/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_9__); +/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(2731); +/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_10__); +/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(7642); +/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_11__); +/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(8004); +/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_12__); +/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(3853); +/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_13__); +/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(5876); +/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_14___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_14__); +/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(2475); +/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_15__); +/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(5024); +/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_16___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_16__); +/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(1698); +/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_17___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_17__); +/* harmony import */ var core_js_modules_es_weak_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(8454); +/* harmony import */ var core_js_modules_es_weak_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_18___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_weak_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_18__); +/* harmony import */ var core_js_modules_es_weak_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(9452); +/* harmony import */ var core_js_modules_es_weak_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_19___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_weak_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_19__); +/* harmony import */ var _vue_reactivity__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(144); +/* harmony import */ var _vue_shared__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(5187); + + + + + + + + + + + + + + + + + + + + +/** +* @vue/runtime-core v3.5.13 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/ + + + + +const stack = (/* unused pure expression or super */ null && ([])); +function pushWarningContext(vnode) { + stack.push(vnode); +} +function popWarningContext() { + stack.pop(); +} +let isWarning = false; +function warn$1(msg, ...args) { + if (isWarning) return; + isWarning = true; + pauseTracking(); + const instance = stack.length ? stack[stack.length - 1].component : null; + const appWarnHandler = instance && instance.appContext.config.warnHandler; + const trace = getComponentTrace(); + if (appWarnHandler) { + callWithErrorHandling(appWarnHandler, instance, 11, [ + // eslint-disable-next-line no-restricted-syntax + msg + args.map(a => { + var _a, _b; + return (_b = (_a = a.toString) == null ? void 0 : _a.call(a)) != null ? _b : JSON.stringify(a); + }).join(""), instance && instance.proxy, trace.map(({ + vnode + }) => `at <${formatComponentName(instance, vnode.type)}>`).join("\n"), trace]); + } else { + const warnArgs = [`[Vue warn]: ${msg}`, ...args]; + if (trace.length && + // avoid spamming console during tests + true) { + warnArgs.push(` +`, ...formatTrace(trace)); + } + console.warn(...warnArgs); + } + resetTracking(); + isWarning = false; +} +function getComponentTrace() { + let currentVNode = stack[stack.length - 1]; + if (!currentVNode) { + return []; + } + const normalizedStack = []; + while (currentVNode) { + const last = normalizedStack[0]; + if (last && last.vnode === currentVNode) { + last.recurseCount++; + } else { + normalizedStack.push({ + vnode: currentVNode, + recurseCount: 0 + }); + } + const parentInstance = currentVNode.component && currentVNode.component.parent; + currentVNode = parentInstance && parentInstance.vnode; + } + return normalizedStack; +} +function formatTrace(trace) { + const logs = []; + trace.forEach((entry, i) => { + logs.push(...(i === 0 ? [] : [` +`]), ...formatTraceEntry(entry)); + }); + return logs; +} +function formatTraceEntry({ + vnode, + recurseCount +}) { + const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``; + const isRoot = vnode.component ? vnode.component.parent == null : false; + const open = ` at <${formatComponentName(vnode.component, vnode.type, isRoot)}`; + const close = `>` + postfix; + return vnode.props ? [open, ...formatProps(vnode.props), close] : [open + close]; +} +function formatProps(props) { + const res = []; + const keys = Object.keys(props); + keys.slice(0, 3).forEach(key => { + res.push(...formatProp(key, props[key])); + }); + if (keys.length > 3) { + res.push(` ...`); + } + return res; +} +function formatProp(key, value, raw) { + if (isString(value)) { + value = JSON.stringify(value); + return raw ? value : [`${key}=${value}`]; + } else if (typeof value === "number" || typeof value === "boolean" || value == null) { + return raw ? value : [`${key}=${value}`]; + } else if (isRef(value)) { + value = formatProp(key, toRaw(value.value), true); + return raw ? value : [`${key}=Ref<`, value, `>`]; + } else if (isFunction(value)) { + return [`${key}=fn${value.name ? `<${value.name}>` : ``}`]; + } else { + value = toRaw(value); + return raw ? value : [`${key}=`, value]; + } +} +function assertNumber(val, type) { + if (true) return; + // removed by dead control flow + +} +const ErrorCodes = (/* unused pure expression or super */ null && ({ + "SETUP_FUNCTION": 0, + "0": "SETUP_FUNCTION", + "RENDER_FUNCTION": 1, + "1": "RENDER_FUNCTION", + "NATIVE_EVENT_HANDLER": 5, + "5": "NATIVE_EVENT_HANDLER", + "COMPONENT_EVENT_HANDLER": 6, + "6": "COMPONENT_EVENT_HANDLER", + "VNODE_HOOK": 7, + "7": "VNODE_HOOK", + "DIRECTIVE_HOOK": 8, + "8": "DIRECTIVE_HOOK", + "TRANSITION_HOOK": 9, + "9": "TRANSITION_HOOK", + "APP_ERROR_HANDLER": 10, + "10": "APP_ERROR_HANDLER", + "APP_WARN_HANDLER": 11, + "11": "APP_WARN_HANDLER", + "FUNCTION_REF": 12, + "12": "FUNCTION_REF", + "ASYNC_COMPONENT_LOADER": 13, + "13": "ASYNC_COMPONENT_LOADER", + "SCHEDULER": 14, + "14": "SCHEDULER", + "COMPONENT_UPDATE": 15, + "15": "COMPONENT_UPDATE", + "APP_UNMOUNT_CLEANUP": 16, + "16": "APP_UNMOUNT_CLEANUP" +})); +const ErrorTypeStrings$1 = (/* unused pure expression or super */ null && ({ + ["sp"]: "serverPrefetch hook", + ["bc"]: "beforeCreate hook", + ["c"]: "created hook", + ["bm"]: "beforeMount hook", + ["m"]: "mounted hook", + ["bu"]: "beforeUpdate hook", + ["u"]: "updated", + ["bum"]: "beforeUnmount hook", + ["um"]: "unmounted hook", + ["a"]: "activated hook", + ["da"]: "deactivated hook", + ["ec"]: "errorCaptured hook", + ["rtc"]: "renderTracked hook", + ["rtg"]: "renderTriggered hook", + [0]: "setup function", + [1]: "render function", + [2]: "watcher getter", + [3]: "watcher callback", + [4]: "watcher cleanup function", + [5]: "native event handler", + [6]: "component event handler", + [7]: "vnode hook", + [8]: "directive hook", + [9]: "transition hook", + [10]: "app errorHandler", + [11]: "app warnHandler", + [12]: "ref function", + [13]: "async component loader", + [14]: "scheduler flush", + [15]: "component update", + [16]: "app unmount cleanup function" +})); +function callWithErrorHandling(fn, instance, type, args) { + try { + return args ? fn(...args) : fn(); + } catch (err) { + handleError(err, instance, type); + } +} +function callWithAsyncErrorHandling(fn, instance, type, args) { + if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .isFunction */ .Tn)(fn)) { + const res = callWithErrorHandling(fn, instance, type, args); + if (res && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .isPromise */ .yL)(res)) { + res.catch(err => { + handleError(err, instance, type); + }); + } + return res; + } + if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .isArray */ .cy)(fn)) { + const values = []; + for (let i = 0; i < fn.length; i++) { + values.push(callWithAsyncErrorHandling(fn[i], instance, type, args)); + } + return values; + } else if (false) // removed by dead control flow +{} +} +function handleError(err, instance, type, throwInDev = true) { + const contextVNode = instance ? instance.vnode : null; + const { + errorHandler, + throwUnhandledErrorInProduction + } = instance && instance.appContext.config || _vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .EMPTY_OBJ */ .MZ; + if (instance) { + let cur = instance.parent; + const exposedInstance = instance.proxy; + const errorInfo = false ? 0 : `https://vuejs.org/error-reference/#runtime-${type}`; + while (cur) { + const errorCapturedHooks = cur.ec; + if (errorCapturedHooks) { + for (let i = 0; i < errorCapturedHooks.length; i++) { + if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) { + return; + } + } + } + cur = cur.parent; + } + if (errorHandler) { + (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_20__/* .pauseTracking */ .C4)(); + callWithErrorHandling(errorHandler, null, 10, [err, exposedInstance, errorInfo]); + (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_20__/* .resetTracking */ .bl)(); + return; + } + } + logError(err, type, contextVNode, throwInDev, throwUnhandledErrorInProduction); +} +function logError(err, type, contextVNode, throwInDev = true, throwInProd = false) { + if (false) // removed by dead control flow +{} else if (throwInProd) { + throw err; + } else { + console.error(err); + } +} +const queue = []; +let flushIndex = -1; +const pendingPostFlushCbs = []; +let activePostFlushCbs = null; +let postFlushIndex = 0; +const resolvedPromise = /* @__PURE__ */Promise.resolve(); +let currentFlushPromise = null; +const RECURSION_LIMIT = 100; +function nextTick(fn) { + const p = currentFlushPromise || resolvedPromise; + return fn ? p.then(this ? fn.bind(this) : fn) : p; +} +function findInsertionIndex(id) { + let start = flushIndex + 1; + let end = queue.length; + while (start < end) { + const middle = start + end >>> 1; + const middleJob = queue[middle]; + const middleJobId = getId(middleJob); + if (middleJobId < id || middleJobId === id && middleJob.flags & 2) { + start = middle + 1; + } else { + end = middle; + } + } + return start; +} +function queueJob(job) { + if (!(job.flags & 1)) { + const jobId = getId(job); + const lastJob = queue[queue.length - 1]; + if (!lastJob || + // fast path when the job id is larger than the tail + !(job.flags & 2) && jobId >= getId(lastJob)) { + queue.push(job); + } else { + queue.splice(findInsertionIndex(jobId), 0, job); + } + job.flags |= 1; + queueFlush(); + } +} +function queueFlush() { + if (!currentFlushPromise) { + currentFlushPromise = resolvedPromise.then(flushJobs); + } +} +function queuePostFlushCb(cb) { + if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .isArray */ .cy)(cb)) { + if (activePostFlushCbs && cb.id === -1) { + activePostFlushCbs.splice(postFlushIndex + 1, 0, cb); + } else if (!(cb.flags & 1)) { + pendingPostFlushCbs.push(cb); + cb.flags |= 1; + } + } else { + pendingPostFlushCbs.push(...cb); + } + queueFlush(); +} +function flushPreFlushCbs(instance, seen, i = flushIndex + 1) { + if (false) // removed by dead control flow +{} + for (; i < queue.length; i++) { + const cb = queue[i]; + if (cb && cb.flags & 2) { + if (instance && cb.id !== instance.uid) { + continue; + } + if (false) // removed by dead control flow +{} + queue.splice(i, 1); + i--; + if (cb.flags & 4) { + cb.flags &= ~1; + } + cb(); + if (!(cb.flags & 4)) { + cb.flags &= ~1; + } + } + } +} +function flushPostFlushCbs(seen) { + if (pendingPostFlushCbs.length) { + const deduped = [...new Set(pendingPostFlushCbs)].sort((a, b) => getId(a) - getId(b)); + pendingPostFlushCbs.length = 0; + if (activePostFlushCbs) { + activePostFlushCbs.push(...deduped); + return; + } + activePostFlushCbs = deduped; + if (false) // removed by dead control flow +{} + for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) { + const cb = activePostFlushCbs[postFlushIndex]; + if (false) // removed by dead control flow +{} + if (cb.flags & 4) { + cb.flags &= ~1; + } + if (!(cb.flags & 8)) cb(); + cb.flags &= ~1; + } + activePostFlushCbs = null; + postFlushIndex = 0; + } +} +const getId = job => job.id == null ? job.flags & 2 ? -1 : Infinity : job.id; +function flushJobs(seen) { + if (false) // removed by dead control flow +{} + const check = false ? 0 : _vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .NOOP */ .tE; + try { + for (flushIndex = 0; flushIndex < queue.length; flushIndex++) { + const job = queue[flushIndex]; + if (job && !(job.flags & 8)) { + if (false) // removed by dead control flow +{} + if (job.flags & 4) { + job.flags &= ~1; + } + callWithErrorHandling(job, job.i, job.i ? 15 : 14); + if (!(job.flags & 4)) { + job.flags &= ~1; + } + } + } + } finally { + for (; flushIndex < queue.length; flushIndex++) { + const job = queue[flushIndex]; + if (job) { + job.flags &= ~1; + } + } + flushIndex = -1; + queue.length = 0; + flushPostFlushCbs(seen); + currentFlushPromise = null; + if (queue.length || pendingPostFlushCbs.length) { + flushJobs(seen); + } + } +} +function checkRecursiveUpdates(seen, fn) { + const count = seen.get(fn) || 0; + if (count > RECURSION_LIMIT) { + const instance = fn.i; + const componentName = instance && getComponentName(instance.type); + handleError(`Maximum recursive updates exceeded${componentName ? ` in component <${componentName}>` : ``}. This means you have a reactive effect that is mutating its own dependencies and thus recursively triggering itself. Possible sources include component template, render function, updated hook or watcher source function.`, null, 10); + return true; + } + seen.set(fn, count + 1); + return false; +} +let isHmrUpdating = false; +const hmrDirtyComponents = /* @__PURE__ */(/* unused pure expression or super */ null && (new Map())); +if (false) // removed by dead control flow +{} +const map = /* @__PURE__ */(/* unused pure expression or super */ null && (new Map())); +function registerHMR(instance) { + const id = instance.type.__hmrId; + let record = map.get(id); + if (!record) { + createRecord(id, instance.type); + record = map.get(id); + } + record.instances.add(instance); +} +function unregisterHMR(instance) { + map.get(instance.type.__hmrId).instances.delete(instance); +} +function createRecord(id, initialDef) { + if (map.has(id)) { + return false; + } + map.set(id, { + initialDef: normalizeClassComponent(initialDef), + instances: /* @__PURE__ */new Set() + }); + return true; +} +function normalizeClassComponent(component) { + return isClassComponent(component) ? component.__vccOpts : component; +} +function rerender(id, newRender) { + const record = map.get(id); + if (!record) { + return; + } + record.initialDef.render = newRender; + [...record.instances].forEach(instance => { + if (newRender) { + instance.render = newRender; + normalizeClassComponent(instance.type).render = newRender; + } + instance.renderCache = []; + isHmrUpdating = true; + instance.update(); + isHmrUpdating = false; + }); +} +function reload(id, newComp) { + const record = map.get(id); + if (!record) return; + newComp = normalizeClassComponent(newComp); + updateComponentDef(record.initialDef, newComp); + const instances = [...record.instances]; + for (let i = 0; i < instances.length; i++) { + const instance = instances[i]; + const oldComp = normalizeClassComponent(instance.type); + let dirtyInstances = hmrDirtyComponents.get(oldComp); + if (!dirtyInstances) { + if (oldComp !== record.initialDef) { + updateComponentDef(oldComp, newComp); + } + hmrDirtyComponents.set(oldComp, dirtyInstances = /* @__PURE__ */new Set()); + } + dirtyInstances.add(instance); + instance.appContext.propsCache.delete(instance.type); + instance.appContext.emitsCache.delete(instance.type); + instance.appContext.optionsCache.delete(instance.type); + if (instance.ceReload) { + dirtyInstances.add(instance); + instance.ceReload(newComp.styles); + dirtyInstances.delete(instance); + } else if (instance.parent) { + queueJob(() => { + isHmrUpdating = true; + instance.parent.update(); + isHmrUpdating = false; + dirtyInstances.delete(instance); + }); + } else if (instance.appContext.reload) { + instance.appContext.reload(); + } else if (typeof window !== "undefined") { + window.location.reload(); + } else { + console.warn("[HMR] Root or manually mounted instance modified. Full reload required."); + } + if (instance.root.ce && instance !== instance.root) { + instance.root.ce._removeChildStyle(oldComp); + } + } + queuePostFlushCb(() => { + hmrDirtyComponents.clear(); + }); +} +function updateComponentDef(oldComp, newComp) { + extend(oldComp, newComp); + for (const key in oldComp) { + if (key !== "__file" && !(key in newComp)) { + delete oldComp[key]; + } + } +} +function tryWrap(fn) { + return (id, arg) => { + try { + return fn(id, arg); + } catch (e) { + console.error(e); + console.warn(`[HMR] Something went wrong during Vue component hot-reload. Full reload required.`); + } + }; +} +let devtools$1; +let buffer = (/* unused pure expression or super */ null && ([])); +let devtoolsNotInstalled = false; +function emit$1(event, ...args) { + if (devtools$1) { + devtools$1.emit(event, ...args); + } else if (!devtoolsNotInstalled) { + buffer.push({ + event, + args + }); + } +} +function setDevtoolsHook$1(hook, target) { + var _a, _b; + devtools$1 = hook; + if (devtools$1) { + devtools$1.enabled = true; + buffer.forEach(({ + event, + args + }) => devtools$1.emit(event, ...args)); + buffer = []; + } else if ( + // handle late devtools injection - only do this if we are in an actual + // browser environment to avoid the timer handle stalling test runner exit + // (#4815) + typeof window !== "undefined" && + // some envs mock window but not fully + window.HTMLElement && + // also exclude jsdom + // eslint-disable-next-line no-restricted-syntax + !((_b = (_a = window.navigator) == null ? void 0 : _a.userAgent) == null ? void 0 : _b.includes("jsdom"))) { + const replay = target.__VUE_DEVTOOLS_HOOK_REPLAY__ = target.__VUE_DEVTOOLS_HOOK_REPLAY__ || []; + replay.push(newHook => { + setDevtoolsHook$1(newHook, target); + }); + setTimeout(() => { + if (!devtools$1) { + target.__VUE_DEVTOOLS_HOOK_REPLAY__ = null; + devtoolsNotInstalled = true; + buffer = []; + } + }, 3e3); + } else { + devtoolsNotInstalled = true; + buffer = []; + } +} +function devtoolsInitApp(app, version) { + emit$1("app:init" /* APP_INIT */, app, version, { + Fragment, + Text, + Comment, + Static + }); +} +function devtoolsUnmountApp(app) { + emit$1("app:unmount" /* APP_UNMOUNT */, app); +} +const devtoolsComponentAdded = /* @__PURE__ */(/* unused pure expression or super */ null && (createDevtoolsComponentHook("component:added" /* COMPONENT_ADDED */))); +const devtoolsComponentUpdated = /* @__PURE__ */(/* unused pure expression or super */ null && (createDevtoolsComponentHook("component:updated" /* COMPONENT_UPDATED */))); +const _devtoolsComponentRemoved = /* @__PURE__ */(/* unused pure expression or super */ null && (createDevtoolsComponentHook("component:removed" /* COMPONENT_REMOVED */))); +const devtoolsComponentRemoved = component => { + if (devtools$1 && typeof devtools$1.cleanupBuffer === "function" && + // remove the component if it wasn't buffered + !devtools$1.cleanupBuffer(component)) { + _devtoolsComponentRemoved(component); + } +}; +/*! #__NO_SIDE_EFFECTS__ */ +// @__NO_SIDE_EFFECTS__ +function createDevtoolsComponentHook(hook) { + return component => { + emit$1(hook, component.appContext.app, component.uid, component.parent ? component.parent.uid : void 0, component); + }; +} +const devtoolsPerfStart = /* @__PURE__ */(/* unused pure expression or super */ null && (createDevtoolsPerformanceHook("perf:start" /* PERFORMANCE_START */))); +const devtoolsPerfEnd = /* @__PURE__ */(/* unused pure expression or super */ null && (createDevtoolsPerformanceHook("perf:end" /* PERFORMANCE_END */))); +function createDevtoolsPerformanceHook(hook) { + return (component, type, time) => { + emit$1(hook, component.appContext.app, component.uid, component, type, time); + }; +} +function devtoolsComponentEmit(component, event, params) { + emit$1("component:emit" /* COMPONENT_EMIT */, component.appContext.app, component, event, params); +} +let currentRenderingInstance = null; +let currentScopeId = null; +function setCurrentRenderingInstance(instance) { + const prev = currentRenderingInstance; + currentRenderingInstance = instance; + currentScopeId = instance && instance.type.__scopeId || null; + return prev; +} +function pushScopeId(id) { + currentScopeId = id; +} +function popScopeId() { + currentScopeId = null; +} +const withScopeId = _id => withCtx; +function withCtx(fn, ctx = currentRenderingInstance, isNonScopedSlot) { + if (!ctx) return fn; + if (fn._n) { + return fn; + } + const renderFnWithContext = (...args) => { + if (renderFnWithContext._d) { + setBlockTracking(-1); + } + const prevInstance = setCurrentRenderingInstance(ctx); + let res; + try { + res = fn(...args); + } finally { + setCurrentRenderingInstance(prevInstance); + if (renderFnWithContext._d) { + setBlockTracking(1); + } + } + if (false) // removed by dead control flow +{} + return res; + }; + renderFnWithContext._n = true; + renderFnWithContext._c = true; + renderFnWithContext._d = true; + return renderFnWithContext; +} +function validateDirectiveName(name) { + if (isBuiltInDirective(name)) { + warn$1("Do not use built-in directive ids as custom directive id: " + name); + } +} +function withDirectives(vnode, directives) { + if (currentRenderingInstance === null) { + false && 0; + return vnode; + } + const instance = getComponentPublicInstance(currentRenderingInstance); + const bindings = vnode.dirs || (vnode.dirs = []); + for (let i = 0; i < directives.length; i++) { + let [dir, value, arg, modifiers = _vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .EMPTY_OBJ */ .MZ] = directives[i]; + if (dir) { + if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .isFunction */ .Tn)(dir)) { + dir = { + mounted: dir, + updated: dir + }; + } + if (dir.deep) { + (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_20__/* .traverse */ .hV)(value); + } + bindings.push({ + dir, + instance, + value, + oldValue: void 0, + arg, + modifiers + }); + } + } + return vnode; +} +function invokeDirectiveHook(vnode, prevVNode, instance, name) { + const bindings = vnode.dirs; + const oldBindings = prevVNode && prevVNode.dirs; + for (let i = 0; i < bindings.length; i++) { + const binding = bindings[i]; + if (oldBindings) { + binding.oldValue = oldBindings[i].value; + } + let hook = binding.dir[name]; + if (hook) { + (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_20__/* .pauseTracking */ .C4)(); + callWithAsyncErrorHandling(hook, instance, 8, [vnode.el, binding, vnode, prevVNode]); + (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_20__/* .resetTracking */ .bl)(); + } + } +} +const TeleportEndKey = Symbol("_vte"); +const isTeleport = type => type.__isTeleport; +const isTeleportDisabled = props => props && (props.disabled || props.disabled === ""); +const isTeleportDeferred = props => props && (props.defer || props.defer === ""); +const isTargetSVG = target => typeof SVGElement !== "undefined" && target instanceof SVGElement; +const isTargetMathML = target => typeof MathMLElement === "function" && target instanceof MathMLElement; +const resolveTarget = (props, select) => { + const targetSelector = props && props.to; + if (isString(targetSelector)) { + if (!select) { + false && 0; + return null; + } else { + const target = select(targetSelector); + if (false) // removed by dead control flow +{} + return target; + } + } else { + if (false) // removed by dead control flow +{} + return targetSelector; + } +}; +const TeleportImpl = (/* unused pure expression or super */ null && ({ + name: "Teleport", + __isTeleport: true, + process(n1, n2, container, anchor, parentComponent, parentSuspense, namespace, slotScopeIds, optimized, internals) { + const { + mc: mountChildren, + pc: patchChildren, + pbc: patchBlockChildren, + o: { + insert, + querySelector, + createText, + createComment + } + } = internals; + const disabled = isTeleportDisabled(n2.props); + let { + shapeFlag, + children, + dynamicChildren + } = n2; + if (false) // removed by dead control flow +{} + if (n1 == null) { + const placeholder = n2.el = false ? 0 : createText(""); + const mainAnchor = n2.anchor = false ? 0 : createText(""); + insert(placeholder, container, anchor); + insert(mainAnchor, container, anchor); + const mount = (container2, anchor2) => { + if (shapeFlag & 16) { + if (parentComponent && parentComponent.isCE) { + parentComponent.ce._teleportTarget = container2; + } + mountChildren(children, container2, anchor2, parentComponent, parentSuspense, namespace, slotScopeIds, optimized); + } + }; + const mountToTarget = () => { + const target = n2.target = resolveTarget(n2.props, querySelector); + const targetAnchor = prepareAnchor(target, n2, createText, insert); + if (target) { + if (namespace !== "svg" && isTargetSVG(target)) { + namespace = "svg"; + } else if (namespace !== "mathml" && isTargetMathML(target)) { + namespace = "mathml"; + } + if (!disabled) { + mount(target, targetAnchor); + updateCssVars(n2, false); + } + } else if (false) // removed by dead control flow +{} + }; + if (disabled) { + mount(container, mainAnchor); + updateCssVars(n2, true); + } + if (isTeleportDeferred(n2.props)) { + queuePostRenderEffect(() => { + mountToTarget(); + n2.el.__isMounted = true; + }, parentSuspense); + } else { + mountToTarget(); + } + } else { + if (isTeleportDeferred(n2.props) && !n1.el.__isMounted) { + queuePostRenderEffect(() => { + TeleportImpl.process(n1, n2, container, anchor, parentComponent, parentSuspense, namespace, slotScopeIds, optimized, internals); + delete n1.el.__isMounted; + }, parentSuspense); + return; + } + n2.el = n1.el; + n2.targetStart = n1.targetStart; + const mainAnchor = n2.anchor = n1.anchor; + const target = n2.target = n1.target; + const targetAnchor = n2.targetAnchor = n1.targetAnchor; + const wasDisabled = isTeleportDisabled(n1.props); + const currentContainer = wasDisabled ? container : target; + const currentAnchor = wasDisabled ? mainAnchor : targetAnchor; + if (namespace === "svg" || isTargetSVG(target)) { + namespace = "svg"; + } else if (namespace === "mathml" || isTargetMathML(target)) { + namespace = "mathml"; + } + if (dynamicChildren) { + patchBlockChildren(n1.dynamicChildren, dynamicChildren, currentContainer, parentComponent, parentSuspense, namespace, slotScopeIds); + traverseStaticChildren(n1, n2, true); + } else if (!optimized) { + patchChildren(n1, n2, currentContainer, currentAnchor, parentComponent, parentSuspense, namespace, slotScopeIds, false); + } + if (disabled) { + if (!wasDisabled) { + moveTeleport(n2, container, mainAnchor, internals, 1); + } else { + if (n2.props && n1.props && n2.props.to !== n1.props.to) { + n2.props.to = n1.props.to; + } + } + } else { + if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) { + const nextTarget = n2.target = resolveTarget(n2.props, querySelector); + if (nextTarget) { + moveTeleport(n2, nextTarget, null, internals, 0); + } else if (false) // removed by dead control flow +{} + } else if (wasDisabled) { + moveTeleport(n2, target, targetAnchor, internals, 1); + } + } + updateCssVars(n2, disabled); + } + }, + remove(vnode, parentComponent, parentSuspense, { + um: unmount, + o: { + remove: hostRemove + } + }, doRemove) { + const { + shapeFlag, + children, + anchor, + targetStart, + targetAnchor, + target, + props + } = vnode; + if (target) { + hostRemove(targetStart); + hostRemove(targetAnchor); + } + doRemove && hostRemove(anchor); + if (shapeFlag & 16) { + const shouldRemove = doRemove || !isTeleportDisabled(props); + for (let i = 0; i < children.length; i++) { + const child = children[i]; + unmount(child, parentComponent, parentSuspense, shouldRemove, !!child.dynamicChildren); + } + } + }, + move: moveTeleport, + hydrate: hydrateTeleport +})); +function moveTeleport(vnode, container, parentAnchor, { + o: { + insert + }, + m: move +}, moveType = 2) { + if (moveType === 0) { + insert(vnode.targetAnchor, container, parentAnchor); + } + const { + el, + anchor, + shapeFlag, + children, + props + } = vnode; + const isReorder = moveType === 2; + if (isReorder) { + insert(el, container, parentAnchor); + } + if (!isReorder || isTeleportDisabled(props)) { + if (shapeFlag & 16) { + for (let i = 0; i < children.length; i++) { + move(children[i], container, parentAnchor, 2); + } + } + } + if (isReorder) { + insert(anchor, container, parentAnchor); + } +} +function hydrateTeleport(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, { + o: { + nextSibling, + parentNode, + querySelector, + insert, + createText + } +}, hydrateChildren) { + const target = vnode.target = resolveTarget(vnode.props, querySelector); + if (target) { + const disabled = isTeleportDisabled(vnode.props); + const targetNode = target._lpa || target.firstChild; + if (vnode.shapeFlag & 16) { + if (disabled) { + vnode.anchor = hydrateChildren(nextSibling(node), vnode, parentNode(node), parentComponent, parentSuspense, slotScopeIds, optimized); + vnode.targetStart = targetNode; + vnode.targetAnchor = targetNode && nextSibling(targetNode); + } else { + vnode.anchor = nextSibling(node); + let targetAnchor = targetNode; + while (targetAnchor) { + if (targetAnchor && targetAnchor.nodeType === 8) { + if (targetAnchor.data === "teleport start anchor") { + vnode.targetStart = targetAnchor; + } else if (targetAnchor.data === "teleport anchor") { + vnode.targetAnchor = targetAnchor; + target._lpa = vnode.targetAnchor && nextSibling(vnode.targetAnchor); + break; + } + } + targetAnchor = nextSibling(targetAnchor); + } + if (!vnode.targetAnchor) { + prepareAnchor(target, vnode, createText, insert); + } + hydrateChildren(targetNode && nextSibling(targetNode), vnode, target, parentComponent, parentSuspense, slotScopeIds, optimized); + } + } + updateCssVars(vnode, disabled); + } + return vnode.anchor && nextSibling(vnode.anchor); +} +const Teleport = (/* unused pure expression or super */ null && (TeleportImpl)); +function updateCssVars(vnode, isDisabled) { + const ctx = vnode.ctx; + if (ctx && ctx.ut) { + let node, anchor; + if (isDisabled) { + node = vnode.el; + anchor = vnode.anchor; + } else { + node = vnode.targetStart; + anchor = vnode.targetAnchor; + } + while (node && node !== anchor) { + if (node.nodeType === 1) node.setAttribute("data-v-owner", ctx.uid); + node = node.nextSibling; + } + ctx.ut(); + } +} +function prepareAnchor(target, vnode, createText, insert) { + const targetStart = vnode.targetStart = createText(""); + const targetAnchor = vnode.targetAnchor = createText(""); + targetStart[TeleportEndKey] = targetAnchor; + if (target) { + insert(targetStart, target); + insert(targetAnchor, target); + } + return targetAnchor; +} +const leaveCbKey = Symbol("_leaveCb"); +const enterCbKey = Symbol("_enterCb"); +function useTransitionState() { + const state = { + isMounted: false, + isLeaving: false, + isUnmounting: false, + leavingVNodes: /* @__PURE__ */new Map() + }; + onMounted(() => { + state.isMounted = true; + }); + onBeforeUnmount(() => { + state.isUnmounting = true; + }); + return state; +} +const TransitionHookValidator = (/* unused pure expression or super */ null && ([Function, Array])); +const BaseTransitionPropsValidators = (/* unused pure expression or super */ null && ({ + mode: String, + appear: Boolean, + persisted: Boolean, + // enter + onBeforeEnter: TransitionHookValidator, + onEnter: TransitionHookValidator, + onAfterEnter: TransitionHookValidator, + onEnterCancelled: TransitionHookValidator, + // leave + onBeforeLeave: TransitionHookValidator, + onLeave: TransitionHookValidator, + onAfterLeave: TransitionHookValidator, + onLeaveCancelled: TransitionHookValidator, + // appear + onBeforeAppear: TransitionHookValidator, + onAppear: TransitionHookValidator, + onAfterAppear: TransitionHookValidator, + onAppearCancelled: TransitionHookValidator +})); +const recursiveGetSubtree = instance => { + const subTree = instance.subTree; + return subTree.component ? recursiveGetSubtree(subTree.component) : subTree; +}; +const BaseTransitionImpl = (/* unused pure expression or super */ null && ({ + name: `BaseTransition`, + props: BaseTransitionPropsValidators, + setup(props, { + slots + }) { + const instance = getCurrentInstance(); + const state = useTransitionState(); + return () => { + const children = slots.default && getTransitionRawChildren(slots.default(), true); + if (!children || !children.length) { + return; + } + const child = findNonCommentChild(children); + const rawProps = toRaw(props); + const { + mode + } = rawProps; + if (false) // removed by dead control flow +{} + if (state.isLeaving) { + return emptyPlaceholder(child); + } + const innerChild = getInnerChild$1(child); + if (!innerChild) { + return emptyPlaceholder(child); + } + let enterHooks = resolveTransitionHooks(innerChild, rawProps, state, instance, + // #11061, ensure enterHooks is fresh after clone + hooks => enterHooks = hooks); + if (innerChild.type !== Comment) { + setTransitionHooks(innerChild, enterHooks); + } + let oldInnerChild = instance.subTree && getInnerChild$1(instance.subTree); + if (oldInnerChild && oldInnerChild.type !== Comment && !isSameVNodeType(innerChild, oldInnerChild) && recursiveGetSubtree(instance).type !== Comment) { + let leavingHooks = resolveTransitionHooks(oldInnerChild, rawProps, state, instance); + setTransitionHooks(oldInnerChild, leavingHooks); + if (mode === "out-in" && innerChild.type !== Comment) { + state.isLeaving = true; + leavingHooks.afterLeave = () => { + state.isLeaving = false; + if (!(instance.job.flags & 8)) { + instance.update(); + } + delete leavingHooks.afterLeave; + oldInnerChild = void 0; + }; + return emptyPlaceholder(child); + } else if (mode === "in-out" && innerChild.type !== Comment) { + leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => { + const leavingVNodesCache = getLeavingNodesForType(state, oldInnerChild); + leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild; + el[leaveCbKey] = () => { + earlyRemove(); + el[leaveCbKey] = void 0; + delete enterHooks.delayedLeave; + oldInnerChild = void 0; + }; + enterHooks.delayedLeave = () => { + delayedLeave(); + delete enterHooks.delayedLeave; + oldInnerChild = void 0; + }; + }; + } else { + oldInnerChild = void 0; + } + } else if (oldInnerChild) { + oldInnerChild = void 0; + } + return child; + }; + } +})); +function findNonCommentChild(children) { + let child = children[0]; + if (children.length > 1) { + let hasFound = false; + for (const c of children) { + if (c.type !== Comment) { + if (false) // removed by dead control flow +{} + child = c; + hasFound = true; + if (true) break; + } + } + } + return child; +} +const BaseTransition = (/* unused pure expression or super */ null && (BaseTransitionImpl)); +function getLeavingNodesForType(state, vnode) { + const { + leavingVNodes + } = state; + let leavingVNodesCache = leavingVNodes.get(vnode.type); + if (!leavingVNodesCache) { + leavingVNodesCache = /* @__PURE__ */Object.create(null); + leavingVNodes.set(vnode.type, leavingVNodesCache); + } + return leavingVNodesCache; +} +function resolveTransitionHooks(vnode, props, state, instance, postClone) { + const { + appear, + mode, + persisted = false, + onBeforeEnter, + onEnter, + onAfterEnter, + onEnterCancelled, + onBeforeLeave, + onLeave, + onAfterLeave, + onLeaveCancelled, + onBeforeAppear, + onAppear, + onAfterAppear, + onAppearCancelled + } = props; + const key = String(vnode.key); + const leavingVNodesCache = getLeavingNodesForType(state, vnode); + const callHook = (hook, args) => { + hook && callWithAsyncErrorHandling(hook, instance, 9, args); + }; + const callAsyncHook = (hook, args) => { + const done = args[1]; + callHook(hook, args); + if (isArray(hook)) { + if (hook.every(hook2 => hook2.length <= 1)) done(); + } else if (hook.length <= 1) { + done(); + } + }; + const hooks = { + mode, + persisted, + beforeEnter(el) { + let hook = onBeforeEnter; + if (!state.isMounted) { + if (appear) { + hook = onBeforeAppear || onBeforeEnter; + } else { + return; + } + } + if (el[leaveCbKey]) { + el[leaveCbKey](true + /* cancelled */); + } + const leavingVNode = leavingVNodesCache[key]; + if (leavingVNode && isSameVNodeType(vnode, leavingVNode) && leavingVNode.el[leaveCbKey]) { + leavingVNode.el[leaveCbKey](); + } + callHook(hook, [el]); + }, + enter(el) { + let hook = onEnter; + let afterHook = onAfterEnter; + let cancelHook = onEnterCancelled; + if (!state.isMounted) { + if (appear) { + hook = onAppear || onEnter; + afterHook = onAfterAppear || onAfterEnter; + cancelHook = onAppearCancelled || onEnterCancelled; + } else { + return; + } + } + let called = false; + const done = el[enterCbKey] = cancelled => { + if (called) return; + called = true; + if (cancelled) { + callHook(cancelHook, [el]); + } else { + callHook(afterHook, [el]); + } + if (hooks.delayedLeave) { + hooks.delayedLeave(); + } + el[enterCbKey] = void 0; + }; + if (hook) { + callAsyncHook(hook, [el, done]); + } else { + done(); + } + }, + leave(el, remove) { + const key2 = String(vnode.key); + if (el[enterCbKey]) { + el[enterCbKey](true + /* cancelled */); + } + if (state.isUnmounting) { + return remove(); + } + callHook(onBeforeLeave, [el]); + let called = false; + const done = el[leaveCbKey] = cancelled => { + if (called) return; + called = true; + remove(); + if (cancelled) { + callHook(onLeaveCancelled, [el]); + } else { + callHook(onAfterLeave, [el]); + } + el[leaveCbKey] = void 0; + if (leavingVNodesCache[key2] === vnode) { + delete leavingVNodesCache[key2]; + } + }; + leavingVNodesCache[key2] = vnode; + if (onLeave) { + callAsyncHook(onLeave, [el, done]); + } else { + done(); + } + }, + clone(vnode2) { + const hooks2 = resolveTransitionHooks(vnode2, props, state, instance, postClone); + if (postClone) postClone(hooks2); + return hooks2; + } + }; + return hooks; +} +function emptyPlaceholder(vnode) { + if (isKeepAlive(vnode)) { + vnode = cloneVNode(vnode); + vnode.children = null; + return vnode; + } +} +function getInnerChild$1(vnode) { + if (!isKeepAlive(vnode)) { + if (isTeleport(vnode.type) && vnode.children) { + return findNonCommentChild(vnode.children); + } + return vnode; + } + if (false) // removed by dead control flow +{} + const { + shapeFlag, + children + } = vnode; + if (children) { + if (shapeFlag & 16) { + return children[0]; + } + if (shapeFlag & 32 && isFunction(children.default)) { + return children.default(); + } + } +} +function setTransitionHooks(vnode, hooks) { + if (vnode.shapeFlag & 6 && vnode.component) { + vnode.transition = hooks; + setTransitionHooks(vnode.component.subTree, hooks); + } else if (vnode.shapeFlag & 128) { + vnode.ssContent.transition = hooks.clone(vnode.ssContent); + vnode.ssFallback.transition = hooks.clone(vnode.ssFallback); + } else { + vnode.transition = hooks; + } +} +function getTransitionRawChildren(children, keepComment = false, parentKey) { + let ret = []; + let keyedFragmentCount = 0; + for (let i = 0; i < children.length; i++) { + let child = children[i]; + const key = parentKey == null ? child.key : String(parentKey) + String(child.key != null ? child.key : i); + if (child.type === Fragment) { + if (child.patchFlag & 128) keyedFragmentCount++; + ret = ret.concat(getTransitionRawChildren(child.children, keepComment, key)); + } else if (keepComment || child.type !== Comment) { + ret.push(key != null ? cloneVNode(child, { + key + }) : child); + } + } + if (keyedFragmentCount > 1) { + for (let i = 0; i < ret.length; i++) { + ret[i].patchFlag = -2; + } + } + return ret; +} + +/*! #__NO_SIDE_EFFECTS__ */ +// @__NO_SIDE_EFFECTS__ +function defineComponent(options, extraOptions) { + return isFunction(options) ? + // #8236: extend call and options.name access are considered side-effects + // by Rollup, so we have to wrap it in a pure-annotated IIFE. + /* @__PURE__ */ + (() => extend({ + name: options.name + }, extraOptions, { + setup: options + }))() : options; +} +function useId() { + const i = getCurrentInstance(); + if (i) { + return (i.appContext.config.idPrefix || "v") + "-" + i.ids[0] + i.ids[1]++; + } else if (false) // removed by dead control flow +{} + return ""; +} +function markAsyncBoundary(instance) { + instance.ids = [instance.ids[0] + instance.ids[2]++ + "-", 0, 0]; +} +const knownTemplateRefs = /* @__PURE__ */(/* unused pure expression or super */ null && (new WeakSet())); +function useTemplateRef(key) { + const i = getCurrentInstance(); + const r = shallowRef(null); + if (i) { + const refs = i.refs === EMPTY_OBJ ? i.refs = {} : i.refs; + let desc; + if (false) // removed by dead control flow +{} else { + Object.defineProperty(refs, key, { + enumerable: true, + get: () => r.value, + set: val => r.value = val + }); + } + } else if (false) // removed by dead control flow +{} + const ret = false ? 0 : r; + if (false) // removed by dead control flow +{} + return ret; +} +function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) { + if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .isArray */ .cy)(rawRef)) { + rawRef.forEach((r, i) => setRef(r, oldRawRef && ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .isArray */ .cy)(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount)); + return; + } + if (isAsyncWrapper(vnode) && !isUnmount) { + if (vnode.shapeFlag & 512 && vnode.type.__asyncResolved && vnode.component.subTree.component) { + setRef(rawRef, oldRawRef, parentSuspense, vnode.component.subTree); + } + return; + } + const refValue = vnode.shapeFlag & 4 ? getComponentPublicInstance(vnode.component) : vnode.el; + const value = isUnmount ? null : refValue; + const { + i: owner, + r: ref + } = rawRef; + if (false) // removed by dead control flow +{} + const oldRef = oldRawRef && oldRawRef.r; + const refs = owner.refs === _vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .EMPTY_OBJ */ .MZ ? owner.refs = {} : owner.refs; + const setupState = owner.setupState; + const rawSetupState = (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_20__/* .toRaw */ .ux)(setupState); + const canSetSetupRef = setupState === _vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .EMPTY_OBJ */ .MZ ? () => false : key => { + if (false) // removed by dead control flow +{} + return (0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .hasOwn */ .$3)(rawSetupState, key); + }; + if (oldRef != null && oldRef !== ref) { + if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .isString */ .Kg)(oldRef)) { + refs[oldRef] = null; + if (canSetSetupRef(oldRef)) { + setupState[oldRef] = null; + } + } else if ((0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_20__/* .isRef */ .i9)(oldRef)) { + oldRef.value = null; + } + } + if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .isFunction */ .Tn)(ref)) { + callWithErrorHandling(ref, owner, 12, [value, refs]); + } else { + const _isString = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .isString */ .Kg)(ref); + const _isRef = (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_20__/* .isRef */ .i9)(ref); + if (_isString || _isRef) { + const doSet = () => { + if (rawRef.f) { + const existing = _isString ? canSetSetupRef(ref) ? setupState[ref] : refs[ref] : ref.value; + if (isUnmount) { + (0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .isArray */ .cy)(existing) && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .remove */ .TF)(existing, refValue); + } else { + if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .isArray */ .cy)(existing)) { + if (_isString) { + refs[ref] = [refValue]; + if (canSetSetupRef(ref)) { + setupState[ref] = refs[ref]; + } + } else { + ref.value = [refValue]; + if (rawRef.k) refs[rawRef.k] = ref.value; + } + } else if (!existing.includes(refValue)) { + existing.push(refValue); + } + } + } else if (_isString) { + refs[ref] = value; + if (canSetSetupRef(ref)) { + setupState[ref] = value; + } + } else if (_isRef) { + ref.value = value; + if (rawRef.k) refs[rawRef.k] = value; + } else if (false) // removed by dead control flow +{} + }; + if (value) { + doSet.id = -1; + queuePostRenderEffect(doSet, parentSuspense); + } else { + doSet(); + } + } else if (false) // removed by dead control flow +{} + } +} +let hasLoggedMismatchError = false; +const logMismatchError = () => { + if (hasLoggedMismatchError) { + return; + } + console.error("Hydration completed but contains mismatches."); + hasLoggedMismatchError = true; +}; +const isSVGContainer = container => container.namespaceURI.includes("svg") && container.tagName !== "foreignObject"; +const isMathMLContainer = container => container.namespaceURI.includes("MathML"); +const getContainerType = container => { + if (container.nodeType !== 1) return void 0; + if (isSVGContainer(container)) return "svg"; + if (isMathMLContainer(container)) return "mathml"; + return void 0; +}; +const isComment = node => node.nodeType === 8; +function createHydrationFunctions(rendererInternals) { + const { + mt: mountComponent, + p: patch, + o: { + patchProp, + createText, + nextSibling, + parentNode, + remove, + insert, + createComment + } + } = rendererInternals; + const hydrate = (vnode, container) => { + if (!container.hasChildNodes()) { + ( false) && 0; + patch(null, vnode, container); + flushPostFlushCbs(); + container._vnode = vnode; + return; + } + hydrateNode(container.firstChild, vnode, null, null, null); + flushPostFlushCbs(); + container._vnode = vnode; + }; + const hydrateNode = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized = false) => { + optimized = optimized || !!vnode.dynamicChildren; + const isFragmentStart = isComment(node) && node.data === "["; + const onMismatch = () => handleMismatch(node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragmentStart); + const { + type, + ref, + shapeFlag, + patchFlag + } = vnode; + let domType = node.nodeType; + vnode.el = node; + if (false) // removed by dead control flow +{} + if (patchFlag === -2) { + optimized = false; + vnode.dynamicChildren = null; + } + let nextNode = null; + switch (type) { + case Text: + if (domType !== 3) { + if (vnode.children === "") { + insert(vnode.el = createText(""), parentNode(node), node); + nextNode = node; + } else { + nextNode = onMismatch(); + } + } else { + if (node.data !== vnode.children) { + ( false) && 0; + logMismatchError(); + node.data = vnode.children; + } + nextNode = nextSibling(node); + } + break; + case Comment: + if (isTemplateNode(node)) { + nextNode = nextSibling(node); + replaceNode(vnode.el = node.content.firstChild, node, parentComponent); + } else if (domType !== 8 || isFragmentStart) { + nextNode = onMismatch(); + } else { + nextNode = nextSibling(node); + } + break; + case Static: + if (isFragmentStart) { + node = nextSibling(node); + domType = node.nodeType; + } + if (domType === 1 || domType === 3) { + nextNode = node; + const needToAdoptContent = !vnode.children.length; + for (let i = 0; i < vnode.staticCount; i++) { + if (needToAdoptContent) vnode.children += nextNode.nodeType === 1 ? nextNode.outerHTML : nextNode.data; + if (i === vnode.staticCount - 1) { + vnode.anchor = nextNode; + } + nextNode = nextSibling(nextNode); + } + return isFragmentStart ? nextSibling(nextNode) : nextNode; + } else { + onMismatch(); + } + break; + case Fragment: + if (!isFragmentStart) { + nextNode = onMismatch(); + } else { + nextNode = hydrateFragment(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized); + } + break; + default: + if (shapeFlag & 1) { + if ((domType !== 1 || vnode.type.toLowerCase() !== node.tagName.toLowerCase()) && !isTemplateNode(node)) { + nextNode = onMismatch(); + } else { + nextNode = hydrateElement(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized); + } + } else if (shapeFlag & 6) { + vnode.slotScopeIds = slotScopeIds; + const container = parentNode(node); + if (isFragmentStart) { + nextNode = locateClosingAnchor(node); + } else if (isComment(node) && node.data === "teleport start") { + nextNode = locateClosingAnchor(node, node.data, "teleport end"); + } else { + nextNode = nextSibling(node); + } + mountComponent(vnode, container, null, parentComponent, parentSuspense, getContainerType(container), optimized); + if (isAsyncWrapper(vnode) && !vnode.type.__asyncResolved) { + let subTree; + if (isFragmentStart) { + subTree = createVNode(Fragment); + subTree.anchor = nextNode ? nextNode.previousSibling : container.lastChild; + } else { + subTree = node.nodeType === 3 ? createTextVNode("") : createVNode("div"); + } + subTree.el = node; + vnode.component.subTree = subTree; + } + } else if (shapeFlag & 64) { + if (domType !== 8) { + nextNode = onMismatch(); + } else { + nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, rendererInternals, hydrateChildren); + } + } else if (shapeFlag & 128) { + nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, getContainerType(parentNode(node)), slotScopeIds, optimized, rendererInternals, hydrateNode); + } else if (false) // removed by dead control flow +{} + } + if (ref != null) { + setRef(ref, null, parentSuspense, vnode); + } + return nextNode; + }; + const hydrateElement = (el, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => { + optimized = optimized || !!vnode.dynamicChildren; + const { + type, + props, + patchFlag, + shapeFlag, + dirs, + transition + } = vnode; + const forcePatch = type === "input" || type === "option"; + if ( false || forcePatch || patchFlag !== -1) { + if (dirs) { + invokeDirectiveHook(vnode, null, parentComponent, "created"); + } + let needCallTransitionHooks = false; + if (isTemplateNode(el)) { + needCallTransitionHooks = needTransition(null, + // no need check parentSuspense in hydration + transition) && parentComponent && parentComponent.vnode.props && parentComponent.vnode.props.appear; + const content = el.content.firstChild; + if (needCallTransitionHooks) { + transition.beforeEnter(content); + } + replaceNode(content, el, parentComponent); + vnode.el = el = content; + } + if (shapeFlag & 16 && + // skip if element has innerHTML / textContent + !(props && (props.innerHTML || props.textContent))) { + let next = hydrateChildren(el.firstChild, vnode, el, parentComponent, parentSuspense, slotScopeIds, optimized); + let hasWarned = false; + while (next) { + if (!isMismatchAllowed(el, 1 /* CHILDREN */)) { + if (false) // removed by dead control flow +{} + logMismatchError(); + } + const cur = next; + next = next.nextSibling; + remove(cur); + } + } else if (shapeFlag & 8) { + let clientText = vnode.children; + if (clientText[0] === "\n" && (el.tagName === "PRE" || el.tagName === "TEXTAREA")) { + clientText = clientText.slice(1); + } + if (el.textContent !== clientText) { + if (!isMismatchAllowed(el, 0 /* TEXT */)) { + ( false) && 0; + logMismatchError(); + } + el.textContent = vnode.children; + } + } + if (props) { + if ( false || forcePatch || !optimized || patchFlag & (16 | 32)) { + const isCustomElement = el.tagName.includes("-"); + for (const key in props) { + if (false) // removed by dead control flow +{} + if (forcePatch && (key.endsWith("value") || key === "indeterminate") || isOn(key) && !isReservedProp(key) || + // force hydrate v-bind with .prop modifiers + key[0] === "." || isCustomElement) { + patchProp(el, key, null, props[key], void 0, parentComponent); + } + } + } else if (props.onClick) { + patchProp(el, "onClick", null, props.onClick, void 0, parentComponent); + } else if (patchFlag & 4 && isReactive(props.style)) { + for (const key in props.style) props.style[key]; + } + } + let vnodeHooks; + if (vnodeHooks = props && props.onVnodeBeforeMount) { + invokeVNodeHook(vnodeHooks, parentComponent, vnode); + } + if (dirs) { + invokeDirectiveHook(vnode, null, parentComponent, "beforeMount"); + } + if ((vnodeHooks = props && props.onVnodeMounted) || dirs || needCallTransitionHooks) { + queueEffectWithSuspense(() => { + vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode); + needCallTransitionHooks && transition.enter(el); + dirs && invokeDirectiveHook(vnode, null, parentComponent, "mounted"); + }, parentSuspense); + } + } + return el.nextSibling; + }; + const hydrateChildren = (node, parentVNode, container, parentComponent, parentSuspense, slotScopeIds, optimized) => { + optimized = optimized || !!parentVNode.dynamicChildren; + const children = parentVNode.children; + const l = children.length; + let hasWarned = false; + for (let i = 0; i < l; i++) { + const vnode = optimized ? children[i] : children[i] = normalizeVNode(children[i]); + const isText = vnode.type === Text; + if (node) { + if (isText && !optimized) { + if (i + 1 < l && normalizeVNode(children[i + 1]).type === Text) { + insert(createText(node.data.slice(vnode.children.length)), container, nextSibling(node)); + node.data = vnode.children; + } + } + node = hydrateNode(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized); + } else if (isText && !vnode.children) { + insert(vnode.el = createText(""), container); + } else { + if (!isMismatchAllowed(container, 1 /* CHILDREN */)) { + if (false) // removed by dead control flow +{} + logMismatchError(); + } + patch(null, vnode, container, null, parentComponent, parentSuspense, getContainerType(container), slotScopeIds); + } + } + return node; + }; + const hydrateFragment = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => { + const { + slotScopeIds: fragmentSlotScopeIds + } = vnode; + if (fragmentSlotScopeIds) { + slotScopeIds = slotScopeIds ? slotScopeIds.concat(fragmentSlotScopeIds) : fragmentSlotScopeIds; + } + const container = parentNode(node); + const next = hydrateChildren(nextSibling(node), vnode, container, parentComponent, parentSuspense, slotScopeIds, optimized); + if (next && isComment(next) && next.data === "]") { + return nextSibling(vnode.anchor = next); + } else { + logMismatchError(); + insert(vnode.anchor = createComment(`]`), container, next); + return next; + } + }; + const handleMismatch = (node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragment) => { + if (!isMismatchAllowed(node.parentElement, 1 /* CHILDREN */)) { + ( false) && 0; + logMismatchError(); + } + vnode.el = null; + if (isFragment) { + const end = locateClosingAnchor(node); + while (true) { + const next2 = nextSibling(node); + if (next2 && next2 !== end) { + remove(next2); + } else { + break; + } + } + } + const next = nextSibling(node); + const container = parentNode(node); + remove(node); + patch(null, vnode, container, next, parentComponent, parentSuspense, getContainerType(container), slotScopeIds); + if (parentComponent) { + parentComponent.vnode.el = vnode.el; + updateHOCHostEl(parentComponent, vnode.el); + } + return next; + }; + const locateClosingAnchor = (node, open = "[", close = "]") => { + let match = 0; + while (node) { + node = nextSibling(node); + if (node && isComment(node)) { + if (node.data === open) match++; + if (node.data === close) { + if (match === 0) { + return nextSibling(node); + } else { + match--; + } + } + } + } + return node; + }; + const replaceNode = (newNode, oldNode, parentComponent) => { + const parentNode2 = oldNode.parentNode; + if (parentNode2) { + parentNode2.replaceChild(newNode, oldNode); + } + let parent = parentComponent; + while (parent) { + if (parent.vnode.el === oldNode) { + parent.vnode.el = parent.subTree.el = newNode; + } + parent = parent.parent; + } + }; + const isTemplateNode = node => { + return node.nodeType === 1 && node.tagName === "TEMPLATE"; + }; + return [hydrate, hydrateNode]; +} +function propHasMismatch(el, key, clientValue, vnode, instance) { + let mismatchType; + let mismatchKey; + let actual; + let expected; + if (key === "class") { + actual = el.getAttribute("class"); + expected = normalizeClass(clientValue); + if (!isSetEqual(toClassSet(actual || ""), toClassSet(expected))) { + mismatchType = 2 /* CLASS */; + mismatchKey = `class`; + } + } else if (key === "style") { + actual = el.getAttribute("style") || ""; + expected = isString(clientValue) ? clientValue : stringifyStyle(normalizeStyle(clientValue)); + const actualMap = toStyleMap(actual); + const expectedMap = toStyleMap(expected); + if (vnode.dirs) { + for (const { + dir, + value + } of vnode.dirs) { + if (dir.name === "show" && !value) { + expectedMap.set("display", "none"); + } + } + } + if (instance) { + resolveCssVars(instance, vnode, expectedMap); + } + if (!isMapEqual(actualMap, expectedMap)) { + mismatchType = 3 /* STYLE */; + mismatchKey = "style"; + } + } else if (el instanceof SVGElement && isKnownSvgAttr(key) || el instanceof HTMLElement && (isBooleanAttr(key) || isKnownHtmlAttr(key))) { + if (isBooleanAttr(key)) { + actual = el.hasAttribute(key); + expected = includeBooleanAttr(clientValue); + } else if (clientValue == null) { + actual = el.hasAttribute(key); + expected = false; + } else { + if (el.hasAttribute(key)) { + actual = el.getAttribute(key); + } else if (key === "value" && el.tagName === "TEXTAREA") { + actual = el.value; + } else { + actual = false; + } + expected = isRenderableAttrValue(clientValue) ? String(clientValue) : false; + } + if (actual !== expected) { + mismatchType = 4 /* ATTRIBUTE */; + mismatchKey = key; + } + } + if (mismatchType != null && !isMismatchAllowed(el, mismatchType)) { + const format = v => v === false ? `(not rendered)` : `${mismatchKey}="${v}"`; + const preSegment = `Hydration ${MismatchTypeString[mismatchType]} mismatch on`; + const postSegment = ` + - rendered on server: ${format(actual)} + - expected on client: ${format(expected)} + Note: this mismatch is check-only. The DOM will not be rectified in production due to performance overhead. + You should fix the source of the mismatch.`; + { + warn$1(preSegment, el, postSegment); + } + return true; + } + return false; +} +function toClassSet(str) { + return new Set(str.trim().split(/\s+/)); +} +function isSetEqual(a, b) { + if (a.size !== b.size) { + return false; + } + for (const s of a) { + if (!b.has(s)) { + return false; + } + } + return true; +} +function toStyleMap(str) { + const styleMap = /* @__PURE__ */new Map(); + for (const item of str.split(";")) { + let [key, value] = item.split(":"); + key = key.trim(); + value = value && value.trim(); + if (key && value) { + styleMap.set(key, value); + } + } + return styleMap; +} +function isMapEqual(a, b) { + if (a.size !== b.size) { + return false; + } + for (const [key, value] of a) { + if (value !== b.get(key)) { + return false; + } + } + return true; +} +function resolveCssVars(instance, vnode, expectedMap) { + const root = instance.subTree; + if (instance.getCssVars && (vnode === root || root && root.type === Fragment && root.children.includes(vnode))) { + const cssVars = instance.getCssVars(); + for (const key in cssVars) { + expectedMap.set(`--${getEscapedCssVarName(key, false)}`, String(cssVars[key])); + } + } + if (vnode === root && instance.parent) { + resolveCssVars(instance.parent, instance.vnode, expectedMap); + } +} +const allowMismatchAttr = "data-allow-mismatch"; +const MismatchTypeString = (/* unused pure expression or super */ null && ({ + [0 /* TEXT */]: "text", + [1 /* CHILDREN */]: "children", + [2 /* CLASS */]: "class", + [3 /* STYLE */]: "style", + [4 /* ATTRIBUTE */]: "attribute" +})); +function isMismatchAllowed(el, allowedType) { + if (allowedType === 0 /* TEXT */ || allowedType === 1 /* CHILDREN */) { + while (el && !el.hasAttribute(allowMismatchAttr)) { + el = el.parentElement; + } + } + const allowedAttr = el && el.getAttribute(allowMismatchAttr); + if (allowedAttr == null) { + return false; + } else if (allowedAttr === "") { + return true; + } else { + const list = allowedAttr.split(","); + if (allowedType === 0 /* TEXT */ && list.includes("children")) { + return true; + } + return allowedAttr.split(",").includes(MismatchTypeString[allowedType]); + } +} +const requestIdleCallback = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .getGlobalThis */ .We)().requestIdleCallback || (cb => setTimeout(cb, 1)); +const cancelIdleCallback = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .getGlobalThis */ .We)().cancelIdleCallback || (id => clearTimeout(id)); +const hydrateOnIdle = (timeout = 1e4) => hydrate => { + const id = requestIdleCallback(hydrate, { + timeout + }); + return () => cancelIdleCallback(id); +}; +function elementIsVisibleInViewport(el) { + const { + top, + left, + bottom, + right + } = el.getBoundingClientRect(); + const { + innerHeight, + innerWidth + } = window; + return (top > 0 && top < innerHeight || bottom > 0 && bottom < innerHeight) && (left > 0 && left < innerWidth || right > 0 && right < innerWidth); +} +const hydrateOnVisible = opts => (hydrate, forEach) => { + const ob = new IntersectionObserver(entries => { + for (const e of entries) { + if (!e.isIntersecting) continue; + ob.disconnect(); + hydrate(); + break; + } + }, opts); + forEach(el => { + if (!(el instanceof Element)) return; + if (elementIsVisibleInViewport(el)) { + hydrate(); + ob.disconnect(); + return false; + } + ob.observe(el); + }); + return () => ob.disconnect(); +}; +const hydrateOnMediaQuery = query => hydrate => { + if (query) { + const mql = matchMedia(query); + if (mql.matches) { + hydrate(); + } else { + mql.addEventListener("change", hydrate, { + once: true + }); + return () => mql.removeEventListener("change", hydrate); + } + } +}; +const hydrateOnInteraction = (interactions = []) => (hydrate, forEach) => { + if (isString(interactions)) interactions = [interactions]; + let hasHydrated = false; + const doHydrate = e => { + if (!hasHydrated) { + hasHydrated = true; + teardown(); + hydrate(); + e.target.dispatchEvent(new e.constructor(e.type, e)); + } + }; + const teardown = () => { + forEach(el => { + for (const i of interactions) { + el.removeEventListener(i, doHydrate); + } + }); + }; + forEach(el => { + for (const i of interactions) { + el.addEventListener(i, doHydrate, { + once: true + }); + } + }); + return teardown; +}; +function forEachElement(node, cb) { + if (isComment(node) && node.data === "[") { + let depth = 1; + let next = node.nextSibling; + while (next) { + if (next.nodeType === 1) { + const result = cb(next); + if (result === false) { + break; + } + } else if (isComment(next)) { + if (next.data === "]") { + if (--depth === 0) break; + } else if (next.data === "[") { + depth++; + } + } + next = next.nextSibling; + } + } else { + cb(node); + } +} +const isAsyncWrapper = i => !!i.type.__asyncLoader; +/*! #__NO_SIDE_EFFECTS__ */ +// @__NO_SIDE_EFFECTS__ +function defineAsyncComponent(source) { + if (isFunction(source)) { + source = { + loader: source + }; + } + const { + loader, + loadingComponent, + errorComponent, + delay = 200, + hydrate: hydrateStrategy, + timeout, + // undefined = never times out + suspensible = true, + onError: userOnError + } = source; + let pendingRequest = null; + let resolvedComp; + let retries = 0; + const retry = () => { + retries++; + pendingRequest = null; + return load(); + }; + const load = () => { + let thisRequest; + return pendingRequest || (thisRequest = pendingRequest = loader().catch(err => { + err = err instanceof Error ? err : new Error(String(err)); + if (userOnError) { + return new Promise((resolve, reject) => { + const userRetry = () => resolve(retry()); + const userFail = () => reject(err); + userOnError(err, userRetry, userFail, retries + 1); + }); + } else { + throw err; + } + }).then(comp => { + if (thisRequest !== pendingRequest && pendingRequest) { + return pendingRequest; + } + if (false) // removed by dead control flow +{} + if (comp && (comp.__esModule || comp[Symbol.toStringTag] === "Module")) { + comp = comp.default; + } + if (false) // removed by dead control flow +{} + resolvedComp = comp; + return comp; + })); + }; + return defineComponent({ + name: "AsyncComponentWrapper", + __asyncLoader: load, + __asyncHydrate(el, instance, hydrate) { + const doHydrate = hydrateStrategy ? () => { + const teardown = hydrateStrategy(hydrate, cb => forEachElement(el, cb)); + if (teardown) { + (instance.bum || (instance.bum = [])).push(teardown); + } + } : hydrate; + if (resolvedComp) { + doHydrate(); + } else { + load().then(() => !instance.isUnmounted && doHydrate()); + } + }, + get __asyncResolved() { + return resolvedComp; + }, + setup() { + const instance = currentInstance; + markAsyncBoundary(instance); + if (resolvedComp) { + return () => createInnerComp(resolvedComp, instance); + } + const onError = err => { + pendingRequest = null; + handleError(err, instance, 13, !errorComponent); + }; + if (suspensible && instance.suspense || isInSSRComponentSetup) { + return load().then(comp => { + return () => createInnerComp(comp, instance); + }).catch(err => { + onError(err); + return () => errorComponent ? createVNode(errorComponent, { + error: err + }) : null; + }); + } + const loaded = ref(false); + const error = ref(); + const delayed = ref(!!delay); + if (delay) { + setTimeout(() => { + delayed.value = false; + }, delay); + } + if (timeout != null) { + setTimeout(() => { + if (!loaded.value && !error.value) { + const err = new Error(`Async component timed out after ${timeout}ms.`); + onError(err); + error.value = err; + } + }, timeout); + } + load().then(() => { + loaded.value = true; + if (instance.parent && isKeepAlive(instance.parent.vnode)) { + instance.parent.update(); + } + }).catch(err => { + onError(err); + error.value = err; + }); + return () => { + if (loaded.value && resolvedComp) { + return createInnerComp(resolvedComp, instance); + } else if (error.value && errorComponent) { + return createVNode(errorComponent, { + error: error.value + }); + } else if (loadingComponent && !delayed.value) { + return createVNode(loadingComponent); + } + }; + } + }); +} +function createInnerComp(comp, parent) { + const { + ref: ref2, + props, + children, + ce + } = parent.vnode; + const vnode = createVNode(comp, props, children); + vnode.ref = ref2; + vnode.ce = ce; + delete parent.vnode.ce; + return vnode; +} +const isKeepAlive = vnode => vnode.type.__isKeepAlive; +const KeepAliveImpl = (/* unused pure expression or super */ null && ({ + name: `KeepAlive`, + // Marker for special handling inside the renderer. We are not using a === + // check directly on KeepAlive in the renderer, because importing it directly + // would prevent it from being tree-shaken. + __isKeepAlive: true, + props: { + include: [String, RegExp, Array], + exclude: [String, RegExp, Array], + max: [String, Number] + }, + setup(props, { + slots + }) { + const instance = getCurrentInstance(); + const sharedContext = instance.ctx; + if (!sharedContext.renderer) { + return () => { + const children = slots.default && slots.default(); + return children && children.length === 1 ? children[0] : children; + }; + } + const cache = /* @__PURE__ */new Map(); + const keys = /* @__PURE__ */new Set(); + let current = null; + if (false) // removed by dead control flow +{} + const parentSuspense = instance.suspense; + const { + renderer: { + p: patch, + m: move, + um: _unmount, + o: { + createElement + } + } + } = sharedContext; + const storageContainer = createElement("div"); + sharedContext.activate = (vnode, container, anchor, namespace, optimized) => { + const instance2 = vnode.component; + move(vnode, container, anchor, 0, parentSuspense); + patch(instance2.vnode, vnode, container, anchor, instance2, parentSuspense, namespace, vnode.slotScopeIds, optimized); + queuePostRenderEffect(() => { + instance2.isDeactivated = false; + if (instance2.a) { + invokeArrayFns(instance2.a); + } + const vnodeHook = vnode.props && vnode.props.onVnodeMounted; + if (vnodeHook) { + invokeVNodeHook(vnodeHook, instance2.parent, vnode); + } + }, parentSuspense); + if (false) // removed by dead control flow +{} + }; + sharedContext.deactivate = vnode => { + const instance2 = vnode.component; + invalidateMount(instance2.m); + invalidateMount(instance2.a); + move(vnode, storageContainer, null, 1, parentSuspense); + queuePostRenderEffect(() => { + if (instance2.da) { + invokeArrayFns(instance2.da); + } + const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted; + if (vnodeHook) { + invokeVNodeHook(vnodeHook, instance2.parent, vnode); + } + instance2.isDeactivated = true; + }, parentSuspense); + if (false) // removed by dead control flow +{} + }; + function unmount(vnode) { + resetShapeFlag(vnode); + _unmount(vnode, instance, parentSuspense, true); + } + function pruneCache(filter) { + cache.forEach((vnode, key) => { + const name = getComponentName(vnode.type); + if (name && !filter(name)) { + pruneCacheEntry(key); + } + }); + } + function pruneCacheEntry(key) { + const cached = cache.get(key); + if (cached && (!current || !isSameVNodeType(cached, current))) { + unmount(cached); + } else if (current) { + resetShapeFlag(current); + } + cache.delete(key); + keys.delete(key); + } + watch(() => [props.include, props.exclude], ([include, exclude]) => { + include && pruneCache(name => matches(include, name)); + exclude && pruneCache(name => !matches(exclude, name)); + }, + // prune post-render after `current` has been updated + { + flush: "post", + deep: true + }); + let pendingCacheKey = null; + const cacheSubtree = () => { + if (pendingCacheKey != null) { + if (isSuspense(instance.subTree.type)) { + queuePostRenderEffect(() => { + cache.set(pendingCacheKey, getInnerChild(instance.subTree)); + }, instance.subTree.suspense); + } else { + cache.set(pendingCacheKey, getInnerChild(instance.subTree)); + } + } + }; + onMounted(cacheSubtree); + onUpdated(cacheSubtree); + onBeforeUnmount(() => { + cache.forEach(cached => { + const { + subTree, + suspense + } = instance; + const vnode = getInnerChild(subTree); + if (cached.type === vnode.type && cached.key === vnode.key) { + resetShapeFlag(vnode); + const da = vnode.component.da; + da && queuePostRenderEffect(da, suspense); + return; + } + unmount(cached); + }); + }); + return () => { + pendingCacheKey = null; + if (!slots.default) { + return current = null; + } + const children = slots.default(); + const rawVNode = children[0]; + if (children.length > 1) { + if (false) // removed by dead control flow +{} + current = null; + return children; + } else if (!isVNode(rawVNode) || !(rawVNode.shapeFlag & 4) && !(rawVNode.shapeFlag & 128)) { + current = null; + return rawVNode; + } + let vnode = getInnerChild(rawVNode); + if (vnode.type === Comment) { + current = null; + return vnode; + } + const comp = vnode.type; + const name = getComponentName(isAsyncWrapper(vnode) ? vnode.type.__asyncResolved || {} : comp); + const { + include, + exclude, + max + } = props; + if (include && (!name || !matches(include, name)) || exclude && name && matches(exclude, name)) { + vnode.shapeFlag &= ~256; + current = vnode; + return rawVNode; + } + const key = vnode.key == null ? comp : vnode.key; + const cachedVNode = cache.get(key); + if (vnode.el) { + vnode = cloneVNode(vnode); + if (rawVNode.shapeFlag & 128) { + rawVNode.ssContent = vnode; + } + } + pendingCacheKey = key; + if (cachedVNode) { + vnode.el = cachedVNode.el; + vnode.component = cachedVNode.component; + if (vnode.transition) { + setTransitionHooks(vnode, vnode.transition); + } + vnode.shapeFlag |= 512; + keys.delete(key); + keys.add(key); + } else { + keys.add(key); + if (max && keys.size > parseInt(max, 10)) { + pruneCacheEntry(keys.values().next().value); + } + } + vnode.shapeFlag |= 256; + current = vnode; + return isSuspense(rawVNode.type) ? rawVNode : vnode; + }; + } +})); +const KeepAlive = (/* unused pure expression or super */ null && (KeepAliveImpl)); +function matches(pattern, name) { + if (isArray(pattern)) { + return pattern.some(p => matches(p, name)); + } else if (isString(pattern)) { + return pattern.split(",").includes(name); + } else if (isRegExp(pattern)) { + pattern.lastIndex = 0; + return pattern.test(name); + } + return false; +} +function onActivated(hook, target) { + registerKeepAliveHook(hook, "a", target); +} +function onDeactivated(hook, target) { + registerKeepAliveHook(hook, "da", target); +} +function registerKeepAliveHook(hook, type, target = currentInstance) { + const wrappedHook = hook.__wdc || (hook.__wdc = () => { + let current = target; + while (current) { + if (current.isDeactivated) { + return; + } + current = current.parent; + } + return hook(); + }); + injectHook(type, wrappedHook, target); + if (target) { + let current = target.parent; + while (current && current.parent) { + if (isKeepAlive(current.parent.vnode)) { + injectToKeepAliveRoot(wrappedHook, type, target, current); + } + current = current.parent; + } + } +} +function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) { + const injected = injectHook(type, hook, keepAliveRoot, true + /* prepend */); + onUnmounted(() => { + (0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .remove */ .TF)(keepAliveRoot[type], injected); + }, target); +} +function resetShapeFlag(vnode) { + vnode.shapeFlag &= ~256; + vnode.shapeFlag &= ~512; +} +function getInnerChild(vnode) { + return vnode.shapeFlag & 128 ? vnode.ssContent : vnode; +} +function injectHook(type, hook, target = currentInstance, prepend = false) { + if (target) { + const hooks = target[type] || (target[type] = []); + const wrappedHook = hook.__weh || (hook.__weh = (...args) => { + (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_20__/* .pauseTracking */ .C4)(); + const reset = setCurrentInstance(target); + const res = callWithAsyncErrorHandling(hook, target, type, args); + reset(); + (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_20__/* .resetTracking */ .bl)(); + return res; + }); + if (prepend) { + hooks.unshift(wrappedHook); + } else { + hooks.push(wrappedHook); + } + return wrappedHook; + } else if (false) // removed by dead control flow +{} +} +const createHook = lifecycle => (hook, target = currentInstance) => { + if (!isInSSRComponentSetup || lifecycle === "sp") { + injectHook(lifecycle, (...args) => hook(...args), target); + } +}; +const onBeforeMount = createHook("bm"); +const onMounted = createHook("m"); +const onBeforeUpdate = createHook("bu"); +const onUpdated = createHook("u"); +const onBeforeUnmount = createHook("bum"); +const onUnmounted = createHook("um"); +const onServerPrefetch = createHook("sp"); +const onRenderTriggered = createHook("rtg"); +const onRenderTracked = createHook("rtc"); +function onErrorCaptured(hook, target = currentInstance) { + injectHook("ec", hook, target); +} +const COMPONENTS = "components"; +const DIRECTIVES = "directives"; +function resolveComponent(name, maybeSelfReference) { + return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name; +} +const NULL_DYNAMIC_COMPONENT = Symbol.for("v-ndc"); +function resolveDynamicComponent(component) { + if (isString(component)) { + return resolveAsset(COMPONENTS, component, false) || component; + } else { + return component || NULL_DYNAMIC_COMPONENT; + } +} +function resolveDirective(name) { + return resolveAsset(DIRECTIVES, name); +} +function resolveAsset(type, name, warnMissing = true, maybeSelfReference = false) { + const instance = currentRenderingInstance || currentInstance; + if (instance) { + const Component = instance.type; + if (type === COMPONENTS) { + const selfName = getComponentName(Component, false); + if (selfName && (selfName === name || selfName === camelize(name) || selfName === capitalize(camelize(name)))) { + return Component; + } + } + const res = + // local registration + // check instance[type] first which is resolved for options API + resolve(instance[type] || Component[type], name) || + // global registration + resolve(instance.appContext[type], name); + if (!res && maybeSelfReference) { + return Component; + } + if (false) // removed by dead control flow +{} + return res; + } else if (false) // removed by dead control flow +{} +} +function resolve(registry, name) { + return registry && (registry[name] || registry[camelize(name)] || registry[capitalize(camelize(name))]); +} +function renderList(source, renderItem, cache, index) { + let ret; + const cached = cache && cache[index]; + const sourceIsArray = isArray(source); + if (sourceIsArray || isString(source)) { + const sourceIsReactiveArray = sourceIsArray && isReactive(source); + let needsWrap = false; + if (sourceIsReactiveArray) { + needsWrap = !isShallow(source); + source = shallowReadArray(source); + } + ret = new Array(source.length); + for (let i = 0, l = source.length; i < l; i++) { + ret[i] = renderItem(needsWrap ? toReactive(source[i]) : source[i], i, void 0, cached && cached[i]); + } + } else if (typeof source === "number") { + if (false) // removed by dead control flow +{} + ret = new Array(source); + for (let i = 0; i < source; i++) { + ret[i] = renderItem(i + 1, i, void 0, cached && cached[i]); + } + } else if (isObject(source)) { + if (source[Symbol.iterator]) { + ret = Array.from(source, (item, i) => renderItem(item, i, void 0, cached && cached[i])); + } else { + const keys = Object.keys(source); + ret = new Array(keys.length); + for (let i = 0, l = keys.length; i < l; i++) { + const key = keys[i]; + ret[i] = renderItem(source[key], key, i, cached && cached[i]); + } + } + } else { + ret = []; + } + if (cache) { + cache[index] = ret; + } + return ret; +} +function createSlots(slots, dynamicSlots) { + for (let i = 0; i < dynamicSlots.length; i++) { + const slot = dynamicSlots[i]; + if (isArray(slot)) { + for (let j = 0; j < slot.length; j++) { + slots[slot[j].name] = slot[j].fn; + } + } else if (slot) { + slots[slot.name] = slot.key ? (...args) => { + const res = slot.fn(...args); + if (res) res.key = slot.key; + return res; + } : slot.fn; + } + } + return slots; +} +function renderSlot(slots, name, props = {}, fallback, noSlotted) { + if (currentRenderingInstance.ce || currentRenderingInstance.parent && isAsyncWrapper(currentRenderingInstance.parent) && currentRenderingInstance.parent.ce) { + if (name !== "default") props.name = name; + return openBlock(), createBlock(Fragment, null, [createVNode("slot", props, fallback && fallback())], 64); + } + let slot = slots[name]; + if (false) // removed by dead control flow +{} + if (slot && slot._c) { + slot._d = false; + } + openBlock(); + const validSlotContent = slot && ensureValidVNode(slot(props)); + const slotKey = props.key || + // slot content array of a dynamic conditional slot may have a branch + // key attached in the `createSlots` helper, respect that + validSlotContent && validSlotContent.key; + const rendered = createBlock(Fragment, { + key: (slotKey && !isSymbol(slotKey) ? slotKey : `_${name}`) + ( + // #7256 force differentiate fallback content from actual content + !validSlotContent && fallback ? "_fb" : "") + }, validSlotContent || (fallback ? fallback() : []), validSlotContent && slots._ === 1 ? 64 : -2); + if (!noSlotted && rendered.scopeId) { + rendered.slotScopeIds = [rendered.scopeId + "-s"]; + } + if (slot && slot._c) { + slot._d = true; + } + return rendered; +} +function ensureValidVNode(vnodes) { + return vnodes.some(child => { + if (!isVNode(child)) return true; + if (child.type === Comment) return false; + if (child.type === Fragment && !ensureValidVNode(child.children)) return false; + return true; + }) ? vnodes : null; +} +function toHandlers(obj, preserveCaseIfNecessary) { + const ret = {}; + if (false) // removed by dead control flow +{} + for (const key in obj) { + ret[preserveCaseIfNecessary && /[A-Z]/.test(key) ? `on:${key}` : toHandlerKey(key)] = obj[key]; + } + return ret; +} +const getPublicInstance = i => { + if (!i) return null; + if (isStatefulComponent(i)) return getComponentPublicInstance(i); + return getPublicInstance(i.parent); +}; +const publicPropertiesMap = +// Move PURE marker to new line to workaround compiler discarding it +// due to type annotation +/* @__PURE__ */ +(0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .extend */ .X$)(/* @__PURE__ */Object.create(null), { + $: i => i, + $el: i => i.vnode.el, + $data: i => i.data, + $props: i => false ? 0 : i.props, + $attrs: i => false ? 0 : i.attrs, + $slots: i => false ? 0 : i.slots, + $refs: i => false ? 0 : i.refs, + $parent: i => getPublicInstance(i.parent), + $root: i => getPublicInstance(i.root), + $host: i => i.ce, + $emit: i => i.emit, + $options: i => true ? resolveMergedOptions(i) : 0, + $forceUpdate: i => i.f || (i.f = () => { + queueJob(i.update); + }), + $nextTick: i => i.n || (i.n = nextTick.bind(i.proxy)), + $watch: i => true ? instanceWatch.bind(i) : 0 +}); +const isReservedPrefix = key => key === "_" || key === "$"; +const hasSetupBinding = (state, key) => state !== _vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .EMPTY_OBJ */ .MZ && !state.__isScriptSetup && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .hasOwn */ .$3)(state, key); +const PublicInstanceProxyHandlers = { + get({ + _: instance + }, key) { + if (key === "__v_skip") { + return true; + } + const { + ctx, + setupState, + data, + props, + accessCache, + type, + appContext + } = instance; + if (false) // removed by dead control flow +{} + let normalizedProps; + if (key[0] !== "$") { + const n = accessCache[key]; + if (n !== void 0) { + switch (n) { + case 1 /* SETUP */: + return setupState[key]; + case 2 /* DATA */: + return data[key]; + case 4 /* CONTEXT */: + return ctx[key]; + case 3 /* PROPS */: + return props[key]; + } + } else if (hasSetupBinding(setupState, key)) { + accessCache[key] = 1 /* SETUP */; + return setupState[key]; + } else if (data !== _vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .EMPTY_OBJ */ .MZ && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .hasOwn */ .$3)(data, key)) { + accessCache[key] = 2 /* DATA */; + return data[key]; + } else if ( + // only cache other properties when instance has declared (thus stable) + // props + (normalizedProps = instance.propsOptions[0]) && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .hasOwn */ .$3)(normalizedProps, key)) { + accessCache[key] = 3 /* PROPS */; + return props[key]; + } else if (ctx !== _vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .EMPTY_OBJ */ .MZ && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .hasOwn */ .$3)(ctx, key)) { + accessCache[key] = 4 /* CONTEXT */; + return ctx[key]; + } else if ( false || shouldCacheAccess) { + accessCache[key] = 0 /* OTHER */; + } + } + const publicGetter = publicPropertiesMap[key]; + let cssModule, globalProperties; + if (publicGetter) { + if (key === "$attrs") { + (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_20__/* .track */ .u4)(instance.attrs, "get", ""); + false && 0; + } else if (false) // removed by dead control flow +{} + return publicGetter(instance); + } else if ( + // css module (injected by vue-loader) + (cssModule = type.__cssModules) && (cssModule = cssModule[key])) { + return cssModule; + } else if (ctx !== _vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .EMPTY_OBJ */ .MZ && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .hasOwn */ .$3)(ctx, key)) { + accessCache[key] = 4 /* CONTEXT */; + return ctx[key]; + } else if ( + // global properties + globalProperties = appContext.config.globalProperties, (0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .hasOwn */ .$3)(globalProperties, key)) { + { + return globalProperties[key]; + } + } else if (false) // removed by dead control flow +{} + }, + set({ + _: instance + }, key, value) { + const { + data, + setupState, + ctx + } = instance; + if (hasSetupBinding(setupState, key)) { + setupState[key] = value; + return true; + } else if (false) // removed by dead control flow +{} else if (data !== _vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .EMPTY_OBJ */ .MZ && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .hasOwn */ .$3)(data, key)) { + data[key] = value; + return true; + } else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .hasOwn */ .$3)(instance.props, key)) { + false && 0; + return false; + } + if (key[0] === "$" && key.slice(1) in instance) { + false && 0; + return false; + } else { + if (false) // removed by dead control flow +{} else { + ctx[key] = value; + } + } + return true; + }, + has({ + _: { + data, + setupState, + accessCache, + ctx, + appContext, + propsOptions + } + }, key) { + let normalizedProps; + return !!accessCache[key] || data !== _vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .EMPTY_OBJ */ .MZ && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .hasOwn */ .$3)(data, key) || hasSetupBinding(setupState, key) || (normalizedProps = propsOptions[0]) && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .hasOwn */ .$3)(normalizedProps, key) || (0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .hasOwn */ .$3)(ctx, key) || (0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .hasOwn */ .$3)(publicPropertiesMap, key) || (0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .hasOwn */ .$3)(appContext.config.globalProperties, key); + }, + defineProperty(target, key, descriptor) { + if (descriptor.get != null) { + target._.accessCache[key] = 0; + } else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_21__/* .hasOwn */ .$3)(descriptor, "value")) { + this.set(target, key, descriptor.value, null); + } + return Reflect.defineProperty(target, key, descriptor); + } +}; +if (false) // removed by dead control flow +{} +const RuntimeCompiledPublicInstanceProxyHandlers = /* @__PURE__ */(/* unused pure expression or super */ null && (extend({}, PublicInstanceProxyHandlers, { + get(target, key) { + if (key === Symbol.unscopables) { + return; + } + return PublicInstanceProxyHandlers.get(target, key, target); + }, + has(_, key) { + const has = key[0] !== "_" && !isGloballyAllowed(key); + if (false) // removed by dead control flow +{} + return has; + } +}))); +function createDevRenderContext(instance) { + const target = {}; + Object.defineProperty(target, `_`, { + configurable: true, + enumerable: false, + get: () => instance + }); + Object.keys(publicPropertiesMap).forEach(key => { + Object.defineProperty(target, key, { + configurable: true, + enumerable: false, + get: () => publicPropertiesMap[key](instance), + // intercepted by the proxy so no need for implementation, + // but needed to prevent set errors + set: NOOP + }); + }); + return target; +} +function exposePropsOnRenderContext(instance) { + const { + ctx, + propsOptions: [propsOptions] + } = instance; + if (propsOptions) { + Object.keys(propsOptions).forEach(key => { + Object.defineProperty(ctx, key, { + enumerable: true, + configurable: true, + get: () => instance.props[key], + set: NOOP + }); + }); + } +} +function exposeSetupStateOnRenderContext(instance) { + const { + ctx, + setupState + } = instance; + Object.keys(toRaw(setupState)).forEach(key => { + if (!setupState.__isScriptSetup) { + if (isReservedPrefix(key[0])) { + warn$1(`setup() return property ${JSON.stringify(key)} should not start with "$" or "_" which are reserved prefixes for Vue internals.`); + return; + } + Object.defineProperty(ctx, key, { + enumerable: true, + configurable: true, + get: () => setupState[key], + set: NOOP + }); + } + }); +} +const warnRuntimeUsage = method => warn$1(`${method}() is a compiler-hint helper that is only usable inside + + + +
+ + diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..7fad392 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,17 @@ + + + diff --git a/src/components/ChatShell.vue b/src/components/ChatShell.vue new file mode 100644 index 0000000..87d9458 --- /dev/null +++ b/src/components/ChatShell.vue @@ -0,0 +1,34 @@ + + + diff --git a/src/components/DocumentedShell.vue b/src/components/DocumentedShell.vue new file mode 100644 index 0000000..bce1bc9 --- /dev/null +++ b/src/components/DocumentedShell.vue @@ -0,0 +1,186 @@ + + + diff --git a/src/components/LoginView.vue b/src/components/LoginView.vue new file mode 100644 index 0000000..50ce114 --- /dev/null +++ b/src/components/LoginView.vue @@ -0,0 +1,502 @@ + + + diff --git a/src/components/chat/ChatPanel.vue b/src/components/chat/ChatPanel.vue new file mode 100644 index 0000000..c320160 --- /dev/null +++ b/src/components/chat/ChatPanel.vue @@ -0,0 +1,1067 @@ + + + diff --git a/src/components/chat/MessageComposer.vue b/src/components/chat/MessageComposer.vue new file mode 100644 index 0000000..84b3190 --- /dev/null +++ b/src/components/chat/MessageComposer.vue @@ -0,0 +1,223 @@ + + + diff --git a/src/components/chat/MessageList.vue b/src/components/chat/MessageList.vue new file mode 100644 index 0000000..ecb9cd7 --- /dev/null +++ b/src/components/chat/MessageList.vue @@ -0,0 +1,757 @@ + + + diff --git a/src/components/contacts/ContactPanel.vue b/src/components/contacts/ContactPanel.vue new file mode 100644 index 0000000..cbacee5 --- /dev/null +++ b/src/components/contacts/ContactPanel.vue @@ -0,0 +1,111 @@ + + + diff --git a/src/components/favorites/FavoriteList.vue b/src/components/favorites/FavoriteList.vue new file mode 100644 index 0000000..6b03949 --- /dev/null +++ b/src/components/favorites/FavoriteList.vue @@ -0,0 +1,79 @@ + + + diff --git a/src/components/favorites/FavoritePanel.vue b/src/components/favorites/FavoritePanel.vue new file mode 100644 index 0000000..c46adbb --- /dev/null +++ b/src/components/favorites/FavoritePanel.vue @@ -0,0 +1,202 @@ + + + diff --git a/src/components/sidebar/ContactList.vue b/src/components/sidebar/ContactList.vue new file mode 100644 index 0000000..dbb4108 --- /dev/null +++ b/src/components/sidebar/ContactList.vue @@ -0,0 +1,103 @@ + + + diff --git a/src/components/sidebar/ConversationList.vue b/src/components/sidebar/ConversationList.vue new file mode 100644 index 0000000..00b6673 --- /dev/null +++ b/src/components/sidebar/ConversationList.vue @@ -0,0 +1,525 @@ + + + diff --git a/src/components/sidebar/NavigationRail.vue b/src/components/sidebar/NavigationRail.vue new file mode 100644 index 0000000..95fad26 --- /dev/null +++ b/src/components/sidebar/NavigationRail.vue @@ -0,0 +1,724 @@ + + + diff --git a/src/config.js b/src/config.js new file mode 100644 index 0000000..0114e8f --- /dev/null +++ b/src/config.js @@ -0,0 +1,36 @@ +const currentHost = window.location.hostname || '127.0.0.1'; +const runtimeConfig = window.JC_WEB_IM_CONFIG || {}; +const appServerOrigin = `${window.location.protocol}//${currentHost}:8888`; +const qrAppServerOrigin = `${window.location.protocol}//${currentHost}:18888`; +const adminServerOrigin = `${window.location.protocol}//${currentHost}:8024`; + +export const appConfig = { + appName: 'Web IM', + adminServer: runtimeConfig.adminServer || process.env.VUE_APP_ADMIN_SERVER || adminServerOrigin, + appServer: runtimeConfig.appServer || process.env.VUE_APP_APP_SERVER || appServerOrigin, + qrAppServer: runtimeConfig.qrAppServer || process.env.VUE_APP_QR_APP_SERVER || qrAppServerOrigin, + platformConfigApi: runtimeConfig.platformConfigApi || process.env.VUE_APP_PLATFORM_CONFIG_API || (process.env.NODE_ENV === 'development' ? '/local-api/platform_config.php' : '/api/platform_config.php'), + registerConfigApi: runtimeConfig.registerConfigApi || process.env.VUE_APP_REGISTER_CONFIG_API || `${adminServerOrigin}/api/register-config`, + registerPhoneExistsApi: runtimeConfig.registerPhoneExistsApi || process.env.VUE_APP_REGISTER_PHONE_EXISTS_API || `${adminServerOrigin}/api/register-phone-exists`, + contactsApi: runtimeConfig.contactsApi || process.env.VUE_APP_CONTACTS_API || (process.env.NODE_ENV === 'development' ? '/local-api/contacts.php' : '/api/contacts.php'), + updateAliasApi: runtimeConfig.updateAliasApi || process.env.VUE_APP_UPDATE_ALIAS_API || (process.env.NODE_ENV === 'development' ? '/local-api/update_alias.php' : '/api/update_alias.php'), + addContactApi: runtimeConfig.addContactApi || process.env.VUE_APP_ADD_CONTACT_API || (process.env.NODE_ENV === 'development' ? '/local-api/add_contact.php' : '/api/add_contact.php'), + conversationActionsApi: runtimeConfig.conversationActionsApi || process.env.VUE_APP_CONVERSATION_ACTIONS_API || (process.env.NODE_ENV === 'development' ? '/local-api/conversation_actions.php' : '/api/conversation_actions.php'), + sendMessageApi: runtimeConfig.sendMessageApi || process.env.VUE_APP_SEND_MESSAGE_API || (process.env.NODE_ENV === 'development' ? '/local-api/send_message.php' : '/api/send_message.php'), + messageActionApi: runtimeConfig.messageActionApi || process.env.VUE_APP_MESSAGE_ACTION_API || (process.env.NODE_ENV === 'development' ? '/local-api/message_action.php' : '/api/message_action.php'), + messageDetailApi: runtimeConfig.messageDetailApi || process.env.VUE_APP_MESSAGE_DETAIL_API || (process.env.NODE_ENV === 'development' ? '/local-api/message_detail.php' : '/api/message_detail.php'), + messagesApi: runtimeConfig.messagesApi || process.env.VUE_APP_MESSAGES_API || (process.env.NODE_ENV === 'development' ? '/local-api/messages.php' : '/api/messages.php'), + profileApi: runtimeConfig.profileApi || process.env.VUE_APP_PROFILE_API || (process.env.NODE_ENV === 'development' ? '/local-api/profile.php' : '/api/profile.php'), + changePasswordApi: runtimeConfig.changePasswordApi || process.env.VUE_APP_CHANGE_PASSWORD_API || `${appServerOrigin}/auth/changePassword`, + logoutApi: runtimeConfig.logoutApi || process.env.VUE_APP_LOGOUT_API || `${appServerOrigin}/auth/logout`, + imServerHost: runtimeConfig.imServerHost || process.env.VUE_APP_IM_SERVER_HOST || currentHost, + imRoutePort: Number(runtimeConfig.imRoutePort || process.env.VUE_APP_IM_ROUTE_PORT || 18000), + useWss: runtimeConfig.useWss ?? process.env.VUE_APP_USE_WSS === 'true', + wsPath: runtimeConfig.wsPath || process.env.VUE_APP_WS_PATH || '/ws', + wsUrl: runtimeConfig.wsUrl || process.env.VUE_APP_WS_URL || '', + sdkMode: runtimeConfig.sdkMode || process.env.VUE_APP_IM_MODE || 'http', + syncIntervalMs: Number(runtimeConfig.syncIntervalMs || process.env.VUE_APP_SYNC_INTERVAL_MS || 300), + platform: 5, + clientIdStorageKey: 'qmt-web-im-client-id', + authTokenStoragePrefix: 'qmt-web-im-auth-token-' +}; diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..4ce2b30 --- /dev/null +++ b/src/main.js @@ -0,0 +1,6 @@ +import { createApp } from 'vue'; +import { createPinia } from 'pinia'; +import App from './App.vue'; +import './styles/base.css'; + +createApp(App).use(createPinia()).mount('#app'); diff --git a/src/services/appServerClient.js b/src/services/appServerClient.js new file mode 100644 index 0000000..214e3f2 --- /dev/null +++ b/src/services/appServerClient.js @@ -0,0 +1,266 @@ +import axios from 'axios'; +import { appConfig } from '@/config'; + +const AES_KEY = 'xczx2026!@#secKe'; +const ENCRYPTION_EXCLUDE_PATHS = ['/avatar/', '/f/', '/amr2mp3', '/appVersion/check']; +const AUTH_STORAGE_KEY = 'qmt-web-im-app-auth-v1'; +const AUTH_ERROR_CODE = 13; +const REFRESH_ERROR_CODE = 20045; + +let importedCryptoKeyPromise = null; +let refreshPromise = null; + +function storageScope() { + return appConfig.appServer || ''; +} + +function readAuthStore() { + try { + return JSON.parse(localStorage.getItem(AUTH_STORAGE_KEY) || '{}'); + } catch (error) { + return {}; + } +} + +function writeAuthStore(store) { + localStorage.setItem(AUTH_STORAGE_KEY, JSON.stringify(store)); +} + +function normalizeAuthBundle(bundle = {}) { + const accessToken = String(bundle.accessToken || '').trim(); + const refreshToken = String(bundle.refreshToken || '').trim(); + if (!accessToken || !refreshToken) { + return null; + } + return { + accessToken, + refreshToken, + tokenType: String(bundle.tokenType || 'Bearer').trim() || 'Bearer', + accessTokenExpireIn: Number(bundle.accessTokenExpireIn || 0) || 0, + accessTokenExpireAt: Number(bundle.accessTokenExpireAt || 0) || 0, + refreshTokenExpireIn: Number(bundle.refreshTokenExpireIn || 0) || 0, + refreshTokenExpireAt: Number(bundle.refreshTokenExpireAt || 0) || 0 + }; +} + +export function getStoredAppAuth() { + const store = readAuthStore(); + return normalizeAuthBundle(store[storageScope()]); +} + +export function persistAppAuth(bundle) { + const normalized = normalizeAuthBundle(bundle); + const store = readAuthStore(); + if (!normalized) { + delete store[storageScope()]; + writeAuthStore(store); + return null; + } + store[storageScope()] = normalized; + writeAuthStore(store); + return normalized; +} + +export function clearStoredAppAuth() { + persistAppAuth(null); +} + +function hasFormData(value) { + return typeof FormData !== 'undefined' && value instanceof FormData; +} + +function absoluteUrl(url) { + return new URL(url, window.location.origin); +} + +function shouldEncrypt(url) { + const pathname = absoluteUrl(url).pathname; + return !ENCRYPTION_EXCLUDE_PATHS.some(path => pathname === path || pathname.startsWith(path)); +} + +function shouldAttachAuth(config) { + return !config.skipAuth; +} + +function textEncoder() { + return new TextEncoder(); +} + +function textDecoder() { + return new TextDecoder(); +} + +function bytesToBase64(bytes) { + let binary = ''; + bytes.forEach(byte => { + binary += String.fromCharCode(byte); + }); + return btoa(binary); +} + +function base64ToBytes(base64) { + const binary = atob(base64); + const bytes = new Uint8Array(binary.length); + for (let index = 0; index < binary.length; index += 1) { + bytes[index] = binary.charCodeAt(index); + } + return bytes; +} + +async function getCryptoKey() { + if (!importedCryptoKeyPromise) { + importedCryptoKeyPromise = window.crypto.subtle.importKey( + 'raw', + textEncoder().encode(AES_KEY), + { name: 'AES-CBC' }, + false, + ['encrypt', 'decrypt'] + ); + } + return importedCryptoKeyPromise; +} + +async function encryptPayload(plainText) { + const iv = window.crypto.getRandomValues(new Uint8Array(16)); + const key = await getCryptoKey(); + const encrypted = await window.crypto.subtle.encrypt( + { name: 'AES-CBC', iv }, + key, + textEncoder().encode(plainText) + ); + return `${bytesToBase64(iv)}:${bytesToBase64(new Uint8Array(encrypted))}`; +} + +async function decryptPayload(cipherText) { + const [ivBase64, encryptedBase64] = String(cipherText || '').split(':', 2); + if (!ivBase64 || !encryptedBase64) { + throw new Error('Encrypted payload format is invalid'); + } + const key = await getCryptoKey(); + const decrypted = await window.crypto.subtle.decrypt( + { name: 'AES-CBC', iv: base64ToBytes(ivBase64) }, + key, + base64ToBytes(encryptedBase64) + ); + return textDecoder().decode(decrypted); +} + +function normalizeBusinessResponse(payload) { + if (payload && typeof payload === 'object' && !Array.isArray(payload)) { + return payload; + } + return { + code: 0, + message: 'success', + data: payload + }; +} + +async function decodeResponsePayload(response) { + const encrypted = String(response.headers?.['x-encrypted'] || '').toLowerCase() === 'true'; + if (encrypted && typeof response.data === 'string') { + const plainText = await decryptPayload(response.data); + response.data = normalizeBusinessResponse(JSON.parse(plainText)); + return response; + } + response.data = normalizeBusinessResponse(response.data); + return response; +} + +const client = axios.create({ + withCredentials: false +}); + +client.interceptors.request.use(async config => { + const nextConfig = { ...config }; + const url = absoluteUrl(nextConfig.url || '').toString(); + + if (shouldAttachAuth(nextConfig)) { + const auth = getStoredAppAuth(); + if (auth?.accessToken) { + nextConfig.headers = { + ...(nextConfig.headers || {}), + Authorization: `${auth.tokenType || 'Bearer'} ${auth.accessToken}` + }; + } + } + + if (!hasFormData(nextConfig.data) && nextConfig.method?.toLowerCase() !== 'get' && shouldEncrypt(url)) { + const plainBody = JSON.stringify(nextConfig.data ?? {}); + nextConfig.data = await encryptPayload(plainBody); + nextConfig.headers = { + ...(nextConfig.headers || {}), + 'Content-Type': 'text/plain;charset=UTF-8', + 'X-Timestamp': `${Math.floor(Date.now() / 1000)}` + }; + } + + return nextConfig; +}); + +client.interceptors.response.use(async response => decodeResponsePayload(response)); + +async function refreshAccessToken() { + if (refreshPromise) { + return refreshPromise; + } + const auth = getStoredAppAuth(); + if (!auth?.refreshToken) { + clearStoredAppAuth(); + throw new Error('登录状态已失效,请重新登录'); + } + + refreshPromise = client.post(`${appConfig.appServer}/auth/refreshToken`, { + refreshToken: auth.refreshToken + }, { + skipAuth: true + }).then(response => { + const payload = response.data || {}; + if (Number(payload.code) !== 0 || !payload.data) { + if (Number(payload.code) === REFRESH_ERROR_CODE) { + clearStoredAppAuth(); + } + throw new Error(payload.message || '刷新登录状态失败'); + } + persistAppAuth(payload.data); + return payload.data; + }).finally(() => { + refreshPromise = null; + }); + + return refreshPromise; +} + +async function request(config) { + const response = await client.request(config); + const payload = response.data || {}; + if (Number(payload.code) === AUTH_ERROR_CODE && shouldAttachAuth(config) && !config._retriedAfterRefresh) { + await refreshAccessToken(); + return request({ + ...config, + _retriedAfterRefresh: true + }); + } + return response; +} + +export async function appServerRequest(config) { + return request(config); +} + +export async function appServerGet(url, config = {}) { + return request({ + ...config, + method: 'get', + url + }); +} + +export async function appServerPost(url, data = {}, config = {}) { + return request({ + ...config, + method: 'post', + url, + data + }); +} diff --git a/src/services/documentedHttpImClient.js b/src/services/documentedHttpImClient.js new file mode 100644 index 0000000..7e6a546 --- /dev/null +++ b/src/services/documentedHttpImClient.js @@ -0,0 +1,273 @@ +import { appConfig } from '@/config'; +import { HttpImClient } from './httpImClient'; +import axios from 'axios'; +import { + appServerGet, + appServerPost, + clearStoredAppAuth, + getStoredAppAuth, + persistAppAuth +} from './appServerClient'; + +function inferAccountType(account) { + return String(account || '').includes('@') ? 2 : 1; +} + +function unwrapData(response) { + return response.data?.data ?? response.data?.result ?? null; +} + +function unwrapMessage(response, fallback) { + return response.data?.message || response.data?.msg || fallback; +} + +export class DocumentedHttpImClient extends HttpImClient { + unsupported(feature) { + throw new Error(`当前对接文档未提供“${feature}”接口,已禁用旧本地代理链路`); + } + + async loginWithPassword(account, password, type = inferAccountType(account)) { + const response = await appServerPost(`${appConfig.appServer}/auth/login_pwd`, { + type, + number: account, + password, + platform: appConfig.platform, + clientId: this.getClientId() + }, { + skipAuth: true + }); + + if (response.data?.code !== 0) { + throw new Error(unwrapMessage(response, '登录失败')); + } + + persistAppAuth(unwrapData(response)); + return unwrapData(response); + } + + async requestAuthCode(email) { + const response = await appServerPost(`${appConfig.appServer}/auth/sendEmailCode`, { + email + }, { + skipAuth: true + }); + + if (response.data?.code !== 0) { + throw new Error(unwrapMessage(response, '验证码发送失败')); + } + + return unwrapData(response); + } + + async loginWithCode(account, code) { + void account; + void code; + throw new Error('接口文档未提供验证码登录接口,请使用密码登录'); + } + + async register({ type, number, code = '', password, invitationCode = '' }) { + const response = await appServerPost(`${appConfig.appServer}/auth/register`, { + type, + number, + code, + password, + clientId: this.getClientId(), + platform: appConfig.platform, + invitationCode + }, { + skipAuth: true + }); + + if (response.data?.code !== 0) { + throw new Error(unwrapMessage(response, '注册失败')); + } + + persistAppAuth(unwrapData(response)); + return unwrapData(response); + } + + async createPcSession(userId = '') { + const response = await axios.post(`${appConfig.qrAppServer}/pc_session`, { + flag: 1, + device_name: 'Web IM', + userId, + clientId: this.getClientId(), + platform: appConfig.platform + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(unwrapMessage(response, '二维码登录会话创建失败')); + } + + return unwrapData(response) || {}; + } + + async loginWithPcSession(token) { + const url = `${appConfig.qrAppServer}/session_login/${encodeURIComponent(token)}`; + let response; + try { + response = await axios.post(url, null, { withCredentials: false }); + } catch (postError) { + response = await axios.get(url, { withCredentials: false }); + } + + this.persistAppToken(url, response); + + const payload = response.data || {}; + const result = payload.result ?? payload.data ?? null; + + if (Number(payload.code) === 0 && result) { + persistAppAuth(result); + } + + if ([0, 8, 9, 10, 13, 18, 20042].includes(Number(payload.code))) { + return { + ...payload, + data: result + }; + } + + throw new Error(payload.message || '扫码登录失败'); + } + + async changePassword({ oldPassword, newPassword }) { + const response = await appServerPost(appConfig.changePasswordApi, { + oldPassword, + newPassword + }); + + if (response.data?.code !== 0) { + throw new Error(unwrapMessage(response, '密码修改失败')); + } + + return true; + } + + async resetPasswordWithCode({ mobile, resetCode, newPassword }) { + void mobile; + void resetCode; + void newPassword; + throw new Error('接口文档未提供重置密码接口,请联系服务端确认流程'); + } + + async logout() { + const auth = getStoredAppAuth(); + if (!auth?.refreshToken) { + clearStoredAppAuth(); + return true; + } + + try { + const response = await appServerPost(appConfig.logoutApi, { + refreshToken: auth.refreshToken + }); + if (response.data?.code !== 0) { + throw new Error(unwrapMessage(response, '退出登录失败')); + } + } finally { + clearStoredAppAuth(); + } + + return true; + } + + async fetchRemoteConversations() { + return []; + } + + async fetchRemoteMessages() { + return []; + } + + async getServerContactList() { + return []; + } + + async getProfile() { + return null; + } + + async sendTextMessage() { + this.unsupported('发送消息'); + } + + async sendAttachmentMessage() { + this.unsupported('发送附件消息'); + } + + async addContact() { + this.unsupported('添加联系人'); + } + + async updateContactAlias() { + this.unsupported('联系人备注'); + } + + async createGroup() { + this.unsupported('创建群组'); + } + + async joinGroup() { + this.unsupported('加入群组'); + } + + async broadcastMessage() { + this.unsupported('群发消息'); + } + + async getGroupDetail() { + this.unsupported('群详情'); + } + + async getGroupMembers() { + this.unsupported('群成员'); + } + + async updateGroupAlias() { + this.unsupported('群备注'); + } + + async leaveGroup() { + this.unsupported('退出群组'); + } + + async dismissGroup() { + this.unsupported('解散群组'); + } + + async transferGroup() { + this.unsupported('转让群组'); + } + + async setGroupAdmins() { + this.unsupported('设置群管理员'); + } + + async updateGroupProfile() { + this.unsupported('更新群资料'); + } + + async kickGroupMembers() { + this.unsupported('移除群成员'); + } + + async updateGroupMuteSetting() { + this.unsupported('群禁言设置'); + } + + async updateProfile() { + this.unsupported('更新个人资料'); + } + + async recallMessage() { + this.unsupported('撤回消息'); + } + + async editMessage() { + this.unsupported('编辑消息'); + } + + async getMessageDetail() { + this.unsupported('消息详情'); + } +} diff --git a/src/services/httpImClient.js b/src/services/httpImClient.js new file mode 100644 index 0000000..5ea697b --- /dev/null +++ b/src/services/httpImClient.js @@ -0,0 +1,1069 @@ +import axios from 'axios'; +import { appConfig } from '@/config'; +import { + appServerGet, + appServerPost, + clearStoredAppAuth, + getStoredAppAuth, + persistAppAuth +} from '@/services/appServerClient'; + +const LOCAL_MESSAGE_STORAGE_KEY = 'qmt-web-im-local-messages-v2'; +const LOCAL_HIDDEN_MESSAGE_STORAGE_KEY = 'qmt-web-im-hidden-messages-v1'; +const LOCAL_RECALLED_MESSAGE_STORAGE_KEY = 'qmt-web-im-recalled-messages-v1'; + +function scopedStorageKey(baseKey, userId = '') { + const scope = `${appConfig.appServer || ''}:${userId || 'anonymous'}`; + return `${baseKey}:${encodeURIComponent(scope)}`; +} + +function randomId() { + if (window.crypto && window.crypto.randomUUID) { + return window.crypto.randomUUID().replaceAll('-', ''); + } + return `${Date.now()}${Math.random().toString(16).slice(2)}`; +} + +function readLocalMessages(userId) { + try { + return JSON.parse(localStorage.getItem(scopedStorageKey(LOCAL_MESSAGE_STORAGE_KEY, userId)) || '{}'); + } catch (error) { + return {}; + } +} + +function readMessageSet(storageKey, userId) { + try { + return JSON.parse(localStorage.getItem(scopedStorageKey(storageKey, userId)) || '{}'); + } catch (error) { + return {}; + } +} + +function writeMessageSet(storageKey, messagesByConversation, userId) { + localStorage.setItem(scopedStorageKey(storageKey, userId), JSON.stringify(messagesByConversation)); +} + +function messageKeys(message) { + return [message?.id, message?.messageUid] + .filter(Boolean) + .map(value => String(value)); +} + +function hasStoredMessage(storageKey, conversationId, message, userId) { + const stored = readMessageSet(storageKey, userId); + const ids = new Set(stored[conversationId] || []); + return messageKeys(message).some(id => ids.has(id)); +} + +function storeMessageKeys(storageKey, conversationId, messages, userId) { + const stored = readMessageSet(storageKey, userId); + const ids = new Set(stored[conversationId] || []); + messages.forEach(message => { + messageKeys(message).forEach(id => ids.add(id)); + }); + stored[conversationId] = Array.from(ids); + writeMessageSet(storageKey, stored, userId); +} + +function withRecalledState(message) { + return { + ...message, + status: 'recalled', + deliveryStatus: '', + recalled: true, + recallStatus: '已撤回' + }; +} + +function applyLocalMessageState(conversationId, messages, userId) { + return messages + .filter(message => !hasStoredMessage(LOCAL_HIDDEN_MESSAGE_STORAGE_KEY, conversationId, message, userId)) + .map(message => { + const isRecalled = Boolean(message.recalled) + || message.status === 'recalled' + || hasStoredMessage(LOCAL_RECALLED_MESSAGE_STORAGE_KEY, conversationId, message, userId); + if (!isRecalled) { + return message; + } + return withRecalledState(message); + }); +} + +function writeLocalMessages(messagesByConversation, userId) { + localStorage.setItem(scopedStorageKey(LOCAL_MESSAGE_STORAGE_KEY, userId), JSON.stringify(messagesByConversation)); +} + +function saveLocalMessage(message, userId) { + const messagesByConversation = readLocalMessages(userId); + messagesByConversation[message.conversationId] = messagesByConversation[message.conversationId] || []; + const index = messagesByConversation[message.conversationId].findIndex(item => item.id === message.id); + if (index >= 0) { + messagesByConversation[message.conversationId].splice(index, 1, message); + } else { + messagesByConversation[message.conversationId].push(message); + } + writeLocalMessages(messagesByConversation, userId); +} + +function mergeSyncedMessages(localMessages, remoteMessages, conversationId, userId) { + const visibleLocalMessages = applyLocalMessageState(conversationId, localMessages, userId); + const localByKey = new Map(); + visibleLocalMessages.forEach(message => { + messageKeys(message).forEach(key => { + if (!localByKey.has(key)) { + localByKey.set(key, message); + } + }); + }); + + const visibleRemoteMessages = applyLocalMessageState(conversationId, remoteMessages, userId).map(remoteMessage => { + if (!remoteMessage.recalled || String(remoteMessage.text || '').trim()) { + return remoteMessage; + } + const localMessage = messageKeys(remoteMessage) + .map(key => localByKey.get(key)) + .find(message => message?.text && message.text !== '你撤回了一条消息'); + return localMessage ? { ...remoteMessage, text: localMessage.text } : remoteMessage; + }); + const remoteKeys = new Set(); + visibleRemoteMessages.forEach(message => { + messageKeys(message).forEach(key => remoteKeys.add(key)); + }); + const now = Date.now(); + + function hasRemoteMatch(localMessage) { + if (localMessage.messageUid && remoteKeys.has(localMessage.messageUid)) { + return true; + } + return visibleRemoteMessages.some(remoteMessage => { + return remoteMessage.direction === localMessage.direction + && remoteMessage.text === localMessage.text + && Math.abs(Number(remoteMessage.timestamp || 0) - Number(localMessage.timestamp || 0)) < 15000; + }); + } + + const pendingLocalMessages = visibleLocalMessages.filter(message => { + if (message.status === 'recalled' || message.recalled) { + return message.direction === 'out' && !hasRemoteMatch(message); + } + if (message.direction !== 'out') { + return false; + } + if (message.status === 'sent' && message.messageUid) { + return !hasRemoteMatch(message); + } + if (message.status === 'sent') { + return !hasRemoteMatch(message) && now - Number(message.timestamp || 0) < 30000; + } + return message.status === 'sending' || message.status === 'failed'; + }); + + return [...visibleRemoteMessages, ...pendingLocalMessages].sort((a, b) => { + return Number(a.displayTimestamp || a.timestamp || 0) - Number(b.displayTimestamp || b.timestamp || 0); + }); +} + +function getTitle(value, fallback) { + return value || fallback || ''; +} + +function getUniqueEquipment(mobile, fallback) { + const allowedDevices = { + '18301902119': '67072d37062c4f31b1165073552933ba', + '18301902116': '1777479418113eeea8e236edce', + '18301902118': 'de89fb2f2a61480a8c381f6c16e28bd8', + '18301902117': 'd117f480faa64145b6162107b1b49617' + }; + return allowedDevices[mobile] || localStorage.getItem('uniqueEquipment') || fallback; +} + +function canUseLocalLoginFallback(response) { + const message = response.data?.message || ''; + return process.env.NODE_ENV === 'development' && message.includes('允许此设备登录'); +} + +export class HttpImClient { + constructor() { + this.listeners = new Map(); + this.connected = false; + this.currentUser = null; + } + + getClientId() { + let clientId = localStorage.getItem(appConfig.clientIdStorageKey); + if (!clientId) { + clientId = randomId(); + localStorage.setItem(appConfig.clientIdStorageKey, clientId); + } + return clientId; + } + + restoreClientId(clientId) { + if (clientId) { + localStorage.setItem(appConfig.clientIdStorageKey, clientId); + } + } + + getSdkVersion() { + return 'HTTP'; + } + + async ensureSdk() { + return true; + } + + async loginWithPassword(mobile, password) { + const url = `${appConfig.appServer}/login_pwd`; + const deviceId = getUniqueEquipment(mobile, this.getClientId()); + const response = await axios.post(url, { + mobile, + password, + platform: appConfig.platform, + clientId: deviceId, + uniqueEquipment: deviceId + }, { withCredentials: false }); + + this.persistAppToken(url, response); + if (response.data?.code !== 0) { + if (canUseLocalLoginFallback(response)) { + return { + userId: mobile, + token: `local-device-pending-${Date.now()}`, + displayName: mobile, + localOnly: true + }; + } + throw new Error(response.data?.message || '登录失败'); + } + return response.data.result; + } + + async requestAuthCode(mobile) { + const response = await axios.post(`${appConfig.appServer}/send_code`, { mobile }, { withCredentials: false }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '验证码发送失败'); + } + return response.data.result; + } + + async loginWithCode(mobile, code) { + const url = `${appConfig.appServer}/login`; + const deviceId = getUniqueEquipment(mobile, this.getClientId()); + const response = await axios.post(url, { + mobile, + code, + platform: appConfig.platform, + clientId: deviceId, + uniqueEquipment: deviceId + }, { withCredentials: false }); + + this.persistAppToken(url, response); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '登录失败'); + } + return response.data.result; + } + + async createPcSession(userId = '') { + const response = await axios.post(`${appConfig.appServer}/pc_session`, { + flag: 1, + device_name: 'Web IM', + userId, + clientId: this.getClientId(), + platform: appConfig.platform + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '二维码登录会话创建失败'); + } + return response.data.result || {}; + } + + async loginWithPcSession(token) { + const url = `${appConfig.appServer}/session_login/${encodeURIComponent(token)}`; + const response = await axios.post(url, null, { withCredentials: false }); + this.persistAppToken(url, response); + const data = response.data || {}; + if ([0, 8, 9, 10, 18].includes(Number(data.code))) { + return data; + } + throw new Error(data.message || '扫码登录失败'); + } + + async registerWithPhone(mobile, code) { + const url = `${appConfig.appServer}/register`; + const deviceId = getUniqueEquipment(mobile, this.getClientId()); + + try { + const response = await axios.post(url, { + mobile, + code, + platform: appConfig.platform, + clientId: deviceId, + uniqueEquipment: deviceId + }, { withCredentials: false }); + + this.persistAppToken(url, response); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '注册失败'); + } + return response.data.result; + } catch (error) { + const status = error.response?.status; + if (status === 404 || status === 405) { + return this.loginWithCode(mobile, code); + } + throw error; + } + } + + connect(userId, token) { + this.currentUser = { userId, token }; + this.connected = true; + this.emit('connectionStatusChanged', { connected: true, statusText: '已连接' }); + this.refreshConversationList(); + } + + disconnect() { + this.connected = false; + this.currentUser = null; + this.emit('connectionStatusChanged', { connected: false, statusText: '未连接' }); + } + + getConversationList() { + return []; + } + + refreshConversationList() { + const conversations = this.getConversationList(); + if (conversations.length) { + this.emit('conversationsChanged', conversations); + } + if (this.currentUser?.userId) { + this.fetchRemoteConversations().then(remoteConversations => { + this.emit('conversationsChanged', remoteConversations); + }).catch(() => {}); + } + return conversations; + } + + async fetchRemoteConversations(limit = 50) { + if (!this.currentUser?.userId) { + return []; + } + const response = await axios.post(appConfig.messagesApi, { + userId: this.currentUser.userId, + limit + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '会话同步失败'); + } + + return (response.data?.result?.conversations || []).map(conversation => ({ + ...conversation, + updatedAt: Number(conversation.updatedAt || Date.now()), + avatarText: conversation.avatarText || String(conversation.title || conversation.target || '?').slice(0, 1).toUpperCase(), + raw: conversation.raw || { type: 'single', target: conversation.target, line: 0 } + })); + } + + getMessages(conversation) { + if (!conversation?.id) { + return []; + } + const userId = this.currentUser?.userId || ''; + return applyLocalMessageState(conversation.id, readLocalMessages(userId)[conversation.id] || [], userId); + } + + async fetchRemoteMessages(conversation, limit = 50, options = {}) { + if (!conversation?.id || !this.currentUser?.userId) { + return []; + } + const response = await axios.post(appConfig.messagesApi, { + userId: this.currentUser.userId, + target: conversation.target || conversation.raw?.target || conversation.id.replace(/^single-/, ''), + limit, + conversationType: conversation.type || conversation.raw?.type || 0, + markRead: Boolean(options.markRead) + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '消息同步失败'); + } + + const messages = (response.data?.result?.messages || []).map(message => ({ + ...message, + displayTimestamp: message.displayTimestamp || message.timestamp, + conversationId: conversation.id + })); + const userId = this.currentUser?.userId || ''; + const messagesByConversation = readLocalMessages(userId); + messagesByConversation[conversation.id] = mergeSyncedMessages(messagesByConversation[conversation.id] || [], messages, conversation.id, userId); + writeLocalMessages(messagesByConversation, userId); + return messagesByConversation[conversation.id]; + } + + hideMessages(conversation, messages) { + const items = Array.isArray(messages) ? messages : [messages]; + if (!conversation?.id || !items.length) { + return; + } + const userId = this.currentUser?.userId || ''; + storeMessageKeys(LOCAL_HIDDEN_MESSAGE_STORAGE_KEY, conversation.id, items, userId); + const messagesByConversation = readLocalMessages(userId); + messagesByConversation[conversation.id] = applyLocalMessageState( + conversation.id, + messagesByConversation[conversation.id] || [], + userId + ); + writeLocalMessages(messagesByConversation, userId); + } + + markMessagesRecalled(conversation, messages) { + const items = Array.isArray(messages) ? messages : [messages]; + if (!conversation?.id || !items.length) { + return; + } + const userId = this.currentUser?.userId || ''; + storeMessageKeys(LOCAL_RECALLED_MESSAGE_STORAGE_KEY, conversation.id, items, userId); + const messagesByConversation = readLocalMessages(userId); + messagesByConversation[conversation.id] = applyLocalMessageState( + conversation.id, + messagesByConversation[conversation.id] || [], + userId + ); + writeLocalMessages(messagesByConversation, userId); + } + + async recallMessage(conversation, message) { + const messageUid = String(message?.messageUid || message?.id || '').trim(); + if (!/^\d+$/.test(messageUid)) { + throw new Error('缺少可撤回的消息ID'); + } + + const response = await axios.post(appConfig.messageActionApi, { + action: 'recall', + userId: this.currentUser?.userId || message.from || '', + messageUid + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '撤回失败'); + } + this.markMessagesRecalled(conversation, [message]); + return response.data.result; + } + + async editMessage(conversation, message, text) { + const messageUid = String(message?.messageUid || message?.id || '').trim(); + if (!/^\d+$/.test(messageUid)) { + throw new Error('缺少可编辑的消息ID'); + } + const nextText = String(text || '').trim(); + if (!nextText) { + throw new Error('编辑内容不能为空'); + } + + const response = await axios.post(appConfig.messageActionApi, { + action: 'edit', + userId: this.currentUser?.userId || message.from || '', + messageUid, + text: nextText + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '编辑失败'); + } + + const result = response.data?.result?.message || {}; + const editedMessage = { + ...message, + text: result.text || nextText, + status: 'delivered', + deliveryStatus: 'delivered', + editedAt: Number(result.editedAt || Date.now()), + activityTimestamp: Number(result.editedAt || Date.now()) + }; + saveLocalMessage(editedMessage, this.currentUser?.userId || ''); + this.emit('messageStatusChanged', editedMessage); + return editedMessage; + } + + async getMessageDetail(conversation, message) { + const messageUid = String(message?.messageUid || message?.id || '').trim(); + if (!messageUid) { + throw new Error('缺少消息ID'); + } + const response = await axios.post(appConfig.messageDetailApi, { + userId: this.currentUser?.userId || '', + target: conversation?.target || conversation?.raw?.target || conversation?.id?.replace(/^single-/, '') || '', + conversationType: conversation?.type || conversation?.raw?.type || 'single', + messageUid + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '消息详情加载失败'); + } + + return response.data?.result?.detail || null; + } + + async sendTextMessage(conversation, text, initialMessage = null) { + const senderRole = conversation?.role || conversation?.raw?.role || ''; + const message = initialMessage || { + id: randomId(), + conversationId: conversation.id, + from: this.currentUser?.userId || 'me', + senderRole, + direction: 'out', + type: 'text', + text, + status: 'sending', + deliveryStatus: 'sending', + timestamp: Date.now() + }; + saveLocalMessage(message, this.currentUser?.userId || ''); + if (!initialMessage) { + this.emit('messageSent', message); + } + + try { + const response = await axios.post(appConfig.sendMessageApi, { + sender: this.currentUser?.userId || '', + target: conversation.target || conversation.raw?.target || conversation.id.replace(/^single-/, ''), + conversationType: conversation.type || conversation.raw?.type || 0, + text + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '发送失败'); + } + + const sentMessage = { + ...message, + status: 'sent', + deliveryStatus: 'sent', + messageUid: response.data?.result?.messageUid ? String(response.data.result.messageUid) : '', + senderRole: response.data?.result?.senderRole || message.senderRole || '', + serverTimestamp: Number(response.data?.result?.timestamp || 0) || null, + timestamp: message.timestamp, + displayTimestamp: message.displayTimestamp || message.timestamp + }; + saveLocalMessage(sentMessage, this.currentUser?.userId || ''); + this.emit('messageStatusChanged', sentMessage); + return sentMessage; + } catch (error) { + const failedMessage = { + ...message, + status: 'failed', + deliveryStatus: '', + error: error.response?.data?.message || error.message || '发送失败' + }; + saveLocalMessage(failedMessage, this.currentUser?.userId || ''); + this.emit('messageStatusChanged', failedMessage); + return failedMessage; + } + } + + async sendAttachmentMessage(conversation, { type, file, text = '' }, initialMessage = null) { + const senderRole = conversation?.role || conversation?.raw?.role || ''; + const message = initialMessage || { + id: randomId(), + conversationId: conversation.id, + from: this.currentUser?.userId || 'me', + senderRole, + direction: 'out', + type, + text, + attachment: { + type, + name: file?.name || (type === 'image' ? '图片' : '文件'), + mime: file?.type || '', + size: file?.size || 0, + url: type === 'image' && file ? URL.createObjectURL(file) : '' + }, + status: 'sending', + deliveryStatus: 'sending', + timestamp: Date.now() + }; + saveLocalMessage(message, this.currentUser?.userId || ''); + if (!initialMessage) { + this.emit('messageSent', message); + } + + try { + const formData = new FormData(); + formData.append('sender', this.currentUser?.userId || ''); + formData.append('target', conversation.target || conversation.raw?.target || conversation.id.replace(/^single-/, '')); + formData.append('conversationType', conversation.type || conversation.raw?.type || 0); + formData.append('messageType', type); + formData.append('text', text || ''); + formData.append('attachment', file); + + const response = await axios.post(appConfig.sendMessageApi, formData, { + withCredentials: false + }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '发送失败'); + } + + const sentMessage = { + ...message, + status: 'sent', + deliveryStatus: 'sent', + messageUid: response.data?.result?.messageUid ? String(response.data.result.messageUid) : '', + senderRole: response.data?.result?.senderRole || message.senderRole || '', + attachment: response.data?.result?.attachment || message.attachment, + serverTimestamp: Number(response.data?.result?.timestamp || 0) || null, + timestamp: message.timestamp, + displayTimestamp: message.displayTimestamp || message.timestamp + }; + saveLocalMessage(sentMessage, this.currentUser?.userId || ''); + this.emit('messageStatusChanged', sentMessage); + return sentMessage; + } catch (error) { + const failedMessage = { + ...message, + status: 'failed', + deliveryStatus: '', + error: error.response?.data?.message || error.message || '发送失败' + }; + saveLocalMessage(failedMessage, this.currentUser?.userId || ''); + this.emit('messageStatusChanged', failedMessage); + return failedMessage; + } + } + + getContactList() { + return []; + } + + async getServerContactList(userId) { + if (!userId) { + return []; + } + const response = await axios.post(appConfig.contactsApi, { userId }, { + withCredentials: false, + headers: this.getAppAuthHeaders(appConfig.contactsApi) + }); + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '联系人加载失败'); + } + return (response.data?.result?.contacts || []).map(item => { + return this.mapContact(item.uid, { alias: item.alias }, { + uid: item.uid, + displayName: item.displayName, + name: item.name, + mobile: item.mobile, + portrait: item.portrait, + address: item.address, + friendAlias: item.alias + }); + }).sort((a, b) => a.title.localeCompare(b.title, 'zh-CN')); + } + + async addContact(userId, keyword, reason = '') { + const response = await axios.post(appConfig.addContactApi, { + userId, + keyword, + reason + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '添加联系人失败'); + } + + const item = response.data?.result?.contact; + if (!item?.uid) { + return null; + } + + return this.mapContact(item.uid, { alias: item.alias }, { + uid: item.uid, + displayName: item.displayName, + name: item.name, + mobile: item.mobile, + portrait: item.portrait, + address: item.address, + friendAlias: item.alias + }); + } + + normalizeConversation(conversation) { + const title = getTitle(conversation?.title, conversation?.target || ''); + return { + ...conversation, + id: conversation?.id || `${conversation?.type === 'single' ? 'single' : 'group'}-${conversation?.target}`, + target: conversation?.target || conversation?.raw?.target || '', + title, + subtitle: conversation?.subtitle || '', + unread: Number(conversation?.unread || 0), + portrait: conversation?.portrait || '', + avatarText: conversation?.avatarText || title.slice(0, 1).toUpperCase(), + updatedAt: Number(conversation?.updatedAt || Date.now()), + raw: conversation?.raw || { + type: conversation?.type === 'single' ? 'single' : 'group', + target: conversation?.target || '', + line: 0 + } + }; + } + + async createGroup(userId, { name, memberIds = [], announcement = '', welcomeText = '', channel = false }) { + const response = await axios.post(appConfig.conversationActionsApi, { + action: channel ? 'create_channel' : 'create_group', + userId, + name, + memberIds, + announcement, + welcomeText + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || (channel ? '创建公告群失败' : '创建群组失败')); + } + + return this.normalizeConversation(response.data?.result?.conversation || {}); + } + + async joinGroup(userId, groupKey) { + const response = await axios.post(appConfig.conversationActionsApi, { + action: 'join_group', + userId, + groupKey + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '加入群组失败'); + } + + return this.normalizeConversation(response.data?.result?.conversation || {}); + } + + async broadcastMessage(userId, targetIds, text) { + const response = await axios.post(appConfig.conversationActionsApi, { + action: 'broadcast', + userId, + targetIds, + text + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '群发失败'); + } + + return response.data?.result || {}; + } + + async getGroupDetail(userId, groupId) { + const response = await axios.post(appConfig.conversationActionsApi, { + action: 'group_detail', + userId, + groupId + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '群资料加载失败'); + } + + return response.data?.result?.group || null; + } + + async getGroupMembers(userId, groupId) { + const response = await axios.post(appConfig.conversationActionsApi, { + action: 'group_members', + userId, + groupId + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '群员加载失败'); + } + + return response.data?.result?.members || []; + } + + async updateGroupAlias(userId, groupId, alias) { + const response = await axios.post(appConfig.conversationActionsApi, { + action: 'update_group_alias', + userId, + groupId, + alias + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '本群昵称保存失败'); + } + + return response.data?.result?.alias || ''; + } + + async leaveGroup(userId, groupId) { + const response = await axios.post(appConfig.conversationActionsApi, { + action: 'leave_group', + userId, + groupId + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '退出群组失败'); + } + + return response.data?.result || {}; + } + + async dismissGroup(userId, groupId) { + const response = await axios.post(appConfig.conversationActionsApi, { + action: 'dismiss_group', + userId, + groupId + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '解散群组失败'); + } + + return response.data?.result || {}; + } + + async transferGroup(userId, groupId, targetUserId) { + const response = await axios.post(appConfig.conversationActionsApi, { + action: 'transfer_group', + userId, + groupId, + targetUserId + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '转让群组失败'); + } + + return response.data?.result || {}; + } + + async setGroupAdmins(userId, groupId, adminIds) { + const response = await axios.post(appConfig.conversationActionsApi, { + action: 'set_group_admins', + userId, + groupId, + adminIds + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '管理员设置失败'); + } + + return response.data?.result || {}; + } + + async updateGroupProfile(userId, groupId, { name, announcement, welcomeText }) { + const response = await axios.post(appConfig.conversationActionsApi, { + action: 'update_group_profile', + userId, + groupId, + name, + announcement, + welcomeText + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '群资料保存失败'); + } + + return response.data?.result || {}; + } + + async kickGroupMembers(userId, groupId, targetIds) { + const response = await axios.post(appConfig.conversationActionsApi, { + action: 'kick_group_members', + userId, + groupId, + targetIds + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '踢人失败'); + } + + return response.data?.result || {}; + } + + async updateGroupMuteSetting(userId, groupId, setting) { + const response = await axios.post(appConfig.conversationActionsApi, { + action: 'update_mute_setting', + userId, + groupId, + ...setting + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '禁言设置保存失败'); + } + + return response.data?.result?.muteSetting || null; + } + + async updateContactAlias(userId, targetId, alias) { + const response = await axios.post(appConfig.updateAliasApi, { + userId, + targetId, + alias + }, { + withCredentials: false, + headers: this.getAppAuthHeaders(appConfig.updateAliasApi) + }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '备注名修改失败'); + } + + return response.data?.result?.contact?.alias || ''; + } + + async getProfile(userId) { + const response = await axios.post(appConfig.profileApi, { + action: 'get', + userId + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '用户资料加载失败'); + } + + return response.data?.result?.profile || null; + } + + async updateProfile(userId, { displayName, portraitFile }) { + const formData = new FormData(); + formData.append('action', 'update'); + formData.append('userId', userId); + formData.append('displayName', displayName); + if (portraitFile) { + formData.append('portraitFile', portraitFile); + } + + const response = await axios.post(appConfig.profileApi, formData, { + withCredentials: false, + headers: this.getAppAuthHeaders(appConfig.appServer) + }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || '用户资料保存失败'); + } + + return response.data?.result?.profile || null; + } + + async changePassword({ oldPassword, newPassword }) { + const response = await axios.post(appConfig.changePasswordApi, { + oldPassword, + newPassword + }, { + withCredentials: false, + headers: this.getAppAuthHeaders(appConfig.changePasswordApi) + }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || response.data?.msg || '密码修改失败'); + } + + return true; + } + + async resetPasswordWithCode({ mobile, resetCode, newPassword }) { + const response = await axios.post(appConfig.resetPasswordApi, { + mobile, + resetCode, + newPassword + }, { withCredentials: false }); + + if (response.data?.code !== 0) { + throw new Error(response.data?.message || response.data?.msg || '密码设置失败'); + } + + return true; + } + + refreshContactList() { + const contacts = this.getContactList(); + this.emit('contactsChanged', contacts); + return contacts; + } + + createSingleConversation(userId, userInfo = null) { + const title = getTitle(userInfo?.title || userInfo?.displayName || userInfo?.name, userId); + return { + id: `single-${userId}`, + type: 'single', + target: userId, + title, + subtitle: '', + unread: 0, + portrait: userInfo?.portrait || '', + avatarText: title.slice(0, 1).toUpperCase(), + updatedAt: Date.now(), + raw: { type: 'single', target: userId, line: 0 } + }; + } + + mapContact(userId, friend, userInfo) { + const title = getTitle(userInfo?.friendAlias || friend?.alias || userInfo?.displayName || userInfo?.name, userId); + return { + id: userId, + uid: userId, + title, + subtitle: userInfo?.mobile || userInfo?.name || userId, + portrait: userInfo?.portrait || '', + address: userInfo?.address || '', + avatarText: title.slice(0, 1).toUpperCase(), + alias: friend?.alias || userInfo?.friendAlias || '', + rawFriend: friend, + rawUser: userInfo + }; + } + + on(eventName, handler) { + if (!this.listeners.has(eventName)) { + this.listeners.set(eventName, new Set()); + } + this.listeners.get(eventName).add(handler); + return () => this.off(eventName, handler); + } + + off(eventName, handler) { + this.listeners.get(eventName)?.delete(handler); + } + + emit(eventName, payload) { + this.listeners.get(eventName)?.forEach(handler => handler(payload)); + } + + persistAppToken(url, response) { + const appToken = response.headers?.authtoken || response.headers?.authToken; + if (appToken) { + localStorage.setItem(appConfig.authTokenStoragePrefix + this.getUrlHost(url), appToken); + } + } + + getAppAuthHeaders(url) { + const host = this.getUrlHost(url); + if (!host) { + return {}; + } + const token = localStorage.getItem(appConfig.authTokenStoragePrefix + host); + return token ? { authToken: token } : {}; + } + + getUrlHost(url) { + try { + return new URL(url, window.location.origin).host; + } catch (error) { + return ''; + } + } +} + +export const imClient = new HttpImClient(); diff --git a/src/services/imClient.js b/src/services/imClient.js new file mode 100644 index 0000000..c2e6acb --- /dev/null +++ b/src/services/imClient.js @@ -0,0 +1,23 @@ +import { appConfig } from '@/config'; +import { HttpImClient } from './httpImClient'; +import { LongConnectionImClient } from './longConnectionImClient'; +import { DocumentedHttpImClient } from './documentedHttpImClient'; + +class UnsupportedWildfireImClient { + constructor() { + throw new Error('当前本地社区版 Web 客户端未启用 WildFire Web SDK'); + } +} + +export const imClient = appConfig.sdkMode === 'wildfire' + ? new UnsupportedWildfireImClient() + : appConfig.sdkMode === 'custom-ws' || appConfig.sdkMode === 'long' + ? new LongConnectionImClient() + : new DocumentedHttpImClient(); + +export { + DocumentedHttpImClient, + HttpImClient, + LongConnectionImClient, + UnsupportedWildfireImClient as WildfireImClient +}; diff --git a/src/services/longConnectionImClient.js b/src/services/longConnectionImClient.js new file mode 100644 index 0000000..d37e33d --- /dev/null +++ b/src/services/longConnectionImClient.js @@ -0,0 +1,236 @@ +import { appConfig } from '@/config'; +import { HttpImClient } from './httpImClient'; + +const HEARTBEAT_INTERVAL_MS = 25000; +const RECONNECT_MIN_MS = 1000; +const RECONNECT_MAX_MS = 15000; + +function buildWsUrl() { + if (appConfig.wsUrl) { + return appConfig.wsUrl; + } + const protocol = appConfig.useWss ? 'wss' : 'ws'; + const host = appConfig.imServerHost || window.location.hostname; + const port = appConfig.imRoutePort ? `:${appConfig.imRoutePort}` : ''; + const path = appConfig.wsPath?.startsWith('/') ? appConfig.wsPath : `/${appConfig.wsPath || 'ws'}`; + return `${protocol}://${host}${port}${path}`; +} + +function normalizeConversationId(payload) { + const target = payload.target || payload.to || payload.receiver || payload.conversationTarget || payload.from || payload.sender; + return payload.conversationId || (target ? `single-${target}` : ''); +} + +function normalizeIncomingMessage(payload, currentUserId) { + const item = payload.message || payload; + const from = item.from || item.sender || item.fromUser || ''; + const target = item.target || item.to || item.receiver || ''; + const direction = from && String(from) === String(currentUserId) ? 'out' : 'in'; + const conversationId = item.conversationId || normalizeConversationId({ + ...item, + target: direction === 'out' ? target : from + }); + + if (!conversationId) { + return null; + } + + const status = item.status || item.deliveryStatus || 'sent'; + + return { + id: item.id || item.messageId || item.messageUid || `${Date.now()}${Math.random().toString(16).slice(2)}`, + messageUid: item.messageUid || item.uid || item.messageId || '', + conversationId, + from, + target, + direction, + type: item.type || 'text', + text: item.text || item.content || item.searchableContent || '', + status, + deliveryStatus: item.deliveryStatus || (direction === 'out' ? status : ''), + timestamp: Number(item.timestamp || item.serverTimestamp || Date.now()), + displayTimestamp: Number(item.displayTimestamp || item.timestamp || item.serverTimestamp || Date.now()), + raw: item + }; +} + +export class LongConnectionImClient extends HttpImClient { + constructor() { + super(); + this.socket = null; + this.wsUrl = buildWsUrl(); + this.heartbeatTimer = null; + this.reconnectTimer = null; + this.reconnectAttempts = 0; + this.manualClose = false; + } + + getSdkVersion() { + return 'JC-LC/0.1'; + } + + shouldUseMessagePolling() { + return !this.connected; + } + + async ensureSdk() { + if (typeof WebSocket === 'undefined') { + throw new Error('当前浏览器不支持 WebSocket 长连接'); + } + return true; + } + + connect(userId, token) { + this.currentUser = { userId, token }; + this.manualClose = false; + this.openSocket(); + } + + disconnect() { + this.manualClose = true; + this.clearReconnectTimer(); + this.clearHeartbeatTimer(); + if (this.socket) { + this.socket.close(); + this.socket = null; + } + super.disconnect(); + } + + openSocket() { + if (this.socket?.readyState === WebSocket.OPEN) { + this.sendAuthFrame(); + return; + } + if (this.socket?.readyState === WebSocket.CONNECTING) { + return; + } + + this.emit('connectionStatusChanged', { connected: false, statusText: '长连接连接中' }); + + try { + this.socket = new WebSocket(this.wsUrl); + this.socket.binaryType = 'arraybuffer'; + } catch (error) { + this.emit('connectionStatusChanged', { connected: false, statusText: '长连接创建失败,使用HTTP补偿' }); + this.scheduleReconnect(); + return; + } + + this.socket.onopen = () => { + this.connected = true; + this.reconnectAttempts = 0; + this.emit('connectionStatusChanged', { connected: true, statusText: '长连接已连接' }); + this.sendAuthFrame(); + this.startHeartbeat(); + this.refreshConversationList(); + }; + + this.socket.onmessage = event => { + this.handleFrame(event.data); + }; + + this.socket.onerror = () => { + this.emit('connectionStatusChanged', { connected: false, statusText: '长连接异常,使用HTTP补偿' }); + }; + + this.socket.onclose = () => { + this.connected = false; + this.clearHeartbeatTimer(); + this.socket = null; + if (this.manualClose) { + return; + } + this.emit('connectionStatusChanged', { connected: false, statusText: '长连接重连中' }); + this.scheduleReconnect(); + }; + } + + sendAuthFrame() { + this.sendFrame({ + type: 'auth', + userId: this.currentUser?.userId || '', + token: this.currentUser?.token || '', + clientId: this.getClientId(), + platform: appConfig.platform, + timestamp: Date.now() + }); + } + + sendFrame(frame) { + if (this.socket?.readyState !== WebSocket.OPEN) { + return false; + } + this.socket.send(JSON.stringify(frame)); + return true; + } + + handleFrame(rawData) { + if (rawData instanceof ArrayBuffer) { + this.emit('rawFrameReceived', rawData); + return; + } + + let payload; + try { + payload = typeof rawData === 'string' ? JSON.parse(rawData) : rawData; + } catch (error) { + return; + } + + const type = payload.type || payload.event || payload.cmd || ''; + if (type === 'pong' || type === 'auth_ok' || type === 'connected') { + return; + } + if (type === 'contactsChanged') { + this.emit('contactsChanged', payload.contacts || []); + return; + } + if (type === 'conversationsChanged') { + this.emit('conversationsChanged', payload.conversations || []); + return; + } + if (type === 'messages' && Array.isArray(payload.messages)) { + payload.messages + .map(message => normalizeIncomingMessage(message, this.currentUser?.userId)) + .filter(Boolean) + .forEach(message => this.emit('messageReceived', message)); + return; + } + + const message = normalizeIncomingMessage(payload, this.currentUser?.userId); + if (message) { + this.emit(message.direction === 'out' ? 'messageStatusChanged' : 'messageReceived', message); + } + } + + startHeartbeat() { + this.clearHeartbeatTimer(); + this.heartbeatTimer = window.setInterval(() => { + this.sendFrame({ type: 'ping', timestamp: Date.now() }); + }, HEARTBEAT_INTERVAL_MS); + } + + clearHeartbeatTimer() { + if (this.heartbeatTimer) { + window.clearInterval(this.heartbeatTimer); + this.heartbeatTimer = null; + } + } + + scheduleReconnect() { + this.clearReconnectTimer(); + const delay = Math.min(RECONNECT_MAX_MS, RECONNECT_MIN_MS * 2 ** this.reconnectAttempts); + this.reconnectAttempts += 1; + this.reconnectTimer = window.setTimeout(() => { + this.openSocket(); + }, delay); + } + + clearReconnectTimer() { + if (this.reconnectTimer) { + window.clearTimeout(this.reconnectTimer); + this.reconnectTimer = null; + } + } +} diff --git a/src/stores/contacts.js b/src/stores/contacts.js new file mode 100644 index 0000000..1195693 --- /dev/null +++ b/src/stores/contacts.js @@ -0,0 +1,233 @@ +import { defineStore } from 'pinia'; +import { imClient } from '@/services/imClient'; +import { useConversationStore } from '@/stores/conversations'; +import { useNavigationStore } from '@/stores/navigation'; +import { useSessionStore } from '@/stores/session'; + +const CONTACT_CACHE_MS = 15000; + +function normalizeContacts(contacts) { + const unique = new Map(); + contacts.forEach(contact => { + const uid = String(contact.uid || contact.id || '').trim(); + if (!uid) { + return; + } + const normalized = { + ...contact, + id: String(contact.id || uid), + uid + }; + unique.set(uid, { + ...(unique.get(uid) || {}), + ...normalized + }); + }); + return Array.from(unique.values()).sort((a, b) => a.title.localeCompare(b.title, 'zh-CN')); +} + +export const useContactStore = defineStore('contacts', { + state: () => ({ + contacts: [], + activeId: '', + loading: false, + eventsBound: false, + refreshSerial: 0, + refreshPromise: null, + loadedForUserId: '', + loadedAt: 0, + actionError: '', + actionInfo: '' + }), + getters: { + activeContact(state) { + return state.contacts.find(item => item.id === state.activeId) || state.contacts[0] || null; + } + }, + actions: { + bindImEvents() { + if (this.eventsBound) { + return; + } + this.eventsBound = true; + imClient.on('contactsChanged', contacts => { + if (!contacts.length && this.contacts.length) { + return; + } + this.contacts = normalizeContacts(contacts); + if (!this.contacts.find(item => item.id === this.activeId)) { + this.activeId = this.contacts[0]?.id || ''; + } + }); + }, + async refreshContacts(options = {}) { + this.bindImEvents(); + const session = useSessionStore(); + const requestUserId = session.userId; + const force = Boolean(options.force); + if (!requestUserId) { + this.clearContacts(); + return []; + } + if (!force + && this.contacts.length + && this.loadedForUserId === requestUserId + && Date.now() - this.loadedAt < CONTACT_CACHE_MS + ) { + return this.contacts; + } + if (this.refreshPromise && !force) { + return this.refreshPromise; + } + const serial = this.refreshSerial + 1; + this.refreshSerial = serial; + this.loading = true; + + this.refreshPromise = (async () => { + this.contacts = normalizeContacts(imClient.refreshContactList()); + if (!this.contacts.find(item => item.id === this.activeId)) { + this.activeId = this.contacts[0]?.id || ''; + } + if (!this.contacts.length || force) { + const serverContacts = await imClient.getServerContactList(requestUserId); + if (serial !== this.refreshSerial || useSessionStore().userId !== requestUserId) { + return this.contacts; + } + this.contacts = normalizeContacts(serverContacts); + this.loadedForUserId = requestUserId; + this.loadedAt = Date.now(); + if (!this.contacts.find(item => item.id === this.activeId)) { + this.activeId = this.contacts[0]?.id || ''; + } + } + window.setTimeout(() => { + if (serial !== this.refreshSerial || useSessionStore().userId !== requestUserId) { + return; + } + const latest = imClient.getContactList(false); + if (latest.length || !this.contacts.length) { + this.contacts = normalizeContacts(latest); + this.loadedForUserId = requestUserId; + this.loadedAt = Date.now(); + if (!this.contacts.find(item => item.id === this.activeId)) { + this.activeId = this.contacts[0]?.id || ''; + } + } + }, 1200); + return this.contacts; + })(); + + try { + return await this.refreshPromise; + } finally { + if (serial === this.refreshSerial) { + this.loading = false; + this.refreshPromise = null; + } + } + }, + async addContact(keyword) { + const session = useSessionStore(); + const value = String(keyword || '').trim(); + this.actionError = ''; + this.actionInfo = ''; + if (!session.userId) { + this.actionError = '请先登录'; + return false; + } + if (!value) { + this.actionError = '请输入用户ID、手机号或用户名'; + return false; + } + + this.loading = true; + try { + const contact = await imClient.addContact(session.userId, value, '添加联系人'); + if (contact) { + this.contacts = normalizeContacts([...this.contacts, contact]); + this.activeId = contact.id; + } + this.actionInfo = '联系人已添加'; + await this.refreshContacts({ force: true }); + return true; + } catch (error) { + this.actionError = error.message || '添加联系人失败'; + return false; + } finally { + this.loading = false; + } + }, + async updateContactAlias(contactId, alias) { + const session = useSessionStore(); + const targetId = String(contactId || '').trim(); + const nextAlias = String(alias || '').trim(); + this.actionError = ''; + this.actionInfo = ''; + if (!session.userId) { + this.actionError = '请先登录'; + return false; + } + if (!targetId) { + this.actionError = '缺少联系人ID'; + return false; + } + + try { + const savedAlias = await imClient.updateContactAlias(session.userId, targetId, nextAlias); + this.contacts = normalizeContacts(this.contacts.map(item => { + if (item.uid !== targetId && item.id !== targetId) { + return item; + } + const rawUser = { + ...(item.rawUser || {}), + friendAlias: savedAlias + }; + const rawFriend = { + ...(item.rawFriend || {}), + alias: savedAlias + }; + const title = savedAlias || rawUser.displayName || rawUser.name || item.uid; + return { + ...item, + title, + avatarText: title.slice(0, 1).toUpperCase(), + alias: savedAlias, + rawFriend, + rawUser + }; + })); + this.loadedAt = Date.now(); + this.actionInfo = '备注名已修改'; + return true; + } catch (error) { + this.actionError = error.message || '备注名修改失败'; + return false; + } + }, + clearContacts() { + this.refreshSerial += 1; + this.contacts = []; + this.activeId = ''; + this.loading = false; + this.refreshPromise = null; + this.loadedForUserId = ''; + this.loadedAt = 0; + this.actionError = ''; + this.actionInfo = ''; + }, + setActiveContact(id) { + this.activeId = id; + }, + openChat(contact) { + if (!contact) { + return; + } + const conversations = useConversationStore(); + const navigation = useNavigationStore(); + const conversation = imClient.createSingleConversation(contact.uid, contact); + conversations.upsertConversation(conversation); + conversations.setActiveConversation(conversation.id); + navigation.showMessages(); + } + } +}); diff --git a/src/stores/conversations.js b/src/stores/conversations.js new file mode 100644 index 0000000..32e8919 --- /dev/null +++ b/src/stores/conversations.js @@ -0,0 +1,1216 @@ +import { defineStore } from 'pinia'; +import { imClient } from '@/services/imClient'; +import { appConfig } from '@/config'; +import { useSessionStore } from '@/stores/session'; + +const LOCAL_CONVERSATION_STORAGE_KEY = 'qmt-web-im-local-conversations-v2'; +const LOCAL_FAVORITE_MESSAGES_KEY = 'qmt-web-im-favorite-messages-v1'; + +function scopedStorageKey(baseKey) { + const session = useSessionStore(); + const scope = `${appConfig.appServer || ''}:${session.userId || 'anonymous'}`; + return `${baseKey}:${encodeURIComponent(scope)}`; +} + +function readFavoriteMessages() { + try { + return JSON.parse(localStorage.getItem(scopedStorageKey(LOCAL_FAVORITE_MESSAGES_KEY)) || '[]'); + } catch (error) { + return []; + } +} + +function writeFavoriteMessages(messages) { + localStorage.setItem(scopedStorageKey(LOCAL_FAVORITE_MESSAGES_KEY), JSON.stringify(messages)); +} + +function readLocalConversations() { + try { + return JSON.parse(localStorage.getItem(scopedStorageKey(LOCAL_CONVERSATION_STORAGE_KEY)) || '[]'); + } catch (error) { + return []; + } +} + +function writeLocalConversations(conversations) { + localStorage.setItem(scopedStorageKey(LOCAL_CONVERSATION_STORAGE_KEY), JSON.stringify(conversations)); +} + +function randomId() { + if (window.crypto && window.crypto.randomUUID) { + return window.crypto.randomUUID().replaceAll('-', ''); + } + return `${Date.now()}${Math.random().toString(16).slice(2)}`; +} + +function messageKey(message) { + return message.id || message.messageUid; +} + +function messageStableKey(message) { + return String(message?.messageUid || message?.id || ''); +} + +function messageActivityTimestamp(message) { + return Number(message?.activityTimestamp || message?.editedAt || message?.displayTimestamp || message?.timestamp || 0); +} + +function isRecalledMessage(message) { + return Boolean(message?.recalled) || message?.status === 'recalled'; +} + +function attachmentLabel(message) { + const attachment = message?.attachment; + if (!attachment) { + return ''; + } + if (attachment.type === 'image') { + return '[图片]'; + } + return `[文件] ${attachment.name || '文件'}`; +} + +function messagePreviewText(message) { + if (isRecalledMessage(message)) { + return `[${message?.recallStatus || '已撤回'}]`; + } + const text = String(message?.text || '').replace(/\s+/g, ' ').trim(); + return text || attachmentLabel(message); +} + +function quotePrefix(message) { + const text = messagePreviewText(message); + return text.length > 48 ? `${text.slice(0, 48)}...` : text; +} + +async function writeClipboard(text) { + if (navigator.clipboard?.writeText) { + await navigator.clipboard.writeText(text); + return; + } + const element = document.createElement('textarea'); + element.value = text; + element.setAttribute('readonly', 'readonly'); + element.style.position = 'fixed'; + element.style.left = '-9999px'; + document.body.appendChild(element); + element.select(); + document.execCommand('copy'); + document.body.removeChild(element); +} + +function isSameMessage(left, right) { + if (left.messageUid && right.messageUid && left.messageUid === right.messageUid) { + return true; + } + if (left.id && right.id && left.id === right.id) { + return true; + } + return left.direction === right.direction + && left.text === right.text + && (left.type || 'text') === (right.type || 'text') + && Math.abs(Number(left.displayTimestamp || left.timestamp || 0) - Number(right.displayTimestamp || right.timestamp || 0)) < 15000; +} + +function hasExactMessage(messages, message) { + return messages.some(item => { + if (item.id && message.id && item.id === message.id) { + return true; + } + return item.messageUid && message.messageUid && item.messageUid === message.messageUid; + }); +} + +function shouldUseMessagePolling() { + return imClient.shouldUseMessagePolling ? imClient.shouldUseMessagePolling() : true; +} + +function canMarkReadNow(options = {}) { + if (typeof document === 'undefined') { + return false; + } + if (document.visibilityState !== 'visible') { + return false; + } + if (options.userAction) { + return true; + } + return true; +} + +function mergeVisibleMessages(currentMessages, syncedMessages) { + const merged = [...syncedMessages]; + currentMessages.forEach(currentMessage => { + const exists = merged.some(message => isSameMessage(message, currentMessage)); + const shouldKeepLocal = currentMessage.status === 'sending' + || currentMessage.status === 'failed' + || (currentMessage.direction === 'out' + && currentMessage.status === 'sent' + && Date.now() - Number(currentMessage.timestamp || 0) < 30000); + if (!exists && shouldKeepLocal) { + merged.push(currentMessage); + } + }); + + return merged + .filter((message, index, messages) => { + const key = messageKey(message); + return messages.findIndex(item => messageKey(item) === key) === index; + }) + .sort((a, b) => Number(a.displayTimestamp || a.timestamp || 0) - Number(b.displayTimestamp || b.timestamp || 0)); +} + +function incomingEditedMessages(previousMessages, nextMessages) { + const previousByKey = new Map(); + (previousMessages || []).forEach(message => { + const key = messageStableKey(message); + if (key) { + previousByKey.set(key, message); + } + }); + + return (nextMessages || []).filter(message => { + if (message.direction !== 'in') { + return false; + } + const editedAt = Number(message.editedAt || 0); + if (editedAt <= 0) { + return false; + } + const previous = previousByKey.get(messageStableKey(message)); + return previous && editedAt > Number(previous.editedAt || 0); + }); +} + +let notificationAudioContext = null; + +function playNotificationSound() { + if (typeof window === 'undefined') { + return; + } + try { + const AudioContext = window.AudioContext || window.webkitAudioContext; + if (!AudioContext) { + return; + } + notificationAudioContext = notificationAudioContext || new AudioContext(); + if (notificationAudioContext.state === 'suspended') { + notificationAudioContext.resume().catch(() => {}); + } + const oscillator = notificationAudioContext.createOscillator(); + const gain = notificationAudioContext.createGain(); + const startAt = notificationAudioContext.currentTime; + oscillator.type = 'sine'; + oscillator.frequency.setValueAtTime(880, startAt); + oscillator.frequency.setValueAtTime(660, startAt + 0.1); + gain.gain.setValueAtTime(0.0001, startAt); + gain.gain.exponentialRampToValueAtTime(0.12, startAt + 0.02); + gain.gain.exponentialRampToValueAtTime(0.0001, startAt + 0.22); + oscillator.connect(gain); + gain.connect(notificationAudioContext.destination); + oscillator.start(startAt); + oscillator.stop(startAt + 0.24); + } catch (error) { + // Notification sound is best-effort; browsers may block audio until user interaction. + } +} + +export const useConversationStore = defineStore('conversations', { + state: () => ({ + activeId: '', + conversations: [], + messagesByConversation: {}, + visibleMessagesByConversation: {}, + eventsBound: false, + usingDemoData: false, + loading: false, + syncTimer: null, + conversationSyncTimer: null, + readPresenceEventsBound: false, + syncInFlight: false, + pendingReadReceiptConversationId: '', + conversationSyncInFlight: false, + syncAfterSendTimer: null, + optimisticMessagesByConversation: {}, + quotedMessage: null, + forwardingMessages: [], + editingMessage: null, + editingText: '', + editingMode: '', + messageDetailOpen: false, + messageDetailLoading: false, + messageDetailError: '', + messageDetail: null, + attentionMessageId: '', + attentionMessageTimer: null, + selectionMode: false, + selectedMessageIds: [], + favoriteMessages: [], + activeFavoriteKey: '', + actionNotice: '', + actionError: '' + }), + getters: { + activeConversation(state) { + return state.conversations.find(item => item.id === state.activeId) || state.conversations[0] || null; + }, + activeMessages(state) { + return state.visibleMessagesByConversation[state.activeId] || []; + }, + totalUnread(state) { + return state.conversations.reduce((sum, item) => sum + Number(item.unread || 0), 0); + }, + canSendActiveConversation(state) { + const conversation = state.conversations.find(item => item.id === state.activeId) || state.conversations[0] || null; + if (!conversation) { + return false; + } + if (conversation.type !== 'channel') { + return true; + } + return ['owner', 'admin'].includes(conversation.role || conversation.raw?.role || ''); + }, + favoriteMessageIds(state) { + return state.favoriteMessages.map(message => message.key); + }, + activeFavorite(state) { + return state.favoriteMessages.find(message => message.key === state.activeFavoriteKey) + || state.favoriteMessages[0] + || null; + }, + selectedMessages(state) { + const selectedIds = new Set(state.selectedMessageIds); + return (state.visibleMessagesByConversation[state.activeId] || []) + .filter(message => selectedIds.has(messageStableKey(message))); + } + }, + actions: { + bootstrapDemoData() { + const session = useSessionStore(); + this.bindImEvents(); + this.usingDemoData = false; + if (!session.userId) { + this.clearUserState(); + return; + } + this.loadScopedLocalState(); + this.startMessageSync(); + }, + loadScopedLocalState() { + this.conversations = []; + this.favoriteMessages = readFavoriteMessages(); + this.activeFavoriteKey = this.favoriteMessages[0]?.key || ''; + this.activeId = ''; + this.messagesByConversation = {}; + this.visibleMessagesByConversation = {}; + this.optimisticMessagesByConversation = {}; + this.quotedMessage = null; + this.forwardingMessages = []; + this.editingMessage = null; + this.editingText = ''; + this.editingMode = ''; + this.messageDetailOpen = false; + this.messageDetailLoading = false; + this.messageDetailError = ''; + this.messageDetail = null; + this.selectionMode = false; + this.selectedMessageIds = []; + }, + clearUserState() { + window.clearInterval(this.syncTimer); + window.clearInterval(this.conversationSyncTimer); + window.clearTimeout(this.syncAfterSendTimer); + window.clearTimeout(this.attentionMessageTimer); + this.syncTimer = null; + this.conversationSyncTimer = null; + this.syncAfterSendTimer = null; + this.attentionMessageTimer = null; + this.syncInFlight = false; + this.conversationSyncInFlight = false; + this.pendingReadReceiptConversationId = ''; + this.activeId = ''; + this.conversations = []; + this.messagesByConversation = {}; + this.visibleMessagesByConversation = {}; + this.optimisticMessagesByConversation = {}; + this.quotedMessage = null; + this.forwardingMessages = []; + this.editingMessage = null; + this.editingText = ''; + this.editingMode = ''; + this.messageDetailOpen = false; + this.messageDetailLoading = false; + this.messageDetailError = ''; + this.messageDetail = null; + this.attentionMessageId = ''; + this.selectionMode = false; + this.selectedMessageIds = []; + this.favoriteMessages = []; + this.activeFavoriteKey = ''; + this.actionNotice = ''; + this.actionError = ''; + }, + bindImEvents() { + if (this.eventsBound) { + return; + } + this.eventsBound = true; + imClient.on('messageSent', message => { + this.appendMessage(message.conversationId, message); + }); + imClient.on('messageReceived', message => { + this.appendMessage(message.conversationId, message); + if (message.conversationId === this.activeId) { + this.syncActiveMessages({ allowReadReceipt: true }); + } + }); + imClient.on('messageStatusChanged', message => { + this.replaceMessage(message.conversationId, message); + }); + imClient.on('conversationsChanged', remoteConversations => { + this.usingDemoData = false; + this.applyRemoteConversations(remoteConversations); + }); + }, + setActiveConversation(id) { + this.activeId = id; + const conversation = this.conversations.find(item => item.id === id); + if (conversation) { + conversation.unread = 0; + } + this.loadActiveMessages({ allowReadReceipt: true, userAction: true }); + }, + sendText(text) { + const conversation = this.activeConversation; + if (!conversation || !text.trim()) { + return; + } + let value = text.trim(); + if (this.quotedMessage) { + value = `引用:${quotePrefix(this.quotedMessage)}\n${value}`; + this.quotedMessage = null; + } + const message = { + id: randomId(), + conversationId: conversation.id, + from: 'me', + direction: 'out', + type: 'text', + text: value, + status: 'sending', + deliveryStatus: 'sending', + timestamp: Date.now(), + displayTimestamp: Date.now() + }; + this.appendVisibleMessage(conversation.id, message); + this.appendMessage(conversation.id, message); + imClient.sendTextMessage(conversation, value, message); + conversation.subtitle = value; + conversation.updatedAt = Date.now(); + writeLocalConversations(this.conversations); + window.clearTimeout(this.syncAfterSendTimer); + this.syncAfterSendTimer = window.setTimeout(() => this.syncActiveMessages(), 250); + }, + sendAttachment({ type, file, text = '' }) { + const conversation = this.activeConversation; + if (!conversation || !file || !['image', 'file'].includes(type)) { + return; + } + let value = text.trim(); + if (this.quotedMessage) { + value = `引用:${quotePrefix(this.quotedMessage)}\n${value}`.trim(); + this.quotedMessage = null; + } + const now = Date.now(); + const message = { + id: randomId(), + conversationId: conversation.id, + from: 'me', + senderRole: conversation.role || conversation.raw?.role || '', + direction: 'out', + type, + text: value, + attachment: { + type, + name: file.name || (type === 'image' ? '图片' : '文件'), + mime: file.type || '', + size: file.size || 0, + url: type === 'image' ? URL.createObjectURL(file) : '' + }, + status: 'sending', + deliveryStatus: 'sending', + timestamp: now, + displayTimestamp: now + }; + this.appendVisibleMessage(conversation.id, message); + this.appendMessage(conversation.id, message); + imClient.sendAttachmentMessage(conversation, { type, file, text: value }, message); + conversation.subtitle = messagePreviewText(message); + conversation.updatedAt = now; + writeLocalConversations(this.conversations); + window.clearTimeout(this.syncAfterSendTimer); + this.syncAfterSendTimer = window.setTimeout(() => this.syncActiveMessages(), 350); + }, + async sendTextToConversation(conversation, text) { + if (!conversation || !text.trim()) { + return null; + } + const value = text.trim(); + const message = { + id: randomId(), + conversationId: conversation.id, + from: 'me', + direction: 'out', + type: 'text', + text: value, + status: 'sending', + deliveryStatus: 'sending', + timestamp: Date.now(), + displayTimestamp: Date.now() + }; + this.appendMessage(conversation.id, message); + const sentMessage = await imClient.sendTextMessage(conversation, value, message); + this.replaceMessage(conversation.id, sentMessage); + return sentMessage; + }, + upsertConversation(conversation) { + const index = this.conversations.findIndex(item => item.id === conversation.id); + if (index >= 0) { + this.conversations.splice(index, 1, { + ...this.conversations[index], + ...conversation + }); + } else { + this.conversations.unshift(conversation); + } + this.usingDemoData = false; + writeLocalConversations(this.conversations); + }, + removeConversation(conversationId) { + this.conversations = this.conversations.filter(conversation => conversation.id !== conversationId); + const { + [conversationId]: removedMessages, + ...messagesByConversation + } = this.messagesByConversation; + const { + [conversationId]: removedVisibleMessages, + ...visibleMessagesByConversation + } = this.visibleMessagesByConversation; + const { + [conversationId]: removedOptimisticMessages, + ...optimisticMessagesByConversation + } = this.optimisticMessagesByConversation; + void removedMessages; + void removedVisibleMessages; + void removedOptimisticMessages; + this.messagesByConversation = messagesByConversation; + this.visibleMessagesByConversation = visibleMessagesByConversation; + this.optimisticMessagesByConversation = optimisticMessagesByConversation; + if (this.activeId === conversationId) { + this.activeId = this.conversations[0]?.id || ''; + } + writeLocalConversations(this.conversations); + if (this.activeId) { + this.loadActiveMessages(); + } + }, + applyRemoteConversations(remoteConversations) { + const remote = Array.isArray(remoteConversations) ? remoteConversations : []; + if (!remote.length && this.conversations.length) { + return; + } + + const merged = new Map(); + this.conversations.forEach(conversation => { + merged.set(conversation.id, conversation); + }); + remote.forEach(conversation => { + const unread = conversation.id === this.activeId && canMarkReadNow() ? 0 : Number(conversation.unread || 0); + merged.set(conversation.id, { + ...(merged.get(conversation.id) || {}), + ...conversation, + unread + }); + }); + + this.conversations = Array.from(merged.values()) + .sort((a, b) => Number(b.updatedAt || 0) - Number(a.updatedAt || 0)) + .slice(0, 100); + + if (!this.conversations.length) { + this.activeId = ''; + this.messagesByConversation = {}; + this.visibleMessagesByConversation = {}; + this.optimisticMessagesByConversation = {}; + writeLocalConversations(this.conversations); + return; + } + + if (!this.conversations.find(item => item.id === this.activeId)) { + this.activeId = this.conversations[0].id; + } + writeLocalConversations(this.conversations); + this.loadActiveMessages(); + }, + appendMessage(conversationId, message) { + if (!this.messagesByConversation[conversationId]) { + this.messagesByConversation = { + ...this.messagesByConversation, + [conversationId]: [] + }; + } + if (message.direction === 'out' && (message.status === 'sending' || message.status === 'sent')) { + this.keepOptimisticMessage(conversationId, message); + } + if (!hasExactMessage(this.messagesByConversation[conversationId], message)) { + this.messagesByConversation = { + ...this.messagesByConversation, + [conversationId]: [...this.messagesByConversation[conversationId], message] + }; + } + this.updateConversationFromMessage(conversationId, message); + this.syncVisibleMessages(conversationId); + writeLocalConversations(this.conversations); + }, + removeMessages(conversationId, messages) { + const ids = new Set(messages.flatMap(message => [message.id, message.messageUid].filter(Boolean).map(String))); + const filterMessages = list => (list || []).filter(message => { + return ![message.id, message.messageUid].filter(Boolean).some(id => ids.has(String(id))); + }); + this.messagesByConversation = { + ...this.messagesByConversation, + [conversationId]: filterMessages(this.messagesByConversation[conversationId]) + }; + this.visibleMessagesByConversation = { + ...this.visibleMessagesByConversation, + [conversationId]: filterMessages(this.visibleMessagesByConversation[conversationId]) + }; + this.optimisticMessagesByConversation = { + ...this.optimisticMessagesByConversation, + [conversationId]: filterMessages(this.optimisticMessagesByConversation[conversationId]) + }; + this.selectedMessageIds = this.selectedMessageIds.filter(id => !ids.has(String(id))); + }, + replaceLocalMessage(conversationId, targetMessage, nextMessage) { + const keys = new Set([targetMessage.id, targetMessage.messageUid].filter(Boolean).map(String)); + const replaceInList = list => (list || []).map(message => { + const matched = [message.id, message.messageUid].filter(Boolean).some(id => keys.has(String(id))); + return matched ? { ...message, ...nextMessage } : message; + }); + this.messagesByConversation = { + ...this.messagesByConversation, + [conversationId]: replaceInList(this.messagesByConversation[conversationId]) + }; + this.visibleMessagesByConversation = { + ...this.visibleMessagesByConversation, + [conversationId]: replaceInList(this.visibleMessagesByConversation[conversationId]) + }; + }, + updateConversationFromMessage(conversationId, message) { + const conversation = this.conversations.find(item => item.id === conversationId); + if (!conversation) { + return; + } + + conversation.subtitle = message.text || conversation.subtitle || ''; + conversation.updatedAt = messageActivityTimestamp(message) || Date.now(); + if (message.direction === 'in') { + conversation.unread = conversationId === this.activeId ? 0 : Number(conversation.unread || 0) + 1; + } + this.conversations = [...this.conversations] + .sort((a, b) => Number(b.updatedAt || 0) - Number(a.updatedAt || 0)); + }, + appendVisibleMessage(conversationId, message) { + const messages = this.visibleMessagesByConversation[conversationId] || []; + this.visibleMessagesByConversation = { + ...this.visibleMessagesByConversation, + [conversationId]: [...messages.filter(item => item.id !== message.id), message] + .sort((a, b) => Number(a.displayTimestamp || a.timestamp || 0) - Number(b.displayTimestamp || b.timestamp || 0)) + }; + }, + replaceMessage(conversationId, message) { + if (!this.messagesByConversation[conversationId]) { + this.messagesByConversation = { + ...this.messagesByConversation, + [conversationId]: [] + }; + } + if (message.direction === 'out' && (message.status === 'sending' || message.status === 'sent' || message.status === 'failed')) { + this.keepOptimisticMessage(conversationId, message); + } + const index = this.messagesByConversation[conversationId].findIndex(item => item.id === message.id); + if (index >= 0) { + const messages = [...this.messagesByConversation[conversationId]]; + messages.splice(index, 1, message); + this.messagesByConversation = { + ...this.messagesByConversation, + [conversationId]: messages + }; + } else { + this.messagesByConversation = { + ...this.messagesByConversation, + [conversationId]: [...this.messagesByConversation[conversationId], message] + }; + } + this.syncVisibleMessages(conversationId); + }, + syncVisibleMessages(conversationId) { + this.visibleMessagesByConversation = { + ...this.visibleMessagesByConversation, + [conversationId]: mergeVisibleMessages( + this.optimisticMessagesByConversation[conversationId] || [], + this.messagesByConversation[conversationId] || [] + ) + }; + }, + keepOptimisticMessage(conversationId, message) { + if (!this.optimisticMessagesByConversation[conversationId]) { + this.optimisticMessagesByConversation = { + ...this.optimisticMessagesByConversation, + [conversationId]: [] + }; + } + const messages = this.optimisticMessagesByConversation[conversationId]; + const index = messages.findIndex(item => item.id === message.id); + let nextMessages; + if (index >= 0) { + nextMessages = [...messages]; + nextMessages.splice(index, 1, message); + } else { + nextMessages = [...messages, message]; + } + this.optimisticMessagesByConversation = { + ...this.optimisticMessagesByConversation, + [conversationId]: nextMessages + }; + }, + pruneOptimisticMessages(conversationId, syncedMessages) { + const messages = this.optimisticMessagesByConversation[conversationId] || []; + if (!messages.length) { + return; + } + this.optimisticMessagesByConversation = { + ...this.optimisticMessagesByConversation, + [conversationId]: messages.filter(message => { + const remoteMatched = syncedMessages.some(syncedMessage => { + return syncedMessage.id !== message.id && isSameMessage(syncedMessage, message); + }); + if (remoteMatched && message.status !== 'failed') { + return false; + } + return Date.now() - Number(message.displayTimestamp || message.timestamp || 0) < 30000 || message.status === 'failed'; + }) + }; + }, + loadActiveMessages(options = {}) { + const syncOptions = typeof options === 'boolean' + ? { allowReadReceipt: options } + : options; + const conversation = this.activeConversation; + if (!conversation) { + return; + } + this.loading = true; + const messages = imClient.getMessages(conversation, 30); + this.pruneOptimisticMessages(conversation.id, messages); + this.messagesByConversation = { + ...this.messagesByConversation, + [conversation.id]: mergeVisibleMessages(this.messagesByConversation[conversation.id] || [], messages) + }; + this.syncVisibleMessages(conversation.id); + this.loading = false; + this.syncActiveMessages(syncOptions); + }, + async syncActiveMessages(options = {}) { + const conversation = this.activeConversation; + if (!conversation) { + return; + } + const wantsReadReceipt = Boolean(options.allowReadReceipt); + const explicitReadReceipt = wantsReadReceipt && canMarkReadNow({ userAction: Boolean(options.userAction) }); + const pollingReadReceipt = canMarkReadNow(); + const markRead = explicitReadReceipt || pollingReadReceipt; + + if (this.syncInFlight) { + if (wantsReadReceipt) { + this.pendingReadReceiptConversationId = conversation.id; + } + return; + } + this.syncInFlight = true; + const syncedConversationId = conversation.id; + const previousMessages = this.messagesByConversation[syncedConversationId] || []; + try { + const messages = await imClient.fetchRemoteMessages(conversation, 50, { + markRead + }); + const editedIncomingMessages = incomingEditedMessages(previousMessages, messages); + this.pruneOptimisticMessages(syncedConversationId, messages); + this.messagesByConversation = { + ...this.messagesByConversation, + [syncedConversationId]: mergeVisibleMessages(this.messagesByConversation[syncedConversationId] || [], messages) + }; + this.syncVisibleMessages(syncedConversationId); + if (editedIncomingMessages.length && syncedConversationId === this.activeId) { + this.focusMessage(editedIncomingMessages.sort((a, b) => messageActivityTimestamp(b) - messageActivityTimestamp(a))[0]); + playNotificationSound(); + } + const latest = messages.reduce((latestMessage, message) => { + if (!latestMessage || messageActivityTimestamp(message) > messageActivityTimestamp(latestMessage)) { + return message; + } + return latestMessage; + }, null); + if (latest) { + conversation.subtitle = messagePreviewText(latest); + conversation.updatedAt = messageActivityTimestamp(latest); + writeLocalConversations(this.conversations); + } + } catch (error) { + // Keep the local view usable if a polling request misses. + } finally { + this.syncInFlight = false; + if (this.pendingReadReceiptConversationId === this.activeId && canMarkReadNow()) { + this.pendingReadReceiptConversationId = ''; + window.setTimeout(() => this.syncActiveMessages({ allowReadReceipt: true }), 0); + } + } + }, + startMessageSync() { + this.bindReadPresenceEvents(); + if (!this.syncTimer) { + this.syncTimer = window.setInterval(() => { + this.syncActiveMessages(); + }, Math.max(250, appConfig.syncIntervalMs)); + } + if (!this.conversationSyncTimer) { + this.conversationSyncTimer = window.setInterval(() => { + this.refreshRemoteConversations(); + }, 2000); + this.refreshRemoteConversations(); + } + }, + bindReadPresenceEvents() { + if (this.readPresenceEventsBound || typeof window === 'undefined' || typeof document === 'undefined') { + return; + } + this.readPresenceEventsBound = true; + const syncWhenReadable = () => { + if (canMarkReadNow()) { + this.syncActiveMessages({ allowReadReceipt: true }); + } + }; + window.addEventListener('focus', syncWhenReadable); + document.addEventListener('visibilitychange', syncWhenReadable); + }, + async refreshRemoteConversations() { + this.bindImEvents(); + this.usingDemoData = false; + if (this.conversationSyncInFlight) { + return; + } + this.conversationSyncInFlight = true; + try { + const remoteConversations = await imClient.fetchRemoteConversations(50); + this.applyRemoteConversations(remoteConversations); + } catch (error) { + imClient.refreshConversationList(); + } finally { + this.conversationSyncInFlight = false; + } + }, + setActionNotice(message) { + this.actionNotice = message; + this.actionError = ''; + }, + setActionError(message) { + this.actionError = message; + this.actionNotice = ''; + }, + focusMessage(message) { + const key = messageStableKey(message); + if (!key) { + return; + } + this.attentionMessageId = key; + window.clearTimeout(this.attentionMessageTimer); + this.attentionMessageTimer = window.setTimeout(() => { + if (this.attentionMessageId === key) { + this.attentionMessageId = ''; + } + }, 2800); + }, + async handleMessageAction({ action, message }) { + if (!message) { + return; + } + if (action === 'copy') { + await this.copyMessages([message]); + } else if (action === 'edit') { + this.startEditMessage(message); + } else if (action === 'delete') { + this.deleteMessages([message]); + } else if (action === 'forward') { + this.startForward([message]); + } else if (action === 'favorite') { + this.toggleFavorite(message); + } else if (action === 'detail') { + await this.openMessageDetail(message); + } else if (action === 'quote') { + this.quoteMessage(message); + } else if (action === 'select') { + this.enterSelectionMode(message); + } else if (action === 'recall') { + await this.recallMessage(message); + } + }, + async openMessageDetail(message) { + const conversation = this.activeConversation; + if (!conversation || !message) { + return; + } + const key = messageStableKey(message); + this.messageDetailOpen = true; + this.messageDetailLoading = true; + this.messageDetailError = ''; + this.messageDetail = { + messageUid: key, + conversationType: conversation.type || conversation.raw?.type || 'single', + sentAt: Number(message.displayTimestamp || message.timestamp || 0), + editedAt: Number(message.editedAt || 0), + recalled: isRecalledMessage(message), + localOnly: true, + sender: { + uid: message.from || '', + name: message.senderName || message.from || '' + } + }; + try { + if (!/^\d+$/.test(key)) { + this.messageDetailError = '本地临时消息暂无送达/已读详情'; + return; + } + const detail = await imClient.getMessageDetail(conversation, message); + this.messageDetail = detail || this.messageDetail; + } catch (error) { + this.messageDetailError = error.message || '消息详情加载失败'; + } finally { + this.messageDetailLoading = false; + } + }, + closeMessageDetail() { + this.messageDetailOpen = false; + this.messageDetailLoading = false; + this.messageDetailError = ''; + this.messageDetail = null; + }, + async copyMessages(messages) { + const text = messages.map(message => message.text || '').join('\n'); + if (!text.trim()) { + return; + } + try { + await writeClipboard(text); + this.setActionNotice(messages.length > 1 ? '已复制所选消息' : '已复制'); + } catch (error) { + this.setActionError('复制失败'); + } + }, + deleteMessages(messages) { + const conversation = this.activeConversation; + if (!conversation || !messages.length) { + return; + } + imClient.hideMessages(conversation, messages); + this.removeMessages(conversation.id, messages); + if (!this.selectedMessageIds.length) { + this.selectionMode = false; + } + this.setActionNotice(messages.length > 1 ? '已删除所选消息' : '已删除'); + }, + toggleFavorite(message) { + const key = messageStableKey(message); + if (!key) { + return; + } + const index = this.favoriteMessages.findIndex(item => item.key === key); + if (index >= 0) { + this.favoriteMessages.splice(index, 1); + if (this.activeFavoriteKey === key) { + this.activeFavoriteKey = this.favoriteMessages[0]?.key || ''; + } + this.setActionNotice('已取消收藏'); + } else { + const conversation = this.conversations.find(item => item.id === message.conversationId) || {}; + this.favoriteMessages.unshift({ + key, + id: message.id, + messageUid: message.messageUid, + conversationId: message.conversationId, + conversationTitle: conversation.title || message.conversationTitle || '', + type: message.type || 'text', + text: message.text || '', + preview: messagePreviewText(message), + senderName: message.senderName || message.from || '', + timestamp: Number(message.displayTimestamp || message.timestamp || Date.now()), + editedAt: Number(message.editedAt || 0), + recalled: isRecalledMessage(message), + recallStatus: message.recallStatus || (isRecalledMessage(message) ? '已撤回' : ''), + attachment: message.attachment ? { ...message.attachment } : null + }); + this.activeFavoriteKey = key; + this.setActionNotice('已收藏'); + } + this.favoriteMessages = this.favoriteMessages.slice(0, 200); + writeFavoriteMessages(this.favoriteMessages); + }, + setActiveFavorite(key) { + this.activeFavoriteKey = String(key || ''); + }, + removeFavorite(key) { + const value = String(key || ''); + if (!value) { + return; + } + this.favoriteMessages = this.favoriteMessages.filter(message => message.key !== value); + if (this.activeFavoriteKey === value) { + this.activeFavoriteKey = this.favoriteMessages[0]?.key || ''; + } + writeFavoriteMessages(this.favoriteMessages); + }, + quoteMessage(message) { + this.quotedMessage = { + ...message, + quoteText: quotePrefix(message) + }; + this.setActionNotice('已引用,输入后发送'); + }, + cancelQuote() { + this.quotedMessage = null; + }, + enterSelectionMode(message = null) { + this.selectionMode = true; + if (message) { + const key = messageStableKey(message); + this.selectedMessageIds = key ? [key] : []; + } + }, + toggleSelectedMessage(message) { + const key = messageStableKey(message); + if (!key) { + return; + } + const selected = new Set(this.selectedMessageIds); + if (selected.has(key)) { + selected.delete(key); + } else { + selected.add(key); + } + this.selectedMessageIds = Array.from(selected); + this.selectionMode = this.selectedMessageIds.length > 0; + }, + clearSelection() { + this.selectionMode = false; + this.selectedMessageIds = []; + }, + copySelectedMessages() { + return this.copyMessages(this.selectedMessages); + }, + deleteSelectedMessages() { + this.deleteMessages(this.selectedMessages); + }, + startForward(messages) { + this.forwardingMessages = messages.filter(message => message?.text); + if (!this.forwardingMessages.length) { + this.setActionError('没有可转发的消息'); + } + }, + startForwardSelectedMessages() { + this.startForward(this.selectedMessages); + }, + cancelForward() { + this.forwardingMessages = []; + }, + startEditMessage(message) { + const isResend = isRecalledMessage(message); + if (!isResend && !message?.text) { + this.setActionError('没有可编辑的文字内容'); + return; + } + this.editingMessage = message; + this.editingText = message.text || ''; + this.editingMode = isResend ? 'resend' : 'edit'; + }, + cancelEditMessage() { + this.editingMessage = null; + this.editingText = ''; + this.editingMode = ''; + }, + async completeEditMessage() { + const conversation = this.activeConversation; + const message = this.editingMessage; + const text = this.editingText.trim(); + const isResend = this.editingMode === 'resend' || isRecalledMessage(message); + if (!conversation || !message) { + this.cancelEditMessage(); + return; + } + if (!text) { + this.setActionError('编辑内容不能为空'); + return; + } + if (!isResend && text === String(message.text || '').trim()) { + this.cancelEditMessage(); + return; + } + try { + if (isResend) { + await this.sendTextToConversation(conversation, text); + this.cancelEditMessage(); + this.setActionNotice('已重新发送'); + return; + } + const editedMessage = await imClient.editMessage(conversation, message, text); + this.replaceLocalMessage(conversation.id, message, editedMessage); + if (messageActivityTimestamp(editedMessage) >= Number(conversation.updatedAt || 0)) { + conversation.subtitle = editedMessage.text; + conversation.updatedAt = messageActivityTimestamp(editedMessage); + writeLocalConversations(this.conversations); + } + this.cancelEditMessage(); + this.setActionNotice('已编辑'); + } catch (error) { + this.setActionError(error.message || '编辑失败'); + } + }, + async completeForward(targetConversationId) { + const target = this.conversations.find(conversation => conversation.id === targetConversationId); + if (!target || !this.forwardingMessages.length) { + return; + } + const text = this.forwardingMessages + .map(message => `转发:${message.text || ''}`) + .join('\n\n'); + try { + await this.sendTextToConversation(target, text); + this.forwardingMessages = []; + this.clearSelection(); + this.setActionNotice('已转发'); + } catch (error) { + this.setActionError(error.message || '转发失败'); + } + }, + async recallMessage(message) { + const conversation = this.activeConversation; + if (!conversation) { + return; + } + try { + await imClient.recallMessage(conversation, message); + if (message.direction !== 'out') { + this.removeMessages(conversation.id, [message]); + this.setActionNotice('已撤回'); + this.syncActiveMessages(); + return; + } + this.replaceLocalMessage(conversation.id, message, { + status: 'recalled', + deliveryStatus: '', + recalled: true, + recallStatus: '已撤回' + }); + this.setActionNotice('已撤回'); + } catch (error) { + this.setActionError(error.message || '撤回失败'); + } + }, + async createGroup(options = {}) { + const session = useSessionStore(); + if (!session.userId) { + this.setActionError('请先登录'); + return false; + } + try { + const conversation = await imClient.createGroup(session.userId, options); + this.upsertConversation(conversation); + this.setActiveConversation(conversation.id); + this.setActionNotice(options.channel ? '公告群已创建' : '群组已创建'); + this.refreshRemoteConversations(); + return true; + } catch (error) { + this.setActionError(error.message || (options.channel ? '创建公告群失败' : '创建群组失败')); + return false; + } + }, + async joinGroup(groupKey) { + const session = useSessionStore(); + if (!session.userId) { + this.setActionError('请先登录'); + return false; + } + try { + const conversation = await imClient.joinGroup(session.userId, groupKey); + this.upsertConversation(conversation); + this.setActiveConversation(conversation.id); + this.setActionNotice('已加入群组'); + this.refreshRemoteConversations(); + return true; + } catch (error) { + this.setActionError(error.message || '加入群组失败'); + return false; + } + }, + async broadcastMessage(targetIds, text) { + const session = useSessionStore(); + if (!session.userId) { + this.setActionError('请先登录'); + return false; + } + try { + const result = await imClient.broadcastMessage(session.userId, targetIds, text); + const successCount = Number(result.successCount || 0); + const failedCount = Number(result.failedCount || 0); + this.setActionNotice(failedCount > 0 ? `已群发 ${successCount} 条,失败 ${failedCount} 条` : `已群发 ${successCount} 条`); + this.refreshRemoteConversations(); + return true; + } catch (error) { + this.setActionError(error.message || '群发失败'); + return false; + } + }, + async leaveGroup(conversation) { + const session = useSessionStore(); + if (!session.userId || !conversation?.target) { + this.setActionError('缺少群组信息'); + return false; + } + try { + await imClient.leaveGroup(session.userId, conversation.target); + this.removeConversation(conversation.id); + this.setActionNotice('已退出群组'); + this.refreshRemoteConversations(); + return true; + } catch (error) { + this.setActionError(error.message || '退出群组失败'); + return false; + } + }, + async dismissGroup(conversation) { + const session = useSessionStore(); + if (!session.userId || !conversation?.target) { + this.setActionError('缺少群组信息'); + return false; + } + try { + await imClient.dismissGroup(session.userId, conversation.target); + this.removeConversation(conversation.id); + this.setActionNotice('群组已解散'); + this.refreshRemoteConversations(); + return true; + } catch (error) { + this.setActionError(error.message || '解散群组失败'); + return false; + } + } + } +}); diff --git a/src/stores/navigation.js b/src/stores/navigation.js new file mode 100644 index 0000000..fa0daa0 --- /dev/null +++ b/src/stores/navigation.js @@ -0,0 +1,18 @@ +import { defineStore } from 'pinia'; + +export const useNavigationStore = defineStore('navigation', { + state: () => ({ + section: 'messages' + }), + actions: { + showMessages() { + this.section = 'messages'; + }, + showContacts() { + this.section = 'contacts'; + }, + showFavorites() { + this.section = 'favorites'; + } + } +}); diff --git a/src/stores/session.js b/src/stores/session.js new file mode 100644 index 0000000..3bc2a92 --- /dev/null +++ b/src/stores/session.js @@ -0,0 +1,225 @@ +import { defineStore } from 'pinia'; +import { imClient } from '@/services/imClient'; +import { appConfig } from '@/config'; + +const STORAGE_KEY = 'qmt-web-im-session'; + +function normalizeStoredPortrait(portrait) { + return portrait || ''; +} + +function nextProfilePortrait(profilePortrait, currentPortrait) { + return normalizeStoredPortrait(profilePortrait) || normalizeStoredPortrait(currentPortrait); +} + +function inferAccountType(account) { + return String(account || '').includes('@') ? 2 : 1; +} + +export const useSessionStore = defineStore('session', { + state: () => ({ + isAuthenticated: false, + connecting: false, + connected: false, + connectionStatusText: '未连接', + userId: '', + token: '', + displayName: '', + portrait: '', + error: '', + sdkVersion: '', + eventsBound: false + }), + actions: { + restore() { + const raw = localStorage.getItem(STORAGE_KEY); + if (!raw) { + return; + } + + try { + const session = JSON.parse(raw); + if (session.appServer !== appConfig.appServer) { + localStorage.removeItem(STORAGE_KEY); + return; + } + + if (session.userId && session.token) { + if (!session.clientId) { + localStorage.removeItem(STORAGE_KEY); + return; + } + this.userId = session.userId; + this.token = session.token; + this.displayName = session.displayName || session.userId; + this.portrait = normalizeStoredPortrait(session.portrait); + this.isAuthenticated = true; + imClient.restoreClientId(session.clientId); + this.connect(); + this.refreshProfile(); + } + } catch (error) { + localStorage.removeItem(STORAGE_KEY); + } + }, + + async loginWithPassword(account, password, type = inferAccountType(account)) { + this.error = ''; + this.connecting = true; + try { + const result = await imClient.loginWithPassword(account, password, type); + this.applyLoginResult(result); + await this.connect(); + } catch (error) { + this.error = error.message || '登录失败'; + } finally { + this.connecting = false; + } + }, + + async loginWithCode(account, code) { + this.error = ''; + this.connecting = true; + try { + const result = await imClient.loginWithCode(account, code); + this.applyLoginResult(result); + await this.connect(); + } catch (error) { + this.error = error.message || '登录失败'; + } finally { + this.connecting = false; + } + }, + + async completePcSessionLogin(result) { + this.error = ''; + this.connecting = true; + try { + this.applyLoginResult(result); + await this.connect(); + } catch (error) { + this.error = error.message || '扫码登录失败'; + } finally { + this.connecting = false; + } + }, + + async register(payload) { + this.error = ''; + this.connecting = true; + try { + const result = await imClient.register(payload); + this.applyLoginResult(result); + await this.connect(); + return result; + } catch (error) { + this.error = error.message || '注册失败'; + return null; + } finally { + this.connecting = false; + } + }, + + applyLoginResult(result) { + this.userId = result.userId || result.uid || result.id || ''; + this.token = result.token || result.imToken || ''; + this.displayName = result.displayName || result.userName || result.name || this.userId; + this.portrait = normalizeStoredPortrait(result.portrait); + this.isAuthenticated = Boolean(this.userId && this.token); + this.persistSession(); + }, + + persistSession() { + localStorage.setItem(STORAGE_KEY, JSON.stringify({ + userId: this.userId, + token: this.token, + displayName: this.displayName, + portrait: this.portrait, + clientId: imClient.getClientId(), + appServer: appConfig.appServer + })); + }, + + applyProfile(profile) { + if (!profile) { + return; + } + this.userId = profile.userId || profile.uid || this.userId; + this.displayName = profile.displayName || profile.name || this.displayName || this.userId; + this.portrait = nextProfilePortrait(profile.portrait, this.portrait); + this.persistSession(); + }, + + async refreshProfile() { + if (!this.userId) { + return null; + } + try { + const profile = await imClient.getProfile(this.userId); + this.applyProfile(profile); + return profile; + } catch (error) { + return null; + } + }, + + async saveProfile({ displayName, portraitFile }) { + if (!this.userId) { + throw new Error('请先登录'); + } + const profile = await imClient.updateProfile(this.userId, { + displayName, + portraitFile + }); + this.applyProfile(profile); + return profile; + }, + + async changePassword({ oldPassword, newPassword }) { + if (!this.userId) { + throw new Error('请先登录'); + } + await imClient.changePassword({ oldPassword, newPassword }); + await this.logout(); + return true; + }, + + async resetPasswordWithCode({ mobile, resetCode, newPassword }) { + await imClient.resetPasswordWithCode({ mobile, resetCode, newPassword }); + return true; + }, + + async connect() { + if (!this.userId || !this.token) { + return; + } + await imClient.ensureSdk(); + this.sdkVersion = imClient.getSdkVersion(); + this.bindImEvents(); + await imClient.connect(this.userId, this.token); + }, + + bindImEvents() { + if (this.eventsBound) { + return; + } + this.eventsBound = true; + imClient.on('connectionStatusChanged', status => { + this.connected = status.connected; + this.connectionStatusText = status.statusText || (status.connected ? '已连接' : '未连接'); + }); + }, + + async logout() { + try { + await imClient.logout?.(); + } catch (error) { + this.error = error.message || '退出登录失败'; + } finally { + imClient.disconnect(); + localStorage.removeItem(STORAGE_KEY); + this.$reset(); + } + } + } +}); diff --git a/src/styles/base.css b/src/styles/base.css new file mode 100644 index 0000000..dc70141 --- /dev/null +++ b/src/styles/base.css @@ -0,0 +1,3022 @@ +:root { + color-scheme: light; + --bg: #f4f6f8; + --panel: #ffffff; + --panel-soft: #f8fafc; + --line: #d9e0e7; + --text: #18212f; + --muted: #6a7584; + --primary: #177d72; + --primary-strong: #0f625a; + --accent: #d84e3f; + --bubble-in: #ffffff; + --bubble-out: #dff4ef; + --rail: #202a33; +} + +* { + box-sizing: border-box; +} + +html, +body, +#app { + width: 100%; + height: 100%; + overflow: hidden; +} + +body { + margin: 0; + min-width: 320px; + background: var(--bg); + color: var(--text); + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; +} + +button, +input, +textarea { + font: inherit; +} + +button { + cursor: pointer; +} + +.login-page { + min-height: 100vh; + display: grid; + place-items: center; + padding: 24px; + background: linear-gradient(135deg, #eef6f3 0%, #f7f3ee 55%, #eef2f7 100%); +} + +.login-panel { + width: min(420px, 100%); + padding: 32px; + background: var(--panel); + border: 1px solid var(--line); + border-radius: 8px; + box-shadow: 0 18px 48px rgba(30, 40, 50, 0.12); +} + +.brand-lockup { + display: flex; + align-items: center; + gap: 14px; + margin-bottom: 28px; +} + +.brand-mark, +.rail-avatar, +.conversation-avatar { + display: grid; + place-items: center; + flex: 0 0 auto; +} + +.image-avatar { + object-fit: cover; +} + +.brand-mark { + width: 48px; + height: 48px; + border-radius: 8px; + object-fit: contain; + background: #fff; +} + +.brand-lockup h1, +.list-header h2, +.chat-header h2 { + margin: 0; + font-size: 20px; +} + +.brand-lockup p, +.list-header p, +.chat-header p { + margin: 4px 0 0; + color: var(--muted); + font-size: 13px; +} + +.login-form { + display: grid; + gap: 16px; +} + +.login-tabs, +.code-row, +.phone-row, +.captcha-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 8px; +} + +.login-tabs button, +.code-action { + height: 38px; + border: 1px solid var(--line); + border-radius: 6px; + background: #fff; + color: var(--text); +} + +.login-tabs button.active { + border-color: var(--primary); + background: #e8f4f2; + color: var(--primary-strong); + font-weight: 700; +} + +.login-tabs { + grid-template-columns: repeat(3, minmax(0, 1fr)); +} + +.login-tabs button { + min-width: 0; + padding: 0 6px; + overflow-wrap: anywhere; +} + +.code-row { + grid-template-columns: minmax(0, 1fr) 112px; +} + +.captcha-row { + grid-template-columns: minmax(0, 1fr) 112px; +} + +.phone-row { + grid-template-columns: 86px minmax(0, 1fr); +} + +.country-code-field { + height: 42px; + display: grid; + grid-template-columns: 24px minmax(0, 1fr); + align-items: center; + border: 1px solid var(--line); + border-radius: 6px; + background: #fff; + color: var(--text); + overflow: hidden; +} + +.country-code-field:focus-within { + border-color: var(--primary); + box-shadow: 0 0 0 3px rgba(23, 125, 114, 0.12); +} + +.country-code-field span { + display: grid; + place-items: center; + color: var(--muted); + font-weight: 700; +} + +.code-action:disabled { + cursor: not-allowed; + opacity: 0.55; +} + +.login-form label { + display: grid; + gap: 8px; + color: var(--muted); + font-size: 13px; +} + +.label-row { + min-height: 18px; + display: grid; + grid-template-columns: 86px minmax(0, 1fr); + align-items: center; + gap: 8px; +} + +.field-error-badge { + min-height: 28px; + display: grid; + place-items: center; + padding: 4px 10px; + border-radius: 2px; + background: var(--accent); + color: #fff; + font-weight: 700; + line-height: 1.2; + text-align: center; +} + +.login-form input, +.login-form select, +.modal-panel input, +.modal-panel textarea, +.search-box input, +.message-composer textarea { + width: 100%; + border: 1px solid var(--line); + border-radius: 6px; + outline: none; + background: #fff; + color: var(--text); +} + +.login-form input, +.login-form select, +.modal-panel input, +.search-box input { + height: 42px; + padding: 0 12px; +} + +.modal-panel textarea { + min-height: 92px; + resize: vertical; + padding: 10px 12px; + line-height: 1.5; +} + +.login-form .country-code-field input { + height: 40px; + padding: 0 10px 0 0; + border: 0; + border-radius: 0; +} + +.login-form .country-code-field input:focus { + border-color: transparent; + box-shadow: none; +} + +.login-form input:focus, +.login-form select:focus, +.modal-panel input:focus, +.modal-panel textarea:focus, +.search-box input:focus, +.message-composer textarea:focus { + border-color: var(--primary); + box-shadow: 0 0 0 3px rgba(23, 125, 114, 0.12); +} + +.login-form input.captcha-input-valid { + border-color: var(--primary); + background: var(--primary); + color: #fff; + font-weight: 700; +} + +.login-form input.captcha-input-valid::placeholder { + color: rgba(255, 255, 255, 0.75); +} + +.login-form input.captcha-input-invalid { + border-color: var(--accent); + color: var(--accent); + box-shadow: 0 0 0 3px rgba(216, 78, 63, 0.12); +} + +.login-form input.field-input-error { + border-color: var(--accent); + color: var(--accent); + box-shadow: 0 0 0 3px rgba(216, 78, 63, 0.12); +} + +.login-form input.field-input-error::placeholder { + color: rgba(216, 78, 63, 0.78); +} + +.captcha-button { + width: 112px; + height: 42px; + padding: 0; + border: 1px solid var(--line); + border-radius: 6px; + background: #f7fbfa; + overflow: hidden; +} + +.captcha-button img { + display: block; + width: 100%; + height: 100%; + object-fit: contain; +} + +.qr-login-card { + position: relative; + width: min(248px, 100%); + aspect-ratio: 1; + display: grid; + place-items: center; + justify-self: center; + border: 1px solid var(--line); + border-radius: 8px; + background: #fff; + overflow: hidden; +} + +.qr-code-button { + width: 100%; + height: 100%; + display: grid; + place-items: center; + padding: 18px; + border: 0; + background: #fff; + color: var(--muted); + font-weight: 700; +} + +.qr-code-button:disabled { + cursor: default; +} + +.qr-code-button img { + width: 100%; + height: 100%; + object-fit: contain; + image-rendering: pixelated; +} + +.qr-login-card.scanned .qr-code-button, +.qr-login-card.expired .qr-code-button, +.qr-login-card.error .qr-code-button { + opacity: 0.22; +} + +.qr-scan-user { + position: absolute; + inset: 0; + display: grid; + place-items: center; + background: rgba(255, 255, 255, 0.76); +} + +.qr-scan-user img, +.qr-scan-user span { + width: 70px; + height: 70px; + display: grid; + place-items: center; + border-radius: 8px; + background: var(--primary); + color: #fff; + font-size: 28px; + font-weight: 800; + object-fit: cover; +} + +.qr-login-status { + min-height: 48px; + display: grid; + gap: 4px; + text-align: center; +} + +.qr-login-status strong { + color: var(--text); + font-size: 15px; +} + +.qr-login-status span { + color: var(--muted); + font-size: 13px; +} + +.primary-action, +.primary-inline-action, +.send-button { + border: 0; + border-radius: 6px; + background: var(--primary); + color: #fff; + font-weight: 700; +} + +.primary-action { + height: 44px; +} + +.primary-action:hover, +.primary-inline-action:hover, +.send-button:hover { + background: var(--primary-strong); +} + +.primary-action:disabled, +.primary-inline-action:disabled, +.send-button:disabled { + cursor: not-allowed; + opacity: 0.55; +} + +.ghost-action { + width: 100%; + height: 40px; + margin-top: 12px; + border: 1px solid var(--line); + border-radius: 6px; + background: #fff; + color: var(--text); +} + +.ghost-inline-action, +.primary-inline-action, +.danger-inline-action { + height: 38px; + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0 16px; + border-radius: 6px; + font-weight: 700; + line-height: 1; +} + +.ghost-inline-action { + border: 1px solid var(--line); + background: #fff; + color: var(--text); +} + +.ghost-inline-action:hover { + background: #edf2f5; +} + +.danger-inline-action { + border: 1px solid #ef4444; + background: #fff; + color: #b91c1c; +} + +.danger-inline-action:hover { + background: #fee2e2; +} + +.form-error { + margin: 0; + color: var(--accent); + font-size: 13px; +} + +.form-info { + margin: 0; + color: var(--muted); + font-size: 13px; +} + +.app-shell { + height: 100dvh; + min-height: 0; + display: grid; + grid-template-columns: 64px minmax(260px, 340px) minmax(0, 1fr); + overflow: hidden; + background: var(--panel); +} + +.documented-shell { + min-height: 100dvh; + display: grid; + grid-template-columns: 260px minmax(0, 1fr); + background: + radial-gradient(circle at top left, rgba(23, 125, 114, 0.08), transparent 28%), + linear-gradient(180deg, #f4f8f7 0%, #eef3f7 100%); +} + +.documented-rail { + min-height: 0; + display: grid; + align-content: start; + gap: 14px; + padding: 24px 20px; + border-right: 1px solid var(--line); + background: rgba(255, 255, 255, 0.82); + backdrop-filter: blur(12px); +} + +.documented-avatar { + width: 64px; + height: 64px; + display: grid; + place-items: center; + overflow: hidden; + border-radius: 16px; + background: #dff4ef; + color: var(--primary-strong); + font-size: 28px; + font-weight: 800; +} + +.documented-avatar img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.documented-rail-copy { + display: grid; + gap: 4px; +} + +.documented-rail-copy strong { + font-size: 16px; +} + +.documented-rail-copy small { + color: var(--muted); + overflow-wrap: anywhere; +} + +.documented-rail-button { + min-height: 40px; + padding: 0 14px; + border: 0; + border-radius: 10px; + background: var(--primary); + color: #fff; + font-weight: 700; + text-align: left; +} + +.documented-rail-button.ghost { + border: 1px solid var(--line); + background: #fff; + color: var(--text); +} + +.documented-main { + min-width: 0; + min-height: 0; + overflow: auto; + padding: 28px; + display: grid; + align-content: start; + gap: 18px; +} + +.documented-header { + display: flex; + align-items: end; + justify-content: space-between; + gap: 18px; +} + +.documented-header h1 { + margin: 0; + font-size: 28px; +} + +.documented-header p { + margin: 6px 0 0; + color: var(--muted); +} + +.documented-status { + min-width: 180px; + display: grid; + gap: 4px; + padding: 14px 16px; + border: 1px solid var(--line); + border-radius: 14px; + background: rgba(255, 255, 255, 0.88); +} + +.documented-status span { + color: var(--muted); + font-size: 12px; +} + +.documented-status strong { + font-size: 15px; +} + +.documented-card { + display: grid; + gap: 12px; + padding: 20px; + border: 1px solid var(--line); + border-radius: 16px; + background: rgba(255, 255, 255, 0.88); + box-shadow: 0 16px 36px rgba(24, 33, 47, 0.06); +} + +.documented-card h2 { + margin: 0; + font-size: 18px; +} + +.documented-text { + margin: 0; + color: var(--muted); + line-height: 1.6; +} + +.documented-list { + margin: 0; + padding-left: 18px; + display: grid; + gap: 8px; + line-height: 1.55; +} + +.documented-list.muted { + color: var(--muted); +} + +.documented-meta { + margin: 0; + display: grid; + gap: 10px; +} + +.documented-meta div { + display: grid; + grid-template-columns: 110px minmax(0, 1fr); + gap: 12px; + padding-top: 10px; + border-top: 1px solid var(--line); +} + +.documented-meta dt { + color: var(--muted); +} + +.documented-meta dd { + margin: 0; + overflow-wrap: anywhere; +} + +.documented-password-panel { + width: min(100%, 360px); +} + +.navigation-rail { + min-height: 0; + display: flex; + flex-direction: column; + align-items: center; + gap: 14px; + padding: 16px 10px; + background: var(--rail); +} + +.rail-avatar { + width: 40px; + height: 40px; + border-radius: 8px; + background: #e9f7f4; + color: var(--primary-strong); + font-weight: 800; + overflow: hidden; +} + +.rail-avatar-button { + position: relative; + border: 0; + padding: 0; + cursor: pointer; +} + +.rail-avatar-button::after { + content: "+"; + position: absolute; + right: -2px; + bottom: -2px; + width: 15px; + height: 15px; + display: grid; + place-items: center; + border: 1px solid var(--rail); + border-radius: 50%; + background: var(--primary); + color: #fff; + font-size: 11px; + font-weight: 800; + line-height: 1; +} + +.rail-avatar-button:hover, +.rail-avatar-button:focus-visible { + box-shadow: 0 0 0 3px rgba(47, 196, 178, 0.28); +} + +.rail-avatar img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.rail-button, +.icon-button { + display: grid; + place-items: center; + border: 0; + border-radius: 6px; + background: transparent; +} + +.rail-button { + width: 40px; + height: 40px; + color: #dbe5ea; + font-size: 18px; +} + +.rail-button svg { + width: 22px; + height: 22px; + fill: none; + stroke: currentColor; + stroke-width: 1.8; + stroke-linecap: round; + stroke-linejoin: round; +} + +.rail-button.active, +.rail-button:hover { + background: rgba(255, 255, 255, 0.12); +} + +.rail-logout-button:hover { + background: rgba(239, 68, 68, 0.2); + color: #fecaca; +} + +.rail-spacer { + flex: 1; +} + +.conversation-list { + position: relative; + min-height: 0; + display: grid; + grid-template-rows: 72px auto minmax(0, 1fr); + border-right: 1px solid var(--line); + background: var(--panel-soft); + overflow: hidden; +} + +.modal-backdrop { + position: absolute; + inset: 0; + z-index: 5; + display: grid; + place-items: start center; + padding: 88px 16px 16px; + background: rgba(24, 33, 47, 0.28); +} + +.modal-panel { + width: min(100%, 308px); + display: grid; + gap: 14px; + padding: 16px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--panel); + box-shadow: 0 18px 40px rgba(24, 33, 47, 0.18); +} + +.modal-panel header, +.modal-actions { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; +} + +.modal-panel header strong { + font-size: 16px; +} + +.modal-panel label { + display: grid; + gap: 8px; + color: var(--muted); + font-size: 13px; +} + +.settings-backdrop { + z-index: 24; + place-items: center; + padding: 24px 16px; +} + +.settings-panel { + width: min(620px, calc(100vw - 32px)); + max-height: calc(100dvh - 48px); + display: grid; + gap: 14px; + overflow: auto; + padding: 16px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--panel); + box-shadow: 0 18px 40px rgba(24, 33, 47, 0.18); +} + +.settings-panel header, +.settings-password-form footer { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; +} + +.settings-panel header strong { + font-size: 16px; +} + +.settings-layout { + display: grid; + grid-template-columns: 170px minmax(0, 1fr); + gap: 14px; +} + +.settings-menu { + display: grid; + align-content: start; + gap: 8px; +} + +.settings-menu button { + min-height: 46px; + display: grid; + gap: 2px; + justify-items: start; + padding: 8px 10px; + border: 1px solid var(--line); + border-radius: 6px; + background: #fff; + color: var(--text); + text-align: left; +} + +.settings-menu button.active, +.settings-menu button:hover { + border-color: var(--primary); + background: #e8f4f2; + color: var(--primary-strong); +} + +.settings-menu button span { + font-weight: 700; +} + +.settings-menu button small { + color: var(--muted); + font-size: 11px; +} + +.settings-password-form, +.settings-placeholder { + min-height: 250px; + display: grid; + align-content: start; + gap: 12px; +} + +.settings-password-form h3, +.settings-placeholder h3 { + margin: 0; + font-size: 16px; +} + +.settings-password-form label { + display: grid; + gap: 8px; + color: var(--muted); + font-size: 13px; +} + +.settings-password-form input { + width: 100%; + height: 42px; + padding: 0 12px; + border: 1px solid var(--line); + border-radius: 6px; + outline: none; + background: #fff; + color: var(--text); +} + +.settings-password-form input:focus { + border-color: var(--primary); + box-shadow: 0 0 0 3px rgba(23, 125, 114, 0.12); +} + +.settings-password-form footer { + margin-top: 4px; + justify-content: flex-end; + flex-wrap: wrap; +} + +.settings-password-form footer .inline-save-status { + margin-right: auto; +} + +.settings-placeholder { + place-items: center; + border: 1px dashed var(--line); + border-radius: 8px; + color: var(--muted); + text-align: center; +} + +.settings-placeholder p { + margin: 0; +} + +.profile-edit-panel { + width: min(100%, 360px); +} + +.profile-avatar-field { + display: grid; + justify-items: center; + gap: 10px; +} + +.profile-avatar-field input[type="file"] { + position: absolute; + inline-size: 1px; + block-size: 1px; + opacity: 0; + pointer-events: none; +} + +.profile-avatar-preview { + width: 88px; + height: 88px; + display: grid; + place-items: center; + overflow: hidden; + padding: 0; + border: 0; + border-radius: 8px; + background: #dce8f2; + color: #24435c; + cursor: default; + font-size: 30px; + font-weight: 800; +} + +.profile-avatar-preview.clickable { + cursor: zoom-in; +} + +.profile-avatar-preview.clickable:hover { + box-shadow: 0 0 0 3px rgba(23, 125, 114, 0.16); +} + +.profile-avatar-preview img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.profile-avatar-change-button { + min-width: 96px; +} + +.avatar-preview-backdrop { + z-index: 32; + place-items: center; + padding: 24px 16px; +} + +.avatar-preview-dialog { + width: min(520px, calc(100vw - 32px)); + max-height: calc(100dvh - 48px); + display: grid; + gap: 12px; + padding: 14px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--panel); + box-shadow: 0 18px 40px rgba(24, 33, 47, 0.18); +} + +.avatar-preview-dialog header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; +} + +.avatar-preview-actions { + display: flex; + align-items: center; + gap: 6px; +} + +.avatar-preview-actions button { + min-width: 34px; + height: 34px; + display: inline-flex; + align-items: center; + justify-content: center; + border: 1px solid var(--line); + border-radius: 6px; + background: #fff; + color: var(--text); + font-weight: 700; +} + +.avatar-preview-actions .icon-button { + border: 0; + color: var(--muted); +} + +.avatar-preview-stage { + height: min(430px, calc(100dvh - 160px)); + min-height: 260px; + display: grid; + place-items: center; + overflow: hidden; + border-radius: 8px; + background: #101820; + cursor: zoom-in; + touch-action: none; +} + +.avatar-preview-stage.dragging { + cursor: grabbing; +} + +.avatar-preview-stage img { + max-width: min(100%, 430px); + max-height: 100%; + border-radius: 8px; + object-fit: contain; + transform-origin: center center; + transition: transform 0.08s ease-out; + user-select: none; + pointer-events: none; +} + +.avatar-preview-stage.dragging img { + transition: none; +} + +.avatar-cropper-backdrop { + z-index: 30; + place-items: center; + padding: 24px 16px; +} + +.avatar-cropper-panel { + width: min(720px, calc(100vw - 32px)); + max-height: calc(100dvh - 48px); + overflow: auto; +} + +.avatar-cropper-header-actions { + display: flex; + align-items: center; + gap: 8px; +} + +.avatar-cropper-layout { + display: grid; + grid-template-columns: minmax(0, 1fr) 190px; + gap: 14px; +} + +.avatar-cropper-stage { + position: relative; + height: 360px; + min-height: 360px; + overflow: hidden; + border: 1px dashed #b8ccd7; + border-radius: 8px; + background: #0f1b24; + touch-action: none; + cursor: grab; +} + +.avatar-cropper-stage.dragging { + cursor: grabbing; +} + +.avatar-cropper-stage canvas { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + display: block; +} + +.avatar-cropper-box { + position: absolute; + left: 50%; + top: 50%; + width: 74%; + aspect-ratio: 1; + max-width: calc(100% - 44px); + max-height: calc(100% - 44px); + transform: translate(-50%, -50%); + border: 2px dashed var(--primary); + border-radius: 8px; + box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.72); + pointer-events: none; +} + +.avatar-cropper-mask { + position: absolute; + inset: 0; + pointer-events: none; +} + +.avatar-cropper-placeholder { + position: absolute; + inset: 0; + display: grid; + place-items: center; + color: #d9e8ee; + font-size: 13px; + pointer-events: none; +} + +.avatar-cropper-controls { + min-width: 0; + display: grid; + align-content: start; + gap: 12px; +} + +.avatar-cropper-tools { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 8px; +} + +.avatar-cropper-tools button { + min-height: 34px; + padding: 0 10px; + border: 1px solid var(--line); + border-radius: 6px; + background: #fff; + color: var(--text); + font-weight: 700; +} + +.avatar-cropper-tools button:hover { + border-color: var(--primary); + color: var(--primary-strong); +} + +.avatar-cropper-preview { + width: 108px; + height: 108px; + justify-self: center; + overflow: hidden; + border: 1px solid var(--line); + border-radius: 8px; + background: #eef4f7; +} + +.avatar-cropper-preview canvas { + width: 100%; + height: 100%; + display: block; +} + +.avatar-cropper-controls footer { + display: flex; + align-items: center; + justify-content: flex-end; + flex-wrap: wrap; + gap: 8px; +} + +.avatar-cropper-controls footer .inline-save-status { + flex: 1 1 100%; +} + +.modal-actions { + justify-content: flex-end; +} + +.list-header, +.chat-header { + display: flex; + align-items: center; + justify-content: space-between; + min-height: 72px; + padding: 16px 18px; + border-bottom: 1px solid var(--line); +} + +.icon-button { + width: 34px; + height: 34px; + color: var(--muted); + font-size: 20px; +} + +.icon-button:hover { + background: #edf2f5; + color: var(--text); +} + +.search-box { + padding: 12px 14px; +} + +.sidebar-scroll { + min-height: 0; + overflow: auto; + overscroll-behavior: contain; +} + +.conversation-item { + width: 100%; + display: grid; + grid-template-columns: 42px minmax(0, 1fr) auto; + align-items: center; + gap: 10px; + padding: 12px 14px; + border: 0; + border-top: 1px solid rgba(217, 224, 231, 0.7); + background: transparent; + color: inherit; + text-align: left; +} + +.conversation-item.active, +.conversation-item:hover { + background: #eaf3f1; +} + +.favorite-item { + width: 100%; + display: grid; + grid-template-columns: 32px minmax(0, 1fr) auto; + align-items: center; + gap: 10px; + padding: 12px 14px; + border: 0; + border-top: 1px solid rgba(217, 224, 231, 0.7); + background: transparent; + color: inherit; + text-align: left; +} + +.favorite-item.active, +.favorite-item:hover { + background: #eaf3f1; +} + +.favorite-item-icon { + width: 32px; + height: 32px; + display: grid; + place-items: center; + border-radius: 6px; + background: #fff7df; + color: #c79520; + font-size: 16px; +} + +.favorite-item-main { + min-width: 0; + display: grid; + gap: 4px; +} + +.favorite-item-main strong, +.favorite-item-main small { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.favorite-item-main strong { + font-size: 14px; +} + +.favorite-item-main small, +.favorite-item time { + color: var(--muted); + font-size: 12px; +} + +.favorite-panel { + min-width: 0; + min-height: 0; + display: grid; + grid-template-rows: auto minmax(0, 1fr); + background: #eef3f6; +} + +.favorite-detail { + min-height: 0; + display: grid; + align-content: start; + gap: 16px; + padding: 28px; + overflow: auto; +} + +.favorite-detail-message { + width: min(680px, 100%); + display: grid; + grid-template-columns: auto minmax(0, 1fr); + gap: 10px 12px; + padding: 18px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--panel); + box-shadow: 0 8px 24px rgba(24, 33, 47, 0.08); +} + +.favorite-detail-message.recalled { + border-color: #f1c7c1; + background: #fff7f6; +} + +.favorite-detail-star { + color: #c79520; + font-size: 18px; + line-height: 1.4; +} + +.favorite-detail-body { + min-width: 0; + display: grid; + gap: 10px; +} + +.favorite-detail-message p { + margin: 0; + white-space: pre-wrap; + overflow-wrap: anywhere; + line-height: 1.55; +} + +.favorite-detail-message time { + grid-column: 2; + color: var(--muted); + font-size: 12px; +} + +.favorite-detail-image { + width: min(420px, 100%); + display: block; + overflow: hidden; + border: 1px solid #b9ded8; + border-radius: 8px; + background: #fff; +} + +.favorite-detail-image img { + display: block; + width: 100%; + max-height: 360px; + object-fit: contain; + background: #f8fbfc; +} + +.favorite-detail-file { + width: min(360px, 100%); +} + +.favorite-detail-actions { + width: min(680px, 100%); + display: flex; + align-items: center; + justify-content: flex-end; + gap: 8px; +} + +.favorite-detail-actions .inline-save-status { + margin-right: auto; +} + +.empty-list, +.empty-chat { + display: grid; + place-items: center; + align-content: center; + gap: 8px; + color: var(--muted); + text-align: center; +} + +.empty-list { + min-height: 180px; + padding: 24px; +} + +.empty-chat { + min-height: 0; + padding: 24px; +} + +.empty-list strong, +.empty-chat strong { + color: var(--text); +} + +.conversation-avatar { + width: 42px; + height: 42px; + border-radius: 8px; + background: #dce8f2; + color: #24435c; + font-weight: 700; +} + +.conversation-copy { + min-width: 0; + display: grid; + gap: 4px; +} + +.conversation-copy strong, +.conversation-copy small { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.conversation-copy small { + color: var(--muted); +} + +.unread-badge { + justify-self: end; + min-width: 20px; + height: 20px; + padding: 0 6px; + border-radius: 999px; + background: #ef4444; + color: #fff; + font-size: 12px; + font-weight: 800; + line-height: 20px; + text-align: center; + box-shadow: 0 0 0 2px #f7fafc; +} + +.chat-panel { + position: relative; + min-width: 0; + min-height: 0; + height: 100%; + display: grid; + grid-template-rows: 72px minmax(0, 1fr) auto auto; + overflow: hidden; + background: #eef2f5; +} + +.contact-panel { + min-width: 0; + min-height: 0; + height: 100%; + display: grid; + grid-template-rows: 72px minmax(0, 1fr); + overflow: auto; + background: #eef2f5; +} + +.contact-profile { + align-self: start; + width: min(520px, calc(100% - 48px)); + margin: 48px auto; + display: grid; + justify-items: center; + gap: 18px; + padding: 32px; + background: var(--panel); + border: 1px solid var(--line); + border-radius: 8px; +} + +.profile-avatar { + width: 76px; + height: 76px; + display: grid; + place-items: center; + border-radius: 8px; + background: #dce8f2; + color: #24435c; + font-size: 28px; + font-weight: 800; +} + +.profile-main { + text-align: center; +} + +.remark-row { + min-width: 0; + display: flex; + align-items: center; + justify-content: center; + gap: 8px; +} + +.profile-main h3 { + margin: 0; + font-size: 22px; + overflow-wrap: anywhere; +} + +.remark-edit-button { + width: 32px; + height: 32px; + flex: 0 0 auto; + font-size: 16px; +} + +.profile-main p { + margin: 6px 0 0; + color: var(--muted); +} + +.profile-fields { + width: 100%; + display: grid; + gap: 12px; + margin: 0; +} + +.profile-fields div { + display: grid; + grid-template-columns: 80px minmax(0, 1fr); + gap: 12px; + padding: 10px 0; + border-top: 1px solid var(--line); +} + +.profile-fields dt { + color: var(--muted); +} + +.profile-fields dd { + margin: 0; + overflow-wrap: anywhere; +} + +.profile-action { + width: 160px; +} + +.contact-panel .contact-modal-backdrop { + position: fixed; +} + +.header-actions { + display: flex; + gap: 8px; +} + +.chat-header-actions { + position: relative; +} + +.chat-title-button { + display: grid; + grid-template-columns: 38px minmax(0, 1fr); + align-items: center; + gap: 10px; + max-width: min(460px, 52vw); + padding: 0; + border: 0; + background: transparent; + color: var(--text); + text-align: left; +} + +.chat-title-avatar { + width: 38px; + height: 38px; + display: grid; + place-items: center; + border-radius: 8px; + background: #dce8f2; + color: #24435c; + font-size: 16px; + font-weight: 800; +} + +.chat-title-copy { + min-width: 0; +} + +.chat-title-button h2 { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.chat-title-button:hover h2 { + color: var(--primary-strong); +} + +.chat-more-menu { + top: 38px; + width: 150px; +} + +.action-menu-anchor { + position: relative; +} + +.quick-action-menu { + position: absolute; + top: 40px; + right: 0; + z-index: 7; + width: 168px; + display: grid; + padding: 6px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--panel); + box-shadow: 0 14px 34px rgba(24, 33, 47, 0.16); +} + +.quick-action-menu button { + height: 34px; + padding: 0 10px; + border: 0; + border-radius: 6px; + background: transparent; + color: var(--text); + text-align: left; +} + +.quick-action-menu button:hover { + background: #edf2f5; +} + +.quick-action-menu.chat-more-menu { + top: 38px; + width: 150px; +} + +.conversation-action-panel { + width: min(100%, 340px); + max-height: calc(100dvh - 116px); + overflow: auto; +} + +.contact-picker { + display: grid; + gap: 10px; +} + +.contact-picker > input { + width: 100%; + height: 38px; + padding: 0 10px; + border: 1px solid var(--line); + border-radius: 6px; + outline: none; +} + +.contact-picker-list { + max-height: 220px; + overflow: auto; + display: grid; + gap: 6px; + padding-right: 2px; +} + +.contact-picker-row { + width: 100%; + min-height: 48px; + display: grid; + grid-template-columns: 22px 36px minmax(0, 1fr); + align-items: center; + gap: 8px; + padding: 6px; + border: 1px solid var(--line); + border-radius: 6px; + background: #fff; + color: var(--text); + text-align: left; +} + +.contact-picker-row:hover, +.contact-picker-row.selected { + border-color: #9fd4cc; + background: #edf8f5; +} + +.contact-picker-row .conversation-avatar { + width: 36px; + height: 36px; + border-radius: 6px; + font-size: 13px; +} + +.contact-check { + width: 20px; + height: 20px; + display: grid; + place-items: center; + border: 1px solid var(--line); + border-radius: 4px; + color: var(--primary-strong); + font-size: 13px; + font-weight: 800; +} + +.contact-picker-copy { + min-width: 0; + display: grid; + gap: 2px; +} + +.contact-picker-copy strong, +.contact-picker-copy small { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.contact-picker-copy small { + color: var(--muted); + font-size: 12px; +} + +.contact-picker-empty { + min-height: 64px; + display: grid; + place-items: center; + color: var(--muted); + border: 1px dashed var(--line); + border-radius: 6px; +} + +.group-dialog { + width: min(420px, calc(100% - 32px)); + max-height: calc(100dvh - 116px); + display: grid; + gap: 16px; + padding: 18px; + overflow: auto; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--panel); + box-shadow: 0 18px 40px rgba(24, 33, 47, 0.18); +} + +.group-dialog header, +.group-dialog footer { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; +} + +.group-dialog h3 { + margin: 0; + font-size: 18px; +} + +.single-profile-dialog { + width: min(420px, calc(100% - 32px)); +} + +.single-profile-summary { + display: grid; + justify-items: center; + gap: 10px; +} + +.single-profile-summary strong { + max-width: 100%; + overflow-wrap: anywhere; + font-size: 18px; +} + +.single-profile-footer { + align-items: center; + justify-content: flex-end; +} + +.single-profile-footer .inline-save-status { + margin-right: auto; +} + +.message-detail-dialog { + width: min(560px, calc(100% - 32px)); +} + +.message-detail-meta div { + grid-template-columns: 88px minmax(0, 1fr); +} + +.message-detail-muted { + color: var(--muted); +} + +.message-detail-summary { + display: flex; + flex-wrap: wrap; + gap: 8px; +} + +.message-detail-summary span { + min-height: 30px; + display: inline-flex; + align-items: center; + gap: 4px; + padding: 0 10px; + border: 1px solid var(--line); + border-radius: 6px; + background: #f8fbfb; + color: var(--muted); + font-size: 13px; +} + +.message-detail-summary strong { + color: var(--text); +} + +.message-detail-groups { + display: grid; + gap: 14px; +} + +.message-detail-section { + display: grid; + gap: 8px; +} + +.message-detail-section header { + min-height: 28px; + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + border-bottom: 1px solid var(--line); +} + +.message-detail-section header strong { + font-size: 14px; +} + +.message-detail-section header span { + color: var(--muted); + font-size: 12px; +} + +.message-detail-member-list { + display: grid; + overflow: hidden; + border: 1px solid var(--line); + border-radius: 6px; + background: #fff; +} + +.message-detail-member-row { + display: grid; + grid-template-columns: 34px minmax(0, 1fr) auto auto; + align-items: center; + gap: 8px; + min-height: 48px; + padding: 7px 8px; + border-top: 1px solid var(--line); +} + +.message-detail-member-row:first-child { + border-top: 0; +} + +.message-detail-member-row .conversation-avatar { + width: 34px; + height: 34px; + border-radius: 6px; + font-size: 13px; +} + +.message-detail-member-main { + min-width: 0; + display: grid; + gap: 2px; +} + +.message-detail-member-main strong, +.message-detail-member-main small { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.message-detail-member-main strong { + font-size: 13px; +} + +.message-detail-member-main small, +.message-detail-member-time { + color: var(--muted); + font-size: 12px; +} + +.message-detail-member-time { + white-space: nowrap; +} + +.message-detail-role { + min-height: 22px; + display: inline-flex; + align-items: center; + padding: 0 7px; + border: 1px solid #c7d9e5; + border-radius: 6px; + color: #416272; + font-size: 12px; + white-space: nowrap; +} + +.group-dialog label { + display: grid; + gap: 8px; + color: var(--muted); + font-size: 13px; +} + +.group-dialog input { + width: 100%; + height: 42px; + padding: 0 12px; + border: 1px solid var(--line); + border-radius: 6px; + outline: none; +} + +.group-dialog textarea, +.group-dialog select { + width: 100%; + border: 1px solid var(--line); + border-radius: 6px; + outline: none; + background: #fff; + color: var(--text); +} + +.group-dialog textarea { + min-height: 86px; + resize: vertical; + padding: 10px 12px; + line-height: 1.5; +} + +.group-dialog select { + height: 42px; + padding: 0 10px; +} + +.group-dialog input:focus { + border-color: var(--primary); + box-shadow: 0 0 0 3px rgba(23, 125, 114, 0.12); +} + +.group-dialog textarea:focus, +.group-dialog select:focus { + border-color: var(--primary); + box-shadow: 0 0 0 3px rgba(23, 125, 114, 0.12); +} + +.group-profile { + display: grid; + gap: 10px; + margin: 0; +} + +.group-profile div { + display: grid; + grid-template-columns: 78px minmax(0, 1fr); + gap: 12px; + padding: 10px 0; + border-top: 1px solid var(--line); +} + +.group-profile dt { + color: var(--muted); +} + +.group-profile dd { + margin: 0; + overflow-wrap: anywhere; +} + +.group-loading { + min-height: 96px; + display: grid; + place-items: center; + color: var(--muted); +} + +.group-member-list { + display: grid; + gap: 8px; +} + +.group-member-row { + display: grid; + grid-template-columns: 42px minmax(0, 1fr); + align-items: center; + gap: 10px; + min-height: 54px; + padding: 8px; + border: 1px solid var(--line); + border-radius: 6px; + background: #fff; +} + +.group-member-row.selectable { + cursor: pointer; +} + +.group-member-row.with-check { + grid-template-columns: 24px 42px minmax(0, 1fr); +} + +.group-member-row.selectable:hover, +.group-member-row.selectable.selected { + border-color: #9fd4cc; + background: #edf8f5; +} + +.group-member-row input[type="checkbox"] { + justify-self: center; + width: 16px; + height: 16px; +} + +.group-member-row span:last-child { + min-width: 0; + display: grid; + gap: 3px; +} + +.group-member-row strong, +.group-member-row small { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.group-member-row small { + color: var(--muted); + font-size: 12px; +} + +.group-management-dialog { + width: min(520px, calc(100% - 32px)); +} + +.group-management-tabs { + display: flex; + flex-wrap: wrap; + gap: 8px; +} + +.group-management-tabs button { + height: 34px; + padding: 0 10px; + border: 1px solid var(--line); + border-radius: 6px; + background: #fff; + color: var(--text); +} + +.group-management-tabs button.active, +.group-management-tabs button:hover { + border-color: var(--primary); + background: #e8f4f2; + color: var(--primary-strong); + font-weight: 700; +} + +.group-manage-section { + display: grid; + gap: 14px; +} + +.group-manage-section footer { + justify-content: flex-end; +} + +.mute-save-footer { + align-items: center; + gap: 10px; +} + +.inline-save-status { + color: var(--primary-strong); + font-size: 13px; +} + +.inline-save-status.error { + color: var(--accent); +} + +.mute-time-grid { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); + gap: 10px; +} + +.message-list { + min-height: 0; + overflow: auto; + overscroll-behavior: contain; + padding: 24px; +} + +.message-row { + display: flex; + align-items: flex-end; + gap: 8px; + margin-bottom: 14px; +} + +.message-row.out { + justify-content: flex-end; +} + +.message-sender-avatar { + width: 34px; + height: 34px; + flex: 0 0 auto; + display: grid; + place-items: center; + overflow: hidden; + padding: 0; + border: 0; + border-radius: 8px; + background: #dce8f2; + color: #24435c; + font-size: 14px; + font-weight: 800; +} + +.message-sender-avatar img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.message-stack { + max-width: min(68%, 720px); + display: grid; + justify-items: start; + gap: 4px; +} + +.message-row.out .message-stack { + justify-items: end; +} + +.message-sender-name { + min-height: 18px; + max-width: 100%; + padding: 0; + border: 0; + background: transparent; + color: var(--muted); + font-size: 12px; + font-weight: 700; + text-align: left; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.message-sender-name:hover { + color: var(--primary-strong); +} + +.message-sender-role { + margin-left: 4px; + color: var(--primary-strong); + font-size: 11px; +} + +.message-row.selected .message-bubble { + box-shadow: 0 0 0 2px rgba(24, 138, 121, 0.26); +} + +.message-row.attention .message-bubble { + animation: message-attention 1.4s ease-in-out 2; + box-shadow: 0 0 0 3px rgba(24, 138, 121, 0.3); +} + +@keyframes message-attention { + 0%, + 100% { + box-shadow: 0 0 0 2px rgba(24, 138, 121, 0.16); + } + + 45% { + box-shadow: 0 0 0 5px rgba(24, 138, 121, 0.36); + } +} + +.message-select { + width: 24px; + height: 24px; + display: grid; + place-items: center; +} + +.message-select input { + width: 16px; + height: 16px; +} + +.message-bubble { + position: relative; + max-width: min(68%, 720px); + padding: 10px 12px 8px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--bubble-in); + box-shadow: 0 2px 8px rgba(30, 40, 50, 0.05); +} + +.message-stack .message-bubble { + max-width: 100%; +} + +.message-row.out .message-bubble { + background: var(--bubble-out); + border-color: #bfe4dc; +} + +.message-bubble:hover { + border-color: #9fd4cc; +} + +.message-bubble.role-bubble-owner, +.message-bubble.role-bubble-admin { + overflow: hidden; +} + +.message-bubble.role-bubble-owner::after, +.message-bubble.role-bubble-admin::after { + content: ""; + position: absolute; + top: 0; + right: 0; + width: 0; + height: 0; + border-top: 16px solid #d79d22; + border-left: 16px solid transparent; +} + +.message-bubble.role-bubble-admin::after { + border-top-color: #178a79; +} + +.message-bubble p { + margin: 0; + line-height: 1.5; + white-space: pre-wrap; + overflow-wrap: anywhere; +} + +.message-image { + padding: 0; + border: 0; + display: block; + max-width: min(280px, 62vw); + overflow: hidden; + border-radius: 6px; + background: #edf2f5; + cursor: zoom-in; +} + +.message-image + p, +.message-file + p { + margin-top: 8px; +} + +.message-image img { + display: block; + max-width: 100%; + max-height: 320px; + object-fit: contain; +} + +.image-viewer-backdrop { + position: fixed; + inset: 0; + z-index: 80; + display: grid; + place-items: center; + padding: 24px; + background: rgba(12, 18, 26, 0.58); +} + +.image-viewer-dialog { + width: min(880px, calc(100vw - 48px)); + height: min(640px, calc(100vh - 48px)); + min-width: 360px; + min-height: 280px; + max-width: calc(100vw - 48px); + max-height: calc(100vh - 48px); + display: grid; + grid-template-rows: 52px minmax(0, 1fr); + overflow: hidden; + resize: both; + border: 1px solid rgba(255, 255, 255, 0.18); + border-radius: 8px; + background: #101820; + box-shadow: 0 24px 70px rgba(0, 0, 0, 0.36); +} + +.image-viewer-toolbar { + min-width: 0; + display: flex; + align-items: center; + justify-content: flex-end; + gap: 8px; + padding: 8px 10px; + border-bottom: 1px solid rgba(255, 255, 255, 0.12); + background: rgba(24, 33, 47, 0.94); +} + +.image-viewer-title { + min-width: 0; + flex: 1; + overflow: hidden; + color: #f8fafc; + font-size: 13px; + font-weight: 700; + text-overflow: ellipsis; + white-space: nowrap; +} + +.image-viewer-toolbar button { + width: 36px; + height: 36px; + display: grid; + place-items: center; + border: 0; + border-radius: 6px; + background: transparent; + color: #f8fafc; + font-size: 17px; + font-weight: 700; + line-height: 1; +} + +.image-viewer-toolbar button:hover { + background: rgba(255, 255, 255, 0.14); +} + +.image-viewer-stage { + min-width: 0; + min-height: 0; + display: grid; + place-items: center; + overflow: hidden; + background: #0c121a; + cursor: default; + touch-action: none; +} + +.image-viewer-stage.zoomed { + cursor: grab; +} + +.image-viewer-stage.dragging { + cursor: grabbing; +} + +.image-viewer-img { + max-width: calc(100% - 32px); + max-height: calc(100% - 32px); + object-fit: contain; + transform-origin: center center; + transition: transform 0.08s ease-out; + user-select: none; + pointer-events: none; +} + +.image-viewer-stage.dragging .image-viewer-img { + transition: none; +} + +.sender-profile-backdrop { + position: fixed; + inset: 0; + z-index: 84; + display: grid; + place-items: center; + padding: 24px; + background: rgba(24, 33, 47, 0.32); +} + +.sender-profile-dialog { + width: min(380px, calc(100vw - 32px)); + display: grid; + gap: 16px; + padding: 18px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--panel); + box-shadow: 0 18px 40px rgba(24, 33, 47, 0.18); +} + +.sender-profile-dialog header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; +} + +.sender-profile-main { + display: grid; + justify-items: center; + gap: 8px; + text-align: center; +} + +.sender-profile-main strong { + max-width: 100%; + overflow-wrap: anywhere; + font-size: 18px; +} + +.sender-profile-main span { + color: var(--primary-strong); + font-size: 12px; + font-weight: 700; +} + +.sender-profile-fields { + display: grid; + gap: 8px; + margin: 0; +} + +.sender-profile-fields div { + display: grid; + grid-template-columns: 72px minmax(0, 1fr); + gap: 10px; + padding-top: 8px; + border-top: 1px solid var(--line); +} + +.sender-profile-fields dt { + color: var(--muted); +} + +.sender-profile-fields dd { + margin: 0; + overflow-wrap: anywhere; +} + +.sender-profile-alias { + display: grid; + gap: 8px; + color: var(--muted); + font-size: 13px; +} + +.sender-profile-alias input { + width: 100%; + height: 40px; + padding: 0 12px; + border: 1px solid var(--line); + border-radius: 6px; + outline: none; + background: #fff; + color: var(--text); +} + +.sender-profile-alias input:focus { + border-color: var(--primary); + box-shadow: 0 0 0 3px rgba(23, 125, 114, 0.12); +} + +.sender-profile-actions { + display: flex; + align-items: center; + justify-content: flex-end; + gap: 8px; +} + +.sender-profile-actions .inline-save-status { + margin-right: auto; +} + +@media (max-width: 480px) { + .image-viewer-backdrop { + padding: 12px; + } + + .image-viewer-dialog { + width: calc(100vw - 24px); + height: min(560px, calc(100vh - 24px)); + min-width: 280px; + min-height: 240px; + max-width: calc(100vw - 24px); + max-height: calc(100vh - 24px); + } + + .image-viewer-toolbar { + gap: 4px; + padding: 6px; + } + + .image-viewer-toolbar button { + width: 32px; + height: 32px; + font-size: 15px; + } + + .message-detail-member-row { + grid-template-columns: 34px minmax(0, 1fr); + } + + .message-detail-member-time, + .message-detail-role { + grid-column: 2; + justify-self: start; + } + + .avatar-cropper-panel { + width: calc(100vw - 24px); + max-height: calc(100dvh - 24px); + } + + .avatar-cropper-layout { + grid-template-columns: minmax(0, 1fr); + } + + .avatar-cropper-stage { + height: 300px; + min-height: 300px; + } + + .avatar-cropper-controls { + grid-template-columns: minmax(0, 1fr) auto; + align-items: center; + } + + .avatar-cropper-tools { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .avatar-cropper-preview { + width: 82px; + height: 82px; + } + + .avatar-cropper-controls footer { + grid-column: 1 / -1; + } + + .settings-panel { + width: calc(100vw - 24px); + max-height: calc(100dvh - 24px); + } + + .settings-layout { + grid-template-columns: minmax(0, 1fr); + } + + .settings-menu { + grid-auto-flow: column; + grid-auto-columns: minmax(120px, 1fr); + overflow-x: auto; + padding-bottom: 2px; + } + + .settings-password-form footer .inline-save-status { + flex: 1 1 100%; + } +} + +.message-file { + width: min(280px, 62vw); + display: grid; + grid-template-columns: 38px minmax(0, 1fr); + align-items: center; + gap: 10px; + padding: 10px; + border: 1px solid #d6e2e7; + border-radius: 6px; + background: #f8fbfc; + color: var(--text); + text-decoration: none; +} + +.message-file:hover { + border-color: #9fd4cc; + background: #edf8f5; +} + +.message-file-icon { + width: 38px; + height: 38px; + display: grid; + place-items: center; + border-radius: 6px; + background: #e3eff2; + color: var(--primary-strong); + font-size: 18px; + font-weight: 800; +} + +.message-file-main { + min-width: 0; + display: grid; + gap: 3px; +} + +.message-file-main strong, +.message-file-main small { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.message-file-main strong { + font-size: 13px; +} + +.message-file-main small { + color: var(--muted); + font-size: 11px; +} + +.message-bubble time { + display: flex; + align-items: center; + justify-content: flex-end; + flex-wrap: wrap; + gap: 4px; + margin-top: 4px; + color: var(--muted); + font-size: 11px; + text-align: right; +} + +.recall-mark { + margin-right: auto; + color: #d93025; + font-size: 11px; + font-weight: 700; + line-height: 1; +} + +.edit-mark { + color: #7a8792; + font-size: 11px; + font-weight: 600; + line-height: 1; +} + +.delivery-mark { + display: inline-flex; + align-items: center; + justify-content: flex-end; + min-width: 14px; + color: #8f9aa3; + font-size: 14px; + font-weight: 800; + letter-spacing: 0; + line-height: 1; +} + +.delivery-mark-delivered, +.delivery-mark-read { + min-width: 19px; +} + +.delivery-mark-read { + color: #1aa66a; +} + +.favorite-mark { + color: #c79520; + font-size: 12px; + line-height: 1; +} + +.delivery-check { + display: inline-block; +} + +.delivery-check-second { + margin-left: -5px; +} + +.delivery-error { + color: #c0392b; +} + +.message-context-menu { + position: fixed; + z-index: 30; + width: 136px; + padding: 6px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--panel); + box-shadow: 0 16px 40px rgba(24, 33, 47, 0.18); +} + +.message-context-menu button { + width: 100%; + min-height: 32px; + padding: 0 10px; + border: 0; + border-radius: 6px; + background: transparent; + color: var(--text); + text-align: left; +} + +.message-context-menu button:hover { + background: #eaf3f1; +} + +.selection-toolbar { + min-height: 42px; + display: flex; + align-items: center; + gap: 8px; + padding: 8px 16px; + border-top: 1px solid var(--line); + background: #f7fafc; +} + +.selection-toolbar span { + flex: 1; + color: var(--muted); + font-size: 13px; +} + +.selection-toolbar button { + min-height: 30px; + padding: 0 10px; + border-radius: 6px; +} + +.forward-dialog, +.edit-dialog { + width: min(100%, 340px); + max-height: min(520px, calc(100vh - 130px)); + display: grid; + gap: 4px; + padding: 14px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--panel); + box-shadow: 0 18px 40px rgba(24, 33, 47, 0.18); + overflow: auto; +} + +.forward-dialog header, +.edit-dialog header, +.forward-target { + display: flex; + align-items: center; + gap: 10px; +} + +.forward-dialog header, +.edit-dialog header { + justify-content: space-between; + margin-bottom: 6px; +} + +.forward-dialog h3, +.edit-dialog h3 { + margin: 0; + font-size: 16px; +} + +.edit-dialog { + width: min(100%, 420px); + gap: 12px; +} + +.edit-dialog textarea { + width: 100%; + min-height: 132px; + resize: vertical; + border-radius: 8px; + border: 1px solid var(--line); + padding: 10px; + background: #f9fbfc; + color: var(--text); + line-height: 1.5; +} + +.edit-dialog textarea:focus { + border-color: var(--accent); + outline: 0; + box-shadow: 0 0 0 3px rgba(24, 138, 121, 0.14); +} + +.edit-dialog footer { + display: flex; + justify-content: flex-end; + gap: 8px; +} + +.edit-dialog footer button { + min-height: 34px; + padding: 0 14px; + border-radius: 8px; +} + +.forward-target { + min-height: 52px; + padding: 6px; + border: 0; + border-radius: 8px; + background: transparent; + color: var(--text); + text-align: left; +} + +.forward-target:hover { + background: #eaf3f1; +} + +.chat-toast { + position: absolute; + left: 50%; + bottom: 132px; + z-index: 20; + transform: translateX(-50%); + padding: 8px 12px; + border-radius: 8px; + background: rgba(35, 45, 58, 0.92); + color: #fff; + font-size: 13px; + pointer-events: none; +} + +.chat-toast.error { + background: rgba(192, 57, 43, 0.94); +} + +.message-composer { + position: relative; + min-height: 0; + border-top: 1px solid var(--line); + background: var(--panel); +} + +.message-composer::after { + content: ""; + position: absolute; + inset: 6px; + z-index: 4; + border: 2px dashed transparent; + border-radius: 8px; + pointer-events: none; + transition: border-color 0.12s ease, background-color 0.12s ease; +} + +.message-composer.drop-active::after { + border-color: var(--primary); + background: rgba(23, 125, 114, 0.08); +} + +.quote-preview { + display: flex; + align-items: center; + gap: 8px; + padding: 8px 16px 0; + color: var(--muted); + font-size: 13px; +} + +.quote-preview span { + min-width: 0; + flex: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + border-left: 3px solid var(--accent); + padding-left: 8px; +} + +.quote-preview strong { + margin-right: 6px; + color: var(--text); +} + +.quote-preview button { + width: 26px; + height: 26px; + border: 0; + border-radius: 6px; + background: transparent; + color: var(--muted); + font-size: 18px; +} + +.quote-preview button:hover { + background: #edf2f5; +} + +.composer-tools { + position: relative; + display: flex; + gap: 4px; + padding: 8px 16px 0; +} + +.composer-tools input[type="file"] { + display: none; +} + +.composer-tools button { + width: 32px; + height: 32px; + border: 0; + border-radius: 6px; + background: transparent; + color: var(--muted); + font-size: 18px; +} + +.composer-tools button:hover { + background: #edf2f5; +} + +.emoji-picker { + position: absolute; + left: 16px; + bottom: 38px; + z-index: 12; + width: 256px; + display: grid; + grid-template-columns: repeat(8, 1fr); + gap: 2px; + padding: 8px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--panel); + box-shadow: 0 14px 34px rgba(24, 33, 47, 0.16); +} + +.emoji-picker button { + width: 28px; + height: 28px; + border-radius: 6px; + font-size: 17px; +} + +.message-composer textarea { + display: block; + min-height: 86px; + max-height: 180px; + padding: 12px 16px; + border: 0; + border-radius: 0; + resize: none; + box-shadow: none; +} + +.composer-footer { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + padding: 0 16px 14px; + color: var(--muted); + font-size: 12px; +} + +.send-button { + min-width: 72px; + height: 34px; +} + +@media (max-width: 760px) { + .app-shell { + grid-template-columns: 56px minmax(0, 1fr); + } + + .conversation-list { + display: none; + } + + .message-bubble { + max-width: 86%; + } +} diff --git a/vue.config.js b/vue.config.js new file mode 100644 index 0000000..b73dc92 --- /dev/null +++ b/vue.config.js @@ -0,0 +1,51 @@ +const path = require('path'); +const webpack = require('webpack'); + +module.exports = { + outputDir: 'dist', + publicPath: './', + transpileDependencies: true, + configureWebpack: { + resolve: { + alias: { + '@': path.resolve(__dirname, 'src'), + 'legacy-wfc': path.resolve(__dirname, '../src/wfc'), + 'legacy-config': path.resolve(__dirname, '../src/config.js') + }, + fallback: { + path: false, + fs: false, + assert: false, + util: false, + os: false, + crypto: false, + buffer: require.resolve('buffer/') + } + }, + plugins: [ + new webpack.ProvidePlugin({ + process: 'process/browser', + Buffer: ['buffer', 'Buffer'] + }) + ] + }, + devServer: { + allowedHosts: 'all', + client: { + overlay: false + }, + proxy: { + '/local-api': { + target: 'http://127.0.0.1:8024', + changeOrigin: true, + pathRewrite: { + '^/local-api': '/api' + } + } + } + }, + chainWebpack(config) { + config.optimization.concatenateModules(false); + config.optimization.minimize(false); + } +};