most-box 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/README.md +69 -9
  2. package/electron/deepLink.js +29 -0
  3. package/electron/main.js +87 -20
  4. package/out/admin/index.html +0 -0
  5. package/out/app/index.html +0 -0
  6. package/out/assets/AppShell-BOtfY12t.js +1 -0
  7. package/out/assets/FilePreviewOverlay-C5qK9HAE.js +1 -0
  8. package/out/assets/LanguageToggle-Di5b88mK.js +1 -0
  9. package/out/assets/LogoIcon-B2fFe0l1.js +1 -0
  10. package/out/assets/MarketingHeader-BOytKcCc.js +1 -0
  11. package/out/assets/MarketingLayout-B8m1Q7Pa.js +1 -0
  12. package/out/assets/{MarketingThemeToggle-DBaC9bjz.js → MarketingThemeToggle-C6fggkl7.js} +1 -1
  13. package/out/assets/{MilkdownEditor-BqJzntYE.js → MilkdownEditor-Cfze75zl.js} +1 -1
  14. package/out/assets/OpenSidebarButton-DDuALgJ2.js +1 -0
  15. package/out/assets/SidebarAccount-bo1ypzrJ.js +1 -0
  16. package/out/assets/arrow-right-RldN7Rwi.js +1 -0
  17. package/out/assets/circle-alert-BQoSDxUe.js +1 -0
  18. package/out/assets/cloud-DHoTMeZY.js +1 -0
  19. package/out/assets/copy-BtJHJnqH.js +1 -0
  20. package/out/assets/download-Bg-OdoxM.js +1 -0
  21. package/out/assets/downloadValidation-CUvbvj9f.js +1 -0
  22. package/out/assets/external-link-m8ZIQe4p.js +1 -0
  23. package/out/assets/file-text-DG1orIkZ.js +1 -0
  24. package/out/assets/game-s6irY8hS.js +1 -0
  25. package/out/assets/hard-drive-BB-sllXA.js +1 -0
  26. package/out/assets/index-3OD3Chi9.css +1 -0
  27. package/out/assets/index-BSOvFG3o.css +1 -0
  28. package/out/assets/index-C0xqKeu-.css +1 -0
  29. package/out/assets/index-CrAXrmfP.js +31 -0
  30. package/out/assets/index.lazy-0Njp0U6I.js +1 -0
  31. package/out/assets/index.lazy-BTndBeBF.js +1 -0
  32. package/out/assets/index.lazy-Bq39jYTl.js +1 -0
  33. package/out/assets/index.lazy-Bu93oGzJ.js +2 -0
  34. package/out/assets/index.lazy-BvdBwgHx.js +1 -0
  35. package/out/assets/index.lazy-CIx8ist6.js +3 -0
  36. package/out/assets/index.lazy-DK7R297q.js +1 -0
  37. package/out/assets/index.lazy-DVOcrcEB.js +2 -0
  38. package/out/assets/index.lazy-DejOniAm.js +1 -0
  39. package/out/assets/index.lazy-DfsgyiMN.js +1 -0
  40. package/out/assets/index.lazy-DpNIiSXF.js +1 -0
  41. package/out/assets/index.lazy-Vnvz-t7T.js +1 -0
  42. package/out/assets/index.lazy-v7nBJ-sF.js +1 -0
  43. package/out/assets/key-round-DIQ3Xt5F.js +1 -0
  44. package/out/assets/lock-tf1t2yuy.js +1 -0
  45. package/out/assets/message-square-DaQH7q-P.js +1 -0
  46. package/out/assets/mp-DvFTsIL9.js +1 -0
  47. package/out/assets/music-DaFvU2DL.js +1 -0
  48. package/out/assets/notebook-pen-CqEFOHKx.js +1 -0
  49. package/out/assets/play-B7q6F75-.js +1 -0
  50. package/out/assets/plus-H2i2mspM.js +1 -0
  51. package/out/assets/refresh-cw-roxAhABl.js +1 -0
  52. package/out/assets/save-DR0O9ReR.js +1 -0
  53. package/out/assets/search-ncblG-zw.js +1 -0
  54. package/out/assets/send-m1XCcuPn.js +1 -0
  55. package/out/assets/shield-check-BwcvTU4U.js +1 -0
  56. package/out/assets/trash-2-CNpsqYc1.js +1 -0
  57. package/out/assets/triangle-alert-DP9EP7IM.js +1 -0
  58. package/out/assets/upload-V--8p13l.js +1 -0
  59. package/out/assets/useChannelMessages-46C52EyL.js +3 -0
  60. package/out/assets/useGameRoom-BtxPpfck.js +1 -0
  61. package/out/assets/useNavigate-DWlBD_-b.js +1 -0
  62. package/out/assets/userStore-C4vdYsQp.js +4 -0
  63. package/out/assets/wallet-CozFU6yK.js +1 -0
  64. package/out/assets/wifi-DIR3g_8A.js +1 -0
  65. package/out/avatars/default/LICENSE.md +7 -0
  66. package/out/avatars/default/dolphin.svg +25 -0
  67. package/out/avatars/default/owl.svg +60 -0
  68. package/out/avatars/default/panda.svg +29 -0
  69. package/out/avatars/default/snow-mountain.svg +100 -0
  70. package/out/avatars/default/tiger.svg +55 -0
  71. package/out/avatars/default/turtle.svg +34 -0
  72. package/out/chat/index.html +0 -0
  73. package/out/chat/join/index.html +0 -0
  74. package/out/download/index.html +4 -3
  75. package/out/game/gandengyan/index.html +0 -0
  76. package/out/game/index.html +0 -0
  77. package/out/game/zhajinhua/index.html +0 -0
  78. package/out/index.html +4 -3
  79. package/out/note/index.html +0 -0
  80. package/out/ping/index.html +4 -3
  81. package/out/{demo → profile}/index.html +0 -0
  82. package/out/web3/index.html +0 -0
  83. package/package.json +9 -1
  84. package/public/avatars/default/LICENSE.md +7 -0
  85. package/public/avatars/default/dolphin.svg +25 -0
  86. package/public/avatars/default/owl.svg +60 -0
  87. package/public/avatars/default/panda.svg +29 -0
  88. package/public/avatars/default/snow-mountain.svg +100 -0
  89. package/public/avatars/default/tiger.svg +55 -0
  90. package/public/avatars/default/turtle.svg +34 -0
  91. package/server/index.js +36 -7
  92. package/server/src/core/channelIdentity.js +6 -11
  93. package/server/src/core/gameRoom.js +15 -5
  94. package/server/src/core/mostLink.js +8 -7
  95. package/server/src/core/zhajinhua.js +6 -0
  96. package/server/src/games/gandengyan.js +10 -0
  97. package/server/src/http/access.js +63 -12
  98. package/server/src/http/app.js +34 -840
  99. package/server/src/http/nodeStatus.js +101 -9
  100. package/server/src/http/routePolicy.js +2 -0
  101. package/server/src/http/routes/channelRoutes.js +163 -0
  102. package/server/src/http/routes/fileRoutes.js +345 -0
  103. package/server/src/http/routes/nodeRoutes.js +323 -0
  104. package/server/src/http/routes/seedRoutes.js +58 -0
  105. package/server/src/index.js +483 -265
  106. package/server/src/node/config.js +2 -6
  107. package/server/src/utils/avatar.js +59 -3
  108. package/server/src/utils/downloadMessages.js +0 -2
  109. package/out/assets/AppShell-CQhg6DJU.js +0 -1
  110. package/out/assets/ChatUi-BepWs-ZU.js +0 -1
  111. package/out/assets/LanguageToggle-CtzCCAYv.js +0 -1
  112. package/out/assets/LogoIcon-Dxto3Sb4.js +0 -1
  113. package/out/assets/MarketingLayout-BQw0IS2i.js +0 -1
  114. package/out/assets/MoveModal-4D9n11Kw.js +0 -1
  115. package/out/assets/Nav-9MDdvgNs.js +0 -1
  116. package/out/assets/NoteSidebar-C-rIt32H.js +0 -1
  117. package/out/assets/OpenSidebarButton-Dd0JmKuE.js +0 -1
  118. package/out/assets/PemBlock-C8dEIzu-.js +0 -1
  119. package/out/assets/SidebarAccount-ClS-N0lq.js +0 -1
  120. package/out/assets/arrow-right-urE9Rd7j.js +0 -1
  121. package/out/assets/channelApi-BwQU0-h1.js +0 -1
  122. package/out/assets/check-DUNsD2t6.js +0 -1
  123. package/out/assets/chevron-down-D6mpsfv4.js +0 -1
  124. package/out/assets/circle-alert-W0iyN4sC.js +0 -1
  125. package/out/assets/cloud-BMyOoC2x.js +0 -1
  126. package/out/assets/code-B1Cb_Icm.js +0 -1
  127. package/out/assets/copy-C1MttOli.js +0 -1
  128. package/out/assets/download-y7SZXu6E.js +0 -1
  129. package/out/assets/downloadValidation-B0p9Ai_9.js +0 -1
  130. package/out/assets/filePreview-UI9NH34f.js +0 -1
  131. package/out/assets/game-CdU3xnZo.js +0 -1
  132. package/out/assets/hard-drive-D13Qbobu.js +0 -1
  133. package/out/assets/image-DJCA16l_.js +0 -1
  134. package/out/assets/index-8eWJAjpY.css +0 -1
  135. package/out/assets/index-BZc4blbW.css +0 -1
  136. package/out/assets/index-BdaFEQG-.css +0 -1
  137. package/out/assets/index-QxXZzOUL.js +0 -33
  138. package/out/assets/index.lazy-BBTTFanX.js +0 -1
  139. package/out/assets/index.lazy-BG4ZylHD.js +0 -2
  140. package/out/assets/index.lazy-Bi-6ZXZX.js +0 -1
  141. package/out/assets/index.lazy-BixWVr0B.js +0 -1
  142. package/out/assets/index.lazy-BjFwNYy5.js +0 -3
  143. package/out/assets/index.lazy-C8EIQsXY.js +0 -2
  144. package/out/assets/index.lazy-CarNe2uu.js +0 -1
  145. package/out/assets/index.lazy-DEuGu3H3.js +0 -1
  146. package/out/assets/index.lazy-GPyILCA7.js +0 -3
  147. package/out/assets/index.lazy-I8ofndXl.js +0 -1
  148. package/out/assets/index.lazy-TxhWsA7y.js +0 -1
  149. package/out/assets/index.lazy-azfky8k7.js +0 -1
  150. package/out/assets/key-round-CZniN9lv.js +0 -1
  151. package/out/assets/lock-D5OSNhep.js +0 -1
  152. package/out/assets/log-out-B6phyZ5z.js +0 -1
  153. package/out/assets/music-CbUskKgg.js +0 -1
  154. package/out/assets/notebook-pen-DqKDQ6MJ.js +0 -1
  155. package/out/assets/play-BIl8q9eU.js +0 -1
  156. package/out/assets/plus-BxxbpH6Q.js +0 -1
  157. package/out/assets/save-DkH1n_Ov.js +0 -1
  158. package/out/assets/search-BQi5Z0E-.js +0 -1
  159. package/out/assets/send-Cl6NtD2T.js +0 -1
  160. package/out/assets/trash-2-BBjpgK_f.js +0 -1
  161. package/out/assets/triangle-alert-l98G8u9O.js +0 -1
  162. package/out/assets/upload-ByP6Ydde.js +0 -1
  163. package/out/assets/useChannelMessages-BgbYfF2c.js +0 -3
  164. package/out/assets/useGameRoom-DPmweWwe.js +0 -1
  165. package/out/assets/wallet-c7zIhNSM.js +0 -1
  166. package/out/assets/wifi-Bm4biAjc.js +0 -1
package/README.md CHANGED
@@ -81,11 +81,71 @@ npm run test:unit # 只运行单元测试
81
81
 
82
82
  ## 访问场景
83
83
 
84
- | 场景 | 方式 | 访问地址 |
85
- | -------- | ------------------------------------- | ----------------------- |
86
- | 本地 | 桌面客户端或 `npx most-box@latest` | `http://localhost:1976` |
87
- | 远程管理 | SSH 隧道 + `/admin/` | `http://localhost:1976` |
88
- | 外网 | Caddy 反向代理 | `https://your-domain` |
84
+ | 场景 | 方式 | 访问地址 |
85
+ | ---------- | ------------------------------------- | --------------------------- |
86
+ | 本地 | 桌面客户端或 `npx most-box@latest` | `http://localhost:1976` |
87
+ | 局域网/NAS | 监听 `0.0.0.0`,仅信任家庭局域网 | `http://NAS-IP:1976` |
88
+ | 远程管理 | SSH 隧道 + `/admin/` | `http://localhost:1976` |
89
+ | 外网 | Caddy 反向代理 | `https://your-domain` |
90
+
91
+ ### 飞牛 OS / NAS 局域网部署
92
+
93
+ 飞牛 OS 自带 Docker,可以把 NAS 变成一台 24 小时在线的 MostBox 做种机。普通用户建议直接用飞牛的 Docker 图形界面,不需要 SSH。
94
+
95
+ 你只需要准备两样东西:
96
+
97
+ - 飞牛 OS 已安装并启用 Docker。
98
+ - 知道 NAS 的局域网地址,例如 `192.168.31.107`。如果你是通过 `http://192.168.31.107:5666/` 打开飞牛 OS,那么 NAS 地址就是 `192.168.31.107`。
99
+
100
+ 部署步骤:
101
+
102
+ 1. 打开飞牛 OS 桌面的 **Docker**。
103
+ 2. 找到 **Compose**、**项目** 或 **创建项目** 入口。
104
+ 3. 项目名填写 `mostbox`。
105
+ 4. Compose 内容整段复制下面这一块,不需要改里面的命令。
106
+ 5. 保存并启动项目。
107
+
108
+ ```yaml
109
+ services:
110
+ mostbox:
111
+ image: node:22-bookworm-slim
112
+ container_name: mostbox
113
+ network_mode: host
114
+ restart: unless-stopped
115
+ volumes:
116
+ - /vol1/docker/mostbox:/data
117
+ working_dir: /data
118
+ command: >
119
+ sh -lc "if [ ! -e /usr/lib/x86_64-linux-gnu/libatomic.so.1 ]; then
120
+ apt-get update &&
121
+ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends libatomic1 ca-certificates &&
122
+ rm -rf /var/lib/apt/lists/*;
123
+ fi;
124
+ mkdir -p /data/home /data/npm-cache &&
125
+ chown -R 1000:1000 /data/home /data/npm-cache &&
126
+ su node -s /bin/sh -c 'HOME=/data/home npm_config_cache=/data/npm-cache npm_config_audit=false npm_config_fund=false npx -y most-box@latest --host 0.0.0.0'"
127
+ ```
128
+
129
+ 启动后,在同一局域网的电脑或手机浏览器打开:
130
+
131
+ ```text
132
+ http://你的NAS地址:1976
133
+ ```
134
+
135
+ 例如你的飞牛地址是 `192.168.31.107`,就打开:
136
+
137
+ ```text
138
+ http://192.168.31.107:1976
139
+ ```
140
+
141
+ 看到 MostBox 页面后,就可以在 NAS 上发布文件。发布后复制生成的 `most://<cid>?filename=...` 链接发给别人;下载者运行自己的 MostBox,粘贴链接下载。你的 NAS 会继续在线做种,关闭浏览器页面也不影响容器做种。
142
+
143
+ 常见问题:
144
+
145
+ - 页面打不开:先确认 Docker 项目状态是“运行中”,再确认访问的是 NAS 的局域网 IP 加 `:1976`。
146
+ - 日志里一直下载失败:可能是 NAS 访问 npm 或 Debian 软件源太慢,可以给 Docker 项目临时加代理。
147
+ - 数据目录:文件和节点数据保存在 NAS 的 `/vol1/docker/mostbox`,通常位于飞牛的第一个存储空间。
148
+ - 安全提醒:`--host 0.0.0.0` 是给家庭局域网使用的。不要在路由器里把 `1976` 端口直接暴露到公网;需要公网 Web 入口时,请使用 HTTPS 反向代理,并在管理台配置远程访问邀请码。
89
149
 
90
150
  ### 远程管理节点
91
151
 
@@ -107,7 +167,7 @@ mostbox.example.com {
107
167
  }
108
168
  ```
109
169
 
110
- 开放到局域网或公网时,在 `/admin/` 中配置邀请码,远程请求必须携带有效邀请码。
170
+ 开放到公网时,在 `/admin/` 中配置邀请码,远程请求必须携带有效邀请码。
111
171
 
112
172
  ## 核心功能
113
173
 
@@ -193,7 +253,7 @@ npx most-box@latest
193
253
 
194
254
  ## 路线图
195
255
 
196
- ### v0.2.0(当前版本)
256
+ ### v0.2.1(当前版本)
197
257
 
198
258
  - ✅ P2P 文件上传与下载
199
259
  - ✅ 确定性 CID 生成
@@ -227,8 +287,8 @@ npx most-box@latest
227
287
  发布新版本时,推送 tag 即可自动构建:
228
288
 
229
289
  ```bash
230
- git tag v0.2.0
231
- git push origin v0.2.0
290
+ git tag v0.2.1
291
+ git push origin v0.2.1
232
292
  ```
233
293
 
234
294
  触发后自动执行:
@@ -0,0 +1,29 @@
1
+ const MOST_PROTOCOL_PREFIX = /^most:\/\//i
2
+
3
+ export function findMostDeepLinkArg(argv = []) {
4
+ return (
5
+ argv.find(arg => typeof arg === 'string' && MOST_PROTOCOL_PREFIX.test(arg)) ||
6
+ ''
7
+ )
8
+ }
9
+
10
+ export function createCidRoutePathFromMostLink(link) {
11
+ if (!link || typeof link !== 'string') return ''
12
+
13
+ let url
14
+ try {
15
+ url = new URL(link)
16
+ } catch {
17
+ return ''
18
+ }
19
+
20
+ if (url.protocol !== 'most:' || !url.hostname) return ''
21
+
22
+ return `/cid/${encodeURIComponent(url.hostname)}${url.search}`
23
+ }
24
+
25
+ export function createMostDeepLinkTarget(link, baseUrl) {
26
+ const routePath = createCidRoutePathFromMostLink(link)
27
+ if (!routePath) return ''
28
+ return new URL(routePath, baseUrl).toString()
29
+ }
package/electron/main.js CHANGED
@@ -18,6 +18,10 @@ import {
18
18
  getCurrentPlatform,
19
19
  getReleaseManifestUrl,
20
20
  } from './updateChecker.js'
21
+ import {
22
+ createMostDeepLinkTarget,
23
+ findMostDeepLinkArg,
24
+ } from './deepLink.js'
21
25
 
22
26
  const __dirname = path.dirname(fileURLToPath(import.meta.url))
23
27
  const PORT = 1976
@@ -27,6 +31,9 @@ let engine = null
27
31
  let tray = null
28
32
  let isQuitting = false
29
33
  let hasCheckedForUpdates = false
34
+ let pendingDeepLinkUrl = ''
35
+
36
+ const gotSingleInstanceLock = app.requestSingleInstanceLock()
30
37
 
31
38
  function getIconCandidates() {
32
39
  return [
@@ -72,6 +79,44 @@ function showMainWindow() {
72
79
  mainWindow.focus()
73
80
  }
74
81
 
82
+ function getLocalAppUrl(routePath = '/') {
83
+ return new URL(routePath, `http://localhost:${PORT}`).toString()
84
+ }
85
+
86
+ function getInitialWindowUrl() {
87
+ const initialUrl = pendingDeepLinkUrl || getLocalAppUrl('/')
88
+ pendingDeepLinkUrl = ''
89
+ return initialUrl
90
+ }
91
+
92
+ function registerMostProtocolClient() {
93
+ if (process.defaultApp && process.argv.length >= 2) {
94
+ app.setAsDefaultProtocolClient('most', process.execPath, [
95
+ path.resolve(process.argv[1]),
96
+ ])
97
+ return
98
+ }
99
+
100
+ app.setAsDefaultProtocolClient('most')
101
+ }
102
+
103
+ function openMostDeepLink(link) {
104
+ const targetUrl = createMostDeepLinkTarget(
105
+ link,
106
+ `http://localhost:${PORT}`
107
+ )
108
+ if (!targetUrl) return
109
+
110
+ pendingDeepLinkUrl = targetUrl
111
+ if (!mainWindow) {
112
+ return
113
+ }
114
+
115
+ showMainWindow()
116
+ mainWindow.loadURL(targetUrl)
117
+ pendingDeepLinkUrl = ''
118
+ }
119
+
75
120
  function quitFromTray() {
76
121
  isQuitting = true
77
122
  if (tray) {
@@ -117,7 +162,7 @@ function createWindow() {
117
162
  },
118
163
  })
119
164
 
120
- mainWindow.loadURL(`http://localhost:${PORT}`)
165
+ mainWindow.loadURL(getInitialWindowUrl())
121
166
 
122
167
  mainWindow.on('close', event => {
123
168
  if (isQuitting) {
@@ -204,25 +249,47 @@ async function checkForUpdates() {
204
249
  }
205
250
  }
206
251
 
207
- app.whenReady().then(async () => {
208
- try {
209
- await startServer()
210
- createWindow()
211
- createTray()
212
- Menu.setApplicationMenu(null)
213
- setTimeout(() => {
214
- checkForUpdates()
215
- }, 3000)
216
-
217
- app.on('activate', () => {
218
- showMainWindow()
219
- })
220
- } catch (err) {
221
- console.error('[Electron] Failed to start server:', err)
222
- isQuitting = true
223
- app.quit()
224
- }
225
- })
252
+ if (!gotSingleInstanceLock) {
253
+ isQuitting = true
254
+ app.quit()
255
+ } else {
256
+ registerMostProtocolClient()
257
+ openMostDeepLink(findMostDeepLinkArg(process.argv))
258
+
259
+ app.on('second-instance', (_event, commandLine) => {
260
+ const link = findMostDeepLinkArg(commandLine)
261
+ if (link) {
262
+ openMostDeepLink(link)
263
+ return
264
+ }
265
+ showMainWindow()
266
+ })
267
+
268
+ app.on('open-url', (event, url) => {
269
+ event.preventDefault()
270
+ openMostDeepLink(url)
271
+ })
272
+
273
+ app.whenReady().then(async () => {
274
+ try {
275
+ await startServer()
276
+ createWindow()
277
+ createTray()
278
+ Menu.setApplicationMenu(null)
279
+ setTimeout(() => {
280
+ checkForUpdates()
281
+ }, 3000)
282
+
283
+ app.on('activate', () => {
284
+ showMainWindow()
285
+ })
286
+ } catch (err) {
287
+ console.error('[Electron] Failed to start server:', err)
288
+ isQuitting = true
289
+ app.quit()
290
+ }
291
+ })
292
+ }
226
293
 
227
294
  app.on('window-all-closed', () => {
228
295
  // Keep the daemon alive; users exit from the tray menu.
Binary file
Binary file
@@ -0,0 +1 @@
1
+ import{n as e,o as t,t as n}from"./jsx-runtime-Bt-cYkS5.js";import{y as r}from"./userStore-C4vdYsQp.js";import{t as i}from"./LanguageToggle-Di5b88mK.js";import{B as a}from"./index-CrAXrmfP.js";var o=r(`menu`,[[`path`,{d:`M4 5h16`,key:`1tepv9`}],[`path`,{d:`M4 12h16`,key:`1lakjw`}],[`path`,{d:`M4 19h16`,key:`1djgab`}]]),s=t(e(),1);function c(e,t){return typeof t==`boolean`?t:typeof window<`u`&&`matchMedia`in window?window.matchMedia(e).matches:!1}function l(e,t,{getInitialValueInEffect:n}={getInitialValueInEffect:!0}){let[r,i]=(0,s.useState)(n?t:c(e));return(0,s.useEffect)(()=>{try{if(`matchMedia`in window){let t=window.matchMedia(e);i(t.matches);let n=e=>i(e.matches);return t.addEventListener(`change`,n),()=>{t.removeEventListener(`change`,n)}}}catch{return}},[e]),r||!1}function u(e=!1,t={}){let[n,r]=(0,s.useState)(e),i=(0,s.useCallback)(()=>{r(e=>e||(t.onOpen?.(),!0))},[t.onOpen]),a=(0,s.useCallback)(()=>{r(e=>e&&(t.onClose?.(),!1))},[t.onClose]);return[n,{open:i,close:a,toggle:(0,s.useCallback)(()=>{n?a():i()},[a,i,n]),set:r}]}var d=n(),f=(0,s.createContext)(null);function p(){let e=(0,s.useContext)(f);if(!e)throw Error(`useAppShell must be used within AppShell`);return e}function m({sidebar:e,className:t=``,headerTitle:n,headerRight:r,sidebarToggleReplacement:c,defaultHide:p=!1,children:m}){let[h,g]=u(!1),[_,v]=(0,s.useState)(p),y=(0,s.useRef)(p),b=l(`(max-width: 768px)`),{t:x}=a(),S=(0,s.useCallback)((e={})=>{g.close(),e.collapse&&v(!0)},[g]);(0,s.useEffect)(()=>{p!==y.current&&(p?S({collapse:!0}):v(!1),y.current=p)},[p,S]);let C=()=>{b?g.toggle():v(!_)},w=()=>{b?g.open():v(!1)},T=b?h:!_;return(0,d.jsx)(f.Provider,{value:{closeSidebar:S,openSidebar:w,isSidebarVisible:T},children:(0,d.jsxs)(`div`,{className:[`app-layout`,t].filter(Boolean).join(` `),children:[(0,d.jsx)(`div`,{className:`sidebar-overlay ${h?`visible`:``}`,onClick:()=>S()}),(0,d.jsx)(`div`,{className:`sidebar ${h?`open`:``} ${_?`collapsed`:``}`,children:e({closeSidebar:S,openSidebar:w})}),(0,d.jsxs)(`div`,{className:`main-content`,children:[(0,d.jsxs)(`header`,{className:`app-header`,children:[(0,d.jsxs)(`div`,{className:`header-left`,children:[c??(0,d.jsx)(`button`,{onClick:C,className:`btn btn-icon sidebar-toggle-btn`,"aria-label":x(b?`appShell.openMenu`:_?`appShell.expandSidebar`:`appShell.collapseSidebar`),children:(0,d.jsx)(o,{size:16})}),n]}),(0,d.jsxs)(`div`,{className:`header-right`,children:[(0,d.jsx)(i,{className:`btn btn-icon app-language-toggle`}),r]})]}),m]})]})})}export{p as n,u as r,m as t};
@@ -0,0 +1 @@
1
+ import{n as e,o as t,t as n}from"./jsx-runtime-Bt-cYkS5.js";import{y as r}from"./userStore-C4vdYsQp.js";import{t as i}from"./file-text-DG1orIkZ.js";import{t as a}from"./music-DaFvU2DL.js";import{B as o,C as s,N as c}from"./index-CrAXrmfP.js";var l=r(`film`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M7 3v18`,key:`bbkbws`}],[`path`,{d:`M3 7.5h4`,key:`zfgn84`}],[`path`,{d:`M3 12h18`,key:`1i2n21`}],[`path`,{d:`M3 16.5h4`,key:`1230mu`}],[`path`,{d:`M17 3v18`,key:`in4fa5`}],[`path`,{d:`M17 7.5h4`,key:`myr1c1`}],[`path`,{d:`M17 16.5h4`,key:`go4c1d`}]]),u=r(`image`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,ry:`2`,key:`1m3agn`}],[`circle`,{cx:`9`,cy:`9`,r:`2`,key:`af1f0g`}],[`path`,{d:`m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21`,key:`1xmnt7`}]]),d=r(`loader`,[[`path`,{d:`M12 2v4`,key:`3427ic`}],[`path`,{d:`m16.2 7.8 2.9-2.9`,key:`r700ao`}],[`path`,{d:`M18 12h4`,key:`wj9ykh`}],[`path`,{d:`m16.2 16.2 2.9 2.9`,key:`1bxg5t`}],[`path`,{d:`M12 18v4`,key:`jadmvz`}],[`path`,{d:`m4.9 19.1 2.9-2.9`,key:`bwix9q`}],[`path`,{d:`M2 12h4`,key:`j09sii`}],[`path`,{d:`m4.9 4.9 2.9 2.9`,key:`giyufr`}]]),f=r(`pen`,[[`path`,{d:`M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z`,key:`1a8usu`}]]);function p(e){let t=String(e||``).split(`.`).pop()?.toLowerCase()||``,n=[`jpg`,`jpeg`,`png`,`gif`,`webp`,`svg`,`bmp`,`ico`,`tiff`,`heic`,`heif`],r=[`mp4`,`webm`,`mov`,`avi`,`mkv`,`flv`,`wmv`,`m4v`,`mpeg`,`3gp`],i=[`mp3`,`wav`,`ogg`,`flac`,`aac`,`m4a`,`wma`,`opus`],a=`txt.md.js.ts.jsx.tsx.css.scss.less.json.xml.html.htm.yaml.yml.toml.ini.cfg.conf.log.sh.bash.py.rb.go.rs.java.c.cpp.h.hpp.cs.php.sql.graphql.env.gitignore.dockerfile.readme`.split(`.`);return n.includes(t)?`image`:r.includes(t)?`video`:i.includes(t)?`audio`:a.includes(t)?`text`:`file`}var m=t(e(),1),h=n();function g(e){return e===`image`||e===`video`||e===`audio`}function _({item:e,isBackendReady:t,getFileDownloadUrl:n,onClose:r}){let{t:l}=o(),[u,f]=(0,m.useState)(``),[p,_]=(0,m.useState)(!1),[v,y]=(0,m.useState)(``),[b,x]=(0,m.useState)(``);return(0,m.useEffect)(()=>{if(e.subtype!==`text`)return;let r=!1;if(f(``),x(``),!t){f(l(`preview.loadFailed`));return}return _(!0),(async()=>{try{let t=await fetch(n(e.cid),{headers:{...await s(`GET`,`/api/files/${e.cid}/download`),Range:`bytes=0-9999`}});if(!t.ok)throw Error(l(`preview.loadFailed`));let i=await t.text();r||f(i||l(`preview.emptyFile`))}catch{r||f(l(`preview.loadFailed`))}finally{r||_(!1)}})(),()=>{r=!0}},[n,t,e.cid,e.subtype]),(0,m.useEffect)(()=>{if(!g(e.subtype)){y(``);return}if(y(``),x(``),!t){x(l(`preview.loadFailed`));return}let r=``,i=!1;return(async()=>{try{let t=await fetch(n(e.cid),{headers:await s(`GET`,`/api/files/${e.cid}/download`)});if(!t.ok)throw Error(l(`preview.loadFailed`));let a=URL.createObjectURL(await t.blob());r=a,i||y(a)}catch{i||x(l(`preview.loadFailed`))}})(),()=>{i=!0,r&&URL.revokeObjectURL(r)}},[n,t,e.cid,e.subtype]),(0,h.jsxs)(`div`,{className:`preview-overlay`,onClick:r,children:[(0,h.jsx)(`button`,{type:`button`,className:`preview-close`,onClick:r,"aria-label":l(`preview.close`),children:(0,h.jsx)(c,{size:20})}),(0,h.jsxs)(`div`,{onClick:e=>e.stopPropagation(),children:[e.subtype===`image`&&(0,h.jsx)(`div`,{className:`preview-media-wrapper`,children:v?(0,h.jsx)(`img`,{src:v,alt:e.fileName,translate:`no`}):b?(0,h.jsxs)(`div`,{className:`preview-unsupported`,children:[(0,h.jsx)(i,{size:48,className:`preview-file-icon`}),(0,h.jsx)(`p`,{translate:`no`,children:e.fileName}),(0,h.jsx)(`p`,{className:`preview-unsupported-hint`,children:b})]}):(0,h.jsx)(`div`,{className:`preview-loading`,children:(0,h.jsx)(`div`,{className:`preview-loading-spinner`})})}),e.subtype===`video`&&(0,h.jsx)(`div`,{className:`preview-media-wrapper`,children:v?(0,h.jsx)(`video`,{src:v,controls:!0}):b?(0,h.jsxs)(`div`,{className:`preview-unsupported`,children:[(0,h.jsx)(i,{size:48,className:`preview-file-icon`}),(0,h.jsx)(`p`,{translate:`no`,children:e.fileName}),(0,h.jsx)(`p`,{className:`preview-unsupported-hint`,children:b})]}):(0,h.jsx)(`div`,{className:`preview-loading`,children:(0,h.jsx)(`div`,{className:`preview-loading-spinner`})})}),e.subtype===`audio`&&(0,h.jsxs)(`div`,{className:`preview-audio`,children:[(0,h.jsx)(`div`,{className:`preview-audio-icon`,children:(0,h.jsx)(a,{size:36,color:`var(--accent)`})}),(0,h.jsx)(`p`,{className:`preview-audio-filename`,translate:`no`,children:e.fileName}),v?(0,h.jsx)(`audio`,{className:`preview-audio-player`,src:v,controls:!0}):(0,h.jsx)(`div`,{className:`preview-text-loading`,children:b?(0,h.jsx)(`p`,{children:b}):(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(d,{size:24,className:`preview-text-spinner`}),(0,h.jsx)(`p`,{children:l(`preview.audioLoading`)})]})})]}),e.subtype===`file`&&(0,h.jsxs)(`div`,{className:`preview-unsupported`,children:[(0,h.jsx)(i,{size:48,className:`preview-file-icon`}),(0,h.jsx)(`p`,{translate:`no`,children:e.fileName}),(0,h.jsx)(`p`,{className:`preview-unsupported-hint`,children:l(`preview.unsupported`)})]}),e.subtype===`text`&&(0,h.jsxs)(`div`,{className:`preview-text-container`,children:[(0,h.jsx)(`div`,{className:`preview-text-header`,children:(0,h.jsx)(`span`,{translate:`no`,children:e.fileName})}),p?(0,h.jsxs)(`div`,{className:`preview-text-loading`,children:[(0,h.jsx)(d,{size:24,className:`preview-text-spinner`}),(0,h.jsx)(`p`,{children:l(`preview.textLoading`)}),(0,h.jsx)(`p`,{className:`preview-text-loading-hint`,children:l(`preview.firstSyncHint`)})]}):(0,h.jsx)(`pre`,{className:`preview-text`,translate:`no`,children:u||l(`preview.emptyFile`)})]})]})]})}export{u as a,d as i,p as n,l as o,f as r,_ as t};
@@ -0,0 +1 @@
1
+ import{t as e}from"./jsx-runtime-Bt-cYkS5.js";import{y as t}from"./userStore-C4vdYsQp.js";import{B as n,H as r,V as i,f as a}from"./index-CrAXrmfP.js";var o=t(`check`,[[`path`,{d:`M20 6 9 17l-5-5`,key:`1gmf2c`}]]),s=t(`languages`,[[`path`,{d:`m5 8 6 6`,key:`1wu5hv`}],[`path`,{d:`m4 14 6-6 2-3`,key:`1k1g8d`}],[`path`,{d:`M2 5h12`,key:`or177f`}],[`path`,{d:`M7 2h1`,key:`1t2jsx`}],[`path`,{d:`m22 22-5-10-5 10`,key:`don7ne`}],[`path`,{d:`M14 18h6`,key:`1m8k6r`}]]),c=t(`moon`,[[`path`,{d:`M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401`,key:`kfwtm`}]]),l=t(`sun`,[[`circle`,{cx:`12`,cy:`12`,r:`4`,key:`4exip2`}],[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M12 20v2`,key:`1lh1kg`}],[`path`,{d:`m4.93 4.93 1.41 1.41`,key:`149t6j`}],[`path`,{d:`m17.66 17.66 1.41 1.41`,key:`ptbguv`}],[`path`,{d:`M2 12h2`,key:`1t8f8n`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}],[`path`,{d:`m6.34 17.66-1.41 1.41`,key:`1m8zz5`}],[`path`,{d:`m19.07 4.93-1.41 1.41`,key:`1shlcs`}]]),u=e();function d({className:e=``}){let{locale:t,localeName:c,setLocale:l,t:d}=n(),f=d(`common.locale.choose`),p=`${f} (${d(`common.locale.current`)}: ${c})`;return(0,u.jsx)(a,{ariaLabel:f,placement:`bottom-end`,items:i.map(e=>({key:e,label:r[e],icon:e===t?(0,u.jsx)(o,{size:16}):(0,u.jsx)(`span`,{"aria-hidden":`true`}),onSelect:()=>{e!==t&&l(e)}})),renderTrigger:t=>(0,u.jsx)(`button`,{...t,className:[`language-toggle`,e].filter(Boolean).join(` `),"aria-label":f,title:p,children:(0,u.jsx)(s,{size:16})})})}export{o as i,l as n,c as r,d as t};
@@ -0,0 +1 @@
1
+ import{t as e}from"./jsx-runtime-Bt-cYkS5.js";var t=e();function n({size:e=24}){return(0,t.jsxs)(`svg`,{width:e,height:e,viewBox:`0 0 24 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:[(0,t.jsx)(`rect`,{x:`2`,y:`2`,width:`8`,height:`8`,rx:`2`,fill:`var(--accent)`,opacity:`0.4`}),(0,t.jsx)(`rect`,{x:`14`,y:`2`,width:`8`,height:`8`,rx:`2`,fill:`var(--accent)`,opacity:`0.7`}),(0,t.jsx)(`rect`,{x:`2`,y:`14`,width:`8`,height:`8`,rx:`2`,fill:`var(--accent)`,opacity:`0.7`}),(0,t.jsx)(`rect`,{x:`14`,y:`14`,width:`8`,height:`8`,rx:`2`,fill:`var(--accent)`})]})}export{n as t};
@@ -0,0 +1 @@
1
+ import{t as e}from"./jsx-runtime-Bt-cYkS5.js";import{t}from"./LanguageToggle-Di5b88mK.js";import{L as n,M as r}from"./index-CrAXrmfP.js";import{t as i}from"./MarketingThemeToggle-C6fggkl7.js";var a=e();function o(){return(0,a.jsx)(`nav`,{className:`mkt-nav`,children:(0,a.jsxs)(`div`,{className:`mkt-nav-inner`,children:[(0,a.jsxs)(`button`,{type:`button`,className:`mkt-nav-logo`,onClick:r(),children:[(0,a.jsx)(n,{size:18}),(0,a.jsx)(`span`,{children:`MOST PEOPLE`})]}),(0,a.jsxs)(`div`,{className:`mkt-nav-cta`,children:[(0,a.jsx)(i,{}),(0,a.jsx)(t,{className:`mkt-theme-toggle`})]})]})})}export{o as t};
@@ -0,0 +1 @@
1
+ import{t as e}from"./jsx-runtime-Bt-cYkS5.js";import{C as t,t as n}from"./userStore-C4vdYsQp.js";import{t as r}from"./LanguageToggle-Di5b88mK.js";import{t as i}from"./download-Bg-OdoxM.js";import{B as a,c as o,g as s}from"./index-CrAXrmfP.js";import{t as c}from"./MarketingThemeToggle-C6fggkl7.js";import{t as l}from"./LogoIcon-B2fFe0l1.js";var u=e();function d(){let e=n(e=>e.identity),d=n(e=>e.openLoginModal),{t:f}=a(),p=s(),m=e?.displayName||e?.username||f(`nav.openWeb`);return(0,u.jsx)(`nav`,{className:`mkt-nav`,children:(0,u.jsxs)(`div`,{className:`mkt-nav-inner`,children:[(0,u.jsxs)(t,{to:`/`,className:`mkt-nav-logo`,children:[(0,u.jsx)(l,{}),`MOST PEOPLE`]}),(0,u.jsxs)(`div`,{className:`mkt-nav-cta`,children:[(0,u.jsx)(c,{}),(0,u.jsx)(r,{className:`mkt-theme-toggle`}),!p&&(0,u.jsxs)(t,{to:`/download/`,className:`btn btn-primary mkt-nav-preview`,children:[(0,u.jsx)(i,{size:16}),f(`nav.downloadClient`)]}),e?(0,u.jsx)(t,{to:`/profile/`,className:`mkt-nav-avatar-trigger`,"aria-label":f(`nav.profile`),title:m,children:(0,u.jsx)(`img`,{className:`mkt-nav-avatar`,src:o(e.address,e.avatar),alt:``,"aria-hidden":`true`})}):(0,u.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:d,children:f(`nav.getStarted`)})]})]})})}var f={name:`most-box`,version:`0.2.2`,description:`MostBox - P2P file sharing application`,type:`module`,main:`electron/main.js`,bin:{"most-box":`server/cli.js`},files:[`out`,`public`,`electron`,`server/src`,`server/index.js`,`server/cli.js`],scripts:{start:`vite`,server:`node --watch server/index.js`,dev:`vite`,build:`vite build && node scripts/prepare-start-static.mjs`,preview:`vite preview`,serve:`npm run build && node server/index.js`,test:`node --test server/tests/**/*.test.js`,"test:unit":`node --test server/tests/unit/*.test.js`,"test:frontend":`node --test src/tests/*.test.js`,"test:protocol":`node --test --test-name-pattern "extracts CID and filename|matches golden CID samples|publishes a file from Buffer|lists published files|pulls through local seed nodes" server/tests/unit/cid.test.js server/tests/integration/cid.test.js server/tests/integration/engine.test.js`,typecheck:`tsc -p tsconfig.typecheck.json`,"typecheck:strict-router":`tsc -p tsconfig.strict-router.json`,"check:static-output":`node scripts/check-static-output.mjs`,format:`npx prettier --write .`,lint:`npx eslint .`,"r2:cors":`node scripts/configure-r2-cors.mjs`,"electron:dev":`concurrently "npm run build" "wait-on out/index.html && electron ."`,"electron:rebuild":`electron-rebuild -f -w sodium-native`,"electron:build":`npm run build && npm run electron:rebuild && electron-builder`,"electron:build:win":`npm run build && npm run electron:rebuild && electron-builder --win`,"electron:build:win:x64":`npm run electron:build:win -- --x64`,"electron:build:win:arm64":`npm run electron:build:win -- --arm64`,"electron:build:mac":`npm run build && npm run electron:rebuild && electron-builder --mac`,"electron:build:linux":`npm run build && npm run electron:rebuild && electron-builder --linux`},keywords:[`p2p`,`file-sharing`,`hyperswarm`,`hyperdrive`],license:`MIT`,dependencies:{"@dicebear/collection":`^9.4.2`,"@dicebear/core":`^9.4.2`,"@hono/node-server":`^2.0.4`,"@tanstack/react-router":`^1.170.15`,"@tanstack/react-start":`^1.168.25`,b4a:`^1.8.1`,busboy:`^1.6.0`,corestore:`^7.10.0`,dayjs:`^1.11.21`,ethers:`^6.16.0`,eventemitter3:`^5.0.4`,hono:`^4.12.23`,hypercore:`^11.33.1`,hyperdrive:`^13.3.2`,hyperswarm:`^4.17.0`,"ipfs-unixfs-importer":`^17.0.1`,multiformats:`^14.0.0`,tweetnacl:`^1.0.3`,ws:`^8.21.0`},devDependencies:{"@electron/rebuild":`^4.0.4`,"@eslint/js":`^10.0.1`,"@iconify/react":`^6.0.2`,"@mantine/hooks":`^9.3.0`,"@milkdown/crepe":`^7.21.2`,"@milkdown/utils":`^7.21.2`,"@types/react":`^19.2.16`,"@vitejs/plugin-react":`^6.0.2`,concurrently:`^10.0.3`,electron:`^42.3.3`,"electron-builder":`^26.8.1`,esbuild:`^0.28.0`,eslint:`^10.4.1`,globals:`^17.6.0`,ky:`^2.0.2`,"lucide-react":`^1.17.0`,prettier:`^3.8.3`,"qrcode.react":`^4.2.0`,react:`^19.2.7`,"react-dom":`^19.2.7`,typescript:`6.0.3`,"typescript-eslint":`^8.60.1`,vite:`^8.0.16`,"wait-on":`^9.0.10`,zustand:`^5.0.14`},overrides:{"brace-expansion":`5.0.6`,postcss:`8.5.15`,ws:`$ws`},build:{appId:`com.mostbox.app`,productName:`MostBox`,publish:[{provider:`github`,releaseType:`release`}],directories:{output:`dist`},afterPack:`electron/afterPack.cjs`,files:[`out/**/*`,`electron/**/*`,`server/src/**/*`,`server/index.js`,`server/cli.js`,`package.json`,`!**/*.map`,`!electron/**/*.test.js`,`!server/tests/**/*`],asarUnpack:[`**/*.node`,`**/sodium-native/**`],protocols:[{name:`MostBox Link`,schemes:[`most`]}],win:{target:[`nsis`],artifactName:"${productName}-${version}-win-${arch}-setup.${ext}",icon:`public/logo.ico`},nsis:{oneClick:!1,allowToChangeInstallationDirectory:!0,createDesktopShortcut:!0,createStartMenuShortcut:!0,shortcutName:`MostBox`},mac:{artifactName:"${productName}-${version}-mac-${arch}.${ext}",target:[{target:`dmg`,arch:[`x64`,`arm64`]}],icon:`public/logo-512.png`,category:`public.app-category.utilities`},dmg:{contents:[{x:130,y:220},{x:410,y:220,type:`link`,path:`/Applications`}]},linux:{artifactName:"${productName}-${version}-linux-${arch}.${ext}",target:[{target:`AppImage`,arch:[`x64`,`arm64`]}],icon:`public/logo-512.png`,category:`Utility`}}},p=[{to:`/`,labelKey:`footer.about`},{to:`/ping/`,labelKey:`footer.network`},{href:`https://github.com/most-people/most`,labelKey:null,label:`GitHub`,external:!0}],m=f.version;function h(){let{t:e}=a();return(0,u.jsx)(`footer`,{className:`mkt-footer`,children:(0,u.jsx)(`div`,{className:`mkt-container`,children:(0,u.jsxs)(`div`,{className:`mkt-footer-inner`,children:[(0,u.jsx)(`div`,{className:`mkt-footer-links`,children:p.map(n=>`external`in n?(0,u.jsx)(`a`,{href:n.href,target:`_blank`,rel:`noopener noreferrer`,children:n.label},n.href):(0,u.jsx)(t,{to:n.to,children:e(n.labelKey)},n.to))}),(0,u.jsxs)(`span`,{className:`mkt-footer-copy`,children:[`© `,new Date().getFullYear(),` MOST PEOPLE · MIT License`]}),(0,u.jsxs)(`span`,{className:`mkt-footer-build`,translate:`no`,children:[`v`,m]})]})})})}function g({children:e,header:t}){return(0,u.jsxs)(`div`,{className:`mkt-layout`,children:[t??(0,u.jsx)(d,{}),(0,u.jsx)(`main`,{className:`mkt-layout-main`,children:e}),(0,u.jsx)(h,{})]})}export{g as t};
@@ -1 +1 @@
1
- import{n as e,o as t,t as n}from"./jsx-runtime-Bt-cYkS5.js";import{n as r,r as i}from"./LanguageToggle-CtzCCAYv.js";import{G as a}from"./index-QxXZzOUL.js";var o=t(e(),1),s=n();function c(){let[e,t]=(0,o.useState)(!1),{t:n}=a();return(0,o.useEffect)(()=>{let e=localStorage.getItem(`theme`),n=window.matchMedia(`(prefers-color-scheme: dark)`).matches;(e===`dark`||!e&&n)&&t(!0)},[]),(0,o.useEffect)(()=>{document.documentElement.setAttribute(`data-theme`,e?`dark`:`light`),localStorage.setItem(`theme`,e?`dark`:`light`)},[e]),(0,s.jsx)(`button`,{type:`button`,className:`mkt-theme-toggle`,onClick:()=>t(!e),"aria-label":n(`common.theme.toggle`),title:n(`common.theme.toggle`),children:e?(0,s.jsx)(r,{size:16}):(0,s.jsx)(i,{size:16})})}export{c as t};
1
+ import{n as e,o as t,t as n}from"./jsx-runtime-Bt-cYkS5.js";import{n as r,r as i}from"./LanguageToggle-Di5b88mK.js";import{B as a}from"./index-CrAXrmfP.js";var o=t(e(),1),s=n();function c(){let[e,t]=(0,o.useState)(!1),{t:n}=a();return(0,o.useEffect)(()=>{let e=localStorage.getItem(`theme`),n=window.matchMedia(`(prefers-color-scheme: dark)`).matches;(e===`dark`||!e&&n)&&t(!0)},[]),(0,o.useEffect)(()=>{document.documentElement.setAttribute(`data-theme`,e?`dark`:`light`),localStorage.setItem(`theme`,e?`dark`:`light`)},[e]),(0,s.jsx)(`button`,{type:`button`,className:`mkt-theme-toggle`,onClick:()=>t(!e),"aria-label":n(`common.theme.toggle`),title:n(`common.theme.toggle`),children:e?(0,s.jsx)(r,{size:16}):(0,s.jsx)(i,{size:16})})}export{c as t};