From 08e1294e5db3cd874ed763ea358bf277d7b88f71 Mon Sep 17 00:00:00 2001 From: Wxw-Gu Date: Mon, 3 Aug 2026 10:43:14 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E5=A4=9A=E8=B4=A6?= =?UTF-8?q?=E5=8F=B7=E8=BF=9E=E6=8E=A5=E8=AF=8A=E6=96=AD=E4=B8=8E=E8=81=8A?= =?UTF-8?q?=E5=A4=A9=E5=AA=92=E4=BD=93=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增微信账号发现、环境诊断和分步数据库连接引导 - 支持按账号安全保存数据库密钥及快速切换账号 - 完善 WCDB 历史消息分片读取和分页状态提示 - 支持导出图片、视频和语音,提供原图优先及缩略图回退 - 更新安装指引、兼容版本说明和相关自动化测试 --- README.md | 14 +- docs/user-guide/getting-started.md | 30 +- src/main/database-key-store.ts | 80 ++++- src/main/export-html-template.ts | 11 +- src/main/export-service.ts | 177 +++++++--- src/main/index.ts | 132 +++++-- src/main/services/account-discovery.ts | 58 ++++ src/main/services/connection-diagnostics.ts | 69 ++++ src/main/services/settings-store.ts | 17 +- src/main/wcdb4-client.ts | 87 ++++- src/preload/index.d.ts | 22 +- src/preload/index.ts | 18 +- src/renderer/src/App.tsx | 264 +++++++++++++- src/renderer/src/components/ChatWindow.tsx | 3 + .../src/components/DatabaseConnectionPage.tsx | 325 ++++++++++++++---- .../src/components/chat/MessageList.tsx | 14 + .../src/components/export/ExportWorkspace.tsx | 56 ++- .../features/settings/SettingsWorkspace.tsx | 16 +- .../account-database/AccountOverview.tsx | 7 +- .../database-key/useDatabaseKeyController.ts | 21 +- .../settings/pages/AccountDatabasePage.tsx | 57 ++- src/renderer/src/styles/chat.scss | 158 ++++++++- src/shared/connection-diagnostics.ts | 16 + src/shared/database-key.ts | 28 ++ src/shared/export-media.ts | 22 ++ src/shared/export.ts | 3 + tests/component/database-connection.test.tsx | 81 +++++ .../win32/visual.spec.ts/archive-page.png | Bin 58566 -> 58614 bytes .../win32/visual.spec.ts/login-page.png | Bin 74638 -> 82755 bytes tests/e2e/app.spec.ts | 51 ++- tests/e2e/support/electron-main.cjs | 44 ++- tests/integration/export-media-flow.test.ts | 173 ++++++++++ tests/unit/account-discovery.test.ts | 69 ++++ tests/unit/connection-diagnostics.test.ts | 26 ++ tests/unit/export-media.test.ts | 62 ++++ tests/unit/message-pagination.test.ts | 10 + tests/unit/wcdb-message-shards.test.ts | 45 +++ 37 files changed, 2011 insertions(+), 255 deletions(-) create mode 100644 src/main/services/account-discovery.ts create mode 100644 src/main/services/connection-diagnostics.ts create mode 100644 src/shared/connection-diagnostics.ts create mode 100644 src/shared/export-media.ts create mode 100644 tests/integration/export-media-flow.test.ts create mode 100644 tests/unit/account-discovery.test.ts create mode 100644 tests/unit/connection-diagnostics.test.ts create mode 100644 tests/unit/export-media.test.ts create mode 100644 tests/unit/wcdb-message-shards.test.ts diff --git a/README.md b/README.md index 2c4a2fd..a3ea76b 100644 --- a/README.md +++ b/README.md @@ -197,10 +197,18 @@ WechatExplorer 希望不仅仅是一个聊天记录查看工具,更希望成 ### 下载并安装 -从 [GitHub Releases](https://github.com/Wxw-Gu/WechatExplorer/releases) 下载对应系统的安装包: +当前 WechatExplorer / 迹忆版本:`v2.1.6`。 -- Windows:下载 `-setup.exe` 并按安装向导完成安装。 -- macOS:下载 `.dmg`,将 WechatExplorer 拖入“应用程序”。首次打开若被系统拦截,请在“系统设置 → 隐私与安全性”中允许打开。 +应用安装包:[WechatExplorer GitHub Releases](https://github.com/Wxw-Gu/WechatExplorer/releases)。Windows 选择 `-setup.exe`,macOS 按处理器架构选择对应 `.dmg`。 + +| 系统 | 已测试的微信客户端 | +| ------- | ------------------------------------------------------------------------------------------------- | +| Windows | [微信 Windows `4.1.9.57`](https://github.com/iibob/wechat-win-archive/releases#release-v4.1.9.57) | +| macOS | [微信 macOS `4.1.8.100`](https://github.com/zsbai/wechat-versions/releases/tag/4.1.8.100) | + +微信客户端来自上表对应的第三方版本存档,请自行核对来源与文件完整性。 + +正常覆盖安装只会替换应用程序文件,WechatExplorer / 迹忆不会主动删除或修改微信原始聊天记录;但应用缓存和本地设置可能随版本升级变化。升级前仍建议使用微信官方迁移或备份功能备份重要记录,不要将唯一副本保存在单一设备。 ### 连接微信 diff --git a/docs/user-guide/getting-started.md b/docs/user-guide/getting-started.md index 9f6edca..968cf21 100644 --- a/docs/user-guide/getting-started.md +++ b/docs/user-guide/getting-started.md @@ -13,12 +13,14 @@ - [我遇到问题](#遇到问题) - [我想让 Agent 读取微信](#接入-api-reader-skill-或-agent) +> 正常覆盖安装只会替换应用程序文件,WechatExplorer / 迹忆不会主动删除或修改微信原始聊天记录。应用缓存和本地设置可能随版本升级发生变化。系统故障、磁盘异常、误操作和微信自身迁移不受本应用控制,因此升级前仍建议使用微信官方迁移或备份功能备份重要聊天记录,不要将唯一副本保存在单一设备。 + ## 开始前确认 -| 系统 | 已测试的微信版本 | 需要注意 | -| --- | --- | --- | -| macOS | `4.1.8.100` | 自动获取数据库密钥前需要关闭 SIP 并完成授权 | -| Windows | `4.1.9.57` | 已完整支持;首次使用时请确认微信数据目录 | +| 系统 | 已测试的微信客户端 | 需要注意 | +| ------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------- | +| macOS | [微信 macOS `4.1.8.100`](https://github.com/zsbai/wechat-versions/releases/tag/4.1.8.100) | 自动获取数据库密钥前需要关闭 SIP 并完成授权 | +| Windows | [微信 Windows `4.1.9.57`](https://github.com/iibob/wechat-win-archive/releases#release-v4.1.9.57) | 已完整支持;首次使用时请确认微信数据目录 | - WechatExplorer 当前面向微信 4.0 数据结构。 - Windows 不需要关闭 SIP。 @@ -26,7 +28,7 @@ - WechatExplorer 必须取得当前微信账号对应的数据库密钥才能读取聊天记录。 - 请只处理你有权访问的微信数据。 -下载入口:[GitHub Releases](https://github.com/Wxw-Gu/WechatExplorer/releases) +WechatExplorer / 迹忆应用安装包:[GitHub Releases](https://github.com/Wxw-Gu/WechatExplorer/releases)。Windows 选择 `-setup.exe`,macOS 按处理器架构选择对应 `.dmg`。微信客户端请使用上方“已测试的微信客户端”链接。 ## 第一次连接微信 @@ -140,15 +142,15 @@ AI 功能使用你配置的模型服务。相关聊天内容会按请求发送 先判断你遇到的现象,再按对应路径处理。 -| 现象 | 优先检查 | -| --- | --- | -| 软件打不开 | macOS 安全提示或应用损坏处理;Windows 重新运行安装包 | -| 找不到微信数据 | 在首次连接页面或设置中确认数据目录,Windows 检查目录层级 | -| 获取不到数据库密钥 | 微信是否停留在登录页面、微信和应用是否同时运行 | -| 数据库连接失败 | 当前账号是否匹配、微信版本是否兼容、数据库目录是否正确 | -| 已连接但图片不显示 | 配置图片 XOR Key 和 AES Key | -| AI 问问微信或日报不可用 | 在「设置 → AI 模型」配置并测试模型服务 | -| API、Reader Skill 或 Agent 不可用 | 先连接数据库,再确认 API 服务状态和对应配置 | +| 现象 | 优先检查 | +| --------------------------------- | -------------------------------------------------------- | +| 软件打不开 | macOS 安全提示或应用损坏处理;Windows 重新运行安装包 | +| 找不到微信数据 | 在首次连接页面或设置中确认数据目录,Windows 检查目录层级 | +| 获取不到数据库密钥 | 微信是否停留在登录页面、微信和应用是否同时运行 | +| 数据库连接失败 | 当前账号是否匹配、微信版本是否兼容、数据库目录是否正确 | +| 已连接但图片不显示 | 配置图片 XOR Key 和 AES Key | +| AI 问问微信或日报不可用 | 在「设置 → AI 模型」配置并测试模型服务 | +| API、Reader Skill 或 Agent 不可用 | 先连接数据库,再确认 API 服务状态和对应配置 | ### 软件打不开 diff --git a/src/main/database-key-store.ts b/src/main/database-key-store.ts index 4ed094a..9a05d7b 100644 --- a/src/main/database-key-store.ts +++ b/src/main/database-key-store.ts @@ -1,6 +1,7 @@ import { app, safeStorage } from 'electron' import fs from 'fs-extra' import path from 'path' +import crypto from 'crypto' import type { DatabaseKeyStorageResult } from '../shared/database-key' const normalizeDatabaseKey = (value: string): string => value.trim().replace(/^0x/i, '') @@ -9,32 +10,42 @@ export const isValidDatabaseKey = (value: string): boolean => /^[0-9a-f]{64}$/i.test(normalizeDatabaseKey(value)) export class DatabaseKeyStore { - private get filePath(): string { + private get legacyFilePath(): string { return path.join(app.getPath('userData'), 'wechat-db-key.bin') } - async getStatus(): Promise<{ saved: boolean; encryptionAvailable: boolean }> { + private get directoryPath(): string { + return path.join(app.getPath('userData'), 'database-keys') + } + + private filePath(accountRoot: string): string { + const normalized = path.resolve(accountRoot).toLowerCase() + const id = crypto.createHash('sha256').update(normalized).digest('hex') + return path.join(this.directoryPath, `${id}.bin`) + } + + async getStatus(accountRoot: string): Promise<{ saved: boolean; encryptionAvailable: boolean }> { return { - saved: await fs.pathExists(this.filePath), + saved: Boolean(accountRoot) && (await fs.pathExists(this.filePath(accountRoot))), encryptionAvailable: safeStorage.isEncryptionAvailable() } } - async load(): Promise { + async load(accountRoot: string): Promise { try { - const status = await this.getStatus() + const status = await this.getStatus(accountRoot) if (!status.saved) return { success: true, ...status } if (!status.encryptionAvailable) { return { success: false, error: '系统安全存储不可用', ...status } } - const encrypted = await fs.readFile(this.filePath) + const encrypted = await fs.readFile(this.filePath(accountRoot)) const key = normalizeDatabaseKey(safeStorage.decryptString(encrypted)) if (!isValidDatabaseKey(key)) { return { success: false, error: '已保存的密钥格式无效', ...status } } return { success: true, key, ...status } } catch (error) { - const status = await this.getStatus() + const status = await this.getStatus(accountRoot) return { success: false, error: error instanceof Error ? error.message : String(error), @@ -43,13 +54,49 @@ export class DatabaseKeyStore { } } - async save(rawKey: string): Promise { + async loadLegacy(): Promise { + const saved = await fs.pathExists(this.legacyFilePath) + const encryptionAvailable = safeStorage.isEncryptionAvailable() + if (!saved) return { success: true, saved, encryptionAvailable } + if (!encryptionAvailable) { + return { success: false, error: '系统安全存储不可用', saved, encryptionAvailable } + } + try { + const key = normalizeDatabaseKey( + safeStorage.decryptString(await fs.readFile(this.legacyFilePath)) + ) + return isValidDatabaseKey(key) + ? { success: true, key, saved, encryptionAvailable } + : { success: false, error: '旧版密钥格式无效', saved, encryptionAvailable } + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : String(error), + saved, + encryptionAvailable + } + } + } + + async clearLegacy(): Promise { + await fs.remove(this.legacyFilePath) + } + + async save(accountRoot: string, rawKey: string): Promise { const key = normalizeDatabaseKey(rawKey) + if (!accountRoot.trim()) { + return { + success: false, + error: '请先选择微信账号', + saved: false, + encryptionAvailable: safeStorage.isEncryptionAvailable() + } + } if (!isValidDatabaseKey(key)) { return { success: false, error: '密钥必须是 64 位十六进制字符', - saved: await fs.pathExists(this.filePath), + saved: await fs.pathExists(this.filePath(accountRoot)), encryptionAvailable: safeStorage.isEncryptionAvailable() } } @@ -57,29 +104,30 @@ export class DatabaseKeyStore { return { success: false, error: '系统安全存储不可用', - saved: await fs.pathExists(this.filePath), + saved: await fs.pathExists(this.filePath(accountRoot)), encryptionAvailable: false } } try { - await fs.ensureDir(path.dirname(this.filePath)) - await fs.writeFile(this.filePath, safeStorage.encryptString(key), { mode: 0o600 }) - await fs.chmod(this.filePath, 0o600) + const filePath = this.filePath(accountRoot) + await fs.ensureDir(this.directoryPath) + await fs.writeFile(filePath, safeStorage.encryptString(key), { mode: 0o600 }) + await fs.chmod(filePath, 0o600) return { success: true, key, saved: true, encryptionAvailable: true } } catch (error) { return { success: false, error: error instanceof Error ? error.message : String(error), - saved: await fs.pathExists(this.filePath), + saved: await fs.pathExists(this.filePath(accountRoot)), encryptionAvailable: true } } } - async clear(): Promise<{ success: boolean; error?: string }> { + async clear(accountRoot: string): Promise<{ success: boolean; error?: string }> { try { - await fs.remove(this.filePath) + if (accountRoot) await fs.remove(this.filePath(accountRoot)) return { success: true } } catch (error) { return { success: false, error: error instanceof Error ? error.message : String(error) } diff --git a/src/main/export-html-template.ts b/src/main/export-html-template.ts index ae2d5b5..bd7041d 100644 --- a/src/main/export-html-template.ts +++ b/src/main/export-html-template.ts @@ -1,6 +1,6 @@ import type { Message } from '../shared/types' -export const exportStyles = `:root{color-scheme:light;--page:#edf2f0;--panel:#fff;--text:#1d2a25;--muted:#68766f;--border:#d8e2dc;--mine:#d9f0e2;--accent:#176b57}*{box-sizing:border-box}body{margin:0;background:var(--page);color:var(--text);font:14px system-ui,-apple-system,"PingFang SC","Microsoft YaHei",sans-serif}.page{max-width:1240px;height:100vh;margin:auto;padding:22px 28px;display:flex;flex-direction:column}.toolbar{display:flex;align-items:center;justify-content:space-between;gap:20px;background:var(--panel);border:1px solid var(--border);border-radius:18px;padding:18px 24px;box-shadow:0 8px 24px #29483b12}.title{font-size:18px;font-weight:750}.meta{color:var(--muted);margin-left:12px;font-size:13px}.controls{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:0}.controls input,.controls button{border:1px solid var(--border);border-radius:10px;padding:9px 12px;background:#fff;font:inherit}.controls input[type=search]{width:260px}.controls input[type=datetime-local],.controls #jump{display:none}.controls button{background:var(--accent);border-color:var(--accent);color:#fff;cursor:pointer}.count{margin-left:8px;color:var(--muted);font-size:13px}.scroll{margin-top:18px;overflow:auto;flex:1;padding:10px 6px 30px;display:flex;flex-direction:column;align-items:center}.message{display:flex;flex-direction:column;gap:6px;width:min(100%,820px);margin:0 0 22px}.message.hidden{display:none}.message.sent{align-items:flex-end;margin-left:auto}.message.system{align-items:center;width:min(100%,820px)}.message.system .row{justify-content:center}.message.system .avatar{display:none}.message.system .bubble{max-width:92%;padding:5px 10px;border:0;border-radius:5px;background:#e9eeeb;color:var(--muted);font-size:11px;text-align:center;box-shadow:none}.message.system .sender{display:none}.time{color:var(--muted);font-size:11px;margin:0 12px}.row{display:flex;gap:12px;align-items:flex-end}.sent .row{flex-direction:row-reverse}.avatar{width:38px;height:38px;flex:0 0 auto;border-radius:50%;overflow:hidden;background:#dcebe4;display:grid;place-items:center}.avatar img{width:100%;height:100%;object-fit:cover}.bubble{max-width:min(78%,760px);padding:13px 15px;border:1px solid var(--border);border-radius:10px 18px 18px 18px;background:#fff;box-shadow:0 4px 12px #29483b0d}.sent .bubble{background:var(--mine);border-color:#c7e6d4;border-radius:18px 10px 18px 18px}.sender{color:var(--muted);font-size:12px;margin-bottom:5px}.content{line-height:1.7;word-break:break-word;white-space:pre-wrap}.audio-wrap{width:260px;min-width:260px}.audio{display:block;width:260px;height:38px}.quote-reference{margin-top:10px;padding:8px 11px;border-left:3px solid #8eb4a3;background:#f1f6f3;color:var(--muted);display:grid;gap:3px}.quote-reference strong{font-weight:650;color:var(--text)}.quote-reference span{white-space:pre-wrap}.media-image{display:block;max-width:100%;max-height:360px;border-radius:12px;object-fit:contain;background:#eef2f5;cursor:zoom-in}.lightbox{position:fixed;inset:0;display:none;place-items:center;background:#14231ddd;z-index:10;padding:24px;overflow:auto}.lightbox.open{display:grid}.lightbox img{width:min(86vw,980px);max-height:88vh;object-fit:contain;cursor:zoom-in;transform:scale(var(--zoom,1));transform-origin:center;transition:transform .12s ease}` +export const exportStyles = `:root{color-scheme:light;--page:#edf2f0;--panel:#fff;--text:#1d2a25;--muted:#68766f;--border:#d8e2dc;--mine:#d9f0e2;--accent:#176b57}*{box-sizing:border-box}body{margin:0;background:var(--page);color:var(--text);font:14px system-ui,-apple-system,"PingFang SC","Microsoft YaHei",sans-serif}.page{max-width:1240px;height:100vh;margin:auto;padding:22px 28px;display:flex;flex-direction:column}.toolbar{display:flex;align-items:center;justify-content:space-between;gap:20px;background:var(--panel);border:1px solid var(--border);border-radius:18px;padding:18px 24px;box-shadow:0 8px 24px #29483b12}.title{font-size:18px;font-weight:750}.meta{color:var(--muted);margin-left:12px;font-size:13px}.controls{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:0}.controls input,.controls button{border:1px solid var(--border);border-radius:10px;padding:9px 12px;background:#fff;font:inherit}.controls input[type=search]{width:260px}.controls input[type=datetime-local],.controls #jump{display:none}.controls button{background:var(--accent);border-color:var(--accent);color:#fff;cursor:pointer}.count{margin-left:8px;color:var(--muted);font-size:13px}.scroll{margin-top:18px;overflow:auto;flex:1;padding:10px 6px 30px;display:flex;flex-direction:column;align-items:center}.message{display:flex;flex-direction:column;gap:6px;width:min(100%,820px);margin:0 0 22px}.message.hidden{display:none}.message.sent{align-items:flex-end;margin-left:auto}.message.system{align-items:center;width:min(100%,820px)}.message.system .row{justify-content:center}.message.system .avatar{display:none}.message.system .bubble{max-width:92%;padding:5px 10px;border:0;border-radius:5px;background:#e9eeeb;color:var(--muted);font-size:11px;text-align:center;box-shadow:none}.message.system .sender{display:none}.time{color:var(--muted);font-size:11px;margin:0 12px}.row{display:flex;gap:12px;align-items:flex-end}.sent .row{flex-direction:row-reverse}.avatar{width:38px;height:38px;flex:0 0 auto;border-radius:50%;overflow:hidden;background:#dcebe4;display:grid;place-items:center}.avatar img{width:100%;height:100%;object-fit:cover}.bubble{max-width:min(78%,760px);padding:13px 15px;border:1px solid var(--border);border-radius:10px 18px 18px 18px;background:#fff;box-shadow:0 4px 12px #29483b0d}.sent .bubble{background:var(--mine);border-color:#c7e6d4;border-radius:18px 10px 18px 18px}.sender{color:var(--muted);font-size:12px;margin-bottom:5px}.content{line-height:1.7;word-break:break-word;white-space:pre-wrap}.audio-wrap{width:260px;min-width:260px}.audio{display:block;width:260px;height:38px}.media-status{margin-top:8px;padding:6px 8px;border-left:3px solid #b27a18;background:#fff8e8;color:#79530f;font-size:12px;line-height:1.5}.quote-reference{margin-top:10px;padding:8px 11px;border-left:3px solid #8eb4a3;background:#f1f6f3;color:var(--muted);display:grid;gap:3px}.quote-reference strong{font-weight:650;color:var(--text)}.quote-reference span{white-space:pre-wrap}.media-image{display:block;max-width:100%;max-height:360px;border-radius:12px;object-fit:contain;background:#eef2f5;cursor:zoom-in}.lightbox{position:fixed;inset:0;display:none;place-items:center;background:#14231ddd;z-index:10;padding:24px;overflow:auto}.lightbox.open{display:grid}.lightbox img{width:min(86vw,980px);max-height:88vh;object-fit:contain;cursor:zoom-in;transform:scale(var(--zoom,1));transform-origin:center;transition:transform .12s ease}.lightbox-close{position:fixed;top:20px;right:20px;z-index:11;width:42px;height:42px;border:1px solid #ffffff66;border-radius:50%;background:#14231dcc;color:#fff;font-size:30px;line-height:1;cursor:pointer}` const safe = (value: unknown): string => String(value ?? '').replace( /[&<>"']/g, @@ -14,7 +14,10 @@ export function renderExportPage(name: string, messages: Message[]): string { ? `` : safe((m.name || (m.isSender ? '我' : '友')).slice(0, 1)) const audio = m.voiceDataUrl - ? `
` + ? `
` + : '' + const mediaStatus = m.exportMediaError + ? `
${safe(m.exportMediaError)}
` : '' const quote = m.contentData?.type === 'quote' @@ -34,8 +37,8 @@ export function renderExportPage(name: string, messages: Message[]): string { : `
${m.exportAvatarUrl ? `` : avatar}
` const isPat = m.contentData?.type === 'system' && m.contentData.pat const text = m.content || (m.contentData?.type === 'quote' ? m.contentData.title : '') - return `
${safe(m.datetime)}
${isPat ? '' : avatarMarkup}
${isPat ? '' : safe(m.name || (m.isSender ? '我' : '联系人'))}
${media}${audio}${quote}
${safe(text || (!media && !audio && !quote ? `[${m.type}]` : ''))}
` + return `
${safe(m.datetime)}
${isPat ? '' : avatarMarkup}
${isPat ? '' : safe(m.name || (m.isSender ? '我' : '联系人'))}
${media}${audio}${quote}
${safe(text || (!media && !audio && !quote ? `[${m.type}]` : ''))}
${mediaStatus}
` }) .join('') - return `${safe(name)} - 聊天记录
${safe(name)}${messages.length.toLocaleString()} 条消息
${body}
` + return `${safe(name)} - 聊天记录
${safe(name)}${messages.length.toLocaleString()} 条消息
${body}
` } diff --git a/src/main/export-service.ts b/src/main/export-service.ts index ad34e8c..73b0673 100644 --- a/src/main/export-service.ts +++ b/src/main/export-service.ts @@ -16,6 +16,7 @@ import { ImageDecryptService } from './image-decrypt-service' import { ImageKeyConfigService } from './services/image-key-config-service' import { VideoAssetService } from './video-asset-service' import { StickerService } from './sticker-service' +import { getImageExportAttempts } from '../shared/export-media' const jobs = new Set() const safeFilePart = (value: string): string => @@ -26,6 +27,10 @@ const exportStamp = (): string => { return `${date.getFullYear()}${pad(date.getMonth() + 1)}${pad(date.getDate())}_${pad(date.getHours())}${pad(date.getMinutes())}${pad(date.getSeconds())}` } const imageKeys = new ImageKeyConfigService() + +const keepMediaError = (request: ExportRequest, message: Message, error: string): void => { + if (request.keepMissing !== false) message.exportMediaError = error +} function decodeDataUrl(data: string): { extension: string; buffer: Buffer } | null { const match = /^data:([^;]+);base64,(.+)$/s.exec(data) if (!match) return null @@ -105,11 +110,20 @@ function render(format: ExportRequest['format'], messages: Message[], name: stri if (format === 'json') return JSON.stringify({ name, exportedAt: new Date().toISOString(), messages }, null, 2) if (format === 'markdown') - return `# ${name}\n\n${messages.map((m) => `**${m.name || (m.isSender ? '我' : '联系人')}** · ${m.datetime}\n\n${m.content || `[${m.type}]`}\n`).join('\n')}` + return `# ${name}\n\n${messages.map((m) => `**${m.name || (m.isSender ? '我' : '联系人')}** · ${m.datetime}\n\n${m.content || `[${m.type}]`}${m.exportMediaUrl || m.voiceDataUrl || m.exportMediaError ? `\n\n媒体:${m.exportMediaUrl || m.voiceDataUrl || m.exportMediaError}` : ''}\n`).join('\n')}` return [ - '时间,发送者,类型,内容', + '时间,发送者,类型,内容,媒体路径,媒体状态', ...messages.map((m) => - [m.datetime, m.name || (m.isSender ? '我' : '联系人'), m.type, m.content].map(csv).join(',') + [ + m.datetime, + m.name || (m.isSender ? '我' : '联系人'), + m.type, + m.content, + m.exportMediaUrl || m.voiceDataUrl || '', + m.exportMediaError || '' + ] + .map(csv) + .join(',') ) ].join('\n') } @@ -126,9 +140,19 @@ export async function runExport(request: ExportRequest, win: BrowserWindow): Pro .listMessages(request.userMd5, request.startTime, request.endTime) .filter((m) => request.kinds.includes(kindOf(m))) for (const message of messages) { + message.exportMediaUrl = undefined + message.exportMediaType = undefined + message.exportMediaError = undefined + message.voiceDataUrl = undefined message.exportShowAvatar = request.includeAvatars !== false const mappedName = message.senderId ? request.nameMap?.[message.senderId] : undefined if (mappedName) message.name = mappedName + if ( + request.format !== 'html' && + ['image', 'video', 'voice', 'sticker'].includes(kindOf(message)) + ) { + message.exportMediaError = '当前导出格式记录媒体状态,但不复制媒体文件' + } } send({ jobId: request.jobId, phase: 'reading', processed: 10, total: 100, percent: 10 }) if (!jobs.has(request.jobId)) { @@ -181,25 +205,46 @@ export async function runExport(request: ExportRequest, win: BrowserWindow): Pro : null if (voiceService) { for (const [index, message] of messages.entries()) { - if ( - kindOf(message) !== 'voice' || - !message.sessionId || - !message.localId || - !message.createTime - ) + if (kindOf(message) !== 'voice') continue + if (!message.sessionId || message.localId == null || !message.createTime) { + keepMediaError(request, message, '语音标识不完整,无法定位本地语音') continue - const voice = await voiceService.resolveVoice( - message.sessionId, - message.localId, - message.createTime, - message.serverId - ) - if (!voice.success || !voice.data) continue - const voiceName = `voice_${index + 1}_${message.localId}.wav` - const audioBuffer = Buffer.from(voice.data, 'base64') - await fs.writeFile(join(outputDir, 'voices', voiceName), audioBuffer) - message.voiceDataUrl = `voices/${voiceName}` - message.voiceDuration = Math.max(1, Math.round(audioBuffer.length / (24000 * 2))) + } + try { + const voice = await voiceService.resolveVoice( + message.sessionId, + message.localId, + message.createTime, + message.serverId + ) + if (!voice.success || !voice.data) { + const detail = voice.error || '未知原因' + const reason = /未找到|不存在|获取语音数据失败/.test(detail) + ? `语音文件缺失:${detail}` + : /Silk|解码|数据为空/.test(detail) + ? `语音解析失败:${detail}` + : `语音格式不支持或读取失败:${detail}` + keepMediaError(request, message, reason) + continue + } + const voiceName = `voice_${index + 1}_${message.localId}.wav` + const audioBuffer = Buffer.from(voice.data, 'base64') + await fs.writeFile(join(outputDir, 'voices', voiceName), audioBuffer) + message.voiceDataUrl = `voices/${voiceName}` + message.voiceDuration = Math.max(1, Math.round(audioBuffer.length / (24000 * 2))) + } catch (error) { + keepMediaError( + request, + message, + `语音文件写入失败:${error instanceof Error ? error.message : String(error)}` + ) + } + } + } else if (request.includeMedia) { + for (const message of messages) { + if (kindOf(message) === 'voice') { + keepMediaError(request, message, '数据库未连接,无法读取本地语音') + } } } for (const [index, message] of messages.entries()) { @@ -228,34 +273,78 @@ export async function runExport(request: ExportRequest, win: BrowserWindow): Pro }) continue } - if (message.contentData.type === 'image' && imageService) { - const file = imageService.findImageFile( - message.contentData.md5, - message.contentData.datName, - { allowThumbnail: true } - ) - const decrypted = file ? imageService.decryptImageToBase64WithFallback(file, true) : null - const decoded = decrypted ? decodeDataUrl(decrypted.data) : null - if (decoded) { - const name = `image_${index + 1}.${decoded.extension}` - await fs.writeFile(join(outputDir, 'media', name), decoded.buffer) - message.exportMediaUrl = `media/${name}` - message.exportMediaType = 'image' + if (message.contentData.type === 'image') { + if (!imageService) { + keepMediaError(request, message, '未配置图片解密密钥,无法导出图片') + } else { + let fileFound = false + let decryptedImage: { data: string; filePath: string } | null = null + let usedFallback = false + for (const attempt of getImageExportAttempts(request)) { + const file = imageService.findImageFile( + message.contentData.md5, + message.contentData.datName, + { + allowThumbnail: attempt.allowThumbnail, + preferThumbnail: attempt.preferThumbnail, + sessionId: message.sessionId + } + ) + if (!file) continue + fileFound = true + const decrypted = imageService.decryptImageToBase64WithFallback( + file, + attempt.allowThumbnail + ) + if (!decrypted) continue + decryptedImage = decrypted + usedFallback = attempt.fallback || imageService.isThumbnailFile(decrypted.filePath) + break + } + const decoded = decryptedImage ? decodeDataUrl(decryptedImage.data) : null + if (decoded) { + const name = `image_${index + 1}.${decoded.extension}` + await fs.writeFile(join(outputDir, 'media', name), decoded.buffer) + message.exportMediaUrl = `media/${name}` + message.exportMediaType = 'image' + if (usedFallback) { + keepMediaError(request, message, '原图不可用,已降级使用缩略图') + } + } else if (!fileFound) { + keepMediaError( + request, + message, + request.fallbackThumbnail === false + ? '原图文件缺失,未启用缩略图降级' + : '原图和缩略图文件均缺失' + ) + } else { + keepMediaError(request, message, '图片解析失败或当前格式不支持') + } } - } else if (message.contentData.type === 'video' && videoService) { + } else if (message.contentData.type === 'video') { const hashes = [ message.contentData.md5, message.contentData.newMd5, message.contentData.rawMd5 ].filter((value): value is string => Boolean(value)) - const resolved = videoService.resolve(hashes) - const token = resolved.url?.split('/').pop() - const source = token ? videoService.pathForToken(token) : undefined - if (source) { - const name = `video_${index + 1}.mp4` - await fs.copyFile(source, join(outputDir, 'media', name)) - message.exportMediaUrl = `media/${name}` - message.exportMediaType = 'video' + if (!videoService) { + keepMediaError(request, message, '数据库未连接,无法定位本地视频') + } else if (hashes.length === 0) { + keepMediaError(request, message, '视频标识不完整,无法定位本地视频') + } else { + const resolved = videoService.resolve(hashes) + const source = resolved.url ? videoService.pathForUrl(resolved.url) : undefined + if (!resolved.success || !source) { + keepMediaError(request, message, resolved.error || '视频文件缺失或已移动') + } else if (extname(source).toLowerCase() !== '.mp4') { + keepMediaError(request, message, '视频格式不支持,仅支持本地 MP4 文件') + } else { + const name = `video_${index + 1}.mp4` + await fs.copyFile(source, join(outputDir, 'media', name)) + message.exportMediaUrl = `media/${name}` + message.exportMediaType = 'video' + } } } else if (message.contentData.type === 'sticker' && stickerService) { const stickerSource = message.contentData.url || message.contentData.thumbUrl @@ -270,6 +359,8 @@ export async function runExport(request: ExportRequest, win: BrowserWindow): Pro await fs.writeFile(join(outputDir, 'media', name), decoded.buffer) message.exportMediaUrl = `media/${name}` message.exportMediaType = 'sticker' + } else { + keepMediaError(request, message, result.error || '表情资源缺失或下载失败') } } send({ diff --git a/src/main/index.ts b/src/main/index.ts index fa904c6..c6fb1e1 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -58,13 +58,25 @@ import * as chat from './services/chat-service' import { apiServer } from './http-server' import { skillResourceService } from './services/skill-resource-service' import { testLocalApiRequest } from './services/local-api-test-service' -import { isWindowsWechatRunning } from './services/wechat-process-status' +import { isWechatRunning } from './services/wechat-process-status' import { inspectImageDecryptionStatus, testImageDecryption } from './services/image-decryption-status-service' import type { SaveImageKeyRequest, TestImageDecryptionRequest } from '../shared/image-decryption' -import { loadSettings, saveSettings, getSettingsPath, AppSettings } from './services/settings-store' +import { + loadSettings, + saveSettings, + getSettingsPath, + AppSettings, + validateDbRoot +} from './services/settings-store' +import { + detectDataStructureVersion, + detectWechatVersion, + getOsVersionLabel +} from './services/connection-diagnostics' +import { buildSafeDiagnosticSummary } from '../shared/connection-diagnostics' import { flushBootstrapCacheWritesSync, getBootstrapCache, @@ -88,6 +100,7 @@ import { configureRecallArchive, RecallArchiveMonitor } from './services/recall- import { VideoAssetService } from './video-asset-service' import { cancelExport, revealExport, runExport } from './export-service' import type { ExportRequest } from '../shared/export' +import { discoverAccounts } from './services/account-discovery' // electron-vite can close the child's stdout/stderr after spawning Electron. // Plain console.error then throws EPIPE on a closed pipe and crashes the IPC @@ -479,7 +492,7 @@ app.whenReady().then(async () => { return clearCache(scope) }) - ipcMain.handle('db:init', async (_, key: string) => { + ipcMain.handle('db:init', async (_, key: string, accountRoot?: string) => { if (dbInitInFlight) return dbInitInFlight dbInitInFlight = (async () => { @@ -489,17 +502,35 @@ app.whenReady().then(async () => { const trimmedKey = String(key || '').trim() console.log(`db:init build=${BUILD_MARK} keyLength=${trimmedKey.length}`) const settings = loadSettings() + const selectedRoot = String(accountRoot || settings.dbRoot || '').trim() + const rootValidation = validateDbRoot(selectedRoot) + if (!rootValidation.valid) { + return { + success: false, + code: 'ROOT_UNAVAILABLE', + error: rootValidation.error, + monitoring: false + } + } + if (!existsSync(join(selectedRoot, 'db_storage'))) { + return { + success: false, + code: 'ACCOUNT_SELECTION_REQUIRED', + error: '请先明确选择一个微信账号', + monitoring: false + } + } if ( chat.isReady() && chat.getCurrentKey().replace(/^0x/i, '').trim() === trimmedKey.replace(/^0x/i, '') && - (!settings.dbRoot || chat.getCurrentAccountRoot() === settings.dbRoot) + chat.getCurrentAccountRoot() === selectedRoot ) { console.log('[WCDB4] db:init reuse current connection') return { success: true, monitoring: true } } - const nextWechatDb = await WechatDb.create(key, settings.dbRoot) + const nextWechatDb = await WechatDb.create(key, selectedRoot) const resolvedRoot = nextWechatDb.getWcdb4Client().getAccountRoot() - if (resolvedRoot && resolvedRoot !== settings.dbRoot) { + if (resolvedRoot) { // 同步更新 imageKeyRoot,避免自动获取图片密钥时扫描到错误目录 saveSettings({ ...settings, @@ -543,19 +574,43 @@ app.whenReady().then(async () => { return dbInitInFlight }) - ipcMain.handle('key:getSavedDbKey', async () => databaseKeyStore.load()) + ipcMain.handle('accounts:discover', (_, inputPath: string) => + discoverAccounts(inputPath, databaseKeyStore, chat.getCurrentAccountRoot()) + ) + + ipcMain.handle('key:getSavedDbKey', async (_, accountRoot: string) => { + const selectedRoot = String(accountRoot || '').trim() + const scoped = await databaseKeyStore.load(selectedRoot) + if (scoped.saved || !selectedRoot) return scoped + const legacy = await databaseKeyStore.loadLegacy() + if (!legacy.success || !legacy.key) return scoped + const validation = await chat.testConnection(legacy.key, selectedRoot) + if (!validation.success) return scoped + const migrated = await databaseKeyStore.save(selectedRoot, legacy.key) + if (migrated.success) await databaseKeyStore.clearLegacy() + return migrated + }) ipcMain.handle('key:getEnvironment', async () => { - const storage = await databaseKeyStore.getStatus() + const storage = await databaseKeyStore.getStatus( + chat.getCurrentAccountRoot() || loadSettings().dbRoot + ) const self = chat.getSelfAccountInfo() - return { + const settings = loadSettings() + const environment = { platform: process.platform, + osVersion: getOsVersionLabel(), + appVersion: `v${app.getVersion()}`, + wechatVersion: await detectWechatVersion(), + dataStructureVersion: detectDataStructureVersion(settings.dbRoot), + dataDirectoryDetected: validateDbRoot(settings.dbRoot).valid, autoDetectSupported: process.platform === 'win32', - wechatRunning: await isWindowsWechatRunning(), + wechatRunning: await isWechatRunning(), accountIdentified: Boolean(self?.wxid), dbConnected: chat.isReady(), encryptionAvailable: storage.encryptionAvailable } + return { ...environment, diagnosticSummary: buildSafeDiagnosticSummary(environment) } }) ipcMain.handle('key:readClipboardDbKey', () => { @@ -566,36 +621,47 @@ app.whenReady().then(async () => { } }) - ipcMain.handle('key:pasteAndSaveDbKey', async () => { + ipcMain.handle('key:pasteAndSaveDbKey', async (_, accountRoot: string) => { const clipboardKey = clipboard.readText().trim() - return databaseKeyStore.save(clipboardKey) + return databaseKeyStore.save(String(accountRoot || ''), clipboardKey) }) - ipcMain.handle('key:saveDbKey', async (_, key: string) => - databaseKeyStore.save(String(key || '')) + ipcMain.handle('key:saveDbKey', async (_, accountRoot: string, key: string) => + databaseKeyStore.save(String(accountRoot || ''), String(key || '')) ) - ipcMain.handle('key:clearSavedDbKey', async () => databaseKeyStore.clear()) + ipcMain.handle('key:clearSavedDbKey', async (_, accountRoot: string) => + databaseKeyStore.clear(String(accountRoot || '')) + ) - ipcMain.handle('key:autoGetDbKey', async (event, options?: { save?: boolean }) => { - const onStatus = (message: string): void => { - if (!event.sender.isDestroyed()) event.sender.send('key:dbKeyStatus', { message }) + ipcMain.handle( + 'key:autoGetDbKey', + async (event, accountRoot: string, options?: { save?: boolean }) => { + const onStatus = (message: string): void => { + if (!event.sender.isDestroyed()) event.sender.send('key:dbKeyStatus', { message }) + } + const result = + process.platform === 'win32' + ? await keyServiceWin.autoGetDbKey(60_000, onStatus) + : await keyServiceMac.autoGetDbKey(onStatus) + if (!result.success || !result.key) return result + + const selectedRoot = String(accountRoot || '').trim() + if (!selectedRoot) return { success: false, error: '请先选择微信账号' } + const validation = await chat.testConnection(result.key, selectedRoot) + if (!validation.success) { + return { ...result, success: false, key: undefined, error: '获取到的密钥不属于所选账号' } + } + if (options?.save === false) return result + + const saved = await databaseKeyStore.save(selectedRoot, result.key) + return { + ...result, + saved: saved.success, + warning: saved.success ? undefined : saved.error + } } - const result = - process.platform === 'win32' - ? await keyServiceWin.autoGetDbKey(60_000, onStatus) - : await keyServiceMac.autoGetDbKey(onStatus) - if (!result.success || !result.key) return result - - if (options?.save === false) return result - - const saved = await databaseKeyStore.save(result.key) - return { - ...result, - saved: saved.success, - warning: saved.success ? undefined : saved.error - } - }) + ) ipcMain.handle('key:autoGetImageKey', async (event, options?: { save?: boolean }) => { const settings = loadSettings() diff --git a/src/main/services/account-discovery.ts b/src/main/services/account-discovery.ts new file mode 100644 index 0000000..cf2e4b8 --- /dev/null +++ b/src/main/services/account-discovery.ts @@ -0,0 +1,58 @@ +import crypto from 'crypto' +import fs from 'fs-extra' +import path from 'path' +import type { AccountDiscoveryResult, WechatAccountCandidate } from '../../shared/database-key' +import { DatabaseKeyStore } from '../database-key-store' +import { getBootstrapCache } from './bootstrap-cache' +import { validateDbRoot } from './settings-store' + +function accountId(accountRoot: string): string { + return crypto.createHash('sha256').update(path.resolve(accountRoot).toLowerCase()).digest('hex') +} + +export async function discoverAccounts( + inputPath: string, + keyStore: DatabaseKeyStore, + currentAccountRoot?: string +): Promise { + const validation = validateDbRoot(inputPath) + if (!validation.valid) return { success: false, accounts: [], error: validation.error } + + const normalizedInput = path.resolve(inputPath) + const isAccount = await fs.pathExists(path.join(normalizedInput, 'db_storage')) + const roots = isAccount + ? [normalizedInput] + : (await fs.readdir(normalizedInput, { withFileTypes: true })) + .filter((entry) => entry.isDirectory()) + .map((entry) => path.join(normalizedInput, entry.name)) + .filter((candidate) => fs.existsSync(path.join(candidate, 'db_storage'))) + + const accounts: WechatAccountCandidate[] = await Promise.all( + roots.map(async (accountRoot) => { + const cached = getBootstrapCache(accountRoot)?.self + return { + id: accountId(accountRoot), + accountRoot, + directoryName: path.basename(accountRoot), + wxid: cached?.wxid, + nickname: cached?.nickname, + avatar: cached?.avatar, + hasSavedDbKey: (await keyStore.getStatus(accountRoot)).saved, + loginStatus: currentAccountRoot + ? path.resolve(currentAccountRoot).toLowerCase() === + path.resolve(accountRoot).toLowerCase() + ? 'current' + : 'other' + : 'unknown', + selectedByInput: isAccount + } + }) + ) + + return { + success: true, + inputKind: isAccount ? 'account' : 'root', + accounts, + preselectedAccountId: isAccount ? accounts[0]?.id : undefined + } +} diff --git a/src/main/services/connection-diagnostics.ts b/src/main/services/connection-diagnostics.ts new file mode 100644 index 0000000..9bd1a9a --- /dev/null +++ b/src/main/services/connection-diagnostics.ts @@ -0,0 +1,69 @@ +import { execFile } from 'child_process' +import fs from 'fs-extra' +import os from 'os' +import path from 'path' +import { promisify } from 'util' +import { isUsableDbRoot } from './settings-store' + +const execFileAsync = promisify(execFile) + +const platformLabel = (): string => { + if (process.platform === 'win32') return `Windows ${os.release()} (${process.arch})` + if (process.platform === 'darwin') return `macOS ${os.release()} (${process.arch})` + return `${process.platform} ${os.release()} (${process.arch})` +} + +async function detectWindowsWechatVersion(): Promise { + const script = [ + '$process = Get-Process Weixin,WeChat -ErrorAction SilentlyContinue | Where-Object Path | Select-Object -First 1', + '$candidate = if ($process) { $process.Path } else {', + " @($env:ProgramFiles, ${env:ProgramFiles(x86)}) | Where-Object { $_ } | ForEach-Object { Join-Path $_ 'Tencent\\WeChat\\WeChat.exe' } | Where-Object { Test-Path $_ } | Select-Object -First 1", + '}', + 'if ($candidate) { (Get-Item -LiteralPath $candidate).VersionInfo.ProductVersion }' + ].join('; ') + try { + const { stdout } = await execFileAsync( + 'powershell.exe', + ['-NoProfile', '-NonInteractive', '-Command', script], + { timeout: 3000, windowsHide: true } + ) + return stdout.trim() || '未检测到' + } catch { + return '未检测到' + } +} + +async function detectMacWechatVersion(): Promise { + const candidates = [ + '/Applications/WeChat.app/Contents/Info', + path.join(os.homedir(), 'Applications/WeChat.app/Contents/Info') + ] + for (const candidate of candidates) { + if (!fs.existsSync(`${candidate}.plist`)) continue + try { + const { stdout } = await execFileAsync( + '/usr/bin/defaults', + ['read', candidate, 'CFBundleShortVersionString'], + { timeout: 3000 } + ) + if (stdout.trim()) return stdout.trim() + } catch { + // Continue to the next known installation location. + } + } + return '未检测到' +} + +export async function detectWechatVersion(): Promise { + if (process.platform === 'win32') return detectWindowsWechatVersion() + if (process.platform === 'darwin') return detectMacWechatVersion() + return '未检测到' +} + +export function detectDataStructureVersion(dbRoot: string): string { + return isUsableDbRoot(dbRoot) ? '微信 4.x(WCDB)' : '未检测到' +} + +export function getOsVersionLabel(): string { + return platformLabel() +} diff --git a/src/main/services/settings-store.ts b/src/main/services/settings-store.ts index 818f349..dbe4969 100644 --- a/src/main/services/settings-store.ts +++ b/src/main/services/settings-store.ts @@ -86,7 +86,7 @@ function unique(values: string[]): string[] { return Array.from(new Set(values)) } -function isUsableDbRoot(candidate?: string): boolean { +export function isUsableDbRoot(candidate?: string): boolean { if (!candidate || !fs.existsSync(candidate)) return false if (fs.existsSync(path.join(candidate, 'db_storage'))) return true try { @@ -98,6 +98,21 @@ function isUsableDbRoot(candidate?: string): boolean { } } +export function validateDbRoot(candidate?: string): { valid: boolean; error?: string } { + const root = String(candidate || '').trim() + if (!root) return { valid: false, error: '微信数据目录为空,请重新选择目录' } + if (!fs.existsSync(root)) { + return { valid: false, error: '微信数据目录不存在,请检查路径或重新选择目录' } + } + if (!isUsableDbRoot(root)) { + return { + valid: false, + error: '所选目录中未找到微信 4.x 数据库(db_storage),请选择 xwechat_files 或账号目录' + } + } + return { valid: true } +} + const defaultDbRoot = getDefaultDbRoot() const DEFAULT_SETTINGS: AppSettings = { diff --git a/src/main/wcdb4-client.ts b/src/main/wcdb4-client.ts index c8ce8a5..ea2288a 100644 --- a/src/main/wcdb4-client.ts +++ b/src/main/wcdb4-client.ts @@ -938,9 +938,27 @@ export class Wcdb4Client { ): Promise { const startedAt = Date.now() const maxRows = this.normalizeMessageLimit(options.limit) - const messages = await this.getMessagesByCursorAsync(username, startTime, endTime, maxRows) + let cursorMessages: Wcdb4Message[] = [] + try { + cursorMessages = await this.getMessagesByCursorAsync(username, startTime, endTime, maxRows) + } catch (error) { + console.warn(`[WCDB4] async cursor messages failed username=${username}:`, error) + } + + if (endTime && (!this.wcdbGetMessageTableStats || !this.wcdbExecQuery)) { + throw new Error('当前数据服务无法检查历史消息分片,请更新应用或核对微信数据版本') + } + + // Older pages may live in message shards that the native cursor does not + // enumerate. A bounded query must inspect all matching stores so history + // cannot silently stop at a shard boundary. + let tableMessages: Wcdb4Message[] = [] + if (endTime || cursorMessages.length === 0) { + tableMessages = await this.getMessagesByTableScanAsync(username, startTime, endTime, maxRows) + } + const messages = this.mergeMessageRows(cursorMessages, tableMessages, maxRows) console.log( - `[WCDB4] getMessages async username=${username} rows=${messages.length} cost=${Date.now() - startedAt}ms` + `[WCDB4] getMessages async username=${username} rows=${messages.length} cursor=${cursorMessages.length} tables=${tableMessages.length} cost=${Date.now() - startedAt}ms` ) return messages } @@ -998,6 +1016,71 @@ export class Wcdb4Client { return this.finalizeMessages(username, allRows, startTime, endTime, limit) } + private async getMessagesByTableScanAsync( + username: string, + startTime?: number, + endTime?: number, + limit?: number + ): Promise { + if (!this.wcdbGetMessageTableStats || !this.wcdbExecQuery) return [] + + let tables: Wcdb4MessageStore[] = [] + try { + const rows = await this.callJsonAsync[]>( + this.wcdbGetMessageTableStats as unknown as KoffiAsyncFunction, + username + ) + tables = (Array.isArray(rows) ? rows : []) + .map((row) => ({ + tableName: this.pickString(row, ['table_name', 'tableName', 'name']), + dbPath: this.pickString(row, ['db_path', 'dbPath', 'path']) + })) + .filter((row) => row.tableName && row.dbPath) + } catch (error) { + console.warn(`[WCDB4] async message table stats failed username=${username}:`, error) + throw new Error( + `无法读取历史消息分片信息:${error instanceof Error ? error.message : String(error)}` + ) + } + + const begin = this.normalizeTimestamp(startTime || 0) + const end = this.normalizeTimestamp(endTime || 0) + const where = [ + begin > 0 ? `"create_time" >= ${begin}` : '', + end > 0 ? `"create_time" <= ${end}` : '' + ].filter(Boolean) + const whereSql = where.length ? ` WHERE ${where.join(' AND ')}` : '' + const rowLimit = limit || 5000 + const order = limit ? 'DESC' : 'ASC' + + const allRows: Record[] = [] + let successfulTables = 0 + for (const table of tables) { + try { + const sql = `SELECT * FROM ${this.quoteSqlIdentifier(table.tableName)}${whereSql} ORDER BY "create_time" ${order} LIMIT ${rowLimit}` + const rows = await this.callJsonAsync[]>( + this.wcdbExecQuery as unknown as KoffiAsyncFunction, + 'message', + table.dbPath, + sql + ) + successfulTables += 1 + if (Array.isArray(rows)) allRows.push(...rows) + } catch (error) { + console.warn( + `[WCDB4] async message table scan failed username=${username} db=${table.dbPath} table=${table.tableName}:`, + error + ) + } + } + + if (tables.length > 0 && successfulTables === 0) { + throw new Error('历史消息分片均读取失败,请检查数据目录或微信数据版本') + } + + return this.finalizeMessages(username, allRows, startTime, endTime, limit) + } + installRecallJournal(usernames: string[]): { installed: number; failed: number } { const stores = new Map() for (const username of this.uniq(usernames)) { diff --git a/src/preload/index.d.ts b/src/preload/index.d.ts index e8988c6..bcc3f49 100644 --- a/src/preload/index.d.ts +++ b/src/preload/index.d.ts @@ -11,7 +11,8 @@ import { import type { DatabaseKeyEnvironment, DatabaseKeyStorageResult, - DatabaseKeyValidationResult + DatabaseKeyValidationResult, + AccountDiscoveryResult } from '../shared/database-key' import type { ImageDecoderSelectionResult, @@ -115,8 +116,10 @@ declare global { getCacheSummary: () => Promise clearCache: (scope: 'bootstrap' | 'electron' | 'all') => Promise initDb: ( - key: string + key: string, + accountRoot: string ) => Promise + discoverAccounts: (inputPath: string) => Promise getBootstrapCache: () => Promise<{ self?: { wxid: string; nickname: string; avatar?: string; accountRoot: string } contacts: Contact[] @@ -239,14 +242,17 @@ declare global { ) => Promise deleteGeneratedReport: (reportId: string) => Promise revealGroupReport: (filePath: string) => Promise<{ success: boolean; error?: string }> - getSavedDbKey: () => Promise + getSavedDbKey: (accountRoot: string) => Promise getDatabaseKeyEnvironment: () => Promise readDatabaseKeyClipboard: () => Promise<{ success: boolean value?: string error?: string }> - autoGetDbKey: (options?: { save?: boolean }) => Promise<{ + autoGetDbKey: ( + accountRoot: string, + options?: { save?: boolean } + ) => Promise<{ success: boolean key?: string error?: string @@ -290,9 +296,11 @@ declare global { request: TestImageDecryptionRequest ) => Promise clearImageKeyConfig: () => Promise<{ success: boolean; error?: string }> - pasteAndSaveDbKey: () => Promise<{ success: boolean; key?: string; error?: string }> - saveDbKey: (key: string) => Promise - clearSavedDbKey: () => Promise<{ success: boolean; error?: string }> + pasteAndSaveDbKey: ( + accountRoot: string + ) => Promise<{ success: boolean; key?: string; error?: string }> + saveDbKey: (accountRoot: string, key: string) => Promise + clearSavedDbKey: (accountRoot: string) => Promise<{ success: boolean; error?: string }> onWcdbChange: (callback: (payload: { type: string; json: string }) => void) => () => void onDbKeyStatus: (callback: (payload: { message: string }) => void) => () => void onImageKeyStatus: (callback: (payload: { message: string }) => void) => () => void diff --git a/src/preload/index.ts b/src/preload/index.ts index 77c927d..322013f 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -21,6 +21,7 @@ import type { AppUpdateState } from '../shared/app-update' import type { CacheSummary } from '../shared/cache' import type { ExportRequest, ExportJobProgress } from '../shared/export' import type { ImageDecoderSelectionResult, ImageDecoderStatus } from '../shared/image-decryption' +import type { AccountDiscoveryResult } from '../shared/database-key' // 渲染器的自定义 API const api = { @@ -40,7 +41,9 @@ const api = { getCacheSummary: (): Promise => ipcRenderer.invoke('cache:getSummary'), clearCache: (scope: 'bootstrap' | 'electron' | 'all'): Promise => ipcRenderer.invoke('cache:clear', scope), - initDb: (key: string) => ipcRenderer.invoke('db:init', key), + initDb: (key: string, accountRoot: string) => ipcRenderer.invoke('db:init', key, accountRoot), + discoverAccounts: (inputPath: string): Promise => + ipcRenderer.invoke('accounts:discover', inputPath), getBootstrapCache: () => ipcRenderer.invoke('db:getBootstrapCache'), getStartupCache: () => ipcRenderer.invoke('db:getStartupCache'), getContacts: (filter?: string) => ipcRenderer.invoke('db:getContacts', filter), @@ -98,10 +101,11 @@ const api = { deleteGeneratedReport: (reportId: string) => ipcRenderer.invoke('report:deleteGenerated', reportId), revealGroupReport: (filePath: string) => ipcRenderer.invoke('report:reveal', filePath), - getSavedDbKey: () => ipcRenderer.invoke('key:getSavedDbKey'), + getSavedDbKey: (accountRoot: string) => ipcRenderer.invoke('key:getSavedDbKey', accountRoot), getDatabaseKeyEnvironment: () => ipcRenderer.invoke('key:getEnvironment'), readDatabaseKeyClipboard: () => ipcRenderer.invoke('key:readClipboardDbKey'), - autoGetDbKey: (options?: { save?: boolean }) => ipcRenderer.invoke('key:autoGetDbKey', options), + autoGetDbKey: (accountRoot: string, options?: { save?: boolean }) => + ipcRenderer.invoke('key:autoGetDbKey', accountRoot, options), autoGetImageKey: (options?: { save?: boolean }) => ipcRenderer.invoke('key:autoGetImageKey', options), getImageKeyConfig: () => ipcRenderer.invoke('image:getConfig'), @@ -115,9 +119,11 @@ const api = { saveImageKeyConfig: (request) => ipcRenderer.invoke('image:saveConfig', request), testImageDecryption: (request) => ipcRenderer.invoke('image:testConfig', request), clearImageKeyConfig: () => ipcRenderer.invoke('image:clearConfig'), - pasteAndSaveDbKey: () => ipcRenderer.invoke('key:pasteAndSaveDbKey'), - saveDbKey: (key: string) => ipcRenderer.invoke('key:saveDbKey', key), - clearSavedDbKey: () => ipcRenderer.invoke('key:clearSavedDbKey'), + pasteAndSaveDbKey: (accountRoot: string) => + ipcRenderer.invoke('key:pasteAndSaveDbKey', accountRoot), + saveDbKey: (accountRoot: string, key: string) => + ipcRenderer.invoke('key:saveDbKey', accountRoot, key), + clearSavedDbKey: (accountRoot: string) => ipcRenderer.invoke('key:clearSavedDbKey', accountRoot), onWcdbChange: (callback: (payload: { type: string; json: string }) => void) => { const listener = ( _event: Electron.IpcRendererEvent, diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index f2a35ae..df82b25 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -24,6 +24,7 @@ import { FirstUseWelcome } from './components/FirstUseWelcome' import { ExportWorkspace } from './components/export/ExportWorkspace' import { AISearchWorkspace } from './components/search/AISearchWorkspace' import type { ExportJobProgress, ExportRequest, ExportTaskRecord } from '../../shared/export' +import type { DatabaseKeyEnvironment, WechatAccountCandidate } from '../../shared/database-key' import { getMessageIdentity, mergeMessagePages, @@ -32,6 +33,23 @@ import { const SIDEBAR_MIN_WIDTH = 260 const SIDEBAR_MAX_WIDTH = 380 +const DATABASE_CONNECT_TIMEOUT_MS = 30_000 + +function withTimeout(promise: Promise, timeoutMs: number, message: string): Promise { + return new Promise((resolve, reject) => { + const timer = window.setTimeout(() => reject(new Error(message)), timeoutMs) + promise.then( + (value) => { + window.clearTimeout(timer) + resolve(value) + }, + (error) => { + window.clearTimeout(timer) + reject(error) + } + ) + }) +} function getDevelopmentDatabaseKey(): string { if (!import.meta.env.DEV) return '' @@ -202,6 +220,7 @@ function App(): React.ReactElement { const [selectedContact, setSelectedContact] = useState(null) const [messages, setMessages] = useState([]) const [isMessagesLoading, setIsMessagesLoading] = useState(false) + const [messageHistoryStatus, setMessageHistoryStatus] = useState<'idle' | 'end' | 'error'>('idle') const [filteredContacts, setFilteredContacts] = useState([]) const [contentFilter, setContentFilter] = useState('') const [isFetchingDbKey, setIsFetchingDbKey] = useState(false) @@ -209,10 +228,16 @@ function App(): React.ReactElement { const [dbKeyStatusKind, setDbKeyStatusKind] = useState<'normal' | 'success' | 'error'>('normal') const [showDbKey, setShowDbKey] = useState(false) const [dbRootInput, setDbRootInput] = useState('') + const [discoveredAccounts, setDiscoveredAccounts] = useState([]) + const [selectedAccountId, setSelectedAccountId] = useState('') + const selectedAccount = discoveredAccounts.find((account) => account.id === selectedAccountId) const [showMacKeyFaq, setShowMacKeyFaq] = useState(false) const [databaseConnectionMode, setDatabaseConnectionMode] = useState( getDevelopmentDatabaseKey() ? 'manual' : 'automatic' ) + const [connectionGuideStep, setConnectionGuideStep] = useState<1 | 2 | 3 | 4 | 5 | 6>(1) + const [databaseEnvironment, setDatabaseEnvironment] = useState() + const connectionOperationRef = React.useRef(0) const [activePage, setActivePage] = useState('archive') const [archiveJumpTime, setArchiveJumpTime] = useState(null) const [settingsCategory, setSettingsCategory] = useState('account-database') @@ -278,6 +303,34 @@ function App(): React.ReactElement { }) }) }, []) + + const refreshConnectionEnvironment = React.useCallback(async (): Promise => { + const root = dbRootInput.trim() + try { + if (root) { + const discovery = await window.api.discoverAccounts(root) + if (!discovery.success) throw new Error(discovery.error || '账号目录识别失败') + setDiscoveredAccounts(discovery.accounts) + setSelectedAccountId(discovery.preselectedAccountId || '') + } + const environment = await window.api.getDatabaseKeyEnvironment() + setDatabaseEnvironment(environment) + setDbKeyStatus('环境检查已更新') + setDbKeyStatusKind('normal') + } catch (error) { + setDbKeyStatus( + error instanceof Error ? `环境检查失败:${error.message}` : '环境检查失败,请重试' + ) + setDbKeyStatusKind('error') + } + }, [dbRootInput]) + + React.useEffect(() => { + void window.api + .getDatabaseKeyEnvironment() + .then(setDatabaseEnvironment) + .catch(() => undefined) + }, []) React.useEffect(() => { const loadAIConfig = async (): Promise => { try { @@ -533,13 +586,26 @@ function App(): React.ReactElement { if (active && settingsResult.settings.dbRoot) { setDbRootInput(settingsResult.settings.dbRoot) } + const discovery = settingsResult.settings.dbRoot + ? await window.api.discoverAccounts(settingsResult.settings.dbRoot) + : { success: false, accounts: [] } + if (active && discovery.success) { + setDiscoveredAccounts(discovery.accounts) + setSelectedAccountId(discovery.preselectedAccountId || '') + } + const startupAccountRoot = discovery.success + ? discovery.accounts.find((account) => account.id === discovery.preselectedAccountId) + ?.accountRoot + : undefined const autoLoginEnabled = settingsResult.settings.autoLogin // 开发环境允许使用 VITE_DB_KEY;生产安装包只能读取目标电脑自己的 safeStorage。 const envKey = getDevelopmentDatabaseKey() // 生产环境以及未配置开发密钥时,读取上一次保存到 safeStorage 的密钥。 let savedKey = '' if (!envKey) { - const result = await window.api.getSavedDbKey() + const result = startupAccountRoot + ? await window.api.getSavedDbKey(startupAccountRoot) + : { success: true, saved: false, encryptionAvailable: true } if (result.success && result.key) savedKey = result.key } const key = envKey || savedKey @@ -570,7 +636,11 @@ function App(): React.ReactElement { try { const startupCacheReady = await loadStartupCache() setIsDatabaseConnecting(true) - const initPromise = window.api.initDb(key) + if (!startupAccountRoot) { + setBootState('login') + return + } + const initPromise = window.api.initDb(key, startupAccountRoot) if (startupCacheReady) { setIsAuthenticated(true) setIsDatabaseConnected(false) @@ -655,13 +725,36 @@ function App(): React.ReactElement { void loadGeneratedReports() }, [isAuthenticated, loadGeneratedReports]) - const handleLogin = async (keyInput?: string): Promise => { + const handleLogin = async (keyInput?: string, accountRootInput?: string): Promise => { const keyToUse = keyInput || dbKey - if (!keyToUse) return - setBootState('connecting') + let accountRoot = accountRootInput || selectedAccount?.accountRoot + if (!keyToUse || isDatabaseConnecting) return + if (!accountRoot) { + const discovery = await window.api.discoverAccounts(dbRootInput.trim()) + if (!discovery.success) { + setDbKeyStatus(discovery.error || '微信数据目录不可用') + setDbKeyStatusKind('error') + return + } + if (!discovery.preselectedAccountId) { + setDiscoveredAccounts(discovery.accounts) + setDbKeyStatus('请选择要连接的微信账号') + setDbKeyStatusKind('error') + return + } + const account = discovery.accounts.find( + (candidate) => candidate.id === discovery.preselectedAccountId + ) + if (!account) return + setDiscoveredAccounts(discovery.accounts) + setSelectedAccountId(account.id) + accountRoot = account.accountRoot + } + const operationId = ++connectionOperationRef.current + if (databaseConnectionMode === 'automatic') setConnectionGuideStep(6) setIsDatabaseConnecting(true) // 持久化用户手动指定的微信聊天文件路径,供 db:init 读取 settings.dbRoot - const trimmedRoot = dbRootInput.trim() + const trimmedRoot = accountRoot if (trimmedRoot) { try { await window.api.setSettings({ dbRoot: trimmedRoot }) @@ -682,7 +775,12 @@ function App(): React.ReactElement { detail: '正在打开 WCDB 数据库', percent: 15 }) - const result = await window.api.initDb(keyToUse) + const result = await withTimeout( + window.api.initDb(keyToUse, trimmedRoot), + DATABASE_CONNECT_TIMEOUT_MS, + '数据库连接超时,请检查数据目录后重试' + ) + if (operationId !== connectionOperationRef.current) return const success = typeof result === 'boolean' ? result : result.success if (success) { setIsNativeMonitorActive(typeof result !== 'boolean' && result.monitoring === true) @@ -693,8 +791,9 @@ function App(): React.ReactElement { percent: 25 }) const hasBootstrap = await loadBootstrapCache() + if (operationId !== connectionOperationRef.current) return // 持久化手动输入的密钥,供下次启动继续使用 - void window.api.saveDbKey(keyToUse).catch(() => undefined) + void window.api.saveDbKey(trimmedRoot, keyToUse).catch(() => undefined) void window.api.getSettings().then((current) => { if (!current.settings.autoLoginPreferenceSet) { void window.api.setSettings({ autoLogin: true }) @@ -734,17 +833,23 @@ function App(): React.ReactElement { }, 500) } else { const error = typeof result === 'boolean' ? '' : result.error + setDbKeyStatus(error || '数据库连接失败,请检查密钥和数据目录后重试') + setDbKeyStatusKind('error') + if (databaseConnectionMode === 'automatic') setConnectionGuideStep(5) setBootState('login') setStartupProgress(null) - alert(`Failed to open database.${error ? `\n\n${error}` : '\nCheck your key.'}`) } } catch (error) { console.error(error) + setDbKeyStatus( + error instanceof Error ? `数据库连接失败:${error.message}` : '数据库连接失败,请重试' + ) + setDbKeyStatusKind('error') + if (databaseConnectionMode === 'automatic') setConnectionGuideStep(5) setBootState('login') setStartupProgress(null) - alert('Error connecting to database') } finally { - setIsDatabaseConnecting(false) + if (operationId === connectionOperationRef.current) setIsDatabaseConnecting(false) } } @@ -864,31 +969,42 @@ function App(): React.ReactElement { const handleAutoGetDbKey = async (): Promise => { if (isFetchingDbKey) return + const operationId = ++connectionOperationRef.current + setConnectionGuideStep(4) setIsFetchingDbKey(true) setDbKeyStatus('正在准备获取密钥...') setDbKeyStatusKind('normal') setShowMacKeyFaq(false) try { - const result = await window.api.autoGetDbKey() + if (!selectedAccount) throw new Error('请先选择微信账号') + const result = await window.api.autoGetDbKey(selectedAccount.accountRoot) + if (operationId !== connectionOperationRef.current) return if (!result.success || !result.key) { setShowMacKeyFaq(result.code === 'SCAN_FAILED') throw new Error(result.error || '获取密钥失败') } setDbKey(result.key) - setDatabaseConnectionMode('manual') + setConnectionGuideStep(5) setDbKeyStatus(result.saved ? '密钥已获取并安全保存' : result.warning || '密钥已获取') setDbKeyStatusKind(result.saved ? 'success' : 'normal') } catch (error) { + if (operationId !== connectionOperationRef.current) return setDbKeyStatus(error instanceof Error ? error.message : String(error)) setDbKeyStatusKind('error') + setConnectionGuideStep(3) } finally { - setIsFetchingDbKey(false) + if (operationId === connectionOperationRef.current) setIsFetchingDbKey(false) } } const handlePasteAndSaveDbKey = async (): Promise => { setShowMacKeyFaq(false) - const result = await window.api.pasteAndSaveDbKey() + if (!selectedAccount) { + setDbKeyStatus('请先选择微信账号') + setDbKeyStatusKind('error') + return + } + const result = await window.api.pasteAndSaveDbKey(selectedAccount.accountRoot) if (result.success && result.key) { setDbKey(result.key) setDatabaseConnectionMode('manual') @@ -902,7 +1018,8 @@ function App(): React.ReactElement { const handleClearSavedDbKey = async (): Promise => { setShowMacKeyFaq(false) - const result = await window.api.clearSavedDbKey() + if (!selectedAccount) return + const result = await window.api.clearSavedDbKey(selectedAccount.accountRoot) if (!result.success) { setDbKeyStatus(result.error || '清除密钥失败') setDbKeyStatusKind('error') @@ -935,12 +1052,54 @@ function App(): React.ReactElement { setStartupProgress(null) } + const handleSwitchAccount = async (account: WechatAccountCandidate): Promise => { + connectionOperationRef.current += 1 + await window.api.disconnectDb({ closeNative: true }) + setIsAuthenticated(false) + setIsDatabaseConnected(false) + setSelectedContact(null) + setMessages([]) + setContacts([]) + setFilteredContacts([]) + setContentFilter('') + setSelfInfo(null) + setReportSourceContact(null) + setExportTasks([]) + messageHistoryRef.current = [] + messagesRef.current = [] + selectedContactMd5Ref.current = '' + currentGroupSnapshotRef.current = null + groupMemberMetaRef.current = {} + syntheticGroupMessagesRef.current = {} + setDiscoveredAccounts((current) => + current.some((item) => item.id === account.id) ? current : [account] + ) + setSelectedAccountId(account.id) + setDbRootInput(account.accountRoot) + await window.api.setSettings({ dbRoot: account.accountRoot, imageKeyRoot: account.accountRoot }) + const saved = await window.api.getSavedDbKey(account.accountRoot) + if (!saved.success || !saved.key) { + setDbKey('') + setDatabaseConnectionMode('automatic') + setBootState('login') + setConnectionGuideStep(3) + setDbKeyStatus('该账号尚无可用密钥,请为所选账号获取密钥') + setDbKeyStatusKind('normal') + return + } + setDbKey(saved.key) + setDatabaseConnectionMode('manual') + setBootState('login') + await handleLogin(saved.key, account.accountRoot) + } + const handleSelectContact = async (contact: Contact, forceLive = false): Promise => { setArchiveJumpTime(null) setSelectedContact(contact) selectedContactMd5Ref.current = contact.md5 currentGroupSnapshotRef.current = null setIsMessagesLoading(true) + setMessageHistoryStatus('idle') const cachedPage = await window.api.getCachedMessagePage(contact.md5) const cachedMsgs = cachedPage.messages if (selectedContactMd5Ref.current !== contact.md5) return @@ -1052,7 +1211,7 @@ function App(): React.ReactElement { const handleLoadOlderMessages = async (): Promise => { const contact = selectedContact - if (!contact || messagesRef.current.length === 0) return + if (!contact || messagesRef.current.length === 0 || messageHistoryStatus === 'end') return if (messagePrefetchRef.current) await messagePrefetchRef.current if (selectedContactMd5Ref.current !== contact.md5) return const currentMessages = messagesRef.current @@ -1089,6 +1248,7 @@ function App(): React.ReactElement { limit: MESSAGE_PAGE_SIZE }) if (selectedContactMd5Ref.current !== contact.md5) return + setMessageHistoryStatus(olderMessages.length === 0 ? 'end' : 'idle') messageHistoryRef.current = mergeMessagePages(olderMessages, historyMessages) setMessages((current) => applyGroupMemberMeta( @@ -1098,6 +1258,7 @@ function App(): React.ReactElement { ) } catch (error) { console.warn('[Messages] older page load failed:', error) + if (selectedContactMd5Ref.current === contact.md5) setMessageHistoryStatus('error') } finally { if (selectedContactMd5Ref.current === contact.md5) setIsMessagesLoading(false) } @@ -1434,6 +1595,7 @@ function App(): React.ReactElement { contact={selectedContact} messages={messages} isLoadingMessages={isMessagesLoading} + messageHistoryStatus={messageHistoryStatus} contentFilter={contentFilter} onContentFilterChange={setContentFilter} onRefresh={() => selectedContact && handleSelectContact(selectedContact, true)} @@ -1561,6 +1723,7 @@ function App(): React.ReactElement { onNotice={setReportNotice} onOpenSettings={openSettings} onAppearanceChange={handleAppearanceChange} + onSwitchAccount={handleSwitchAccount} /> ) case 'search': @@ -1675,15 +1838,80 @@ function App(): React.ReactElement { dbRoot={dbRootInput} showDbKey={showDbKey} isFetching={isFetchingDbKey} + isConnecting={isDatabaseConnecting} + guideStep={connectionGuideStep} + environment={databaseEnvironment} + accounts={discoveredAccounts} + selectedAccountId={selectedAccountId} status={dbKeyStatus} statusKind={dbKeyStatusKind} showMacKeyFaq={showMacKeyFaq} macKeyFaqUrl={MAC_KEY_FAQ_URL} onModeChange={setDatabaseConnectionMode} onDbKeyChange={setDbKey} - onDbRootChange={setDbRootInput} + onDbRootChange={(value) => { + setDbRootInput(value) + setDiscoveredAccounts([]) + setSelectedAccountId('') + }} + onSelectAccount={(account) => { + setSelectedAccountId(account.id) + setDbKey('') + void window.api.getSavedDbKey(account.accountRoot).then((result) => { + if (result.success && result.key) setDbKey(result.key) + }) + }} + onSelectDbRoot={() => { + void window.api.selectDbRoot().then((result) => { + if (!result.canceled && result.path) { + setDbRootInput(result.path) + void window.api.discoverAccounts(result.path).then((discovery) => { + if (!discovery.success) { + setDiscoveredAccounts([]) + setSelectedAccountId('') + setDbKeyStatus(discovery.error || '账号目录识别失败') + setDbKeyStatusKind('error') + return + } + setDiscoveredAccounts(discovery.accounts) + setSelectedAccountId(discovery.preselectedAccountId || '') + }) + } + }) + }} onToggleDbKey={() => setShowDbKey((visible) => !visible)} onAutoGetKey={handleAutoGetDbKey} + onRefreshEnvironment={() => void refreshConnectionEnvironment()} + onGuideNext={() => + setConnectionGuideStep((current) => (current === 1 ? 2 : current === 2 ? 3 : current)) + } + onGuideBack={() => + setConnectionGuideStep((current) => + current === 5 ? 3 : current > 1 ? ((current - 1) as 1 | 2 | 3 | 4 | 5 | 6) : 1 + ) + } + onGuideCancel={() => { + connectionOperationRef.current += 1 + setIsFetchingDbKey(false) + setIsDatabaseConnecting(false) + setBootState('login') + setStartupProgress(null) + setConnectionGuideStep(1) + setDbKeyStatus('已取消,可以重新检查环境') + setDbKeyStatusKind('normal') + }} + onValidateConnection={() => void handleLogin()} + onCopyDiagnostics={() => { + if (!databaseEnvironment?.diagnosticSummary) { + setDbKeyStatus('诊断信息尚未准备好,请先重新检查环境') + setDbKeyStatusKind('error') + return + } + void window.api.copyText(databaseEnvironment.diagnosticSummary).then(() => { + setDbKeyStatus('脱敏诊断摘要已复制') + setDbKeyStatusKind('success') + }) + }} onManualConnect={() => handleLogin()} onPasteKey={handlePasteAndSaveDbKey} onClearKey={handleClearSavedDbKey} diff --git a/src/renderer/src/components/ChatWindow.tsx b/src/renderer/src/components/ChatWindow.tsx index c4de2ec..3a86317 100644 --- a/src/renderer/src/components/ChatWindow.tsx +++ b/src/renderer/src/components/ChatWindow.tsx @@ -10,6 +10,7 @@ interface ChatWindowProps { contact: Contact | null messages: Message[] isLoadingMessages?: boolean + messageHistoryStatus?: 'idle' | 'end' | 'error' contentFilter?: string onContentFilterChange?: (keyword: string) => void onRefresh?: () => void @@ -25,6 +26,7 @@ const ChatWindow: React.FC = ({ contact, messages, isLoadingMessages, + messageHistoryStatus, contentFilter, onContentFilterChange, onRefresh, @@ -205,6 +207,7 @@ const ChatWindow: React.FC = ({ messages={filteredMessages} hiddenMessageCount={0} isLoadingMessages={isLoadingMessages} + messageHistoryStatus={messageHistoryStatus} isGroupChat={isGroupChat} showAvatar={showAvatar} listRef={messageListRef} diff --git a/src/renderer/src/components/DatabaseConnectionPage.tsx b/src/renderer/src/components/DatabaseConnectionPage.tsx index f94699c..6dc667c 100644 --- a/src/renderer/src/components/DatabaseConnectionPage.tsx +++ b/src/renderer/src/components/DatabaseConnectionPage.tsx @@ -1,4 +1,5 @@ import React from 'react' +import type { DatabaseKeyEnvironment, WechatAccountCandidate } from '../../../shared/database-key' const GUIDE_URL = 'https://github.com/Wxw-Gu/WechatExplorer/blob/main/docs/user-guide/getting-started.md' @@ -13,6 +14,11 @@ interface DatabaseConnectionPageProps { dbRoot: string showDbKey: boolean isFetching: boolean + isConnecting: boolean + guideStep: 1 | 2 | 3 | 4 | 5 | 6 + environment?: DatabaseKeyEnvironment + accounts: WechatAccountCandidate[] + selectedAccountId: string status: string statusKind: DatabaseConnectionStatusKind showMacKeyFaq: boolean @@ -20,8 +26,16 @@ interface DatabaseConnectionPageProps { onModeChange: (mode: DatabaseConnectionMode) => void onDbKeyChange: (value: string) => void onDbRootChange: (value: string) => void + onSelectAccount: (account: WechatAccountCandidate) => void + onSelectDbRoot: () => void onToggleDbKey: () => void onAutoGetKey: () => void + onRefreshEnvironment: () => void + onGuideNext: () => void + onGuideBack: () => void + onGuideCancel: () => void + onValidateConnection: () => void + onCopyDiagnostics: () => void onManualConnect: () => void onPasteKey: () => void onClearKey: () => void @@ -92,6 +106,11 @@ export function DatabaseConnectionPage({ dbRoot, showDbKey, isFetching, + isConnecting, + guideStep, + environment, + accounts = [], + selectedAccountId = '', status, statusKind, showMacKeyFaq, @@ -99,8 +118,16 @@ export function DatabaseConnectionPage({ onModeChange, onDbKeyChange, onDbRootChange, + onSelectAccount, + onSelectDbRoot, onToggleDbKey, onAutoGetKey, + onRefreshEnvironment, + onGuideNext, + onGuideBack, + onGuideCancel, + onValidateConnection, + onCopyDiagnostics, onManualConnect, onPasteKey, onClearKey @@ -146,27 +173,27 @@ export function DatabaseConnectionPage({

第一次使用

开始连接微信

-

跟着下面 3 步操作,通常几分钟即可完成连接。

+

按顺序检查环境、准备连接组件并验证数据库,通常几分钟即可完成。

  1. 1
    - 确认微信数据目录 - 没有自动找到时,可在设置中手动选择 + 检查本机环境 + 确认微信版本、数据目录和运行状态
  2. 2
    - 让微信停在登录页面 - 不要在获取密钥前完成登录 + 准备连接组件 + 页面会按当前系统给出对应步骤
  3. 3
    - 点击自动获取密钥 - 提示可以登录后,再回到微信完成登录 + 登录并验证连接 + 验证通过后进入主界面
@@ -202,6 +229,11 @@ export function DatabaseConnectionPage({ {mode === 'automatic' ? (
+
+ {Array.from({ length: 6 }, (_, index) => ( + + ))} +
@@ -209,57 +241,206 @@ export function DatabaseConnectionPage({
- {statusKind === 'error' ? '未能获取数据库密钥' : '已准备检测微信数据库'} + {statusKind === 'error' + ? '当前步骤未完成' + : [ + '检查本机环境', + '让微信停在登录页面', + '确认开始准备', + `正在完成 ${isMac ? 'macOS' : 'Windows'} 授权`, + '现在可以登录微信', + '验证数据库连接' + ][guideStep - 1]}

{statusKind === 'error' ? status - : status || '请保持微信客户端正在运行,系统将尝试安全获取数据库密钥。'} + : status || + [ + '确认下方检测结果;没有找到目录时可以手动选择。', + '请退出当前微信账号,让微信停留在登录页面,然后点击“我已准备好”。', + '开始后请按页面提示完成系统授权。', + '正在准备连接组件,请不要关闭微信或 WechatExplorer。', + '请回到微信完成登录,登录成功后再回来验证。', + '正在验证密钥和本地数据库,请稍候。' + ][guideStep - 1]}

-
-
-
微信客户端
-
{isFetching ? '正在检测' : '等待检测'}
-
-
-
- 存储路径 - -
-
- - onDbRootChange(event.target.value)} - placeholder={defaultPath} - title={dbRoot || defaultPath} - aria-label="微信数据存储路径" - spellCheck={false} - onFocus={(event) => event.currentTarget.select()} - /> - - {dbRoot || defaultPath} - - -
-
-
-
数据库状态
-
{statusKind === 'error' ? '无法连接' : '准备连接'}
-
-
+ {guideStep === 1 && ( + <> +
+
+
操作系统
+
{environment?.osVersion || (isMac ? 'macOS' : 'Windows')}
+
+
+
微信版本
+
{environment?.wechatVersion || '未检测到'}
+
+
+
数据结构
+
{environment?.dataStructureVersion || '未检测到'}
+
+
+
+ 存储路径 + +
+
+ + onDbRootChange(event.target.value)} + placeholder={defaultPath} + title={dbRoot || defaultPath} + aria-label="微信数据存储路径" + spellCheck={false} + onFocus={(event) => event.currentTarget.select()} + /> + + {dbRoot || defaultPath} + + + +
+
+
+
微信状态
+
{environment?.wechatRunning ? '运行中' : '未检测到'}
+
+
+ {accounts.length > 0 && ( +
+

选择微信账号

+ {accounts.map((account) => ( + + ))} + +
+ )} + + )}
- + {guideStep === 1 && ( + <> + + + + + )} + {guideStep === 2 && ( + + )} + {guideStep === 3 && ( + + )} + {guideStep === 4 && ( + + )} + {guideStep === 5 && ( + + )} + {guideStep === 6 && ( + + )} + {guideStep > 1 && !isFetching && !isConnecting && ( +
+ + +
+ )} + {(isFetching || isConnecting) && ( + + )}

{isMac ? ( <> @@ -311,15 +492,21 @@ export function DatabaseConnectionPage({ 微信数据目录 - onDbRootChange(event.target.value)} - placeholder={defaultPath} - title={dbRoot || defaultPath} - spellCheck={false} - onFocus={(event) => event.currentTarget.select()} - /> +

+ onDbRootChange(event.target.value)} + placeholder={defaultPath} + title={dbRoot || defaultPath} + spellCheck={false} + onFocus={(event) => event.currentTarget.select()} + /> + +
)} {status &&
{status}
} @@ -327,11 +514,25 @@ export function DatabaseConnectionPage({ type="button" className="database-login-primary" onClick={onManualConnect} - disabled={!keyIsValid} + disabled={!keyIsValid || isConnecting} > - 连接数据库 + {isConnecting ? '正在连接…' : '连接数据库'} - + )} +
diff --git a/src/renderer/src/components/chat/MessageList.tsx b/src/renderer/src/components/chat/MessageList.tsx index d2fe589..6339135 100644 --- a/src/renderer/src/components/chat/MessageList.tsx +++ b/src/renderer/src/components/chat/MessageList.tsx @@ -9,6 +9,7 @@ interface MessageListProps { messages: Message[] hiddenMessageCount: number isLoadingMessages?: boolean + messageHistoryStatus?: 'idle' | 'end' | 'error' isGroupChat: boolean showAvatar: boolean listRef: React.RefObject @@ -24,6 +25,7 @@ export function MessageList({ messages, hiddenMessageCount, isLoadingMessages, + messageHistoryStatus, isGroupChat, showAvatar, listRef, @@ -119,6 +121,18 @@ export function MessageList({ return (
{isLoadingMessages &&
正在加载聊天记录...
} + {messageHistoryStatus === 'end' && ( +
+
已显示本地数据库中的最早记录
+
+ )} + {messageHistoryStatus === 'error' && ( +
+
+ 无法读取更早记录,请检查数据目录或当前微信数据版本 +
+
+ )} {hiddenMessageCount > 0 && (
diff --git a/src/renderer/src/components/export/ExportWorkspace.tsx b/src/renderer/src/components/export/ExportWorkspace.tsx index 4c0bdc5..f79238e 100644 --- a/src/renderer/src/components/export/ExportWorkspace.tsx +++ b/src/renderer/src/components/export/ExportWorkspace.tsx @@ -41,7 +41,7 @@ export function ExportWorkspace({ const [includeAvatars, setIncludeAvatars] = useState(true) const [preferOriginal, setPreferOriginal] = useState(true) const [fallbackThumbnail, setFallbackThumbnail] = useState(true) - const [keepMissing, setKeepMissing] = useState(false) + const [keepMissing, setKeepMissing] = useState(true) const [format, setFormat] = useState('csv') const [zip, setZip] = useState(false) const [fileName, setFileName] = useState('') @@ -158,6 +158,8 @@ export function ExportWorkspace({ const handleStart = async (): Promise => { if (!activeContact || status === 'running') return + // Runs only from the export button event; a fresh id is required for each job. + // eslint-disable-next-line react-hooks/purity const nextJobId = `export-${Date.now()}` setJobId(nextJobId) setProgress(null) @@ -204,6 +206,9 @@ export function ExportWorkspace({ : undefined, kinds: Array.from(selectedKinds) as ExportMessageKind[], includeMedia, + preferOriginal, + fallbackThumbnail, + keepMissing, includeAvatars, avatarUrls: exportAvatarUrls, nameMode, @@ -303,20 +308,39 @@ export function ExportWorkspace({

导出格式

{formatOrder.map((value) => ( - ))}
-

CSV 默认最快;HTML 会包含图片、引用和其他媒体,导出时间可能较长。

+

+ CSV 默认最快;HTML 会包含图片、引用和其他媒体,导出时间可能较长。 +

{format === 'html' && (
)} @@ -383,19 +407,13 @@ export function ExportWorkspace({

消息内容

{messageKinds.map(([value, label]) => ( -
@@ -424,12 +442,14 @@ export function ExportWorkspace({ 包含图片、视频、语音及动态表情 setIncludeMedia(event.target.checked)} /> -
+
-

资源文件仅在 HTML 导出中生效,CSV、JSON 和 Markdown 只保留文本内容。

+

+ 资源文件仅在 HTML 导出中生效,CSV、JSON 和 Markdown 只保留文本内容。 +

图片解密:已就绪 视频资源:可用 diff --git a/src/renderer/src/features/settings/SettingsWorkspace.tsx b/src/renderer/src/features/settings/SettingsWorkspace.tsx index ebdd020..78cdc1b 100644 --- a/src/renderer/src/features/settings/SettingsWorkspace.tsx +++ b/src/renderer/src/features/settings/SettingsWorkspace.tsx @@ -30,7 +30,8 @@ export function SettingsWorkspace({ onAIRuntimeChange, onNotice, onOpenSettings, - onAppearanceChange + onAppearanceChange, + onSwitchAccount }: { selectedCategory: SettingsCategoryId onCategoryChange: (id: SettingsCategoryId) => void @@ -47,7 +48,13 @@ export function SettingsWorkspace({ onAIRuntimeChange: (config: AIRuntimeModelConfig) => void onNotice: (message: string) => void onOpenSettings: () => void - onAppearanceChange: (settings: { theme: 'system' | 'light' | 'dark'; compactMode: boolean }) => void + onAppearanceChange: (settings: { + theme: 'system' | 'light' | 'dark' + compactMode: boolean + }) => void + onSwitchAccount: ( + account: import('../../../../shared/database-key').WechatAccountCandidate + ) => Promise }): React.ReactElement { const renderSelectedPage = (): React.ReactElement => { switch (selectedCategory) { @@ -59,6 +66,7 @@ export function SettingsWorkspace({ dbConnecting={dbConnecting} selfInfo={selfInfo} onNotice={onNotice} + onSwitchAccount={onSwitchAccount} /> ) case 'database-key': @@ -87,9 +95,7 @@ export function SettingsWorkspace({ case 'cache-cleanup': return case 'appearance': - return ( - - ) + return case 'about': return default: diff --git a/src/renderer/src/features/settings/account-database/AccountOverview.tsx b/src/renderer/src/features/settings/account-database/AccountOverview.tsx index 23c5a56..9bca65c 100644 --- a/src/renderer/src/features/settings/account-database/AccountOverview.tsx +++ b/src/renderer/src/features/settings/account-database/AccountOverview.tsx @@ -25,7 +25,8 @@ export function AccountOverview({ isChecking, onCheck, onOpenDirectory, - onCopyDirectory + onCopyDirectory, + onSwitchAccount }: { selfInfo: SettingsSelfInfo | null connectionStatus: ConnectionOverviewStatus @@ -34,6 +35,7 @@ export function AccountOverview({ onCheck: () => void onOpenDirectory: () => void onCopyDirectory: () => void + onSwitchAccount: () => void }): React.ReactElement { const accountRoot = selfInfo?.accountRoot || '' return ( @@ -83,6 +85,9 @@ export function AccountOverview({ > 打开账号目录 +
diff --git a/src/renderer/src/features/settings/database-key/useDatabaseKeyController.ts b/src/renderer/src/features/settings/database-key/useDatabaseKeyController.ts index a58d358..0da86f7 100644 --- a/src/renderer/src/features/settings/database-key/useDatabaseKeyController.ts +++ b/src/renderer/src/features/settings/database-key/useDatabaseKeyController.ts @@ -36,14 +36,14 @@ export function useDatabaseKeyController({ }, []) const refreshStorage = useCallback(async (): Promise => { - const result = await window.api.getSavedDbKey() + const result = await window.api.getSavedDbKey(selfInfo?.accountRoot || '') dispatch({ type: 'STORAGE_LOADED', saved: result.saved, encryptionAvailable: result.encryptionAvailable, error: result.success ? undefined : result.error }) - }, []) + }, [selfInfo?.accountRoot]) useEffect(() => { void Promise.all([refreshStorage(), refreshEnvironment()]) @@ -109,7 +109,8 @@ export function useDatabaseKeyController({ const saveKey = useCallback(async (): Promise => { if (state.status !== 'valid') return dispatch({ type: 'SAVE_START' }) - const saved = await window.api.saveDbKey(dbKey) + const accountRoot = selfInfo?.accountRoot || '' + const saved = await window.api.saveDbKey(accountRoot, dbKey) if (!saved.success || !saved.key) { dispatch({ type: 'SAVE_ERROR', @@ -117,12 +118,12 @@ export function useDatabaseKeyController({ }) return } - const stored = await window.api.getSavedDbKey() + const stored = await window.api.getSavedDbKey(accountRoot) if (!stored.success || !stored.saved || !stored.key) { dispatch({ type: 'SAVE_ERROR', error: '无法确认密钥保存状态' }) return } - const initialized = await window.api.initDb(stored.key) + const initialized = await window.api.initDb(stored.key, accountRoot) const connected = typeof initialized === 'boolean' ? initialized : initialized.success onDbKeyChange(stored.key) onDatabaseConnectionChange(connected) @@ -148,13 +149,14 @@ export function useDatabaseKeyController({ onNotice, onSelfInfoChange, refreshEnvironment, + selfInfo?.accountRoot, state.status ]) const autoDetectKey = useCallback(async (): Promise => { dispatch({ type: 'AUTO_START' }) await refreshEnvironment() - const result = await window.api.autoGetDbKey({ save: false }) + const result = await window.api.autoGetDbKey(selfInfo?.accountRoot || '', { save: false }) if (!result.success || !result.key) { dispatch({ type: 'AUTO_ERROR', error: result.error || '暂未找到有效密钥' }) return @@ -162,11 +164,11 @@ export function useDatabaseKeyController({ onDbKeyChange(result.key) dispatch({ type: 'AUTO_SUCCESS' }) await runValidation(result.key) - }, [onDbKeyChange, refreshEnvironment, runValidation]) + }, [onDbKeyChange, refreshEnvironment, runValidation, selfInfo?.accountRoot]) const clearSavedKey = useCallback(async (): Promise => { dispatch({ type: 'CLEAR_START' }) - const result = await window.api.clearSavedDbKey() + const result = await window.api.clearSavedDbKey(selfInfo?.accountRoot || '') if (!result.success) { dispatch({ type: 'CLEAR_ERROR', error: '清除密钥失败' }) return @@ -187,7 +189,8 @@ export function useDatabaseKeyController({ onFilteredContactsChange, onNotice, onSelfInfoChange, - refreshEnvironment + refreshEnvironment, + selfInfo?.accountRoot ]) const returnToLogin = useCallback(async (): Promise => { diff --git a/src/renderer/src/features/settings/pages/AccountDatabasePage.tsx b/src/renderer/src/features/settings/pages/AccountDatabasePage.tsx index a974662..d2e8d3a 100644 --- a/src/renderer/src/features/settings/pages/AccountDatabasePage.tsx +++ b/src/renderer/src/features/settings/pages/AccountDatabasePage.tsx @@ -5,6 +5,7 @@ import { LocalPrivacyNotice } from '../account-database/LocalPrivacyNotice' import { useAccountDatabaseController } from '../account-database/useAccountDatabaseController' import type { ConnectionOverviewStatus } from '../account-database/types' import type { SettingsSelfInfo } from '../model/types' +import type { WechatAccountCandidate } from '../../../../../shared/database-key' const STATUS_LABELS: Record = { checking: '正在检测', @@ -19,13 +20,15 @@ export function AccountDatabasePage({ dbReady, dbConnecting = false, selfInfo, - onNotice + onNotice, + onSwitchAccount }: { dbKey: string dbReady: boolean dbConnecting?: boolean selfInfo: SettingsSelfInfo | null onNotice: (message: string) => void + onSwitchAccount: (account: WechatAccountCandidate) => Promise }): React.ReactElement { const controller = useAccountDatabaseController({ dbKey, @@ -35,6 +38,8 @@ export function AccountDatabasePage({ onNotice }) const [autoLogin, setAutoLogin] = useState(false) + const [switching, setSwitching] = useState(false) + const [accounts, setAccounts] = useState([]) useEffect(() => { let active = true @@ -56,6 +61,18 @@ export function AccountDatabasePage({ onNotice(checked ? '已开启启动时自动连接' : '已关闭启动时自动连接') } + const openAccountSwitcher = async (): Promise => { + if (!selfInfo?.accountRoot) return + const parentRoot = selfInfo.accountRoot.replace(/[\\/][^\\/]+[\\/]?$/, '') + const result = await window.api.discoverAccounts(parentRoot) + if (!result.success) { + onNotice(result.error || '无法读取账号列表') + return + } + setAccounts(result.accounts) + setSwitching(true) + } + return (
@@ -79,7 +96,45 @@ export function AccountDatabasePage({ onCheck={() => void controller.testConnection()} onOpenDirectory={() => void controller.openAccountDirectory()} onCopyDirectory={() => void controller.copyAccountDirectory()} + onSwitchAccount={() => void openAccountSwitcher()} /> + {switching && ( +
+

选择要切换的账号

+ {accounts.map((account) => ( + + ))} + +
+ )}

连接健康检查

input, +.database-login-root-control, .database-login-key-input { width: 100%; min-height: 42px; @@ -1604,6 +1657,37 @@ background: #fff; } +.database-login-root-control { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + overflow: hidden; +} + +.database-login-root-control input { + min-width: 0; + padding: 0 12px; + border: 0; + outline: 0; + color: var(--login-text); + background: transparent; + font-size: 13px; +} + +.database-login-root-control button { + padding: 0 12px; + border: 0; + border-left: 1px solid var(--login-border); + color: var(--login-primary-dark); + background: var(--login-surface-low); + cursor: pointer; +} + +.database-login-root-control button:disabled, +.database-login-path-select:disabled { + cursor: not-allowed; + opacity: 0.55; +} + .database-login-field > input { padding: 0 12px; color: var(--login-text); @@ -1617,6 +1701,7 @@ } .database-login-key-input:focus-within, +.database-login-root-control:focus-within, .database-login-field > input:focus { border-color: var(--login-primary); box-shadow: 0 0 0 3px rgba(36, 122, 99, 0.1); @@ -1969,3 +2054,70 @@ pointer-events: none; } } +.database-account-list { + display: grid; + gap: 10px; + margin: 14px 0; + + h3 { + margin: 0; + font-size: 14px; + } +} + +.database-account-card { + width: 100%; + display: grid; + grid-template-columns: 44px minmax(0, 1fr) auto; + gap: 12px; + align-items: center; + padding: 12px; + border: 1px solid var(--border-color, #d8e2dc); + border-radius: 8px; + background: transparent; + color: inherit; + text-align: left; + cursor: pointer; + + &.selected { + border-color: #176b57; + box-shadow: 0 0 0 2px #176b5720; + } +} + +.database-account-avatar { + width: 44px; + height: 44px; + display: grid; + place-items: center; + overflow: hidden; + border-radius: 6px; + background: #dcebe4; + + img { + width: 100%; + height: 100%; + object-fit: cover; + } +} + +.database-account-identity, +.database-account-status { + display: grid; + gap: 3px; + min-width: 0; + + small, + code { + color: var(--text-secondary, #68766f); + } + code { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } +} + +.database-account-status { + text-align: right; +} diff --git a/src/shared/connection-diagnostics.ts b/src/shared/connection-diagnostics.ts new file mode 100644 index 0000000..3865f93 --- /dev/null +++ b/src/shared/connection-diagnostics.ts @@ -0,0 +1,16 @@ +import type { DatabaseKeyEnvironment } from './database-key' + +export function buildSafeDiagnosticSummary( + environment: Omit +): string { + return [ + `WechatExplorer: ${environment.appVersion}`, + `操作系统: ${environment.osVersion}`, + `微信客户端: ${environment.wechatVersion}`, + `数据结构: ${environment.dataStructureVersion}`, + `数据目录: ${environment.dataDirectoryDetected ? '已检测到' : '未检测到'}`, + `微信进程: ${environment.wechatRunning ? '运行中' : '未运行'}`, + `数据库连接: ${environment.dbConnected ? '已连接' : '未连接'}`, + `安全存储: ${environment.encryptionAvailable ? '可用' : '不可用'}` + ].join('\n') +} diff --git a/src/shared/database-key.ts b/src/shared/database-key.ts index 326d4a7..f92634e 100644 --- a/src/shared/database-key.ts +++ b/src/shared/database-key.ts @@ -24,8 +24,36 @@ export interface DatabaseKeyStorageResult { encryptionAvailable: boolean } +export type AccountLoginStatus = 'current' | 'other' | 'unknown' + +export interface WechatAccountCandidate { + id: string + accountRoot: string + directoryName: string + wxid?: string + nickname?: string + avatar?: string + hasSavedDbKey: boolean + loginStatus: AccountLoginStatus + selectedByInput: boolean +} + +export interface AccountDiscoveryResult { + success: boolean + inputKind?: 'root' | 'account' + accounts: WechatAccountCandidate[] + preselectedAccountId?: string + error?: string +} + export interface DatabaseKeyEnvironment { platform: NodeJS.Platform + osVersion: string + appVersion: string + wechatVersion: string + dataStructureVersion: string + dataDirectoryDetected: boolean + diagnosticSummary: string autoDetectSupported: boolean wechatRunning: boolean accountIdentified: boolean diff --git a/src/shared/export-media.ts b/src/shared/export-media.ts new file mode 100644 index 0000000..6e11855 --- /dev/null +++ b/src/shared/export-media.ts @@ -0,0 +1,22 @@ +import type { ExportRequest } from './export' + +export type ImageExportAttempt = { + allowThumbnail: boolean + preferThumbnail: boolean + fallback: boolean +} + +export function getImageExportAttempts( + request: Pick +): ImageExportAttempt[] { + if (request.preferOriginal === false) { + return [{ allowThumbnail: true, preferThumbnail: true, fallback: false }] + } + const attempts: ImageExportAttempt[] = [ + { allowThumbnail: false, preferThumbnail: false, fallback: false } + ] + if (request.fallbackThumbnail !== false) { + attempts.push({ allowThumbnail: true, preferThumbnail: true, fallback: true }) + } + return attempts +} diff --git a/src/shared/export.ts b/src/shared/export.ts index 4d6aad6..5918c34 100644 --- a/src/shared/export.ts +++ b/src/shared/export.ts @@ -23,6 +23,9 @@ export interface ExportRequest { endTime?: number kinds: ExportMessageKind[] includeMedia: boolean + preferOriginal?: boolean + fallbackThumbnail?: boolean + keepMissing?: boolean includeAvatars?: boolean avatarUrls?: Record nameMode?: ExportNameMode diff --git a/tests/component/database-connection.test.tsx b/tests/component/database-connection.test.tsx index 3720915..249dde5 100644 --- a/tests/component/database-connection.test.tsx +++ b/tests/component/database-connection.test.tsx @@ -14,6 +14,35 @@ function renderPage( dbRoot: '', showDbKey: false, isFetching: false, + isConnecting: false, + guideStep: 1 as const, + environment: { + platform: 'win32', + osVersion: 'Windows fixture', + appVersion: 'v2.1.6', + wechatVersion: '4.1.9.57', + dataStructureVersion: '微信 4.x(WCDB)', + dataDirectoryDetected: true, + diagnosticSummary: 'WechatExplorer: v2.1.6', + autoDetectSupported: true, + wechatRunning: true, + accountIdentified: false, + dbConnected: false, + encryptionAvailable: true + }, + accounts: [ + { + id: 'account-a', + accountRoot: 'C:\\fixture\\account-a', + directoryName: 'account-a', + nickname: '脱敏账号 A', + wxid: 'wxid_fixture_a', + hasSavedDbKey: true, + loginStatus: 'unknown' as const, + selectedByInput: true + } + ], + selectedAccountId: 'account-a', status: '', statusKind: 'normal' as const, showMacKeyFaq: false, @@ -21,8 +50,16 @@ function renderPage( onModeChange: vi.fn(), onDbKeyChange: vi.fn(), onDbRootChange: vi.fn(), + onSelectAccount: vi.fn(), + onSelectDbRoot: vi.fn(), onToggleDbKey: vi.fn(), onAutoGetKey: vi.fn(), + onRefreshEnvironment: vi.fn(), + onGuideNext: vi.fn(), + onGuideBack: vi.fn(), + onGuideCancel: vi.fn(), + onValidateConnection: vi.fn(), + onCopyDiagnostics: vi.fn(), onManualConnect: vi.fn(), onPasteKey: vi.fn(), onClearKey: vi.fn(), @@ -52,4 +89,48 @@ describe('DatabaseConnectionPage', () => { expect(onManualConnect).toHaveBeenCalledOnce() expect(screen.getByRole('button', { name: '从剪贴板粘贴并安全保存' })).toBeEnabled() }) + + it('restores directory editing and selection after a failed connection', async () => { + const onDbRootChange = vi.fn() + const onSelectDbRoot = vi.fn() + renderPage({ + dbKey: 'b'.repeat(64), + dbRoot: 'Z:\\missing-wechat-data', + status: '微信数据目录不存在,请重新选择目录', + statusKind: 'error', + onDbRootChange, + onSelectDbRoot + }) + + await userEvent.clear(screen.getByLabelText('微信数据目录')) + await userEvent.type(screen.getByLabelText('微信数据目录'), 'C:\\fixture-account') + await userEvent.click(screen.getByRole('button', { name: '选择目录' })) + + expect(onDbRootChange).toHaveBeenCalled() + expect(onSelectDbRoot).toHaveBeenCalledOnce() + expect(screen.getByRole('button', { name: '连接数据库' })).toBeEnabled() + }) + + it('supports forward, back, cancel and safe diagnostic actions in onboarding', async () => { + const onGuideNext = vi.fn() + const onCopyDiagnostics = vi.fn() + const { rerender, props } = renderPage({ + mode: 'automatic', + guideStep: 1, + onGuideNext, + onCopyDiagnostics + }) + + expect(screen.getByText('4.1.9.57')).toBeVisible() + expect(screen.getByText('微信 4.x(WCDB)')).toBeVisible() + await userEvent.click(screen.getByRole('button', { name: '复制脱敏诊断摘要' })) + await userEvent.click(screen.getByRole('button', { name: '检查完成,继续' })) + expect(onCopyDiagnostics).toHaveBeenCalledOnce() + expect(onGuideNext).toHaveBeenCalledOnce() + + rerender() + expect(screen.getByRole('button', { name: '我已准备好' })).toBeEnabled() + expect(screen.getByRole('button', { name: '返回上一步' })).toBeEnabled() + expect(screen.getByRole('button', { name: '取消并重新检查' })).toBeEnabled() + }) }) diff --git a/tests/e2e/__screenshots__/win32/visual.spec.ts/archive-page.png b/tests/e2e/__screenshots__/win32/visual.spec.ts/archive-page.png index 086df4c891da3736bb997b900267e0cbc10880bb..e19371d94dac44fd01d79a0f8231b2e3c5d5cef0 100644 GIT binary patch literal 58614 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̵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 literal 58566 zcmZs?WmsEH*EUSO&|<}kw@}=Q7jG$2DDLjAMS?>rP#lW8OR(S&EYRYf;t;Gj1VV5N zkT>o1+~2Qn|C%E^Gka#ul3C|ECtOWM9v_bi4+jSaU*Us{1`f`HA2>MofRFEDe}RQN z*y7+2;V8(w)AGsOTf{Ze(#G^1^6zoKV0{r;od2S-q$CX;-)iq*lgwr?J)zmyRA{dc z90E`7)zsFKf(7^mJ(hd8Ce(i6_b_RaKX~v?_6*bP{oVZGcUdbENmRs^wf&Du6i6!8_^RJ;cNTm0#@mVAE=ijN};3SIPC;!*ToqSpS zuYprU@a4h37AxQ}=fB3=()VWnji5+-_sPGX)DZtaLy_nIScr*5TcSpl(Pt)Yej8U{ zLvND(@JG6((mjZ&vZ?Y*z2z9=Y{Vou0-VMA)Em!}7Y9#v7&)8H?ecFvbitcCMioA9 zgk2Vms+|UEPaU5n#LKMIG}azb9}F8Z%8TfNnd!c^>ARO$@Zcm8{WqHj2i2O=jkF6h ze%n7$I#rwt_0sW=uDwq2d=Ey@XOI7za5kxU^#@f|%t@%LY3jvUR;%|B`Wb(8iQ2nc z#TmP!%V)j^#0h;c;}*Sam47`xALae|(t~i$ur`as9PZfIzx&@`KY!_I?}&}cI#j>y0~w||R)7T#y#-542dl)+*EO4YG4jtbJ1qV&H2)`V z8dfv28lO|1($dmPnu5k7I58?r!9%zxTR_m5Y6dPUCRCbRg_%Il#pBiZr1MGux{9 z-y~}*Uwr97wH}e_t!L@jQQDGg!yz@*kn(M9$XAg3S&bpV{r{8Iw0_tl@2jH_aXGD$ zA12NDX-XXXEbP0fo8NkWNpgwkdu%P8CUr2~`U{F&=}2!E?RCZEJR$yXwiO&7%;FML zGv{5>bhOG+gHR?0((yh-J7g6y8+fZK(!()OhCWTHS>Asd^|PSl?H5_ac;+qWPEt~R z=bp<~pSS6)xc1VF?DKZd+yk67`2J5FtxfNw2#zSUgfyoW6*1?1uKBtdl%Ey?xShfO zPdTkM-m!DK=kM0~N~w!Sb;}ez0zKu?(0G7jl@OoI+##Eqk*1%THnc3eqM-coqe4PQ z(Lf)$O-Sa}U)A$@5kjtKRf!wl!JW~p&{S1w_TJ{si%3sFaEY0H(U_eK@sGn$p*sqy zs;VDUYG2j;U96(YN*gT)dP@^g*L+k4oa ziBX~8>V8)Pbx6!2P|k3=)LEzI>opU7KZx7}-~l89kmJP~ zvP6R}G*ue|J&Y4s@4CtBRN_Sp!9Hv#7AvK<>^t>xs9v}4TErB@4sRb?rO>Ii*Rv~i zBbVJ?nA#GBn>(_!t>jS3^dVCv-FqvmLmeIOV;69=n-^r1W>Y+-ryt?(3%g&lGybc) zHwL+%*^%1EVNI$r#>^!+!YN^l!&)W4uD&;!AldCpOS=~9BJzy8d*hyM&s&g@+;=Y2 zvWHh#f5Lg9v*XP|LoCl_>`{iV3g?2vTA%A8aEI60cKR1x6{qp+j3~Fd-aM1ZQvK~Y zQQWL|@6U&BXcmc6L`z2J%~84pO5imhxx3`x;Pp!F+tQT8#766R z^?d?CxG;{#0(TTp%?KT@&)foCW4K%^{brWW#o!itM2e>c zgPI*~gn#@2As@U$sBC{Y?e(&)x61VJYeuce7+f@zgo!Twba=gi*gJUpuxGh$9xr!~ zm!tVM+4=^Aik7{<<_K5ey&s20&P$8_VzbTe<|(0_tDRz z=9nTFCq#$B^3Koa1D*+mq!%KR~cp+sLSS$EOM zj_zFrHGYzZ)nvH3q_vrCXWLKn7vFMAdG?ujfZ}zqx*-3{R324%eOlaNLW8IBP(t@s zIljZ|QFq6IQNuJBM|h}O1xe?VvWuV!syF2`)M8P>zNgzS8(pQUfVYeNx5uc3F)8HX zhB}k|?+t>>L`v1?isFzJ%u)taqJ4Rs79}`PyZak+8nC8E(m_ezzTju-$-Y^sJrn}9W9IDy8WpfmGA~8zPS1m#9=Uvl?cE$-YXr1AD;anl* zJ#T2szRgKX>G30HpE*XyBPXPmeAp1fx?R{}{Qx8IrlScWwdcqI@z(o<82);14SHKA zJDJnwKN3cDl^(f$vmDgUF)*T-S?3Xp4jeyzB($7p2&PGBtPuZmInZVjMlhyp_ ztg-*90tcSDU(1E_;>g8CqKk1^*jK+MwwLE9M|QnPf8UNIRVcBw$<#}K?MkCL1KfM;{s5|LrH;n-_N4RMt&otdjftznJ70+N ziS%bGne!96vl=vSh3&dBzWb|;qCbVUg-KzW*??+k&uNL{)_hS5QB4Wf30x%o>JL-x z6)QSB7lt{3Uqa5yO*!|<{WG5j9-x!Ld18a|HpJm*-w(qf~HM_q|Vd&khU1~8_D|=^`lg>r)gP)(DMs0~% z!d5^u8ckr}>uk2yOgC5o-zC9Kem*TVhG~SF+HZH#|sqG2X^qWP*j`{XZ zvvIBGc%P{NZ|5`Gm8s4Ts4s&vR=5Uh^d*WPKE~hpPL zWkgF=8BWUP{gvk_U!X~k&@w@?v=@O{lJGFXxn`4P560_$^;VWg;?CuZmCO|T;A|K0 zw3qKB+ZUHotlnN?&n9O>2*XJo(zx#K6MEeRr|Ei&Usw9#dx=EKie&1n7SZwYlzaZQCBX1!CQH$i&yqD+kj7fIq{V?9+EQqJ`Di>Z&` zkT*w*hEfm1iy1M(9?~3y8}mA|N4Kp>`+1T)Bbo2bvD(Xe+K6g#wqbtE84*)dbfmC9 zF<~O!B)x4Ow>-SsS#7C4l~!lOdk?<&4JJD~J!3;4eDD1B5)|HL&q%20A{qB;yIY@I zme#lfX;Cx{lh{e>d%kkH{<#nTJ$Rc@jN9MSHHm2};?}Y2?04(YyP}G?$@{ zO9@i+bVsYIDYDlaH^0pB+rTobUkI1s`Q2nXNDQiO$!km<5%tDVOuqH2cVRss1&BMw z;CI}u^3ojTLviwY+Dl~)lsbTDz6y>rA?P)lu3O0B@wz8C$ z;f0x_$of&#;dbpAFQUhb!KmredU z9~`DMoe!1mHvzJLdIQc%K3uaL{Fc&h-MJwt89gP^AqJi84@}2QG@g-g^|{WT^ftO7 zLHkKCv5^IVI&dxDhjL`^Js6Dow|n+}O^d~c`Lw>6QLXGA`gHO25u|WPiJ<$2tL5%) zuZ(NPL8t#6;iO;Xx@~HPxqIr251E9Bk`Si>Wq_EGrvL{xa*uw8zuYvFiNKnc=~5K z`$JDdU(sGv13`oU)u+>}0Q$qeQsUKjvzJlmwOCP}==2uTlkB64bNGYHz&uSf=n?Y{ zvkPm?D1r}=G8R_Jk5LtiL%PojzI51zILreSU(hJ1sADF@ES>!T+Y;g zTl!ZG!JUjp4F^nga(X^@qy|D76+hV693CjX0slykx;kLwW$O6SGa|JW4RZ_sp~+FK zq8H~}KGP%>REi{rx^0*sk3ai*5DKQfIO6e}pJY=scxkLJR53L;SZTr)xVVa0pkoy_ z5TwH#Lkh{PwWHp5t-#psbYCuV5YU`HpB>aHeP92SieX{$X{Y&l1VEm)mN0=wiopOM zs3@X!&SE)@6d2@eYdH&>3w%{(vik*QPmvXdRZ!eV;}HzR4Jb5B*gEH>F6cZs1qw@F zU^2KId0ygKdhqa4dG?pE8Y^udK*1=G%*4 zWq`N33C@@*(;_ z{;2m!{%()l_0k2X9mO_WU+j!0FVAERHP*GC&!$Kyp`L{YHhc+D5?ghWSinCE4mEnV z`l~qfO(XrApQ4ghGov1dozv)n%B4my&0@iB7&xUzWWz3vj2yX@W$LgihM4i0w*}rD z7ufWM?)V_0G}eh5+kmP}czM-#aXzocWoOgT5xcD%$%+|@!CFq)b=m*8KP6;m;5+(b z3cU44I_UZ6H8@Nm#C2NTzI|WjF%<<)+iu!0HMSe_mZS8|yPu3gEHp+#n8O%^EEE?- zF-8lf4QE8>g;S^y6#0g<`9pH)5zg`WgmDf%`+f3t9!}_2fPsdF0*FkSEi&~2XM@0{ zONWNqrj6~BO&_LWitDvOb6<*~ZQ}?zm5l2}hoCTjww}H|6VswN;8vw!OS!^WZ_ZBh z`s^^PmJ4I9-Rw61OI2cns@;4o{XJ-(^|FWODCHol5pbw^pWJ%l66mT0+#BGe=D*Sr zM-@p*zJL#8t{#H2r8@k3RH+ja-)$FvsTVyQI?Lgv>X>bwI_RssJ{f|u3!S?zQzRkI zo?lEJ$L^k$l98)!OcUIbHWDrW{-iNxpE-qjwr60Mw_BvLY3NxLECk>}A( z7cyz(+o5vcn=9Q7mdD|SOFM2q{}3(OxB^jb*aSMlaJ%S9`82rM_qaIH;}ji!?%LBW zK885Fg`#yT^wdcyDdQ^UFZ%Wa{TCM(sCfnhOMS}l6)ARcb?x`ai zkVnLrLkm~rf8sMApqocK9TdG}i0?)VEyAa7w9=mWNcfO9H3F2*z?{pW+~ zKHdJQVc@+zDn(N3xLj~`dUtBp%W?WkdtbYsw7}K#TMudQ7dd0MlsqdA5Laz8Az4y4 zwRNW+_r8}Kwn*95)`Wm6KlX%V?ONQYQ}V3$a#KGSeQ?#XE9wnfAn5cVBh0$0!nDW@ z5Z5B{MDk=_9eTwqskpf8cV2am5mDw(f6}7X)|)x3CTBSkceSv{2TbeL$z_Qi{gDpl zh~}qFx}#`R>v$GbfY>j*sQ%P7-nU&>ZjyHW4Xz`?Yl2po6*(N>hKHoKjxO*wH(*b2 zA;`|6NK?+MvMv%NbBDxIr%`iVt2b&X9lwLesLgJ5)_XXDQ}Dui1X0j;Po98!sVt<* zE7I6{eq&K(BRr^8aXEgN_GrVeeEBpQ{$6~f z&IN4Z9Y*v%QC=sqIBbSasO~kT@SDIlLwvxsB+mDwHDB+O#}E(@$Hj^4t9($K)&*<* z8Xi??CnUeLvdl`(EGZ;wZbW)E0-G+GFO%lF7}!3IJOsFWh#ylGByp9KSr<^>IT{p} z5-k=#@Y|Tzy=VHI{sluaRHV7bwQe3xMNp2^{Y z>y}W!#m8Kq{5r42*o$M}ep1IOEGH_giE$N}ff-Y{QE+nfu7NhMVkD0O_X}=M9}E(~ z_9-PegRUS`pT2!hS7eVH+C@l|1{06T1qvv?&fbrkThp{s!ZnxtK=3Sfe_SQaUailV zG&c7Jog}r8?t7kA4TVi^Yrhx8aMuN$|Ip7^V1fCq|=D8py9fL8Ve=m1acszE0`kQ zU*sV}2E$}tqLaZ z9U0=CqYp4FK<}sFj>XYroxmIs^O+*E-8hVY%a><*VYz?m+#1LDf*wbd^Fd29!j5+m z>aCBh9p&X&ST3bx^9#;0ay45AOat>aNyaj4gW6=elBxI=@@hge^e0dvbB^ zZGsIGmZ)+9XV$n3X>qSx!|q0Q0qNb`DqT`_9&gZ@XhLE_SuKd;h%31(uRw9al|vk3 zk}9gIDXPZhtzr4X0jVDIeM$2z2_V!!z4RvO(RsG2=*dp$wdm1#R*{qm40)Qh5KtBw zF-1!e7Fzt&BuSfh=*=?gC`#8lN5g370PG5k#LNldYEazD_HQQsN`&T;r($> zGv+jh2St?OL&;2<6xes!FeUZzdJ7U>HF~Wn7TD!@Ev%V7D7BcKBj~bb#?<)+C3ThN zv9>u%mrQI>Pm3;Y6MJLh6Xa+p?>N7gVm;f{c@9My_F9WK`v$G0&NAT z{&n(e4mwxg@Dg9l=A{BW7&Edob|zGRi zCBN)^mh6@;=iJ}dv48mXTQ~hJt&0gc0MSh=@yzBz1HelR1-Lfog91tEYc-o6qGSwn zrcZlDJs6yZbdQ~q+Mh2;(%~bbQu%VBsZG{(j}66a2lWlD+s>*R>A+$R%SFKU&q(#}$qqyE=n$KYb|m)~_5ugpb%Z$f|bOU$}DsOSaP}9b|3+ZXHBk z+8ef~UNg)(WL3+8WDZ(~ZWJ?(z2PPVl3CsRk9bP^Q$8OY%6eL9;yu$lv70|zt0G^w zwOUH+xmRfhUkfM5XVvxqGk4RfHyb$fEISa--(z%$Hoj3ejPsepV6GX1?Zlfv8MDPt zPpCSAdY-sk&GbB~N;@69Mq;-2aUAe(nLV_}M7!E=j@J2I_nJzzQeq5BmbbB;YsU|oZ)~9D=M9_t=omOp+T~vyGi^y{uV!6yWvPon1RH@<_DEG$FM5q z>q~9xDwS_Jl#>O{3GkSc1x`&Gi_yx99oN%5KEWG!Xe!>YAc0un30~uq3j}yQs$eN=+^+n4`+v^ zTQlTVwFM2}9R$TnW^ zH9R)ry}=k|RQzV4@)O1^G?|C?8=s`>`VSLKN`cS1n|%4RU8y=&n;Yh>Q^%~4NackVV6eSIx|ka@@o-k4JU6F9qdt}E==(J%$PA*1hl z;=X(Q%Ri8opXD>Q4q&0v1^wQpD+M_7TzeQ@yVv4}L|DptEw7(Cu0F6|5ZKoGv_jxb_7@CMC!`@~&Jp>dkE$+HS20Rzkr2H~Y#i*23;Ko;qdXYgay*|av zcwU^LsJ5!DE~S+A>}bn$H5`759cCS#1&=a*XJTU6u&v%1UcEDc z$MLazZf%K7b{JmMXgKXG49kjt_r772Ke;{a{jMVAhXCRIoL|Q<-QC-jTEZN6{=*6F z`D7FrcN=1H)O`tDBF(Z5$dCa4XpAGu9e}e8SRXa-DY$bim4|E87v?1wa|JL+!adJ>4gIxSl;paP~rn$3UO0^Ci zlL6Fwd$y_R<5;+&9Ph!dGdQHx-zI@0mUv=Wo&Lncry4q*(+Qt`5k(|9Axx8PW($ha zO%@ac7<HdIw?h=UJrEln^fQHvkXr9jL4melJ`}tkX zdAtN0)RTrd5BIAR&oG`Evo8glcErt8wQ9|rRzH_I16%Bxo3ma_F3RDv4=y*TF4O8- zPD~r}b@U?zA402jpVUU zTZUUGS06#uC@Z|#A6w^iy!gFE9@J_#N^zVn$^-_>fm!Th2O3CK|uGkK0=P98ld(Ve@^<*(kU< z()`SPcUn7`!b@{_J}0N%P@rVh44G@h3M|p~kTnSjNV&h)FNW zjyKA|$tiIGIVz!?9SMEzb6%tyddjw+#Qk*jUf)&2X$E-r!mHBKq6uu-9+YWkxIDuu zRb7dkFY+?saj#e|^00|Fch2DYQeC-N>*1WhBgp$4n-2dhfc3&{7N}jF7ivW=P6l#< zjM;KT#YCb5PaEcI+&%)0_OUK)Bwc_^_K(dln5Vfx{n3A zh^hSjZqC;TQ47$7oI}MAak&Bqzr(J}j7pCn^nv4b#`6Ej5UNC?rOENm&VhlQ!6{%ud_t8`vpf5`l8lwr`KWQL=k}|?9Pi$i zIUOCHn>K$Q=b83g6<}OC6;K{TSM8iq;U{o(pu^ z6bUwLm!y(f3EX*wI0Ce?Bu-~E*Sq!GPAD@n7EcD|`^AqBTc|A(F5)xBGvqasQE$iwNx;1>oK~&Q5tXYiyBA^r|IvId1@$I+l*MU2KKZEb9oiThR6_wQjtWbVzz5ljvoFzLs(kFG zb<$O6%bxC;B7J@@qLO7c1(cxkuwA|LXSd-HMNzxgsxrl7v5`>^(^^bYdrwIp{BYI? z4?=Se-8j%=^O{MzRr~BQo%b;ij{&3BS8Ix^YkYp6HdlbhbR>k8ST+*)Jfl>zg}{3&qeSrN7jS z;^9KF5LQ9$;WTf-Ta}=hUot_Y23We*Mp~Oc#!5Bn)_#gR0n~aU$#uQ66Ik}dE%0X8 zwP&a*0%eN|<9+_ZJL}>sI!E@Ld&aw@%K4ykOEv(*Q)P8Vutm`k&>XTuxFQpI4mu%8 zQ|PX#viVM!Jr0u%`-uXX?n*g-_DGIBq4m9?q-jyrdWf|pacQRt!E+LNGubdBnPny7 z*FC+=m_W{GELrUB%TGJ}$f0CvP$183`O*Q9OIXnVv}0ug9cluceirdD?#vip%KGe%O6|(c4YW z4-xhBH;sPfN#EJ+`Y1pMJaRrU(@I%L$kJ}ieifK@I5~MZrG}m0AN93Wi%VG2t1tQM z2#ueYi&*yC!2w^_S5@YH4M>0(Qf8RTdT6ic2m)K0Q^)l1)K!dT#*xZINE7Q6z_v^s zh8UQGTHCFsEgm&|mevAnpP8N(vWpzakAX}#%Qi-Dih;$FKF!N3Y1E9Mrk(H3UO=Ft zje0LwqHcLM;pQ$)%irymSAw=o-zS$HDbH?T{mWtV@tJz0bQ$n7I(p*vQ^u`(&(=zOEI%z}K_BtMjUz z=s>pjk9^}uKxmarp%>Tl!a?mzfva1T&EMmjjdlxi62?~nOnGl?4&IQEVVP*T!`l-R zK{MGGC!J}ecPISLIsb@0$I3+Q@kthKeH~Ys7x9gwNZuj>&A0B?ABFnI_JuJ|;tI6V!Etl=aYm)hHJVrh1-`Zc#~Q$Oa|qar!WZ36Z) z8akz|uskTpp9z+4Dp^PN3r+R~%pwFD20nwi?{*^1+w3$qqsa26xA3w`$?CK<0T51ZrK)KXP1gOU9*4s^e+4Q^&Cm~z&&@PgXL;6sI}@H-=g+4zQsU~zM6iYzX=#d~VMIWlU4FW@`Xnv= z^;!b*Q(9NfZLd5WMI&VJNhYht;s5XK2v-Y`D0Tpc6|FAt`}&Yg?IN z#R;mwRQdX_!X+o&qQ68stC+aacTJzz;|9G8u_*IKG29Jl?GMGCr;XbJ)Niw6Yq(5+ zE8EmSdXkZ+BqRk4*i(guwU&}mhgVnL_Y9(yW^Fyz$ncZDtUYTbj%CG>Kz5fUa%#Vq zyhna~{4#jGy>e?Bi{o|KfMt`j2ids!@@9Ab5Wnb{DguEV1qjhxsCPw0ppE0iFTf|u zHhh7<9Z#=ptMCfgUMgCB;*hJLSfmQ87Sc31)rM%LD7vp%|A-RaQ-hx_+OQ3!LxSoQ{ zfi;2mo~-i=hn7k#E$xrGnR(vM^31#3$rsiAacyEPKunN>pMis7S(`oa+h(g`UVg}H zVPXEdnnt$Uwzsg(;XM;~3nmU~^|oj62^GV`$Nb~x8@h|as>^vf9Of4Jp^|)W&Ze?o z=S^}BFTHGmE-T?arg}c|hm{C&a7qF+DwEV=XI7$B-g!#3q?*HKM;&65Eh@g3?7^}4 z3{=d)Sy_d-O+^h&7@+q54kR1nEcSkiaJ+~NG~-xH8JtWrz!`s zN7$kX$43s|4(8A9Y)pcJY$9wTBA1)UR7Em&1N|f=M%)1n%jCp(Cu?)Ih>sc$5#l@d zpfbV`=~BUd%XPstmoSPBt&}Ixq#?hWmrr0<8}*v4R^e@J=Zo#yA6XI|2vTeY*9n?; zqjQqF3rCh;YAc~!2!q&@ zlat`}SCOGPfJc89+~Jp^w7Hx0!r;R0 z?!@%~?lq#VH9E{Z_*`F$n%aOc(>${H7x*2caNKQ^> znukfF-xjkRrLbxp{kE}r)r{@&c3>^AISyO9qTQo&x_zv+)L%t>nZ$s7gH2PgXHx}b zWsYCjUw<;xcKbk)a3Z& z?CkXHWNyV&xyK&SY1h`)HZFN=>v(bXCjvUJAGou0$gS%}{O$BPKT+Q7D?caSrmHs*#Cqn@0S0H3vNmcwDHeqhBnYkHbNzb)aV|oLx-yO{dFp(M3hpDSSkCeV|Y0V z<_UI58{E`O`fzI8#-!8Uu=;*k%TCgzKBr%LaRPeJ(2;&ZO$uIrfuNk~YGIxGrRraX zkM*2)*Qn1BAbjdX&fXWSyf0KGY~GIARs)8`z^~h~XVUv&>vD&m(n5}KDdse(eb+yp zet7?Pk+~%s&-GqOXegh?M?m|fi^&{?D_zHP$2`7e3kqwhWTmDypHB~|L{{q zGw1Y;rLa_(1T?taGh_nWnHn1r5_h&EtM4E(>yt76!veA}<^Z#Tca~3GsDANYP0Ek#aZK6*a*7t+C(-9&EXZDMVWr_?qO3H5O&J)6wpzIafFrLy7~;lP zF~sbSxfKi9mNN~!kb1jVa1c7gSsT##FFEL8@B7Jc8i&WJF%bzsC^{IxW1y{238*Lp zRkCd7?7Rr|m@x&KdR$wnMHY`7`LY(#yp>{-DXrFPJ*fEPn!C^^zq3EEC>j~1K++q< z!8!T+9rN8Z5~WEs%T%Gs-^wZdsd{b(3nF!Xhm;%IbS)`43m2N6<@@=cJI@_>iru>^ zQp%Vgr_IU8kqyl9UX|er+7jc3re@yt;1@FKmLGc2)70N7Tgo&bs&hkh#P5ss^;naD zZ_wx^UhR{8kMND_DcLT$5IdyJc^)5_0n7RDHeBZ|0wihd%d)8ptT}-zsvSuRqr-1W9Rpkv;6? z5O!Ux2Rk{|>dKOdwU%Uzt^UedyqM7UH|!Gg4cz{%e>?r@bI$9Mx-h+0uFXlm&4+Q2 z63rT=dDkKVPE)715O~ShcX(I6A4>;sR;{)k={g>Lwz_`sRSjzr#Z;yIrXGo#s6c0< zTWh-RS7`>>)4fv)$`ER}3vK7Xl1@fPrnq14=$2r?;S|&{oYuDLNeY7DD7hM3Q4as{ zC9Jg%C*^xgv~Hz@XYoX?1C~e1hqfyu&D-u*&B7*e75g&iU`L663dL$cewVQFt8z#% z8kgCdiJ55-x_ZZGxel##O-o$BT|Or3FO>s*`}U)5+mAWIqxD`{!|0hmKfM2V(ZNB@ zUgrHmOzSIFD!3x8ZetFCE8p4+WH#|$P(};!Q9H}g8?@=9?%BF+O6zT;J5zhPx7B}8 zAUSgIS<#ph+MfovNyzM+qyatw-*jT47=eWwt$ZbWlXpX zoD7yJ)d24#RsNXLXu`yS7cu(9!QBsT>d#~BIPo|=6hC|mf{&&vmOZoeJnW@6>uwL> z^BNOt>c{9LPpPU_X)C@?eD;ij5CVO7Cl0@k`HlIbQ~J^j&^0(6`dGB>%)w{+2v3{D z_s7SvRlgImdB33Sv0M46zRvb9Uf!oF?TrYlAA2=nV9U|nq17)Ux*nu|E$9cu-N>)i zU?)RJOkZW7|J6BS*NRBBdnpEAG|<6p8FU0>wHA!ty>pAOOgZZc4a;ea*rz;4f|7*r zvakGo0$CmuWxg|!UAs+F7MS5S;pu()N%WI=Wi7bcxiXo*Wa6y>K7C=-z_h0(YXV;) z9T73sgXa!<~`>r9Iwts z|9ZmWiYFGUl7D62`go(JWKNDk&WP}Fl(z>3dOF)au_2LBQdGmF?dtVWa%qvmUrFGE zfFIwBYz+_3alS#i5NNVIor7xyKw$hr$vUfJhuBJahwIf^3ZP@ERC~VM1&Te@lx%P3 zPOwZ&jH6hVC>}7m?gR>RA4&a-R+!lGhAV0zu#IOm@rBOUj|Nf_sHfQIBE1Fnm&XFVJq@jyhfXEl9Y(hj zY`c5hbVh?Ro>y{}3EUC9ZCWq=wzm=b+j`dVO8saJUcSqeH&JNX_q)e&MrTAxfDi7) znnS5N6Zqv(rC2!aVA8CEDk-h*+)~qY&sg5k;m;T9<>hBg@V+TPPQs$%eB?W6lPEW~ z&}SZdL#aR9uYS+@tg!!+jO<^@gw19EP2Lzz{2I&C*f9Fuvj8OtK;}3?@^`hpNn!~& zJ`UMFd@3Gr(%%E*Mm?Qn%z^9H(9c3J*h^KA{e`7E!`POF-LSjrHr#d;!p`RgXG}u1 zPFfD+>-d;eSvVV=@)f??F7rtpmy`0yQ3-d!9l-Q=jh@`=m+$XeH^klHvwPzxz-Jiu zb>PY9Qv#JLZ9<6c2Ao6i(dEEyMWvP;=K^azKIbIiJ1cw{DuU-6iG;sCQIZOR``t~P zO$xF^7(An2^YyEKtTH_M)0oxg8Eeu!jrm+)IyF0t2#+Fcd#CJ%a2R|3U+hmm@r>}L$Xb+cHihVCw0sHZtP z+jvpT`?PE~ZOhEq@X<_+r3Cl34$i=~YFe`s$gywKBBy2AhB42ySWB7pM0lMt(oJZ* zaw1KHNk$m|)llM(Vcih8aFkd%k8i)wu-V3Bz#FL7#)FrgYYtTBceJaxj^DpFViMp_ zQnQG8o--rP!v&{yJ;|fgZ1tH%82V5dfeeaQ@}W;RE(nd-zh1X`A_wmU>Q8wNL@|;i zB>W3e>qT#{JZ!uq$*UXCWPLs7JuDh5>F4LO0QI-#tp34$;~|2uIazB5%TSsnKET2I z?+%_U_)WTtpJ*$->%1WL8S?V*@Mz{Z$a#`Kd{|=KSCFeItw_6QQ1(yBNOM*nbJDPD z2i+cy{*x}w3t$9eb(0UHh1<{R$$BR;a+^&{(bH!|;c2~`OoCIL3r0Bo?-U&(t`+|# ztT<|kO}noxT+Fk(@B6>dRZvj)|IX~}F?f+Jqm^}`QG@oVjgsB`$=AaC9~D(9?KIzE zhtN>0{ci|XV7!JV!HvhJ)_M|0jj)5*8{smOa%bdsoy{IM({T5aH@AHe&HlDSr5*Sg zE|ThycTj{&{z*+uV>3XkcWGJ$r~emtzUB;DG-s=}Jg)?cLC*bZ<@VOQ;wjb7hqOlg|!4L+3bWc8G7 z>^eq2*K|Zh$;N1cB72b1hIBNu3!i5Dr52O%oq~K8gAZ5qW5>V~3p>%#jWT;#hr=Bs zLDXY2Q+CIP_NF&&9HCE2XSNruv$B#%oGI$~O?}?`n>*JUH=g;OP_Kt@xvRyh5jA7^ zSWq!-9yv@lm+tp2m4I{m?$7ELhg&OwwwssIB#Gxf>RHQy5bx7H^rZ0c;QY++tIloX z4ZoRzstYUMT`|||_ThUas2bT{r1EBCEip5j-o=sf!AVI;Z4?Z3IJJ>c?dC2nF820p zij!Gl-tEVj6|V(k4d&7n-}^jyB#?p!y)xuV4i$IT+89jo2+HzUR?mv%A+uZp81uMx z2HulOs}+_TAy{Y}C7>3yecQcvI#_K}H9XvA30v9hIDbAfm*WKR??@RlOL7mb^4~rl z7bjUx$A4H7INsjWQ z@nPAy9hN8$@-=t2=AfRa^4>uk^heo)dIg@XMksM~r&>o_FMKM%!B2-|A|2M0p7~_}S9E_jEYOsdpU;_8fb^J~q}_zVnGz`edC!#=FnOLS@&h$3xm*quD`}%Ac{uj@N)mkg+kDUxw1k2sx(Wh` zdedY#Rm=7~qFznrd_dlK4w`%eQ%YHCE=>$}jS>KDk5a?tmLDjOD$(aRauS?T7MOl` zkFk7xj}K3T9WSO?j=3LQb5dCNai&tMp$<};h>K;zea~G`R8Urk*NAsri~(!qS%ibg zu)M|P>w~PP%)QV|$x_h({%Ahv#0|^{L1A`IMt`rV3j1}g4<%`YO&lQyL5eHi+##49fj)}vom69s z&Pp6WuyaajqrXi_-rLry+x<=QI>(V<3?+Rbmc6bTnCxabb<~p|s$Q8_R7jnzKg3)6 z2`OF-J31{tTe?`bUqrKZ{dxbLxT+^W)WlmNW0^+$975E!9bw=ZZ!AP(RI|;5gQc!h~71r)k?mA81^Wf%n zkYVDt13uOfHN1pa;lRN^v}V2L{?T68>)dOSsypAg@KNafk7>9cwg(S2b!;%X2nf*w zo%Jt0Aj9c?(^YlG_jtaRUOc=jDxHgoiIZ5|=1$^A8!G-MPdxbf`TbkjnIuWp_nLoL za{yIT6pyGSr89Kw2Kv4|dU}1;>Uw)Vq8r2$Rf5_{TYG6??as-^c<&PbD%DlR8>QhR z6ZIN8qaWl=-mEFTzcklKrK8u6I`WsDI2`o$6&9{hW`01K=B@TeM0HvBglBw%Doy_N zQ{t1n?_P!J@y}tR>cjSxd*j-;Cd)0_VKkCF@6r$dhXqusLpP*sa;S#UzjgIWk|K^^ zsf&~$bf=*ah)NY<2A9Y5mprCEsRxvAeX%t$>#^n%$96$+q!T*=QdkU9o~zxH_MB~s zQJvQwNmO+9&i*xCFD9~9ga zWnUj~xYBD0&osDJQp)*uPZ>l8f@O;UHkH=C<5LUTvC?H;wR5kHWScWNF&Eg6GOPur zk6ErMMr=y9JTCBkQk4@kpx5Js%dw0ASMye8z%W|PeSedd zHs%SW;G^pQW9}`ZstVh7QB)Kp1f-+|q)WO(Qt9rH?#@Lk-5}j1EV{d;yE~=3W6_+s z@cq8M_t<-!vB&v!=09=GXFhr7bzct)`y<@C>v!4Ez?*Ny?;V(L)Gvwn$zngSg6lmi zvK}}4VNnhHvpkmr=-1=rLauaL@&fUsOI`y(5TLHS)x4ZNc_xpBsEDHl;;_*=(SUMi zFvCDW%HYNAQlvnZL(nLu6dxV+wBhcJR~YBz+R)V)_NcW27P;PN?z!vaa7JHMF^EIM z@$8x|R+cUun70tzoOPbt_poQkp2dumYt$`D!_7AVyO?Y{;A=xFcUWq})Y&sjGkaZ; zZ{0Tv-|i7@&wE@}j=rWB{W+4-kZz;%n5OXE)@th04LuEaKsbq)f#hd!>FC2>I?|85 zDhr4=?XW*e0vA>+4-C+;QZYzm*t*#jz!u(fKY$rDXvtz3u(NvikB>qdp$hg+P4X=}V==hHw53HONg zB6g5L;`;Q~{3jMd3yv4m5P zD>D1hnz!K_97b{FJrgxT;N%R zj>OV^ANoph@ZPO-X|{q<0Lmq&r{r!Y)%jy+FiJK8BAHpxyp1M{JtC5wRaA2pVDiPh zW<4P2(97QNA=IYxM4n%{T!2uks(ajAco9|3G^5o!aW{x!_M~V7=8N8#{*gmGUf~9J zUiYipBJO$HzX{=P*vBClmRTKL`mdN)l6{{Rtw7hwHH=Tpl&Paq)3UE#F6AnO^n_r) zqh4)4H67^C8Nk9fI3A@!a#gLu;eh-PnG)>wolRYhd&8{-*uU%(j_M z$+YqY79!8q<1D`l{lJPn?)QpUIlF{dtE=r(DrszYe?tk4w;f;n*e+X@mRps}s-Haz z8n2*}$VOON=sf_l-QpzQn=TH}VqS_lh%W`W<6}lOBl;gvsJ`*3)T9IQcOO?m zscC;=l?J1wwQ#-*N8mYPDYEu$!W;3b+#Ce??6s0f-;($x{0+q+!m)KZ*KXd_f1oLZ z>}~QG_K~lQ>FsKd*)|=8%4uNHJbmQE!Jl)`d8<{O7ExF7AU3p})6zrkQK5vL+dD~G z)MWy(#EZfAh{11~T4IMpv`hK3>g}YoSZRb44OGn3wF`!+Ps1(Qpg5ULNdQ54roMqb zkImEOzI>|i*aN;}{;k%1ERWd-ko7k1d^444J_YF`&Kz}5?A8KO$~<}YrZC=SeiAoF z@Y4gRDUL&BU_wpf=V_~p<%}dmX+UNNSIMBTtS;-(lj9-TfRqi@ko7KWg?qMbNm>O+&970!C~CgHr-m1_{ydAKwF ziV86275RLi;&VO1i`%I~p_O`A)sqABsEth~Pr_w!_ng#E`kU$WH1^j1t5Ql6x&a<8fu{k?@do*ZbY_ zF~=hyP9SdZLctml?*R{{EHIE|ogNDS(1V&4cVW@cY1o2>FGXBv48zmy(vKG>)PyOc z-|{OVz#+XcCxzK8X@T6)d45jQ&b0T~NAXJLiEWAXLF(-St#Unj%pj-NIXNw}AMcEE z*1Oa2drDdcpe5a)d^?wmP9AU&*bwDL-|#r?xTaE@ZiyorOIgJ;G$P&#+bga~AJvZK zY0(&<6=Q@yL#}WlOQ_SWqOP0Y*gbDsW!^^mtm>rkmVqSHjpGGy2!01k<>YInCzqYx zX+YLi%$^*o#cSpd*^j%uZ2v;EuzzmxvUZn|8Dm+d?Z{h8U7L&F_|zo&vFSwq@kL^& z2vcrUzd&P00y|RT{J0`(FP>h;ISiG5|&)a?Hl_l$%3pWrcTJBi%1dNJo z)?8#Ow{Vm`Z1cD^>$%frlOQToCTyaG`@2@-lC21B$?Il5?8YCt6&7+hy{H_!`I#FOHB>6WPx0g$ax14{b7rrZZw;wwnnW$G zHx$@!B7$YXV*MjNx8*%~=_C)^vb<5FsYesv)18f5KE+r`>S;ep$U!kpn?dT!6K*XW z=8yt!2?{)=QmvIa-i_{R=9yAe4b`C?)~q4@OMAC+i50_AqV%gNSj*E~cwRoO`z89n zDWRV{L()zM?R00G&rZ_aI`xmI-&2I*8FMw|8z3Z?^04JfZMWRU{4wwop@R!Zq2I9C zskchgkKqdOw#V*VQ(C^EiLo)|^AJAY1!L7BUMt?9w$Bh9@ofE|@az@-!`g#5v5E18 zpK_{hp4|~muEFCCM6yl^2=_mJDVz5&x~cW+;p&s3Get6vT!^jzh>= zGR+;|QK1B4Rwq`XdSm-ei|WZQnkZa$|3NRy-Jc!#*Arzw-MLZ0llTqgKyH7?{U?(B zBJ>=lE(M4wMl*SR z59~=I*WI=U%0DX-5^euXVS0rRv~C zIg5Y`ohxa~$*Y*F#RHk}a>{w;gZO;5-#ONoo89<2o%%O2gMA0l`OSfXf)uv3D?sD- zj6a~nP;jAY4`!6uHb1+1P` zhWybylg-t2p!WG>5+eJ}uzkAwf~jhT?!_xGt-}NN=0bhik25$U!Mix6)J0`>B%FgbMV{NWJtj@VJ@Bbv&D)NoK zlVbf&Gdf5#Wo*`4>KM+V-$idmcP=6AMh$`eNtFzi^2;ZG=(`9Rvab-U69hr15c3h% zwA2IPwnxisZWGAsk(kBilkAP23Vp02lNX0Gb#_c-j5Yvr9z!xqO)HfsLN6H9?Zt+_;CM^Yf> z-kw(hTwWXUXp(Q9GjuQ!Btyj<6B7gaztB5<#<$*`eK~yhRA0>x*m$wq6zgI&zr6fm zi7u_?#rge&b)VAZ&^lUOYFGC~%*TItkEaVWgF5J(csF4K*i&%xWsctK>^f`;&; z(Y5(UhL4$fHG2!Snjxh|Nr|R28UO;^TkHC#$9VV8P z21rb6q159bCg(Zd>(VFZ_`aY2jR!k&JS%U*jft4!{6CllWhsK2c%XKmt`~yPd~R~X zEn>uc+FH7-uCW&tz4E97IK(NT!w078`|w!&m99X4uAqgdAJCR3jr@2cBH=olQXW!iHr?F&+TR`X0>NUazYX~+$_Z4?!wn|M?TCf zYtKz~TF0EESMpMu)JxKkUpd+BJ!Cnx$ug|Y72cF{PUQAi>CHOu>#!D#HuonCej#T- z8Fs;HGMJwvqnHYiTiB93M|l<@Ffmk$svG10luFn}c7j~0xVY#74?X(VPnkFD5K|*v z-L=YE!$(ES%g%e#yGi6nd+DxjN)4={m{z(JTv_X#gXQkhsMW5zv|*;$-c!M!?1VPB zY|Z)Z7*+0j{fKGWmrPe2m-thUl{pL9?lB1Oo(I(r|1xB8F}S|^Dq`h{&(q=pp5M}l zcp{i=;NhwH*1EXIjFUUD7v41@d5qg^A%(6aT9l=^{Gl?ZT_zPNE9R?(Luy{~4jLx0 z9%Lw;oCtJlrsFj3b#{uiu4z{n9^I2Q54n^hx(!WO&F;qffy14e%#O)V*f=H>#Pj@p zN<4U4JB6kC+g@yc2A$J$l!3UG19o+*C=>wVAB`uKi`kwL(6wP&=sTVzsDYljlrQ-p zo21M#qpVbCmEuH8q(b~NJb;UJq~5zdUqoS*=)+VcJL@xBp?Ag4HWHL&?Pbz5uP;Ve zEACIl?zo_b26t-qEtci_o=)5Lj0C~VN#PGFs)0qASoJ{&5jD<^eTLrA$@&)Gf8YNj zAe3c8Ro#&4MjzqlKG;^G*;vQ+=S!DR&kRQ3!E}4{mY2-TV|Ta;%q17aQBs9v&?2DO zt44hun}EpoD26aRHvG%Auf#0cmwTIx7aO_Xb&p4vWolJ-PxU2oi@8b{z_}lo3S8ts z@5?@MMsb^)i&YrrqFRIcTz2(*9&-ulm5dB=bS)ZO}ZE z*B8m6S!yoVAovwqPrf}Y@R2l$V2Tc}V@ugF%k)VkX!yFU%1SqMa4Jxc-s96fSbSp4}`UboxOIiWN9e)yHgIdMjZtGY!jGRLE_iQTr`k3MvK zq)hfsUpm&jX^AfGXB!w$JIz;AWRjs=^%6E0(cVW?+N)p*82;-N0wW{L=AZ z)mpreIVM|tRwV!o01-wcqz$T@1YV4GycAGFcf5$8iz;bOH#1zECv#X}@X{GM6^U(1 zJ6P!k>{6h%oGh3DfOCBdYVvGWuQtQ9uz-cZh}y}%Bheyq4w`jlakZi8fNihbwokM) zG{`HLsbVGk-d?{%^Yorh%wfo7)lX~SsU?%ghHW-sy=12Y&nZO(LHrp-WHwbO0?DV69zOKcvu=>f}``X%mm&4!4`#6X_Obg_M-VnBcbRz)(24%tR&wph#k z)qW%7{q5BOuj_U1msf9q)b*3?=16O?1}RJiYM-Wn6wPF0d-;$8veohZx=qz?dF|S{ zS&m%kLg2Rlr8}*?(Bvk(+zhxy7G=5Z=C(Dn{s`e=+uvT_^0gQ*5d)enqdN41y{%cr zWp!wnmp!@2$a`)mcubS+g3cw=Ep(8hm0HK18ZO7ZYc_LYn7^4+_UuQ~`wyDz;GJx9 z&mi-A&Dz_3eAM#8_*nBjC!)oEIUJjgYgTqA+E$YjmOEM$eWvxidsWdt{>@rBmF03I zw`=}FYeA3i=A1=BxML3r_SiVN6dUejivAtEUT_vNEt}Pnfxg0OA{cHTz!VM>aQSN^ zEdiCoGSRtMTP%;TC!b@~KJ;&dl$a6zoi#g&7Mro)P*+O)nR!th$aULuh79ZuTsD#g zi8E;I0XR#)F;-(D0bskRuf;y#55DX0#nd@rK9WOF`Uys=?`y}d^cG1Hh6(Ts3# zwnv9Kv5Co%WJt1*SiP@f;_Z~ZSmh^OOgB-|=`5KeQ0Jd9{pepXugrysUYtCGhUZ*6 zt}k7GV22TV{OBgpO}2-lf23RhFvSATh7Q^rET@{9GYGe{lygm^n~c_esh-FS7!)b0 zY?D~SWT)i-84q;4Mik`=KV=`Hh3c(5AwCL!jwxGAZlB@my=H zAH6Nl`0*gmNEJyarO za9~<~CoaCejQ^`Zp;2owb#=-HFd~J7gz%%=8SM`rlJGv9_7EMfG^SJP-5}A*k59ax zkRKnPPynzouf6e2eLv46^yw%YZDA!f;X&erpP7UIMyYH_1oJ%|*gNjKSS;6U_O6Is z;w|tlD<=f`coB+AixW;hnTCmyiid|%9D&JKWF*jF&WN>;ud8sIsdjAZhmW|zSBS}qv`^xWA*fk398-YyfnI9rAX4O^l z^c4Eq2PLxy4XIKLrN(3be&QvgyS#dEI}LjK?0!XHirKwJS)2tDCZ5We|AwsFjK=bhQ&!rmLa? z>gz!w=i*dxRL;js&(241*Q=JwhJm3z;o0;HD*O$JP;ak=N zjF2w_U@J$En>-3dy%e7|m4AQOd^vlK7u%Ef4vUkXHN_I6{sjYrb{7xPZ|FxGXlZGw z=P@kpHF5lAl}hZ6AAvL@#&hoidB1;Oovc)8_MkzrK-gPlH+3BeEtb>RVt{w?X8a?e z9KbazCY9ziSeWMSYSCBqeWsk3lpem6Sn6{9l}s0c+ejc0SUP-Y77Iv3R(Z?^XbTyI zT9LpA49xfEe$e9sA%L=CF!rES-QFbePi=z991i$1OA4Cs$UIc;Nf<7J1?QLk!$$;+ z#=62=TkAc;11l;rsZHw0q?+Ncdk_MyJj4pSuwfz*f%3ZZHM2Vs83SG2s8W)U=z(S4 z<@*V=lH_f#auuScX}2qd>hOc^t9q|GX%{uxWX!ScX4;jVteT-)#_?~y!AI#$i=Vbh z+4&!j%ueqwqJ|tad|K15_Ce^`yvW_qT@?`umwvF+Y3&pp@WI|L`j-g{Kif?YB^;XD z<4;uV7*o=1lum?1z1~A^%{x}KF9We*+9lF^osqLeaQX3^_OLL)VCYuq?Jj6fjk#_L zV8gk|SG_tq3mk55IiG#&F*#>hSwm^-gG8m>|6$_p`mVC3HI}u~#^UiTkS}?AWa%KQ z2+)E-OUDM7y1Un|C|`IaPH zJq8yUpIAVJytkOli-le8Ditn6vpYS$odmpvhgW)s+{kDWV5uRKzFkfW3$Xw{v>#FB z?PF6n8|CMTKKW%Zkpbg#*;k!sklMPYOYP;TLWOiRUca3=3VVqY$T{gP9^}InuHI)} z;rvM(4~G5PKe-Gt+jykF2m8bIbf#I%7Uapi%dqKrk=5-GatZ_wxJwTk=Y$=&=zlW! zB2d$w9rjkeJ3hon-9CQGkh)6s@>q0g*PbXXgsiYiz%?SEo$k~4j5N9LWKWZeQMqAH zE50ki7dPOQ=uCGS^1SUHbSXy^ePa91~NTrs3?Gb3*@V`wUKPK z{p@RKcngNZL&qWB1952vj!V57YiU%bA$Q*|=JNV8p#qv&u5vyO{Oc$F{fnOnAMbQt z+AL^wFBX1`Jm5o{{lUmU8f%`|OfJ$bxZ2E>-o3OqGP7ew#{etWSW4iX^&E{C5qm#} zl})jlMBu2Fju$bJjM{|l?q3=rN4(mBzlKa$HxYI6$7{pJI%use?&`S|mz}YJe@Z@K zQ7)w1hTaK(BXind%h&|Y&xao5cZb{tPu;Gbmv_e{%0zR{37@4Q)%N;#S9w>7QZ$lq zMB)QTPyxbYM`$MgwYxIL9<2|4;dq)TYe+X2c`C?;A>V0iNbPzqFO|Ls9hX#0A05H?%3ZAHPfbzYO4eKi~JU z{bNGpm+mb8?k>spX?q|OTV?f zzXtVe4U_c92cR$1)?b=LoeuU5F;er0vrHJG$*qoES&8b5+X?Ih`(-k9nHb$RmH%X5 zg0ATrVQzrmpOkmHEBUpOlv!ttq7-W`Hj>S0&8fnXXVF4A!+P0;D<+07(4N}z(wf8G z3Hpf)lXyOOg74RpSxb3KhQ|U`D^23zmsl;8;Cy8No}#=veEJAkpDa*fJHwu@!!7PKS(Qfx-3*hdyA<&zCr{quNz&^`_kDZ%QZ@+ zqcO+0?vkU6?RU#4vKxn*{>s@kx|$C=8@il3-b&wPvznQS_Oh%!P>b(aq0T{;8TJ^Z zZOa)FTN%P$>bB%e0LU<{-ERjjQmwlYw#Rl{ z{k^`u&+2uvQQ@pYqvNS9B-+1T6nJ&%w&0|%$mWX90OQvW}V-MEV@-DfhCo> z@+_J7=ll3FJ6tYvk4bxWpXPUn*UOe3@8ZTd;xn0_8gJ%G%{Lo;-pG=Rh$3LCBr5wl zKW*?zj`swu zFK|Pws8f=3a?Zu@IA7SrkSt_a_fG&cEkDEOFB^q^}W$pZD1j zUshEs(a>X5znC_dUYHp_#F3*T;VBt(qRwY~jEg}y_6LwzJQCYkpy%f2AS|KUQ(8*~ zt(f}PN}9>+pd_LABlT$w-{7R`G$k&bDo~kEujKEAUY%Mx`49$!PqrpcB{xeO9sZ?s zOJqc)I2tNaGBG{BpF<(uDQK!Z6;+39ym)-%2wgf08)In)OX^hB*G8qNZat3I*EZqV zwNiN1qK%6`m@soXdQ@=xKdtRyIw};azw7@L<@(P6{;4P4o4psP-Zgqt?LI}NIXT?^ zxk`awN667-K%01v%~cZramSB=e$r!qW>>Etah)sh=8m7EN@rJ9_u@>;%^8@XbR{D5 z?cc&hb4@4v6L+QBXpVP0)2=&W5yiNdjz${D?awB2n-7pSlbdqAT^vr+@7b{K_jkhT zE}}qYU7aDCjf?qrImO&P|_yRX%Jwx1M5&_MOT+IXorjF~C? zex8${L1+FQZi$c1KDiV9Jy+Gjz%8Z#Qm!vB&43{!@V|tX`m~CTBWCz!*&d@c!~e=v z8zj+bHegbDiv{=?zK&klocS(=&Hgaq_SRWMw@}ZVA$aESn&~n1*}Df^r{^aB?=PJ> z1IjJwgSCQEo`c)o^6i2j8BBL~fy^$Ywka%@Kw>07SqM~Yro|0oJF4mBjwK|T4w5n3 zc>$6pOAv4=HmWe}nQ7#jfcrPR#nb@ycRTTdK`LscJQGu0Q&U~t?jg&>NWiH``SmO1 zm;3gz7LKZ_daq<-oscEa#F@AA2&mEVSej90G!h(5feAyXc9wSKDPM8_qA6Oax*wB9 zO+zh8IR@vfRQ}Pgzg2m=ApERU^-*M?)e0)@+Pm>gm`50+ob`e&AM1I>F1gEJ3bf>e ztRd5$acP+)wJ+BM3vhn7RuOqXq^JbumeOF8tE{Y4v0kIY=xKM7g5T#UtX>;Q3FQpq zO!y@bkl1qT;*p6@N>cxm`?4By(>Jkuu)CX_j8zGEIRkJlbCU}nnK_?)Hj%|$7U?wh z5tJ;b)e{oUeRIniigIW!H+QK_O>2)=!ek^-VF*Vb?jSTuMT$IOD4R2dJX%NkBI zGLCKjWkA5OS!VJ4R|y#j$%gcll;<0cFyie9R8n@Ul_=i zmK+)i&S;`K;{%Zobg~+4L8~GD?6I1^l)*v@6&W!A1{A47dPdXL zKd9+B)muu?Vn8@tO(xSy5NSA3@#vU#)oNts(8e*swaj^sTPuUH*isI{|3Z-QkfWV! z7nQiaDK_TyEn)S02l$pTO&@}10e^m+&D;K18^(|IK=Emv>^6$zj&U;xNrr-GUz?s^ z1qaN`QynBz*L%AP?WZDTqTo@FMoj~*6CEQXBQ4MUQFCJ!MkM=ptgTJgC>0p8%0BURIv@!$#}8 z9-ehPt=W%*LPO_?88)n1o&4B0xH*}Mn9+g``ZosX zyKV)iaC%zv#_>#hI}n35Ul5Od4HKh5fOTDZo>I9Y6w25H!qN)`Kj!OxwRKXC=c<$> z0FQi>gVBBTXc*$4sW3n{d&#sl4!6#|bta#vrl~CE1fOIB@(de%6^`~uoS7O5r=u~g z^Nq2IeK)P}tqAyr|KdEYv9pJCU0hlcf$>4kL4G`dUY}P`%AbR2Y!*MuLpD2FQeOD! z-T75m8iP-0K2t9|d}78^#=Y-pK%zc%<|lHfdLs)~2EoX-a}B9j9}5X$Z|U1)Dytsg zEm$5hHwtbNG%``NyOp>?N~Q^V?@2yMsM}uYTaNicCM~MpCdbUfvij6N~BOz%~j#NAyMx3`OCh{HBZ>4QEQF~B{r4wD<4SI;U zH>*j>Z-`Cm#=Y;lHdT191@nnv>htg3>kLVg(Pwe+3E=Gz2zvWrdlxJz6j^(L$Yr=v z9K#t%+lWxzp0(Z{swhYm?;I|C!>?9uOgjTw*p z&Y*AYj>e7Fj5AnDS&X73c>Hm0a_-zv;$bW}nIY8dDtZV)iYlqx?<{lKZTs?mzOi%g0HUL(GO1nYp#EG z^?2rPIpZHXhm)wld=*Ae`OOF}wIUqbkBpSQ?<4w;$Wh$+=`?+$8k+b|go@xBH+sG$ zub==fg6xi;LrnE9x8tm1atE4j)A~Puk<{H;YP)9*??3W(Z+rg6&GteeAjm}#4|STl zMD0ONZyXTr5ONvOVrtPxi6VMd#WC7l7(fj&xKyK+o|R6jwQF(kU@Bf42#?X_p!uY8 zv99O5Ies`9Y>20CsWq-_ar&tLQ;6_(@aFIM?+BqY!aOWmgAo3hd@>*U z<(0<7UZgKf{Q?cmpS%`!iYJ43))}4MW~23%<~(nwKM-I6MdWuY(?ppiy;`Exe$p$R z9-SgMJ`SI0vqxjYGzZFYyFLeHv;!M1jpdPS|5K;+%zoNXBmaRAgAXw?pF$*a?INZ8LkvF*7JNR?%{;jI%Nr5l^G1uX zPPsnxl!9v~*BAKPxL22oPRPvWaRb$-6;lSgjDVH>Cri|E=U<*JK{e@JdY7j;=*A+< zQE=7sfU(Xk&?s1#zj(YwX00_s+g&%JzYT4yqWd?UE8zY<+A%K#YcC1p27R*jq+= zuB@X$qigebtX1a2{)1B+y$@1WM~0`q_WO{hQ7?`erxM-;V?ppcf=%;R-5`XBFRTui zXm^5cL1X_F3-ClIKg8pfrcF7H0^y=WRGvF&`m&n}(cJ?7+)1EYt)_H<1JD}}Y>-0=?SkyP?}ipp zyke?%!4L^-51!DPKGaVJhgYAg1v)yi{Z|>M5JCq0(}^}`P#%~{bc}?Ucz4Sc?#c(i zXGy$0M>9u<9J{=yr~8jHP#Zv8l2J)DAu&;kkY5f42FY~hg&OUB)AsGa!mh<#EPXOg z#MBk4$K7S(*dMn;I1ocgluUz&B&0Bvp;W8kx0Rxi_Qj~Q?9AK}^}X0eU>7!ZxxHk806L)Fx(t1CFm z;e4z3GI^Q;{5xq8pqM>%Xnh2-P?#d*Kt@Xl)9pouZ*S=z;MT}nFy#GFaK+K`gRlxk zoF%;uP$a2RRStzMQ1Xaq>&g|YPmPg^z6Jgb7+CH!xw-$j6!S*KeISXiL0&;&eQh28 zfZ*&Q_%9g{9u3>ywP<2BxtWZ`_MM5u$xep11yC4!vI?b__-sofVu5%I{K;M)?Q6n? z?rJIOt&-5koPi_(aaPSB1e@VDhzJ|D6BjA6F{UH zUbcl=nfxPpz!V-=W9_Lf^RT1P#wVBc7hv6qWFt*5Sfx3XSDII>`pIJVijv6kpYJRX z1b{MqzNJaIq2^cqwlzU3V*IrcG9YQfHo0Jfg0vx_0)vyF8j%I20FZ>ija@+Yo7Z_Wc(E|C!xHuytQI+*G!AD1^ zbC1FHG6YWcPdB;FIuNjmNg=75m`zJm5S*Ncvpk2#5tUTVHQF)5Cnq|drE=Br-r=xv zmD#2w>qQlZ8wy(Y{le&{=PxsjfEZQXPBJs_zd>+ZJ{TD#ZNwOu)0qD_`|{{G(CPqn zRt2Hhns0r5D|Za_SWcE3h#mF}rL#<4X5MAaqgxnE9ySg`d>!p`N}?|_X~0ri`3oN> z5H_7X==|fEK2o139^AYVXY|Wj9u1XF?1ol=#FvC)UaG^xko8OI10FU&s^Qt&YIPG& z4-8Q@51#fcSBB zOxGsIV1WJXn$hRA*d&IKC?*573`vbOH-lcbXJ~McJbB5(m2-mwbHfa8GiLNI9Qbuv$Ud13+`ncl*DKuFAtQ0`xw*;HNNL~> zg17a&oV;monNaNz+U8s*9pNN}IqQ-XmjFmp7XVC-fEqTQ^TMK}&;Wo;^A=Q@{UI`0 z!-)v#N?4{iPOpCby5Gamdwq0{R5KQ?ygS=22`C~{ueI1zD%Ez}-dp=aX&!hhJ!0tn zi2m#5y_TteMQ}hmaIjy#GoW=f0|?8a)rT@$_PoyuGBy!oL_aVM1j@RB*!pf?s$k#c z1yYWE3g{%+Q!O*$3Vwqnpj-Bty)`|?Vc#jV*%H&raG;>7s%rLn0a$%D zOvcE z`%Ivk_xg2v25iUjgoJOJGd@@2O?h9TP<3(zCIL@T!a}*C;XV~e+&~7Mm9}3;Q@C{3 zlkX*^!I^m(a3S*JZnJM=77z6PSE<<69B>X8F$R+fJepuiJ2*7-HWQeFV99bwnav)j zsVia!z-33;NA6jf43F^&NNE@+FJ|61!^8MVFOS;EJRezsF<2~YWvR590&kyc#Gn6g zX0o2Knka~g3WJaf`8RH^TBt4k2Cz8+T_7=)@qfSQuh(Nx39{IM!+vTTpj?&3h1=$~} zNCJ8d6rj1~6k=*h8vKjj!E9>pnl$8B)t($o@=^b7E8twvqPWcH{}->cE51&)DoADZ zJK3X$6VCVHZO+oV%ct?VaJo!yn)i}850ZRNJ;7w~Oe_Y6U>d6bqq2A@@b(!=@;{@= z;>V}{F=W69{P&g6fzRNw|MTtA(qpvd2ry)wK+I^qzgsfQUGTV zSYW~*KvXa-$1kTov7Qp^Oc(=7%m>ru-S)DLwA7`arfMU|qKNu=>P14+(OkizJ9rL0qNp-{d_Szn_oV}yEB^gMmCguF z;~{rM>S)imrD_|m(2B0}n_bf6x3+pWcV3MSfm~%eRbKnegwoJep^OJw%D7&fZQ(6= z&`96YhqsJmd_X6g z4bUEpcN+=O|FDIaIi3w5rgYb-a~=luLFHr77%jaWi*;^vbcTo{4lB(XqLQ?WboVBa zqte&14IK4cT~<%r1;#`aw(Hk@AI5}R!E=E!i!~z;t1gP^TlDX+Yplb~<^!I=?B0wo zLz)O~_fNJgHT+TBTB4jgc;N0rKj3m4CLBBPr$;~9liY?Mt^PJZ9_ZqTx75&DPAg8X zBdj)j{OPTV&H%w>(sx2fU$7Py=B%p=)?Au>oV)K$!^spq`DI$z2{qa%qc^r`LwCp+ zzQIsROWoD3@HwyEx%t`TZRdyaSX-oXL%eUhtXFi~Ic|_Mx7~zDR+M_azH^v^IuA_G zvWAK7pQU+<`s-ITV3^p^9n1%A>zrJj4V%|VA~3xQ(T+kyLZtV_{T9j=_{oko|1)_& zUz5JPl`|90_LLIH#dQi1bI5V~ms+>{DtizfaSZH#0q6nTxZG^PEZ^je%ZtTuhV>Or z=#st{^AlMvqNUTh!lPpj*`)Ct)-ghBu$!NZ?MIRD8wtb_*Yd&DHW)$#Fe=&vW~%a; zF<@WU0VRi;<4?B zhYdhuAJt@b8+RA=*A5692ylitw5){_!_lqqQLqjlMBhF^LDZ5m`+?5}3mT`roqZ^B z=wPuh^svErkNdQd=v-LRine^_DLq5bmDL^7ySPXb)R3_)Fs%{A6xSI%e-p+=S|gci zos}+f()}uHSCzsToF+ZN_WClz8JdlQ$v7YdwEru%r9pb?lNbeXH`)(5L4MK>n@fdk zHDbM$d(%Iu-O?-{>ZuDJ7P4c(Qg_uWY+j%;l#t}-vGq5sy`v4k_fXU~ng%Yza&fqK zyy%@WR|(*U-242-gkpHQ17Amz1`Jzy($?9oeB&jF8(eWB&2|->300s0(6~fhd4ui2 zd3bUSVgQOLw}_ZYFkYJjaFs=}%y*pfqGwpKyDhvdiQDMFbe^J~ZD9Mg-&)nTP zLOVA!%EbEsoSDhKL>WIWA>qcZzPWF1dHMZW#G=f?DXtN2jl21;qvPR>IZL0R$%^6e zm{4HyWzN4F*Z-nD6LbfUsjPTpkC{AjZz;)X>RI)0DVAe*9shnxSr^nqZAOZtQc6-2 zzQW(GuzY-xId~VSsLZD1l$Xj83kP8GX%{KxTbF3;{)nSL&^pB6kf}lXo7RDIK0!dg z0g6Xx{l@#1R`%t_|C&M4SkzgsT@ShBrT}I`_8lhZdlW#XsDBsE43+_d!2{saAjrmX z%`|4Ly*Ud&EU>qn-B?{+P02)trHa9AiOa<87Jx_w8??ikYL!Zf1C#~=4?>0sK>Fo; z%r{rRUvIyCp;2TRV?lE2ndK?*aC_-|w4{|UPbSCGF9Yy$OaJ#PZmI`Ml{24iwB*zDj_ySsTt!0mlT$w@{=%sAHFFHZWlvWkVQ9(6Ma z&}sF4^`n$paqGv+)#WwQaC1OE1df7t!`53;-IA(IuyC+ENzWSGU2TqA_UP&V^hm?Q zP-Yvb6MOYltw{?CPEo&8#==roRz7>99YevC@l8@(Tw1yX#NAz^CvqdOHKRBMh^vqM z!Bk~|Eohr-Tk@qX#&;#DRT@W~UB`1Z3NUR#(U3Or*FubG^dpS(Rlq&cB&@u};dlC3 zO}}19i6kSm=L%wKH1_V`ZDCy0rI6}@a7lDpuzy!0E**H!V8&a;Uz!CDP&(&0T z0<_oMx9kt}B_%Im5U90&n+r3(!6J!h6ZEv77={ImIeS|NEZII8zd>4qKzoMMmSRxX z+F%0E+zBQ1d|Q@%{P5-e%uI=e>(PZ;wEhMRrzDI3z+Rk_n23FtB&H@Ef9L&s!{AUd z@=Q}h_tzjTy;h^1MtRmf#+VN@g;`GnG$NlP4%~&XQ0~!_I03H2mKz`{Wwn^hbBj2d zo}LE!wFlgm6HBd3ot8d3U~PEjP#^Iv_C>Jh`gdc7NGV`WA?WDirmX<<)Vt|_Rxnn0 z-tS3U-f4Er1G%sIhf`Q?rX(2I#q2ywMqw*)3A5ho;?!X1Ir2vbevLxtp*L*)Uuua0C#M3Yv zer+!WaL}B$od7B=O5g&{GmIPjl%zQ2W#!L96gQ^dh6>+8?VgXpmTC$xly3mgWI5m> z)KoDtD~!+nA2VmrVgf_)3US~q7?(~)GN=aqKO27U{z(-WN=LxZfj$EHLeJn}AYMlR zv;uu(_x{_44ES#w(hpPhzVT=xKN@@k_n$ycfYR3=B0HG^t840xNAgXn|agvq3SM38?h zHW7C;P-gnGf^{qJNkv2O__rzti@EGgXCJ~d+ETbZhmJ;t;9ktCk6>IqT2Jy;CY?8b2F`_ zh|Son6>sdm2de9%RUbAY$EP;7o}R)Tx9+%72(q(mwT&AZYieKH+=fPov4+l_o_80{ z1H4ho)(^LC(K;3uwvGcO697bNSE$+7#^mYB;=jC#bRa?ve|v7wPjGr!McT04^^Ce)y(Y0L`0$4q>Wd2=?%qD|N1lVl1``Yb zsr|~JNlf58F1lW~k#L;+6zL#Fe>1I|uC;L0)gS%kZG>AOhOR>9PbHzd9iG{V$vQUXWZ5IH*|KCzlW_{)r3i_&}{^OZsFw8?CSJZ9E%X z%1pSE*Ar z3^F9Tw_ZU0&!S)t71ycCO|GGMp3WHs=rW74pms6*pCgR)M@LH=F&F@mAFO1(!(nia zpPyEaIMh1mRnskcuQ#8FOcU-$@ri;$7+<@YyS;q^T=P7GFuf6is$`$wVnr^JN{x%Z zMQz($9I)@bPDgk)EueywzRcwypPk?3`49mhm$IznXDmK&9t8gBA()IwVrcFGcyj(f zpQHaDG=<^(-FD;uVec)Y;`*AsL82tVl3>9@2!Wsp?j#T-!QCN*;53apGz3dz*&bVefsm)UI9itJ+nlOsVjD|LDQq z$;8f|%iRrrr?)}={YLBivawEmg=8jRkitCtnSuY>wEu%~sL1+speWFMo+lwoaVn;R zMewTk|CIi!A}b8=@0Kgr2whtM?t}=Q2wBrXtwBmk@;|M-UZzpCg^?uG%G!ht(zBOgp$6|8S(6CZ}WW!l~!9KIF%b(DGv4k66I%H6u_; zOtO`sxvTJnq@z@vje7T4=ja^EYyRwS)zz3)IZ&?hk>E^Q&v#YRtZS_21yAZ?>X{qT zj*bBs5KBKRaNsIe2l>WkX9J=RMlDxR9#aNxY<_jJ2f!*&_9u?wh%~abXpByLAAZ`(--`O~^xKEuKb4GimBX zs{;)^Pjgv$fF;oZ$S0Fc8U3$6G{l&g067Dgo#Bqg%5?qQTQBBIo>l^Zxv}=JFv|G@ zb1rgb8JTk#;0>0`V-}XbIu&qwF=74*P(*fCP7X6G%jmscY|hZmepw^7gnbo&*LZ)U zD+8SKBTI^&Mlsn3VWRtMYce%6)O)gG12{;OiZYPY1~u1cS#m_l4Kw4y%s4?9Z~#6^ zYqFG+l`jXpg-mq(lQVQ9A@jhB9B2SSRQY}_ih*87CrS5e7O5#wS+{;gWaqrz0Tn)oaR)+Ij-#o%G2E5<8E`feRg901 zKjIT1KdB16;UW)wAO9zubrEKS3xiCy6?N8 zfBbnC{}6xlm#D#dfq@%0j)&|Xy?($Bv<^&LP};4(OwwC9SDJ}suryV`)v=~{WOltj z{26yiF2?r>c)H~x?~(wzQ0jQwYlOOSruY0h@snjQGw6CY|$tf&XC*-8p;inr9(D-?}&Km(r$+A=~ry=wAX*NYB`n zuWS<+(7}8_UjnwIXzSIbi~EU|6YFKFw{5Cp(u!Y}Aq$0lKWG`ACEG9K{7fXd@b zO;QhU(r=TD`F6CF9}umaY=tKv{lVCI47vwZPVootYL&bk6fO-ouhZ8Y1b~jdQ_3SI zv8ewbFIasj^3`gI8BkkX;k&h3o?L}8DO$a0*9%E*wv!>1+co!5$a*1Yz(Kd?pS6g4 z7aBd|zuJl_Tiv&B;MW%417EiJv(W@@rY2A5NgALd?xh@@yM>!vx8p){laT07S0pb6 z!}f`SPq|>b(dH7oYes*)Yyw02cp_{C)Y53!hER+^hrDrt*acil8*U#!NtHGRA)Z~f z7dMHWha%s?fLui5<~Ib_JWz-IX5l0$la~YsuOM+x)xKKyY|orH_JSb3J_;sek-|?N zYl+?BzMDWaE|C;vMY)ond~rHFBE}l?tg`2<$s&&SE6cLsGSjMK3tLO{j~|Wj*2e@( z*Q3cY=}F>3oo=O|UE7a>tIOGh2Y!Fud)(L0L(?pf6o~6lNz4L2d;KjZNnV&i&RGu- zzdECZs~>iRerKfJ(bL1l_Ag21aWw8EOtikun0rz>&xl$Qb~@QlrNwRiHus6(WN3oq z!}xJ`qS^Sf^RBhX1cmBz|NI@gql0(!shhQY4u;rDj}Z$cm9EiOm2G_C*CO_UMHE${ zFI9!5y8LOWVzb1l)M^383|cLH*OL|NR2qyZ`y4D$@#*_xIVlA&(}(f6bDY~>Ch%sQ zl9&L$XAfB@lV&I72H*=q3S-k#-d*bIS4?H3l`ueeEEhfg6!ToxO{G^HTOt zMF0!wXWf`cvKYogxl}IlhVyKJB#I+MrqEno4)Kg-V+{o48$rfVUngWx^!{tpzp;R4 zq@Sz~4kz^s4AlT9XrNEsr7s?_Q~`>A(#YklPD>+vEJk(*?k5(d*dTv@*~hDTp7sQ^ zYzfaGplJx_g`8DlrPa3w+Z0P)?Y9)L)>j_O-D+DsRC3w4hWgQsKe&%`KkwYY(l5|EOk7WC65p@CEY`Us~87ba?uJQ-i1G>X3F+9Gj z%RJ*J+aFJ%uy+GQVu$6Q11l!;ojg?>LzR)eISGNIHwUQbHMQ+*6TRrzDh!``g&8Zo z!a7d|uc3K2q)(PvcC&2JZgTb} zZ0K1W&*m%N)n9GjtQ;SoKX%&6xSDUvl$;ubi{Z*g8u@nso_+3FALaYD0Be-S+ z{pqMSzP|kaen{8ixtKn=VA-#}B4CPsvAh5d!l-!AxpLbaE%Zpnj?0DJek($L#_8t* zyE%nxuO9pdx`6q|Gq#Y#=^vGU+zAD?!gA&_a)=Y`c~5#)#YjtC6s}8rDPOTy{NYrX zeDjE9+)=?{K&Tn}*oO30uSJn3L+FmC2G^NOoL7fRF`=XQtD{3N^OXiq9KqFTL5u*g z=8p;G%{cZiC=2V;_bc+Et>qku8~aiTBVu=6!NIYB%^UZL5{!996SJFz9=QEK^#SY;z9oFcnjaEqY0>AUK)=5@ek%^mzGbrlX5$ zJhT&ANzIzCox$li+s){be_O#~=0EbsOxMyl9wA`ei*0ZDFv(pmFpi7A@BCe@F`M60 z0URo4uN%;N`n6u#?k06?o{v9~lpR|P=p#8(6C2J&>w%;zf6@cyF3gX2z3;aP7+Xb2 zEs(-~8R=x&>+Pu?M*0Ij|I(7U8H**TY0pln;zPoXv?*kF+>IU*b})dORoB)si#foRgiz1;<5e=9Q1&FSnM;vKtA$@uef=S z-X5#-1Fl5mL!xy2JC1?$J_Qqm)+t?0IZlWw$J1vb(nUl4eB<$HLT-}dlwVcp)46IC z!y=9=Dx5dDfPSW0o=u&!mdWH*eD7iXJGGcd?TjBeVyBoIE?pnlZiLvr_+CIY*t1dom*SqrM+Kv|gNm61zi?Dx>I<8j*n9-cuVMf9}d*zj=# zvvX@HW!=KdON?EAkrtET?_*Fq+@t%!{5R=?tyQLHf@ycr&# z-y&aza=fec3ar`pvrE3k_Nl+ztaQ};1!v70-7|51mkA)wGSeJ@W5esvmPVERhl-ZM zU-!!QehJwnZN|=6M#CoZH3p7N!9UI_ElE=cp6zHWV7hWo?Y2*c0fa`_eYZ$jffP%z zMIt~yv=+1*Wn9RCBi{JsJ80!5lMFkueK7DR=wFV75Bk2&gUy; zGxgLnQ)0UXNZOnF7~`4mhW`F<<@X0X-F|s zhJ{t|0+$8weUCQulVuLTr_LBLtD+ER575@qnkZ6I5s9M+#B-H5^Sbt2p_!aiAMi}X zaCl(zeKBiDh>OdC0C*^g+kS@WyxY1-f{GH;)YM;7FmPN-Jktb1c0?w}TwQjG_V@Q! zNswri-Xz7uyu5>h^ajBD*g^=u>&4O7^@WN)X3Jq=9R=02X2>DBqNAgEL9<^Bt#A5& z|4Aoh?+#r!Mp&NSG_3O`s2?HbavtxK{|__zKSlnDeid4&^98h}rTr8t@J z5x6F@Vl9}*xu}@h(K*ks~)V)XEwSWsP@ch3Dt(8BP*n*3icwV1UmC|xb@{WKWYKu6o-J8#6hV8y}a}eZ3 zc5a5P04@T5O;T7`0D@zC^ZVh_w(|Ma{^!hrlVXDeKG$ta&ty7Y$SDHj$N)T_ix}?& z4;z_Uk>h(57_Q++-6q6!o>Hx;u6FcnGT^+tgt5W@36+E;8T95K=-c_Q>t8st^tZo_ zV0EWu;IIs02TXBU-28kTe(t8x;&5dZ*ZzWkeQJ`hJQl(IADVDRccOKw5K*$76iezw z{O)=AFFz6xQyzg45S*$;;l^AgbBOtx24frnp3WeqvIhdx7E8hoqbiQ$rW&(jx?LBYiAsy|H{z- z#`8=1cCcTBQM_NU2C|>^SQzoW+vxrNKV0FtLZXgsd4_CoJrzQ+Lm!Kg_J4Bj`CH^b z*{?70pTb1A|5dZY{|DgG|HK&bzv@+xU>V=R=}2bR?SD=6An<1DA2afQyb&t<9vaI3 zgeVJQ0idja5$tAb{}&;^g#Rhw?el_wMQkt)Z9Gt#RAW6U0-9*8H9jPn>7w8PX;+&Z zpARekiza`I5tRdMH@tzY89n^RL@o))44Rvj)g5ZMw3Kh2kBt@>Zviz$pKGLGA-<%}Pl;rS|_+9>>rZ5NXiW-(OwZqCl1zhzT`( z*pqs&6^EQX*~Kx_gzI36U}1e#@$>1(=QPEq7I{fiwPzj|5%HWxXgWKoGCKO=7h>Ap zv{bj*?YcA6=sm+~To`hOI}iTuZ%r&B^UsFXB|R1N!osH;|GWwU4iWNk@GthnI-C8B zD^J*hUbFkrCm9)dy=kq7cH4ZjJW`<8L+2mB80${Qcw0u0XRI4FH4yJU7Fwm#BqYo{ z3$SI(<81{bx0$Ll9`g|;2)!Oc09@K|$&ftV)*h35AnCMY136oRfEE5dcd@YEC;~Uf zmgoR;YzB~aeb>6TA>hfAC+q9$)ij0lG_{Znq>ngu3RMc=CrJNKZ#jSqMoOjD^MCH# z-=$JX<_@ry-6 zJ`8Yh_@_v>nk_a-jOyP%yoD0}uHqTwWcRLq!S*2O_3aSC=g-IZy^9$+Il3Ryy{NiR z`{2*dc8b`|F|JdKr*eK=8mV)yXtpAxs99%59Js>oiYO7Wf3$iieK%9%L&&X|_xEo} zP^`Wo_{Mk7#T{l-uq}&A{n@ewPCzqNZ3!#UqpS9EFGk;%#;6291TP>f5%A-=?cW{n z4oDyb{N>#aT>b%`AHW#^JWqifwZM;;80ZuWOPcau6?6TztC0z5!iop6<-E=h4H3x? z2{%xKdK23^E8uO)>&BznOd11?bLxsDOm#?YL49Dy==7nJe|5Nmhl%9_`lQUNjN@aY zu27oGVjg4O5SRg+$?w8bGNic@e61=UsSi}cy4h8;CkSTa4P{Q{G(1>eep~~ZpSeNg^}3RsoZsd!rp{ZU@YeYRGr8(q+Y6u&7G>J+ zjMap+W_1sk9G#ROkUR9*wOCWZ@iDLCAp8RXW^I3QbkUb-azeD=g7;PDjl}--azf96 zGnMhBu4v8d@>_+X9$8Z51}~6M@s@WdyHI7#wx=qJB{#^rwI_QMaLus6Ef6e|27LUI zbuk39_-q^(^ZAGWOA7fflh%J%#7yr0&A$8Z$@%Ze`LA*8|E8S(rkww#od4hP)#T0J z%f8n%JMItz41MR#{lI6*k%xH9pl+Q1dGUJb?hF)yZs3K7kSxHV(31qy`@ny^gOZ1- zNlHs~BlR`QEsXz`ZU2GCqFyYN>l(a1kXTIgR}PF7wDsu-r17kCnx6@y5^%DD8zPes zA~&nim@0~qghZMiXG_@Z%~uEM;(=@-w}bJi2q^jXM*G+$nE%Q${9U!1>m_=P`Ucf@ z#}tJNZkNc-FS$5^+!j-Bv^S?(+LA>@DX#g^O@}kpAc$cgKHfI(Uwr5_w^K{4ASE`< z4tfz5F1v8H+c)RwZiA!5+zJ z8Ms|zIkbEKcpH21B__T<5jS&l9oqL4=+y5e%34}lZp-n!C#a_PzV~xe-7JiCBs93q z9_K#fwwx?bJM>e>!bp=(5iZAN(#)JMv!rTw;dK{@W`-BhP38XbT#x7;y<%%#9R)%F7i*S(IS+zm`uDLl%W7l9X4TEJld^8-&aK>90q6vxP@Pi9 zrR?}#vBGsL>E8w<CP^oea}>Mc+WOLf`rJ_*%~^Y@z)rA$d6pXJ}e z^zw5N5z7xBE;A3nIB|B_S93RCY2=SsFN6j|w z;~b7HiCwoi<1#If)U@yzE?>>x*|8z}IGj`Ka<&lv7dUKt*9@sDYLMrop^TjQ`k1qp& zee;%YCL?LTiMo$%XN=E}+m;}B5~N)m`ZSQyxBD(h!dp5rV*G~>Qy!TM;VOG%YDOFGX@^T|jVC+m!1m4f zzp8$NO85^k^v-wlzoK_OZ8Bhc{BuX(Ki84}>k?P+P?%h}9_(=Uo|@jQk*de>H>Cvs zZ-u$|$dTfWc@-MyQbQN7e`X7Ovj*^>t9}l2_Fc6g{a%9Yf-C6N!UE@&S^Mm%ysk<^ z4I0W$4rc}z-s9Z(0735s$SVl*RB3I^n6M7v84e`7Gf4KKg{o0T;_#NnS%QsKYsa-A z11cd-?dW-(7`J}PioM+C1Ku<9n|VLEaQGWO)EnSqzsR=?_oqjSU}yQFD4O+lbBUxU zoTO}Sj)o3zzc#2gMa&n$6b!CUZ_)=`S(&FK(Ab>3ubZDCzmE87#7$d`ji-zLBwW9` zGQ0eO={omF+wylH${wPMJz2ZZq*xo^zCA{VPGcd+p(mx`CE z@%q5w2mUl4a5&ozolnn}b3U7<+f`#Obo~OgURw@s<33U zy$g}94N66nrK(jOug#FH|JgR@I5WGe@31Cubb=w6oPcZMEt4xOO{ zPUnGUja(U%n)4Br;7$W{xB-Z8k_9b_fPX~3Y?om35~-C-;!)bObv74yf_zf~d3%bj z_JQ_wQpR=rys!fXH(cc7JE5h0$g;24EI(`(G1@3Nw-+skYNC=LFhByaO$#?Zn0Hhm zGV>PUUR;N1=(9m170BDS!kpa%%U(}yV;!V@D znQk|WC+Van*gx7kxZCE1t zD{WF~9v)Lq35aK^O`Uz+j@w2o6>IhR%AJt&gz_E$NdzABL!R)Vu=3@P$=L1 zE|HfnZR!7>+(W@e1T0bN%NV|VHa84f8k;`3q|HPnRumuL#m&Rqj>-h%|Du20RPF>g z%7gsSn;qLzIPnEhXj1J9uxFP+IK{$W7o9G#&-+_kH_O*_;?J%NZ4aINhHZ{gL>udE zr_TEI;)i68i(Ot^UFh73vif77?}b1fkBAMBb7LPN;AKnGKnI@R!hLwInqif3?1zUI zvL2lQJBF}B-3$;Tr@|ESE!;!GC#$VUe?$%Rpet8@T7PMML@iuc09js-m>f(|pXOoE zba**b@{zs7okyTX3Vj9x`B+psqguj6&(D7U@ulDeF|jdi&(zBx1*)BQgY0U{+)qo) zJb|I}e2@y!Ohk^Gc&@_>xs#IyTZv>tHYg4wBv4V zsTq}g6|%I*4eAJ`V6!I5W4jbR`@EiJ;!n?LaNEGU$VJ9=fU3 zxZ|PDqF0k8pVBZ86l5`3v_DaJ-@vUWTl~IfwPYwc>kw%A*Pm%p$E}9l0bXa+0tO+M zPhFX5%UHcy4l`UR)mE5(<2Jiv+i0&*g*q(dyiXK36xa#>`F5AWaN4tSGGN7Gz&^bB zkbqZrn#m6d@jRG570`#3$~~AR5vk7lGqG_4Gh*I8f##TIjuwh-bs|zd9Y!Y4PUM)j z1S6+EBQnPp&X*lGS~!s@_A0#WQ-lerIdUji3dV)#3V0~0krI^Lc;w!mCK-MNx(te`nahc*A$D(r*?s)+Sx8BjKb@xd+ zSnuOPMCKgNo2FMXWQx&UGfB{Atp+H{>%!XBfY*dKYXm9iE?Ao>{0CFX^e<~9abr#3 zu-WWIl%il$C0mtw^>y*UQc>K9*pPD$tJYX0q9k4>@wido5eLTvO-7xel9P}`@&ms| z9Kq_>EmWTZ-2soT>XHFse?cpvnbn%G|OxmLh7vyPp9gskNNlMLI9sEVdC0 z@m(JQ8Y#R5@Q7m7{y@QEuz!(ydg5RP69JYyS*VMCjt=^FT1WHyv(P@mI5NLgc*KyiVPhzR7UPU90Qql)7zwM-@j=spp$tIt+c+Lp7ss z;!J7!PWbXY)hR1i!Bctfk*Da3ol3ltzPn_zPR%qmY#t6Xt^LPxxRQKf^1{e*=8LP9 zXoyFFb&5c4iqpjyB++w_pOwdI%4R*mv_|N(>9KREOQUHmHS3Td`#h)(5%*(LoFUhkZZTOJ(2VVZULy4%T_TGZ=uk0x1+dK z5aMAu+i-e9>^KmTng>xwmR0w&E)uy&1L$18*o1EkP>RI@V>K_q`WHon0kbhtbW%Y3^>=;Z%FET5> zVium=)ni*@4=aJiv7LVjPsO81z4lj;uP+nt8YFevo=P_=)~+6UT6& z$O$N$K~B1DUlw+1FWN0R5aKy05Y5IDY8gROSn539_5^_xs+;<=qd*Pz11ZbPFe*sm zrL0@Me2T!GO9DRR_?UW;?*2?g_ExN15?Av<5PP7-Q_uTDuPrc2a9F1;VCN!#TW&EO z;6=wU--J9B-zC@}g{<7z!oT~582dzj0oe34cPUTD!_C1m(2~kfQvza6Y4&b5gHC1u z9`vXq7%^UA4{V<+^W9{sS!XWGNvpQbP=HL49)`KK3;G7SSFQ<;&w!)8UtrKj!lM1d zNY0eyJXTa>Kg_T`h11ET0;YuqFZYK zSe5Fwov&ntx%4DovqGVnm2+ivc5K~2kyejLn+$jlPdpl;ch(a@83g!2Qr_B)4qRyc z?m3BNzQhK2^D2J{@af*63xgdEJNVk66Ch<>r-*M}RT{+OUe-q8spMSs)s6SZ`nEWJ zxcAp|3Z?04+%$0%_#?rKfbkbPocIwg4yTJZo;H&%+DnbdVQgm@0u^n%aoYP$YLQa6 z!O+mSw*_)v=Ph--lt;gDUoJACvt|RVohJL;D8JX4`UswzoWb*?Yb&RHJzhusi`kLz zQs%~R0CBjK&;7=&vmyKQ%x&Wd#x|+hyu)jhs;ScB!}S+iq3CixlCGn7ZUb%IK`8H* zjdiIsybvf8CC)wprsOxA-bW%EpOP=#N5a8*Y0OgSv(3-Fq%~gBz%uheKT-cA)HYEE z-t3I-czqPbILf`N+sC#1T?`S+ARCbh8OHD$-#EUlqjdWqrJNYW^9T?S!#Cn^7-Un& zSP6x#+#R(Tcd41wY;qC1G~A*$ywMm5X7BW+t+?32Lj77UB=y9tXO@&C&G|IGR1me3 zldX}m_!pHEDs)OA61s8c7d;<3+)m#HwPT|GJ? zO8q(FFJ6CeX4YrG{#&ls&$mzO3r3o9In&=Ec#0=W^0NTbGhBX(>rINWRg$pnr@Hdz zFzMj2(BNLDt_KOfm)EU&AD3YhjT1DB~EVj!@`cA5Mb!*St! zS5AP@YJgu%&eJugr+SV`8^&WB$b!Y*Nm%ZQ{Z}7}{H8mMnV+Slou;}E?C7-4te#>3 z+pfi_Kq1Q9rv#R@%{ohV$1yH^pJ=?UMo8t)TVGdO_^)h%0X>?h_!2R`x|Lr9xd_jH6Ua zJTQ1(ntfL)AEtk-Lu}gBj^bN(H}n3{hNv4)(`2WMt=v?Suy97g^TkYp@UMLXm%S&B zQ}qyV0=EoAkbaJDS1`18AeBNa_kD_id-bIpZy>)42^dF@C*BVSdoA%Ak@}3gJPVvT z&o1=l!hfehHa1B0U4&M(NAJp#&dQ37;WYSF94;FvWlZTX*@1K%F%+k27J{sQvP$(rw9V} zpU0gwp&*Ldx@y?3qh9eqd*RCZ}G9zuDZQn|vBms4DfX)Fuf-Pl{wr?$zmV;JcyMB1$FCPgb0 zsUuH(hKu!kqa#h<;Oh4wL>KBQV@y$HHGUM<2fc{JX~gy(ipNXhC1dkk#Zb1(=3*cX zM75co8lPI=DBFHk0&)QR@bC{d@Y3;p?+R-W@d?e@^JLXKvrcIho6}d^%{oqum2%c` zp$^a=N1ub_eJ=)^(fh-uACjMNQS*J7`(0=9p-NY|qS1EWl2FpP&oJlU`%x3^EDs1g zS7cid{J{iHd|H;Lx+I&uR^VgOsQtn4!`8k-gR4jGx7%rIF;iIbe)I(4(?`|i8r*nT z69wB(O$}+{yZ_3_v8U3whoD`yPZP(?EM;oi5J)RCJNm;k01qasV4N7(@p9JaYhp9 zSoZhoPvHUvCnInX*YlJKdUt1@Vik1oMpb?JEU|IT7Dw4o8a3njr@3odz5W*|>>vJo zAo>t9YgAAmaazU-(UeMlk_CPmlr+#|OlDr6AV)BZFtqO}i75Oz0<6{kHD_P!WSKOT z^2e#>b)S(w<;uXT{LR6}EaIxo-Dxy@P&KmTB z7JF-G$J51(&FjmfsWdC{tHmm=-2>;wqEt=qy6Psr|>)Wr0_4~h{oLrh1 zwZOS6uV|Jgb?=rruK#=pSs-H?TkMTAK6TREe{Ve?6j8Cf!7#_MG`U-kO-ywNsj0i1 z+&%Bo+T#j?UZ2n5&k!`TU%$f=3GE#XQn8p!wCnqB(9Gw)kO*Uz<0{xH6e03rU{B?8 zT8Rj1v8y!rxevjUX;8aDYG>!s?^)HoxSsXw*fAGuFo5M=HGhS`y9NTBb#(1PD7v7a zS-b}1&bf+d>9*!@zb3cQ!RUoAQ$u`J@nP$?{ z@KAo2pwU`OzkdTLFw3BVaeI5%3DwKH%$%tAv>7|Y^f+5Cox@Q8S70=L$5%nb>xdl) z&{Q4o+zc&s^$kFImO*Fhi))bcdLKWRpVywwbGB4`1P-V)!K=je{El@Eea^iucIY!V zUG=h#44UgR*isU-saC~JV@wAhx>BK7eKkOGz1f0C*Fv@HVzaX6ZpRza8Y$RH1*zk> zDT1DLZypN&t}X*r)UOXBSt_^q&;eA4*TUPemGo%etLG$WixaxOc_;fV#;Vae~K>s+C^8&G_2d{(~0kwg$L(wfZ}g1RDGM zb0SVdIsHv*^jz%YZ|*c4vFjPUCkS57_>^m)bulx;Lpo1+TKTiZN#iHSWdZuXf#@Jxd z?>j=U9Er11>)PjwZh>$C7DcC|ro9HKBTsOFko`q`6pI+;_M566oU1Es7 z8q;~#@QU!gMCaN|>`T>SUq)}J2!a&NU%utPK`jl5lAUifRUQQut1-rG!CLti?peZqa6~JJa*L_Ml_; zp)G1&y0j3Ah(aKk{->`&Y;v_q8vUt9%j*Zcz17&%i7j-qp9i_*c?J@zIKX2LI1JXO zotNQZUo~^6TI%a8r_f4! z@d9Tda?uRU&kn+E5EQ5Y`wMk9q3NzvwX>`C?W*9kwuwr8T)h%4UQp*C^Kx4KR$j(h zY6GkL2AHB*f1q_VFr!9S^5Z%^^SlCI@~h@c?zEGgZ^cqikGPPI^V~Sg4C&uOla5+G z?`M$}9%}pM3ybo*tDW$JM{~iAc(#5cd$Ek0=G7+Kt7Kbs1tZ_g8`;U6_6N=LTW^qo zb5ZW0_@o!A+tGKhtuF?e1sC9gyOz9qa}`Ly%4`j}O5adt7e0>Z)lQM%#Y3;jWye>% zes@D+`{IqLy`AYvIFv#xFc3;+eXVzKZ)a~$7+S=aK6SDRqe)gF2jPc^h3>rzgc}>2 zxQLGQLW1Hc3=RX`GZt5T6ce=^kRu0w+y(l>oxG&-+Jj|yAV_A3kz2W8put$tRKilw zvBJbScGlurcf6bV0dYLSh*;|3J!U31g-$Xpr@(BQ(DANO&6r*N$S}O+&jM~&33-9ZtE~1rw1B1A3oh8{$&iBI z&Wg6Vo*FL;lc(z{nzDujYew`h@WzZjg<`d&0LrrFgpX3E0kxpuR-^F=D_S6#dy#Kjq@cM&&|BA=~aF zw!UE(E6lP?14G4iK8}3YwvlrK5_M1ww!=QQuKYug^DSu;>tY7YY03lDB-`LB}2_sv^oz00Z z*{(*POHgGqGDyyDyv>bx7Q3BRFq0U-#{!p@Hyv&q#a*$-|V9JY&56e)0~^0 zRgU6?Z_2KNkdK_G)4&SVLYYn|Q1d4WPMwYBGB@z}Zg0(%c)>p0aY)8}7QY_3<3D|v zHxk(|jr~6V#5KpU>Wfo?=1a7dg-Oy}&($$FR=A5|e(wRr$-be1?cff#;b(`vEn?#1 zGRdlL9776Mbvf+1<<$#Ob!{??_It*I(z!fd)(ex58u%S3UAB_OHcF@J_dBjWylRT+ zQOUUfH6c=M+O(zMy;j#Y>CjM!e1-hQF2Qz+l3xO!Q)i zR`r4ewdUS#AIqkFSA_>!vg3^PeYjJvNEiE|9p*(3dr#Nk^rfm|jEcF>seS5d*3`g@ z*>63)tNHYZQ8){|bJ6FHs$aJZ_c(2-PYTp;8&UVbIfk?q=!e!VA+_o*u3=(meZeuU?!-+}uv$daF{s z3Xz~q<{7%P<%aw*_BMe6V*6Y-V3sGz;~WOO2^Q6 zMWOrnCUgv^Jf*lw1mqtlqDvdQJVYBaHVfVw^?@d?3f>ZQ>QVF_m$@|T#LYLFc)f5& zjaVOKIA@}b?O>o3{#Pxfj1J$!AZG>v3#Zp63Hr1~m7)Mn!aTBk4v%6(3!_%a8TwJhH=p}PVZLq-Mc!pHyIzN~? zV=nm?%ERu)?Lc+anai&v^1_(h$JjTV6=$J9lySl;_yldol#`(LG$;r@ zrz_y`%B|aWm@tvRT$^wF1@mRhddFLTaj}CTFWxPC&{dT~$YD`IfM3?mR5KW!(@}V# zI;@d>9bvfw5jbHIrG9ysry@6bw#O!2`my;JY#b+cy2aEW?`o#k!*2069mI8)l-Gkd zT0P67+&GEJ+HN`&s+#~W%!pb`YMEa~oC>?%)V5J2m7ceSN*KCMUvok2=6ab`BL4_G z>((H9O40dOdcCu{tBh}LUd}xkHcQ+PuOrw9 z_S$5Vo+;SG=igYsz@WpNG=UQTTM-aJuqsWmn@a8wc$`z_&y)-uJ`0%d(6J<%q*96R5Rm7;G(XG>T? zLLcOU4L$7y4Yr0huUIy4ivB%_}3;)_DF@ zRnyP~aq!3RK1NvE7t6ZO!)0NCaOY(1aU@q!Md}kdcRUMn?lT6kkg1|MI860h8T-6b zsS0{$bIXlQB=zje#kr8=mZ3;&c-?E$W1Xa+8ONzwhlR-#S1pB`!)PYvz1B|q3;pMDC*F#-XYZ@ zXnW3m>NL~j<$kWmn#cz+-JD;}SrWxhNHVRA8eO2AFdXYUr?R)(t{H%;N)QCkb=7B3 zlWc{_Z={kgxC%B86rG_0UqQ!<^6GwNez;mEn*{%<3N&%9FTM=BntMaE8jzpeeo}_T zcZ*3VUQMwrqn|I#t~b=ei<^{jw{N z26gmDi^hJ57*2}cOJP~w$OZAV1yL{V%ER!?qw)*Mg(GOQhny0qNr@MM*Yyu942$~xsETj4mL!v4V4Qe=2I!5M%X9YQx}DC^(Pt8@ z6!FtT(TL0)CL?2Wg5c?Ce;+vRL`JJvtUosk6RTrnl&kw!!Ly>ox1L=cvG~TljXW3q z0cS`J#g}|kKde&>TA-5pB?W=^-toKovV4L>#noK(m3{MN2lcM@kZU$T3#t+Ma08W%Yu#7l0Bh#LsB9EfE-`WXiisM;Lu+pgZ6 z@mPsE6N?T|vH{9CFMA>;Srgm=uqXep5DyWUUE04;S9?x;&TxL1>320&SR@FvNf1NiU{?xp=X3ik`;t(v8h99auj#$ZuD>JB8KKZ?>1%O&RHFKWo zqjjv#Vzox6Br2q(kM2+e7>&HKaN}kX?D|ylW1>Z4-McbdxVL%$P%C)6Shv@!_j`}W zHHDeoPL@^v7&k;%=~cS#>$nFGhSyT^G0w1DyQxjIWmrvkw~~{%YGg%!)BW@9QDa7t zejP_u<13M@RH`^pjj5g&r&dh|oh@?HfNqA>bpZi7LNC#Lax`0mmJf(x5(ZW}&kPC- z?Z?YxAPJ=?=f4pYwxIh&b7ODsV%w7(ckKn_YHYDP=nDTpCZ!amR?3FE2WlflzwnW!Hds~(%QSJ~&)X=01)SBF^p#hkj3{=SVG#5=9Z_+%zbY&|S} zKb+}8s;R6WN9!|xnw6wN0@kyyE>$DEf!1jW;I_Y_|J zjZ{r7XHQ;I()}+gvISA?FIWYt60IWo19M;&{+#P7KF}q?3mQ;~h zVYT#K4GmiIssVqEjBto7R*94W=}2O?PvzfQ8K+Ch~!b*oZPE_E~j8$q& zC|f9RT@gl!_C>*-;-uB+pqSmEMZzW}ujBQQhF07Ke`Iw{)vr-(CD3L@dV`1^>!=j-$n-yZlaek3Wj|A&ER7s}e}UH#{@SFR z7$_;u2%xa*J$B*-Gev{SAZmdp@!>Wttt{ea;E3?fNqg&%_oPb~N?ssS!+#P)NGiJz z-6`jTv!!@)vLD$di~2P6tSuD<;$^nNtBKY$UzD)a_5P6v=11BN=;}s=dkg=~RpMGM z3>Ka$vuydSK8!o>SLtcJ4`i*89r#y%11*vHp z2H_5iqza{L5Fzuu%;sk7%bcBWLx|Q;+rC>e<7Zq?ULqCVw8+A)_6HwyObb0W@`UYu zYgH2T8Bt>qTPDr4qBeYH$(jf?)<3V(V_+I(1iL=pT#F}a89GDj4o3T_hPx$O2E_s1 zvlD8$0mWV&1F0%v)KPj4OsB2qlJ;X7H?%3dYxCw`**7l7#E7=d)_^*I%@x@g8Wb9D zba78P#g@N29BBx$K?kVwBmaaEn$T90cFytgcoW?Q!&mw}_*eDoqj0M47V4HOOp0($ zQ3q4^Pucf=lVmJ54!YO6TtU@Q*c%-Fz?HO9Ip`+0NulE228Rc*$|s&BXige5>{UA} ziZw9>MLGwNT-FEaumG-4iwDF_Woy=1X3_&A_pPt1{Pige_44sKizK+59&Z?QiQUx; z3;GdHU$N|3c5+@D{5?VnA6_&;j3dP~L&q3uAdBV&B==G}2>JZk<4ze9Zpm*Z^Vg>% zJFh%Gnt#L@6*5uPf#lS0J~o0Y^McCu%fV?Eo*k9AP@*kM>^qZ1y?bijQ8^|ub<^=z z8N7Dz62|w*5Z`RrCT*2G_P)R|M^4=-qV{nvM?!J~#+owCL(eo+@L7OyzqFXoF32v;a*J2Q5Dv-dS=}TEhVlzXD+T z+AfvXyhR=H8J8|GoxkYbu$Pd6izD84VcbW>GJ_j+ zWfDl_C!=!dPceNTa!+#AG($=N7UUrdjs*Oxz^xS^XOr-=hqsu+7FF zvfI9Q&i~53ZLM^|yDeMWW&c~qMq@Gi2M^bG_<2P(?;1NxceRU-%{0Kr#~c07hG?w} z`{Kaq=N@lwC{%)s%dhO}I3cRf$+&ENoOOM|b?VG6;IxkzM)~fFl*25{m=7Mo(80Q` zUS3N--XV#L6p>yy<T-B#&#d8EWi2?gYzWMz^zH zYO!3)B(IJ)@%gRamec6enE{Bgtz`$1c{K|i74dC$ypAFRJKEQ4m(nL)NN|NOgn4o5 zNLM#|5C2Nrs&+TyCF@^40ruRt+coaaegj;y1qFJ0SVB?XMVVYw1S065%^zB#CnE>s zK2_b%?g{pkKni&4@9aCNm{Co;OC)>`TxTt}Y;Naua+Rm?7Sm5JKsMSaT{R0%>E-Qm zS5iqKGt&h`rsNGL35ob@f|DcX%XA7RY^3wa8Scdq>{>N?wCAzs_yXP7_?2SisPSqy zZ&NXBtd{z5hvej@d!g%fB})$2wHdG{rQPhjyRx`+Go)5MnB9xh2xFACDNVrhFnn(( z#EmSSVy&yvX|jTs7+iY`&v`0EvCUJgID^qm`%m(&`jtu@w+f)H+I^NO@S;c?#WF?A0^mGf?W8)3XGA>yBi-^;H5uc5W$I zu4L0m2(6O?Id)>)4mKp^(}c7EZluUW}I3 zty_f8N2`zu!4@$3lO6xtcV;(**Q=B*cEl^{rKZyDCh2Qb# zYz~4c5#J^Iq^teAkkk9Ep;b>=2}K=IYxwpRE5$Ua_%78`DJi!9WGSmXI0qi%xJ%nQ z2}vk#n&i1qBb|8g7AnxKMC^I*UA~)jfBo!-q=ax0TCsz<^v}%l>CF5Baqp zMok=-0kPI&;aEdWEV9wqw$M^*mE7L~(Rld2Uut*p54#1m@2+659tT4|<{tX^qntfc z-K^NDNF)L&;LG`J<;Y{R8uSit8)Q5Dq*|+K^e`a6T%xk21%ZnZj8pKhwq<+Zl4aM( zfBuZk(#XhE%XYBOYPvKsZ=Z9dVxU0G@)X^fW0n^U$8@Dxh<@i>OKA8-5wO~;ZDRGE z&70_1$7HxZ-%8w#x=A@25dZ1bd=T;r#S~n2-#@}3RR8RW8)WLTf|U95P2z`3^O;97 z`No`v>C_;cA2vhrfhy>1qv`lN)4GO+9%(PJmWiA^hM0K{F>?FDPy=^G`{vHZ2^e;y zg-1o!IGzkz_SH<69!DO?U^Vw`58h45WdUO{$AHIIn|d?Ac)P2Fa*sb;!eLB+izQTC zDs%~zvg)6&_LGRQ#J^u^w|`JpDlCcUY6(QWi~iKwJ6`GhG*yTqNVe+xyjXSD5AwyV zWrz}y+r~;zGAL7FSb8;_MX=GgyEY~O?S=+~a5BY436f0TvXL0L>!Dtpq^U`ZQ89bq z?!p$T;z09+w5Q0G%&}^V$(=A;5?id02jY1LM6YYKC|IwDvz;|RnrZ4H(EL!!#v5a= zdoZ|6J8SHhsJ@;^?wtbPR6uXyM!YEisKa$U{R1|+??UUIpwC>l&$Td+I~?YhxHNIL z7ioNeeK;n5Qev0^pX*=*TJ7JHhnT8*?da|ZqXhF%o`0s@i6xuA^lna9Cs(UidjH~r zPPxL)sxumRtpNkqFS5vIVc7a{dlToURH`Gf=B8!vEOh*OiBIzu5!Pm-_uFn|yt#v= z_9`ay*Z;79QI%q%srmnSq{2^A#*n@v|9D@LlwEs9@lU1py8I!H+j0*fJ8Jp9WjG6n zVIXIg%1;&tJ9qxSqa64jAo0Wh5OnchA)cK>u?_t2aNOHrO6+Jk`uFwzUK}XIIDt41 S+ZC_;<2uCAs?x&i@xK8ebH$JV diff --git a/tests/e2e/__screenshots__/win32/visual.spec.ts/login-page.png b/tests/e2e/__screenshots__/win32/visual.spec.ts/login-page.png index 537b93ebfb09780870ed0ec22b60e948b867ec76..9f15429e42a76e26ba25b2211989d97dd3f0bf53 100644 GIT binary patch literal 82755 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

;xT={Wn)^4QjLOb3P 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 T2DReOE~q50{-W@?#ryvOvqo+Y literal 74638 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𝔢hhLK@T(UYI8QC`m$9>2AzCtB#xF7$x;XhY+nnZ9xiT&y5y6#0zd)Qnz)JQ< zt34*$Ywqk(WH1&V7(0}IS>`y$*DHvQ9=`6*k;DeVf~LETfA><2Mty(gXy2$ZN|vCm ztci^O@ahAM{Qlz|*k_s|uvctoeEmBrp_l8EV${Zp1`>vnUQ3w)g*oxenK<}sUS{$% z)AvLXUvecI@(y#bW?r&a_-4T;`T~8w!srimRbv?dWo>-KbzL+9Ac@=%NB$-iL+jBY z@}Nu)@=hz)LQxBj^#1Jtds}{z8cfsAYgraL@kPwoUW2YrsPai z*1Gu+V?Qo?q^W?tu8e8x8vv|44&r)&Of-I-zgj9vqLJF8p(&j^VZlWl20lnOT+tR; zs-YNKyh`|LzQx^VKl#1X*W$Y`a5(&n!}W3;g(H@wEyr$v89E{K*)x%0B$h^UZ6;8c zt`EiiJ<5o~-qhE(s|%Cc3Z5s1)P9)&lXmnU_bhUVTd8xA?r!Xy(*il!R81!4%GD88 zFQg{@7*TrPLnfAhD|v%lDmQ0#en187wO?bLmj)3={{B=cvLw}(kexJg${LNEx$a)O zZxV#YVz*rhAe}FDOQPv1Q!spO&MF<3i> zsOt9e^FxS%1Jjw2J$gJ!UrGk@+# zRq5-_op8FRQ;;4eWCAhOJVK-gX9zijw3%dH??D~TGO`oCWeZ&sV95ufskG$fnJvyl z_v96m{>td?kX@9`IHIDq0U&+}kKI@Q7C8vi*!tdZaiTi{3+c zY2nOnmw>=SW%H`@z-nC_FkFm^q3AJ(b7Rlin(T<=N8qSZO3G;S$=N#LymR7JD8azW zco?l>xW0W>!CJ@4cz?+yoX>TqON3Hb!Qd)72b*k%@kHv*uRj!-b|?0V0GLa4Kr@Kv zs$CyPi(F3FJX6Ae6uBjb@{l^R!%m)b~mR$wyued4doR028gn|4Bq;BRtX0c`&?(G-@Knqd4X`Ei4Lg{S|~H|>iYN@ zABfP}i~uB%?LsL-V2wB*a3f|ckQdt9fs2a9u5dP*GQU;M7H06vAZaGmb(JzGg&Fek z-G4V6Uh{irb=RfT*d#XQ*7tK;17iV*KKFRymwio)c{|T2ZccZMLl1MG z9!(}v$=L0!uV!EyqD;(mkAKA)9XBJBnHrL;wsl*!|I!UfdDyGR28tQO{jWy@9hVcl zXm$Lfdrw(gt{jkL#FmO;PSm0(#L7WlEzNstt~-;wBL&^Mjhu%WU%VfCH2ZdS=Z6w* zX43RRRY246h#C~@ZNCd5K%)qU=;YFP2wzZWCeXlMg6+8#hJ*sU@s2^@aDX-qSp?Ki z)9(}1$z)Oy21@tB0LBNvrNUa9M}Hfw@`KhYt1|)7wEHyL^hpNLdtgdm;>fqzYC2}l zl`N6nt;T%0{*v)Ib>`Ls_u$dSZ7X*J3uO)`zgyS0QNHv56ZBoJH|^`|m6i?d2h>nx z>wuEczN{a_!shYeC~+F=1rL1VqqiN1vad2vG`kZ7%%Yul0mwC!Pd8f8VpDi@)NF1n z2FrC_o~$xwS6kQ?i0KqytJp1{oqjeeG9`@q(={X=*fcxz4KX5gNzxFp?|{}xv|80079||an5i1t)v>Et_z9e=Q|{Y=C^BM~72D~oyN?ft z1aY7`>bu-&(-Xi{$A{nNQzl!?FR4vW6MyI-WGHDMv7wu*7%zXjGa;@c+zsxmCl)aG z`P5NEC+R!N$T=vjcC)9yiyBUnPPpI`LBjrW%`4+oe?&V|sKxppEmF(OX2wJ*ZzXr7{>_3JD7F5}b*&5%g(NJjg zYDwbNrB{;v18S z=5_cWb9hsCu>DG4mG5ns{#>zdZMS!#)W*D>kK311zn(872Sm?!qfPTl^l7_@=d1BO zTs}+7ub>Ua7o41nt)iv{9BaeTI*<8*0RFkfai&I?;wKZ0gThh}9JFD27&F!mo{R)c zV)%4I!E1+n#c&p%IpF^Nfd-wK*zJk~%{(E~YqPUer`ZDhe7VAwM0<3A65}rf=8p@wvR(%rJ&#ZXMex% zAUVKV{^mObzD~SosM(XClz8YgQ}ZP%=PV$t!uszb)44}1`YiEz2vpY5&%?C_NzZ`5 z-|JVc$!-ZPx}Cjy{hDc%gCW&@4_!jogV+UD^Y)XbaMjcZ{48oD_7Wdo?BV0g4t0v% z=&f^FHaq|TPJ8-wMJNr1<$Z6)U5qsJn&ZbjvBwTV)jK}j#1JK5@(PWZDBv5eDVpp@ zVbzg&hLoU1l2K#0lK{!gy^c%TxwN5dgheMB60d?`{O4!C1d5xxim<v{RDg>7_{zGHa{3IY3xgoI3OgLo8nZ8vv; z$y{MnRt zs|sR5oB0h$OwZ1GgzgCzPdKk;)H&v$3NE2VYHWix#m-D@=->VDp6!h-y?kfoSvf&U zxFg8!eDWbGmNF)kwDeOvrFpg~8(O-haFDtM)|}-4;}$*ngt0!ZMa98JHShVL3h53j zbZtbs!Aem$&pm&{q?6&%DEC7qnPh-T*Kn5h@DTr9^5f`+0JP@jCx~(z_<*fZs|rP` z+0guT!1jGD>x7;0g#1`lZrfeinIGwZ(+vzKjKQ~fmve&*LDOCSQtE4)!tf}NQ{_8$ za+=q;s02ZihkQua(InvH%s@`70mwRd0M6Otoi~x`=X~j7nq0(B?Ax-kElK*&hM2;)u^oxFra>MEP za(o;!UEiaD&#~aIp9UX77^Fi3jA=%#G*!ZQx2xKzSqQKC&lp>xGxv94xZxk7ArckB z?*Nwa(IjvNsS1Iv(WRKOqz6rp-jAOnby0&=&{}PB6c( z2xOagJi=LOnDDFOlHN$@O79gg?JDCg2*?aPBD<~4TQhE$gp--DJfeYIcXdkcOZC3m zrS45uEI4vL^!?tgbfZlA=i5*i=&7~&V7aJr>{f3`W!~xif?Z2$oz5U@i|sq4g>O-U zP63JvFW!PM0{L!tB^-k0i3<5kQjLB5)2=4uCwBV!jCIfBR8UneZ-66G&lNAaK-(WW z4JD~Dy~M$*g>qh7Uhku&1uHTN5jBMbWe4Mgr6HfM5$#bQcg z0lAZer78Bl93`SsG=xvJz8=FeO(B&vwW{5T6sC?w6>fbTX%^v`2`N;rIplEi)%;CL{BxcP+5ac?Y@GBumkb zm|>*Lw#H`ec6*F|l*9_|Jl`;@I#qi=k-Vg8u9A0=9l??}+^e1OX+YD4N+a4i$1L^1 zYxPfJ7SrIw-|&uCaqV4z!7(1A`zOlfi)(zQCZv<4M6und)!b-FF0U4~ryZMh=*oWI z`=$@?ju#N~+id!kta8Je)I)M-6`!aC;2WSYf9oyA1!m8RCv|Yxm_4576|as2x2Kci z7F5KWF11qs;v{Z_A!IX-$zOk#7uphc^jVFfa-as3f75qN8&hIH-S3$m2Gdu z^nX6ieHW5y53b7yJhL*Vz?t6rHi=*2@H^1S-&tO0QU-Ht5B`y4ZOkQr6yH{O^~o3z zize5DC9SZ7AC{r~bKke8(ipcbFr1hZEGYi+eogg7Xs-kWE#dxW8za zj?c*nbmL(0BW1kDZ;n*dBmVvTb?O4e!GKMNFTY|%<^m)0+%$KR@35vzqSL%D5|hf= zf6o^#$oNeUUBUxcRYT%u*K{+PB!X<=lcFq5Ay=Xp;e`~*MJQn&pG7|rJI@l*7nWEg z?@HXQWf?wtl?08G!54=kuKAvLI_-PkF0iR&;kSgSc&UH~DlQSf2(y=4X*gH> z$zI4_9+`GAhj(NJ53}s6f(P$J8MYtznIRoRdVqSDKQ2k>M~tD3q{?1`O$5N{^g+yo zg2Wd66LN22PfElleQp%jZm?o}QgvVa%v_YPk?=J9R0k2%o4RIIBfbr&pCIL9)feb6 ztwd`vo`rlP3~n>-vwewHVN6mag3Pi{ZwzEr{ibd%VDA#o1j62F#CQMG0xkePXb1^4 z_oQqkXJg&BR`9XZnHc@}6e+S_AjdpuCOY7kqns(6{25GVsDzVd{OIcJz&bCY6o<-Cvn_0bw(yN`1 zOC2n?R(;F7aEdAXtb@#1Y-C=72Ot(E#Acw^Bv(rZKWivE`zbndr9aovV~ zzW+o$1KMHmi6uJ%@erlvtS_7YmRO9;6w)KT)3e7n;Oe zMnPU~j3!8i3g@5nWh(`W&!2mDCM=f4EO^mRPnCMuY}Hu4%>M;vRqmZqd2c@O?cB7Q zm+qu-(P4Tr5hu6m_hKsk50IFnq1!cIA)bUqcAL^Ro*7KXHHO+uPym{oTg6K7a5p06 z0KUsxUEeBJ#vck?wSQ}EsPD7V`BmdQ>>zSNzb3vx%u$rfvlUqOU|bFAJ3NI6lW)E z@O27p>#CaPB<$X}PNTr@o;Qj?wAc#tvK^)}eJz?Kie;8nwj^e`>@qFnv+mVLR9tAg z|CRF}%S9rh8dT-k1D-4Wi-oB)ABSOsvwh9che}H^D#;Bw=M*k$LYVl7{~Vn;&kyNd zO01u($C`%>f*=8-aUN;0ot1e!@jb?ObIyW7AR;5->{B;S4O*goLTf_mKC6Cu^MxP5 zQX6#YA-+HBp%lJzfu$6f2){8(kG_Ri-!68U)n!PM3fL(g!yF1o@bhe}*yx;jO+Y~n zEpZG^*3eU|p+XqS+;%_2Ntljy^6i;N8H0(DNUq24F)blmvCHKzI@6DJJ$G`MO(~wE zlQtsNG3ig5BI)T~*A>mW;E57rSIT4T^bs~5Osd|7 z^8@HnIxouSt*=hKsZru}zm7vd@!upu*_+2L8}v}96`{9dd%rGHqw@NDzSn_*W(*fH zns=P3lAE1@uo>E{6(i)WQ*mfugPa8`-$Z{|ZpK_~R)1kCkE3WKeUGpZvaz$T!}Y_X1q0o~^<0M{HAQON;O7PD8xo@Y)in0F zYj42s7chn|doF~aX{%>YvIgqSFN2y7Zzjj>>tA+=l|Bu`wI3_9g|N(N;TM8^eOr}1lT#SO^CV1 z*u}>u#;@M?bpJO`7?4$g>MT*ClLPlJ#sdE|`yH5$5x=w~MCn2%Z`nhh=01X9u|e=G z%g%51Jn=C+oc~ti_6mI+9LglZc_7SF+hWsN znak&2-`|e1ix@=yh0%i+ymzXvul5h!)4-O=f!fTMLLOnd=v-{=>ZK*%YV>c=>%=}; ztQPacLGVzhd(PoDUJHciPKeU**`d;^#^vmm{cZ~uhPt<*4i)YjFuJ5TBWHJdz%@b+ zrd5f_@#H+Z-OXr&)a0!kf1_*=)Uh9oS;mMH!Q?G8S<5)6$jF)SVNMq;3YL=zQJA`b z=EA0zYF(vCpZpe;XIlv!rzQVEleAwKvPcp5@e%#rY{)yR?*M}YKKbKoO3t!xB_;It z`I9eQ`%&vJ_-QiNw)xR?Tf#oae5J{Pt137G`Lm45bv5;9StrH65x(E(+P59SzqM;2 zV~7Zk%x-T0kgxQ6`G*i7j1D}lv;VKE-LM0Zvz~R1=lIzNJgNVF_y2pz9A)5?@8N&B zOl@*JTQz)lwzWX+y?e~25@kT|f4CCo*Gb!TQ{-UyvFpVw3)x+NV_ZGxQf@9Ak~~VY z?(MKQ&%EOK?kWUC&2~M)I{S8ed_aZ1f1hU~G?6|mm|~{uRYeD6@{@B#vog?b;JSOP zCaI}ivf$^Y_;`9tZ4yC|>j0#XqoDh(+Dxdaf$m!h?)d<7ub8XWzOL_L;aAhJ4p_mB ztAst#U#$iTz^~TrR|<3@a}w_R%kF6&ALc6_h{5@e@F!^zJB(W8Y!aVR-~VEeDLZLw z04}5h=ze92tmq@zBdy8rjx&et1J{`2Tr$Fz{mju#=_|I$yw#8$cY;z&??4$ z2Zo)m@hY~n^SDQiZ?~Ar7Z#}jAL3>5-}RVw;`ZO$3WPJ0+>YYi+u3;nJ-uj-_9W_Z z;989P`ywL`b?0CYjJe8zB5)^^fNy0@-vM|4H zHDB+ebJ_Jrl+sYqv;W5rN4$&HXHqIk?Dsu+J3@LEC(!G-+`$Ym)j5h(|^!Iko z5gy?CZms!7ANs>%+0DuQ8XM7)T0hU{_dr-xPv)yt9p=t6Yr=~>@90)6o30?Z{rgN;RMsX&6uo#1F&dD0M-;-#+rO6Bz@(cWZ=(3%v-4gf- zEVGUJi%#@$0Yq}G6U&)mFHA6Z()RA(Uhc`QaY4dw7bO@#c_DvPmM7qE4VaZMRSCWDLfZ5P$H=j%Ic9Jya6p`v#t;mKpZv%vo(8q|oDfJ!ErL@M5qqR2h?*%C!EFvfqLFDaAd#E!mk_1C88f_)_vz7lqY?k`(*b|Yde z61ciM+H5Z0i0YH!iQ&9xqKvwhpuK5EpzZ(f3u) ztU4ve59Son5K){nZ~Lgtv?+}PmM^DSVS zoey-6Qc&?DVIj?{0lt*=)Q$d`u6<7^)Z`7rvar{64am<|Q+Q4y$%B%hX}^4ra~W!S3@6=QfD!uihlA ztS{(~d)=?-$enZ^)|RwEYl~JZVi%{NUW_JN0c!9wAo!2%{i@l-a=3f(c7UXrsG9-D-#&NH!S!Eq@AtO(Rf!{n zX20}jMF;AUysNI)){U!PqLGP`o&{Zx3 zGs9gPSaSpBE59V$d5h9?ANm^go_#yOk6agPG%W^O; zP(c$&^LXSmk}#X=q@w2aSlFT@hk+HdajDi-4leTY-i!O#x+m3X8SPpUOfphW(RHVy=AG#P-DnSk{Mok#O`eZq}} zm_r^8T{Enu9!o>TLdZ{qq}Lx;LF593s9|N5(;;bHUmHlpKkcux`6=Jx;Q{A-#k*}hdX&B(Sxq-)hSx~t!NG@~@v$Sh3 z3n9Gj;KnOicv#b&o!(!<2x#m)H;M@v)+*;^q1V$@IV-b|MgfO4iVN&3qLSNRvOt)3EOZeKe-eLWIJmR%&{I!+4Hm_SkL#-eGBb9@2#} zB_`*izk`VP^5xEZ7e^>v>w4#^s=l{KsC?JwqRu82_i<%LI_Ud%wWZfTvsFJ+$&U<* zzzc#Dw<$-tsYo1*z5}(pdK`A}&FGoDJen-mg0XQfW)Fy0MWYXX&Wj$UV={?0>V3!? zkrVN-$gawG?VTI}tXN%fxI$7DcB&~pB95eeR1SS_)lvc^BV$ab`}462y+T5+SZ8=U z$!Tea`IumbOYe#Qrv>claHvE@wSyM;^5RA~lHDOUaSY-(*j_DP-wqavl)&3lID&Tbc%B>|dgBTpy8Xg@VO3cY zge4obTBelf$4VHSDvmx>26Ci6ubAlM_{dIX^K@1>Vur4cuxa31ef%Pkbw4G`V5%qb zBMdXi974$?IHQCVxngIh8TYQqn^DlMEss}A?FM6>YW4`gt<$l<#1j}u)28Y=eJ4}3 z@03YctoXV|MKDCONYo^=FuiL%bm_cHk?HMs5-bjXG4XZO25ZAx)3KOGi%F`?%dcNR z1C;#kw;yUHA6arY1V4_^x@dQ@c@E!x`Mwg|Ov1e0R2%#8N>@9ZkaXpDU3=0a;NY-W zBu}bqk*z9}p3;H;`)vLOP9Poiczqbfu#DCUI|tszQ3!guua5C3qVwP%{sW6p_Rjw1 z`onJEP(^`)ZZu!snfJEr7RyowP5=1VZgLT?<2pNQC?>Gc2ec6ONvKTF&gF5tD_dma zT&{SJygGJ25lFAPczYB;6)?6~a|O39z%A-OM@0D2vA;9T&hF8#s=%J~VM7wjj3Yky zvXIOWqd&mGCzH)C$X}Er?|2+zCDfWs?y3@( zTI}L}LszCGKEC9FOm~#$uT^4+_A?4_A_Z|_+j-81)BSI1{G!=(vZN*86D?do@}k>_=kBnH6#gWv&p@*D5$A1yc83GwsKRcPrvN&>Th zk&Q@^03UCgz)-;TtaL?$^%7Q1r>gbr`HOJx&I?<;Me#;E1jvc6<>E-QO%}XH4Le3n zcDW-WI&NDs1?`uw%HMZCTVHuFUYq48GM#vo139Z&KOUHV`>o%0DiFLZfBzpquRQ?n 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 diff --git a/tests/e2e/app.spec.ts b/tests/e2e/app.spec.ts index d7d48b6..7c15b25 100644 --- a/tests/e2e/app.spec.ts +++ b/tests/e2e/app.spec.ts @@ -23,13 +23,8 @@ test('KEY-01 KEY-02 invalid key remains recoverable and valid key enters the app await fixture.page.getByRole('tab', { name: /高级用户/ }).click() const keyInput = fixture.page.getByLabel('数据库密钥') await keyInput.fill('b'.repeat(64)) - const errorDialog = fixture.page.waitForEvent('dialog') - await fixture.page - .getByRole('button', { name: '连接数据库' }) - .evaluate((element: HTMLButtonElement) => element.click()) - const dialog = await errorDialog - expect(dialog.message()).toContain('数据库密钥无效') - await dialog.dismiss() + await fixture.page.getByRole('button', { name: '连接数据库' }).click() + await expect(fixture.page.getByText('数据库密钥无效')).toBeVisible() await expect(keyInput).toBeVisible() await keyInput.fill('a'.repeat(64)) @@ -40,6 +35,46 @@ test('KEY-01 KEY-02 invalid key remains recoverable and valid key enters the app } }) +test('P0-01 an invalid directory can be corrected and retried without restarting', async () => { + test.skip(process.platform !== 'win32', 'Manual database directory editing is Windows-only') + const fixture = await launchTestApp({ mode: 'disconnected' }) + try { + await fixture.page.getByRole('tab', { name: /高级用户/ }).click() + await fixture.page.getByLabel('数据库密钥').fill('a'.repeat(64)) + await fixture.page.getByLabel('微信数据目录').fill('Z:\\missing-wechat-data') + await fixture.page.getByRole('button', { name: '连接数据库' }).click() + + await expect(fixture.page.getByText('微信数据目录不存在,请重新选择目录')).toBeVisible() + await expect(fixture.page.getByLabel('微信数据目录')).toBeEditable() + await expect(fixture.page.getByRole('button', { name: '选择目录' })).toBeEnabled() + + await fixture.page.getByRole('button', { name: '选择目录' }).click() + await expect(fixture.page.getByLabel('微信数据目录')).toHaveValue('fixture-account') + await fixture.page.getByRole('button', { name: '连接数据库' }).click() + await expect(fixture.page.getByRole('navigation', { name: '一级导航' })).toBeVisible() + } finally { + await fixture.close() + } +}) + +test('P2-01 P2-02 guided connection exposes safe diagnostics and completes all stages', async () => { + const fixture = await launchTestApp({ mode: 'disconnected' }) + try { + await expect(fixture.page.getByText('4.1.9.57')).toBeVisible() + await expect(fixture.page.getByText('微信 4.x(WCDB)')).toBeVisible() + await expect(fixture.page.getByRole('button', { name: '复制脱敏诊断摘要' })).toBeEnabled() + + await fixture.page.getByRole('button', { name: '检查完成,继续' }).click() + await fixture.page.getByRole('button', { name: '我已准备好' }).click() + await fixture.page.getByRole('button', { name: '开始准备连接组件' }).click() + await expect(fixture.page.getByRole('button', { name: '微信已登录,验证连接' })).toBeEnabled() + await fixture.page.getByRole('button', { name: '微信已登录,验证连接' }).click() + await expect(fixture.page.getByRole('navigation', { name: '一级导航' })).toBeVisible() + } finally { + await fixture.close() + } +}) + test('KEY-03 changing one key does not invalidate archive data or unrelated settings', async () => { const fixture = await launchTestApp() try { @@ -188,6 +223,7 @@ test('REPORT-01 REPORT-02 generates a fixed report with non-empty local assets', await fixture.page.getByRole('button', { name: '开始生成日报' }).click() await expect(fixture.page.getByRole('heading', { name: '生成群聊日报' })).toBeVisible() await fixture.page.locator('.report-source-item').filter({ hasText: '产品测试群' }).click() + await fixture.page.getByRole('button', { name: '近 7 天' }).click() const generate = fixture.page.getByRole('button', { name: '开始生成日报' }) await expect(generate).toBeEnabled() await generate.click() @@ -218,6 +254,7 @@ test('REPORT-03 report failure is retryable and leaves other pages usable', asyn await fixture.page.getByRole('button', { name: '日报' }).click() await fixture.page.getByRole('button', { name: '开始生成日报' }).click() await fixture.page.locator('.report-source-item').filter({ hasText: '产品测试群' }).click() + await fixture.page.getByRole('button', { name: '近 7 天' }).click() await fixture.page.getByRole('button', { name: '开始生成日报' }).click() await expect(fixture.page.getByText(/本地假服务错误 401/).first()).toBeVisible() await expect(fixture.page.getByRole('button', { name: '重试' })).toBeEnabled() diff --git a/tests/e2e/support/electron-main.cjs b/tests/e2e/support/electron-main.cjs index 438f378..314142c 100644 --- a/tests/e2e/support/electron-main.cjs +++ b/tests/e2e/support/electron-main.cjs @@ -102,7 +102,7 @@ handle('key:getSavedDbKey', () => ({ saved: Boolean(savedKey), encryptionAvailable: true })) -handle('key:saveDbKey', (key) => { +handle('key:saveDbKey', (_accountRoot, key) => { savedKey = String(key || '') return { success: true, key: savedKey, saved: true, encryptionAvailable: true } }) @@ -112,6 +112,12 @@ handle('key:clearSavedDbKey', () => { }) handle('key:getEnvironment', () => ({ platform: process.platform, + osVersion: process.platform === 'win32' ? 'Windows fixture' : 'macOS fixture', + appVersion: 'v2.1.6', + wechatVersion: '4.1.9.57', + dataStructureVersion: settings.dbRoot === 'fixture-account' ? '微信 4.x(WCDB)' : '未检测到', + dataDirectoryDetected: settings.dbRoot === 'fixture-account', + diagnosticSummary: 'WechatExplorer: v2.1.6\n数据目录: 已检测到', autoDetectSupported: true, wechatRunning: true, accountIdentified: connected, @@ -128,12 +134,22 @@ handle('key:autoGetImageKey', () => ({ verified: true })) -handle('db:init', (key) => { +handle('db:init', (key, accountRoot) => { + if (settings.dbRoot === 'Z:\\missing-wechat-data') { + connected = false + return { + success: false, + code: 'ROOT_UNAVAILABLE', + error: '微信数据目录不存在,请重新选择目录', + monitoring: false + } + } if (key !== VALID_KEY) { connected = false return { success: false, error: '数据库密钥无效', monitoring: false } } connected = true + settings.dbRoot = accountRoot || settings.dbRoot return { success: true, monitoring: true } }) handle('db:testConnection', (key) => @@ -339,6 +355,29 @@ handle('image:getStatus', () => ({ ]) ) })) +handle('settings:selectDbRoot', () => ({ canceled: false, path: 'fixture-account' })) +handle('accounts:discover', (inputPath) => + inputPath === 'Z:\\missing-wechat-data' + ? { success: false, accounts: [], error: '微信数据目录不存在,请重新选择目录' } + : { + success: true, + inputKind: 'account', + preselectedAccountId: 'fixture-account-id', + accounts: [ + { + id: 'fixture-account-id', + accountRoot: inputPath || 'fixture-account', + directoryName: 'fixture-account', + wxid: fixture.self.wxid, + nickname: fixture.self.nickname, + avatar: fixture.self.avatar, + hasSavedDbKey: Boolean(savedKey), + loginStatus: connected ? 'current' : 'unknown', + selectedByInput: true + } + ] + } +) handle('agent-hub:getStatus', () => ({ state: 'disconnected', connected: false })) handle('agent-hub:getLogs', () => []) handle('app-update:getState', () => ({ status: 'idle', currentVersion: '2.1.6' })) @@ -347,7 +386,6 @@ for (const channel of [ 'export:start', 'export:cancel', 'export:reveal', - 'settings:selectDbRoot', 'settings:openAccountRoot', 'db:reopenWithRoot', 'api:skillStatus', diff --git a/tests/integration/export-media-flow.test.ts b/tests/integration/export-media-flow.test.ts new file mode 100644 index 0000000..90783f4 --- /dev/null +++ b/tests/integration/export-media-flow.test.ts @@ -0,0 +1,173 @@ +import { dirname, join } from 'path' +import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'fs' +import { tmpdir } from 'os' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import type { Message } from '../../src/shared/types' + +const state = vi.hoisted(() => ({ + documents: '', + videoPath: '', + messages: [] as Message[], + imageLookups: [] as { allowThumbnail?: boolean; preferThumbnail?: boolean }[] +})) + +vi.mock('electron', () => ({ + app: { getPath: () => state.documents }, + shell: { showItemInFolder: vi.fn() }, + BrowserWindow: class {} +})) +vi.mock('../../src/main/services/chat-service', () => ({ + listMessages: () => structuredClone(state.messages), + getChatDb: () => ({ getWcdb4Client: () => ({}) }), + getContactAvatars: () => ({}) +})) +vi.mock('../../src/main/services/image-key-config-service', () => ({ + ImageKeyConfigService: class { + getConfig(): { aesKey: string; xorKey: string } { + return { aesKey: '0123456789abcdef', xorKey: '0x40' } + } + } +})) +vi.mock('../../src/main/voice-service', () => ({ + VoiceService: class { + async resolveVoice( + _sessionId: string, + localId: number + ): Promise<{ success: boolean; data?: string; error?: string }> { + return localId === 1 + ? { + success: true, + data: 'UklGRiQAAABXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YQAAAAA=' + } + : { success: false, error: '本地未找到语音数据' } + } + } +})) +vi.mock('../../src/main/image-decrypt-service', () => ({ + ImageDecryptService: class { + findImageFile( + _md5: string, + _datName: string, + options: { allowThumbnail?: boolean; preferThumbnail?: boolean } + ): string { + state.imageLookups.push(options) + return 'fixture-original.dat' + } + decryptImageToBase64WithFallback(): { data: string; filePath: string } { + return { + data: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAusB9Y9ZQmcAAAAASUVORK5CYII=', + filePath: 'fixture-original.dat' + } + } + isThumbnailFile(): boolean { + return false + } + } +})) +vi.mock('../../src/main/video-asset-service', () => ({ + VideoAssetService: class { + resolve(): { success: boolean; url: string } { + return { success: true, url: 'wxe-media://local/fixture-video' } + } + pathForUrl(): string { + return state.videoPath + } + } +})) +vi.mock('../../src/main/sticker-service', () => ({ + StickerService: class {} +})) + +const message = (overrides: Partial): Message => ({ + id: 'fixture', + from: 'fixture', + type: '普通文本', + datetime: '2026-08-01 10:00:00', + content: '', + isSender: false, + createTime: 1_785_549_600, + ...overrides +}) + +describe('media export flow', () => { + beforeEach(() => { + state.documents = mkdtempSync(join(tmpdir(), 'wxe-export-fixture-')) + state.videoPath = join(state.documents, 'fixture.mp4') + writeFileSync( + state.videoPath, + Buffer.from('000000186674797069736f6d0000020069736f6d69736f32', 'hex') + ) + state.imageLookups = [] + state.messages = [ + message({ + id: 'voice-ok', + type: '语音', + sessionId: 'fixture-session', + localId: 1, + contentData: { type: 'voice', duration: 1 } + }), + message({ + id: 'voice-missing', + type: '语音', + sessionId: 'fixture-session', + localId: 2, + contentData: { type: 'voice', duration: 1 } + }), + message({ + id: 'image', + type: '图片', + sessionId: 'fixture-session', + contentData: { type: 'image', md5: 'a'.repeat(32), datName: 'fixture.dat' } + }), + message({ + id: 'video', + type: '视频', + contentData: { type: 'video', md5: 'b'.repeat(32) } + }) + ] + }) + + afterEach(() => rmSync(state.documents, { recursive: true, force: true })) + + it('writes playable relative assets, keeps failures, and requests the original image first', async () => { + const { runExport } = await import('../../src/main/export-service') + const progress: unknown[] = [] + const win = { + isDestroyed: () => false, + webContents: { send: (...args: unknown[]) => progress.push(args) } + } + const result = await runExport( + { + jobId: 'fixture-export', + userMd5: 'fixture-user', + name: '脱敏会话', + format: 'html', + outputName: 'fixture', + kinds: ['voice', 'image', 'video'], + includeMedia: true, + preferOriginal: true, + fallbackThumbnail: true, + keepMissing: true + }, + win as never + ) + + expect(result.success).toBe(true) + const html = readFileSync(result.outputPath!, 'utf8') + const outputDir = dirname(result.outputPath!) + expect(readFileSync(join(outputDir, 'voices/voice_1_1.wav')).subarray(0, 4).toString()).toBe( + 'RIFF' + ) + expect(readFileSync(join(outputDir, 'media/video_4.mp4')).subarray(4, 8).toString()).toBe( + 'ftyp' + ) + expect(html).toContain('src="voices/voice_1_1.wav"') + expect(html).toContain('src="media/video_4.mp4"') + expect(html).toContain('语音文件缺失:本地未找到语音数据') + expect(state.imageLookups[0]).toMatchObject({ + allowThumbnail: false, + preferThumbnail: false + }) + expect(progress.length).toBeGreaterThan(0) + }) +}) diff --git a/tests/unit/account-discovery.test.ts b/tests/unit/account-discovery.test.ts new file mode 100644 index 0000000..6e96f08 --- /dev/null +++ b/tests/unit/account-discovery.test.ts @@ -0,0 +1,69 @@ +import fs from 'fs-extra' +import os from 'os' +import path from 'path' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' + +const mocked = vi.hoisted(() => ({ + userData: `${process.env.TEMP || process.env.TMP || '.'}/wxe-account-discovery-tests` +})) + +vi.mock('electron', () => ({ + app: { getPath: () => mocked.userData } +})) + +import { discoverAccounts } from '../../src/main/services/account-discovery' + +describe('account discovery', () => { + let root: string + const keyStore = { + getStatus: vi.fn(async (accountRoot: string) => ({ + saved: accountRoot.endsWith('account-b'), + encryptionAvailable: true + })) + } + + beforeEach(async () => { + root = await fs.mkdtemp(path.join(os.tmpdir(), 'wxe-accounts-')) + await Promise.all( + ['account-a', 'account-b', 'account-c'].map((name) => + fs.ensureDir(path.join(root, name, 'db_storage')) + ) + ) + await fs.ensureDir(path.join(root, 'Backup')) + }) + + afterEach(async () => { + await fs.remove(root) + await fs.remove(mocked.userData) + }) + + it('rejects an invalid Backup directory without continuing', async () => { + const result = await discoverAccounts(path.join(root, 'Backup'), keyStore as never) + expect(result.success).toBe(false) + expect(result.accounts).toEqual([]) + }) + + it('lists every direct account and never preselects one from a root directory', async () => { + const result = await discoverAccounts(root, keyStore as never) + expect(result.success).toBe(true) + expect(result.accounts.map((account) => account.directoryName).sort()).toEqual([ + 'account-a', + 'account-b', + 'account-c' + ]) + expect(result.preselectedAccountId).toBeUndefined() + expect( + result.accounts.find((account) => account.directoryName === 'account-b')?.hasSavedDbKey + ).toBe(true) + }) + + it('preselects a directly selected account directory while retaining its card', async () => { + const accountRoot = path.join(root, 'account-c') + const result = await discoverAccounts(accountRoot, keyStore as never) + expect(result.success).toBe(true) + expect(result.accounts).toHaveLength(1) + expect(result.accounts[0].accountRoot).toBe(accountRoot) + expect(result.preselectedAccountId).toBe(result.accounts[0].id) + expect(result.accounts[0].selectedByInput).toBe(true) + }) +}) diff --git a/tests/unit/connection-diagnostics.test.ts b/tests/unit/connection-diagnostics.test.ts new file mode 100644 index 0000000..3d463a1 --- /dev/null +++ b/tests/unit/connection-diagnostics.test.ts @@ -0,0 +1,26 @@ +import { describe, expect, it } from 'vitest' +import { buildSafeDiagnosticSummary } from '../../src/shared/connection-diagnostics' + +describe('connection diagnostics', () => { + it('contains useful versions and readiness without secrets or full account paths', () => { + const summary = buildSafeDiagnosticSummary({ + platform: 'win32', + osVersion: 'Windows 11 fixture', + appVersion: 'v2.1.6', + wechatVersion: '4.1.9.57', + dataStructureVersion: '微信 4.x(WCDB)', + dataDirectoryDetected: true, + autoDetectSupported: true, + wechatRunning: true, + accountIdentified: true, + dbConnected: false, + encryptionAvailable: true + }) + + expect(summary).toContain('WechatExplorer: v2.1.6') + expect(summary).toContain('微信客户端: 4.1.9.57') + expect(summary).not.toContain('0123456789abcdef') + expect(summary).not.toContain('C:\\Users\\fixture\\xwechat_files\\wxid_secret') + expect(summary).not.toContain('wxid_') + }) +}) diff --git a/tests/unit/export-media.test.ts b/tests/unit/export-media.test.ts new file mode 100644 index 0000000..12dee78 --- /dev/null +++ b/tests/unit/export-media.test.ts @@ -0,0 +1,62 @@ +import { describe, expect, it } from 'vitest' +import { renderExportPage } from '../../src/main/export-html-template' +import { getImageExportAttempts } from '../../src/shared/export-media' +import type { Message } from '../../src/shared/types' + +const baseMessage = (overrides: Partial): Message => ({ + id: 'fixture-message', + from: 'fixture', + type: '文本', + datetime: '2026-08-01 10:00:00', + content: '', + isSender: false, + ...overrides +}) + +describe('export media', () => { + it('always attempts the original before an explicitly enabled thumbnail fallback', () => { + const first = getImageExportAttempts({ preferOriginal: true, fallbackThumbnail: true }) + const repeated = getImageExportAttempts({ preferOriginal: true, fallbackThumbnail: true }) + + expect(first).toEqual([ + { allowThumbnail: false, preferThumbnail: false, fallback: false }, + { allowThumbnail: true, preferThumbnail: true, fallback: true } + ]) + expect(repeated).toEqual(first) + }) + + it('renders movable relative audio and video assets plus accurate missing-media details', () => { + const html = renderExportPage('脱敏导出', [ + baseMessage({ id: 'voice', type: '语音', voiceDataUrl: 'voices/voice_1.wav' }), + baseMessage({ + id: 'video', + type: '视频', + exportMediaType: 'video', + exportMediaUrl: 'media/video_2.mp4' + }), + baseMessage({ + id: 'missing', + type: '语音', + exportMediaError: '语音文件缺失:本地未找到语音数据' + }) + ]) + + expect(html).toContain( + 'audio class="audio" controls preload="metadata" src="voices/voice_1.wav"' + ) + expect(html).toContain('video class="media-image" controls src="media/video_2.mp4"') + expect(html).toContain('语音文件缺失:本地未找到语音数据') + expect(html).not.toMatch(/(?:src|href)="[A-Za-z]:\\/) + }) + + it('renders explicit and keyboard-accessible lightbox closing controls', () => { + const html = renderExportPage('图片预览', [ + baseMessage({ id: 'image', type: '图片', exportMediaUrl: 'media/image.jpg' }) + ]) + + expect(html).toContain('aria-label="关闭图片预览"') + expect(html).toContain("closeButton.addEventListener('click',closeLightbox)") + expect(html).toContain('if(event.target===box)closeLightbox()') + expect(html).toContain("if(event.key==='Escape')closeLightbox()") + }) +}) diff --git a/tests/unit/message-pagination.test.ts b/tests/unit/message-pagination.test.ts index c6a836f..d8357db 100644 --- a/tests/unit/message-pagination.test.ts +++ b/tests/unit/message-pagination.test.ts @@ -20,4 +20,14 @@ describe('message pagination', () => { ) expect(merged.map((message) => message.id)).toEqual(['oldest', 'overlap', 'latest']) }) + + it('keeps cross-year pages continuous through the earliest fixture record', () => { + const page2025 = [makeMessage('2025', 1_735_689_600), makeMessage('2026', 1_767_225_600)] + const page2017 = [makeMessage('2017', 1_483_228_800), makeMessage('2025', 1_735_689_600)] + + const merged = mergeMessagePages(page2017, page2025) + + expect(merged.map((message) => message.id)).toEqual(['2017', '2025', '2026']) + expect(new Set(merged.map((message) => message.id)).size).toBe(merged.length) + }) }) diff --git a/tests/unit/wcdb-message-shards.test.ts b/tests/unit/wcdb-message-shards.test.ts new file mode 100644 index 0000000..02907ba --- /dev/null +++ b/tests/unit/wcdb-message-shards.test.ts @@ -0,0 +1,45 @@ +import { describe, expect, it, vi } from 'vitest' +import { Wcdb4Client, type Wcdb4Message } from '../../src/main/wcdb4-client' + +const message = (id: string, year: number): Wcdb4Message => ({ + mesLocalID: id, + serverId: `server-${id}`, + mesDes: 0, + messageType: '1', + msgCreateTime: String(Math.floor(Date.UTC(year, 0, 1) / 1000)), + msgContent: `fixture-${year}`, + raw: {} +}) + +describe('WCDB message shard pagination', () => { + it('merges cursor and all-store rows for a bounded cross-year page', async () => { + const cursor = vi.fn(async () => [message('2025', 2025)]) + const tableScan = vi.fn(async () => [message('2017', 2017), message('2025', 2025)]) + const client = Object.assign(Object.create(Wcdb4Client.prototype), { + wcdbGetMessageTableStats: vi.fn(), + wcdbExecQuery: vi.fn(), + getMessagesByCursorAsync: cursor, + getMessagesByTableScanAsync: tableScan + }) as Wcdb4Client + + const result = await client.getMessagesAsync( + 'fixture@chatroom', + undefined, + Math.floor(Date.UTC(2026, 0, 1) / 1000), + { limit: 20 } + ) + + expect(tableScan).toHaveBeenCalledOnce() + expect(result.map((item) => item.msgContent)).toEqual(['fixture-2017', 'fixture-2025']) + }) + + it('reports an unsupported shard query instead of claiming history ended', async () => { + const client = Object.assign(Object.create(Wcdb4Client.prototype), { + getMessagesByCursorAsync: vi.fn(async () => []) + }) as Wcdb4Client + + await expect( + client.getMessagesAsync('fixture@chatroom', undefined, 1_767_225_600, { limit: 20 }) + ).rejects.toThrow('无法检查历史消息分片') + }) +})