9remote 3.0.40 → 3.0.46

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 (292) hide show
  1. package/dist/cli.cjs +6 -6
  2. package/dist/extension/background.js +120 -17
  3. package/dist/extension/manifest.json +2 -2
  4. package/dist/extension/popup.html +7 -0
  5. package/dist/extension/popup.js +6 -0
  6. package/dist/ptyDaemon.cjs +5 -5
  7. package/dist/server.cjs +248 -241
  8. package/dist/ui/assets/index-BefL072o.js +8 -0
  9. package/dist/ui/assets/index-DvsANh5-.css +1 -0
  10. package/dist/ui/index.html +2 -2
  11. package/dist/web/404.html +1 -1
  12. package/dist/web/__next.__PAGE__.txt +2 -2
  13. package/dist/web/__next._full.txt +26 -20
  14. package/dist/web/__next._head.txt +1 -1
  15. package/dist/web/__next._index.txt +12 -7
  16. package/dist/web/__next._tree.txt +2 -2
  17. package/dist/web/_next/static/chunks/1772-2df6c72aa1bdf99d.js +1 -0
  18. package/dist/web/_next/static/chunks/1920-64e4610715fd991d.js +1 -0
  19. package/dist/web/_next/static/chunks/1968-90d80a8543ed4f21.js +32 -0
  20. package/dist/web/_next/static/chunks/556-1dec70a3f28ddbe8.js +1 -0
  21. package/dist/web/_next/static/chunks/5587-b8f18d331fdde617.js +1 -0
  22. package/dist/web/_next/static/chunks/6153.189180c190f90b2f.js +1 -0
  23. package/dist/web/_next/static/chunks/6221-2be9b41ee97fc1e6.js +11 -0
  24. package/dist/web/_next/static/chunks/7489.c1e8656da3738df7.js +1 -0
  25. package/dist/web/_next/static/chunks/8126-c11d39a1ae6ac126.js +1 -0
  26. package/dist/web/_next/static/chunks/820-c1bd7547f2433453.js +1 -0
  27. package/dist/web/_next/static/chunks/8534.189180c190f90b2f.js +1 -0
  28. package/dist/web/_next/static/chunks/9121-cf1e65bb26b0908b.js +1 -0
  29. package/dist/web/_next/static/chunks/{9491-6dc334192080d071.js → 9491-970597f510e71615.js} +1 -1
  30. package/dist/web/_next/static/chunks/app/_global-error/page-e60883b219ccba1a.js +1 -0
  31. package/dist/web/_next/static/chunks/app/_not-found/page-bfa58c699e86fa7c.js +1 -0
  32. package/dist/web/_next/static/chunks/app/admin/access/page-79e70c584b6e2150.js +5 -0
  33. package/dist/web/_next/static/chunks/app/admin/login/page-4a768b6df8ed5259.js +1 -0
  34. package/dist/web/_next/static/chunks/app/admin/ota/page-e4d26a8db9968a98.js +5 -0
  35. package/dist/web/_next/static/chunks/app/admin/page-1c13a4c1567ed18e.js +5 -0
  36. package/dist/web/_next/static/chunks/app/admin/turn/page-dbd8be78d0941005.js +5 -0
  37. package/dist/web/_next/static/chunks/app/download/page-e27de0a4170f4b73.js +1 -0
  38. package/dist/web/_next/static/chunks/app/layout-fc9671123388edff.js +1 -0
  39. package/dist/web/_next/static/chunks/app/login/page-8216ac4904ee3551.js +1 -0
  40. package/dist/web/_next/static/chunks/app/{page-1e67d8a5f3775276.js → page-fde2c88f21078fca.js} +2 -2
  41. package/dist/web/_next/static/chunks/app/workspace/browse/page-e60883b219ccba1a.js +1 -0
  42. package/dist/web/_next/static/chunks/app/workspace/editor/page-e60883b219ccba1a.js +1 -0
  43. package/dist/web/_next/static/chunks/app/workspace/files/page-e60883b219ccba1a.js +1 -0
  44. package/dist/web/_next/static/chunks/app/workspace/git/page-e60883b219ccba1a.js +1 -0
  45. package/dist/web/_next/static/chunks/app/workspace/layout-0d349197dc482ccd.js +23 -0
  46. package/dist/web/_next/static/chunks/app/workspace/mobile/page-e60883b219ccba1a.js +1 -0
  47. package/dist/web/_next/static/chunks/app/workspace/page-e60883b219ccba1a.js +1 -0
  48. package/dist/web/_next/static/chunks/app/workspace/pair/page-e60883b219ccba1a.js +1 -0
  49. package/dist/web/_next/static/chunks/app/workspace/remote/page-e60883b219ccba1a.js +1 -0
  50. package/dist/web/_next/static/chunks/app/workspace/settings/page-e60883b219ccba1a.js +1 -0
  51. package/dist/web/_next/static/chunks/app/workspace/terminal/[sessionId]/page-e60883b219ccba1a.js +1 -0
  52. package/dist/web/_next/static/chunks/app/workspace/welcome/page-e60883b219ccba1a.js +1 -0
  53. package/dist/web/_next/static/chunks/app/workspace/workspaces/page-e60883b219ccba1a.js +1 -0
  54. package/dist/web/_next/static/chunks/main-72206f0a3cb91ecb.js +5 -0
  55. package/dist/web/_next/static/chunks/next/dist/client/components/builtin/app-error-e60883b219ccba1a.js +1 -0
  56. package/dist/web/_next/static/chunks/next/dist/client/components/builtin/forbidden-e60883b219ccba1a.js +1 -0
  57. package/dist/web/_next/static/chunks/next/dist/client/components/builtin/not-found-e60883b219ccba1a.js +1 -0
  58. package/dist/web/_next/static/chunks/next/dist/client/components/builtin/unauthorized-e60883b219ccba1a.js +1 -0
  59. package/dist/web/_next/static/chunks/{webpack-dd1f7a5ae02e5d84.js → webpack-31691f9bc04b8076.js} +1 -1
  60. package/dist/web/_next/static/css/{adc0ee53b89bee3c.css → 4da4daf9f2bf1755.css} +1 -1
  61. package/dist/web/_next/static/css/577dbf61f141a630.css +1 -0
  62. package/dist/web/_next/static/{55Oo1FQxj9HIxB7QE1XWG → u29HK3zWfDC3mM40skU_h}/_buildManifest.js +1 -1
  63. package/dist/web/_not-found/__next._full.txt +20 -18
  64. package/dist/web/_not-found/__next._head.txt +1 -1
  65. package/dist/web/_not-found/__next._index.txt +7 -7
  66. package/dist/web/_not-found/__next._not-found.__PAGE__.txt +1 -1
  67. package/dist/web/_not-found/__next._not-found.txt +1 -1
  68. package/dist/web/_not-found/__next._tree.txt +2 -2
  69. package/dist/web/_not-found.html +1 -1
  70. package/dist/web/_not-found.txt +20 -18
  71. package/dist/web/admin/__next._full.txt +29 -22
  72. package/dist/web/admin/__next._head.txt +1 -1
  73. package/dist/web/admin/__next._index.txt +12 -7
  74. package/dist/web/admin/__next._tree.txt +2 -2
  75. package/dist/web/admin/__next.admin.__PAGE__.txt +2 -2
  76. package/dist/web/admin/__next.admin.txt +1 -1
  77. package/dist/web/admin/access/__next._full.txt +30 -22
  78. package/dist/web/admin/access/__next._head.txt +1 -1
  79. package/dist/web/admin/access/__next._index.txt +12 -7
  80. package/dist/web/admin/access/__next._tree.txt +2 -2
  81. package/dist/web/admin/access/__next.admin.access.__PAGE__.txt +2 -2
  82. package/dist/web/admin/access/__next.admin.access.txt +1 -1
  83. package/dist/web/admin/access/__next.admin.txt +1 -1
  84. package/dist/web/admin/access.html +1 -1
  85. package/dist/web/admin/access.txt +30 -22
  86. package/dist/web/admin/login/__next._full.txt +30 -22
  87. package/dist/web/admin/login/__next._head.txt +1 -1
  88. package/dist/web/admin/login/__next._index.txt +12 -7
  89. package/dist/web/admin/login/__next._tree.txt +2 -2
  90. package/dist/web/admin/login/__next.admin.login.__PAGE__.txt +2 -2
  91. package/dist/web/admin/login/__next.admin.login.txt +1 -1
  92. package/dist/web/admin/login/__next.admin.txt +1 -1
  93. package/dist/web/admin/login.html +1 -1
  94. package/dist/web/admin/login.txt +30 -22
  95. package/dist/web/admin/ota/__next._full.txt +30 -22
  96. package/dist/web/admin/ota/__next._head.txt +1 -1
  97. package/dist/web/admin/ota/__next._index.txt +12 -7
  98. package/dist/web/admin/ota/__next._tree.txt +2 -2
  99. package/dist/web/admin/ota/__next.admin.ota.__PAGE__.txt +2 -2
  100. package/dist/web/admin/ota/__next.admin.ota.txt +1 -1
  101. package/dist/web/admin/ota/__next.admin.txt +1 -1
  102. package/dist/web/admin/ota.html +1 -1
  103. package/dist/web/admin/ota.txt +30 -22
  104. package/dist/web/admin/turn/__next._full.txt +30 -22
  105. package/dist/web/admin/turn/__next._head.txt +1 -1
  106. package/dist/web/admin/turn/__next._index.txt +12 -7
  107. package/dist/web/admin/turn/__next._tree.txt +2 -2
  108. package/dist/web/admin/turn/__next.admin.turn.__PAGE__.txt +2 -2
  109. package/dist/web/admin/turn/__next.admin.turn.txt +1 -1
  110. package/dist/web/admin/turn/__next.admin.txt +1 -1
  111. package/dist/web/admin/turn.html +1 -1
  112. package/dist/web/admin/turn.txt +30 -22
  113. package/dist/web/admin.html +1 -1
  114. package/dist/web/admin.txt +29 -22
  115. package/dist/web/download/__next._full.txt +26 -19
  116. package/dist/web/download/__next._head.txt +1 -1
  117. package/dist/web/download/__next._index.txt +12 -7
  118. package/dist/web/download/__next._tree.txt +2 -2
  119. package/dist/web/download/__next.download.__PAGE__.txt +2 -2
  120. package/dist/web/download/__next.download.txt +1 -1
  121. package/dist/web/download.html +1 -1
  122. package/dist/web/download.txt +26 -19
  123. package/dist/web/index.html +1 -1
  124. package/dist/web/index.txt +26 -20
  125. package/dist/web/login/__next._full.txt +29 -22
  126. package/dist/web/login/__next._head.txt +1 -1
  127. package/dist/web/login/__next._index.txt +12 -7
  128. package/dist/web/login/__next._tree.txt +2 -2
  129. package/dist/web/login/__next.login.__PAGE__.txt +2 -2
  130. package/dist/web/login/__next.login.txt +1 -1
  131. package/dist/web/login.html +1 -1
  132. package/dist/web/login.txt +29 -22
  133. package/dist/web/workspace/__next._full.txt +27 -20
  134. package/dist/web/workspace/__next._head.txt +1 -1
  135. package/dist/web/workspace/__next._index.txt +12 -7
  136. package/dist/web/workspace/__next._tree.txt +3 -3
  137. package/dist/web/workspace/__next.workspace.__PAGE__.txt +1 -1
  138. package/dist/web/workspace/__next.workspace.txt +3 -3
  139. package/dist/web/workspace/browse/__next._full.txt +30 -22
  140. package/dist/web/workspace/browse/__next._head.txt +1 -1
  141. package/dist/web/workspace/browse/__next._index.txt +12 -7
  142. package/dist/web/workspace/browse/__next._tree.txt +3 -3
  143. package/dist/web/workspace/browse/__next.workspace.browse.__PAGE__.txt +1 -1
  144. package/dist/web/workspace/browse/__next.workspace.browse.txt +1 -1
  145. package/dist/web/workspace/browse/__next.workspace.txt +3 -3
  146. package/dist/web/workspace/browse.html +1 -1
  147. package/dist/web/workspace/browse.txt +30 -22
  148. package/dist/web/workspace/editor/__next._full.txt +30 -22
  149. package/dist/web/workspace/editor/__next._head.txt +1 -1
  150. package/dist/web/workspace/editor/__next._index.txt +12 -7
  151. package/dist/web/workspace/editor/__next._tree.txt +3 -3
  152. package/dist/web/workspace/editor/__next.workspace.editor.__PAGE__.txt +1 -1
  153. package/dist/web/workspace/editor/__next.workspace.editor.txt +1 -1
  154. package/dist/web/workspace/editor/__next.workspace.txt +3 -3
  155. package/dist/web/workspace/editor.html +1 -1
  156. package/dist/web/workspace/editor.txt +30 -22
  157. package/dist/web/workspace/files/__next._full.txt +30 -22
  158. package/dist/web/workspace/files/__next._head.txt +1 -1
  159. package/dist/web/workspace/files/__next._index.txt +12 -7
  160. package/dist/web/workspace/files/__next._tree.txt +3 -3
  161. package/dist/web/workspace/files/__next.workspace.files.__PAGE__.txt +1 -1
  162. package/dist/web/workspace/files/__next.workspace.files.txt +1 -1
  163. package/dist/web/workspace/files/__next.workspace.txt +3 -3
  164. package/dist/web/workspace/files.html +1 -1
  165. package/dist/web/workspace/files.txt +30 -22
  166. package/dist/web/workspace/git/__next._full.txt +30 -22
  167. package/dist/web/workspace/git/__next._head.txt +1 -1
  168. package/dist/web/workspace/git/__next._index.txt +12 -7
  169. package/dist/web/workspace/git/__next._tree.txt +3 -3
  170. package/dist/web/workspace/git/__next.workspace.git.__PAGE__.txt +1 -1
  171. package/dist/web/workspace/git/__next.workspace.git.txt +1 -1
  172. package/dist/web/workspace/git/__next.workspace.txt +3 -3
  173. package/dist/web/workspace/git.html +1 -1
  174. package/dist/web/workspace/git.txt +30 -22
  175. package/dist/web/workspace/mobile/__next._full.txt +30 -22
  176. package/dist/web/workspace/mobile/__next._head.txt +1 -1
  177. package/dist/web/workspace/mobile/__next._index.txt +12 -7
  178. package/dist/web/workspace/mobile/__next._tree.txt +3 -3
  179. package/dist/web/workspace/mobile/__next.workspace.mobile.__PAGE__.txt +1 -1
  180. package/dist/web/workspace/mobile/__next.workspace.mobile.txt +1 -1
  181. package/dist/web/workspace/mobile/__next.workspace.txt +3 -3
  182. package/dist/web/workspace/mobile.html +1 -1
  183. package/dist/web/workspace/mobile.txt +30 -22
  184. package/dist/web/workspace/pair/__next._full.txt +30 -22
  185. package/dist/web/workspace/pair/__next._head.txt +1 -1
  186. package/dist/web/workspace/pair/__next._index.txt +12 -7
  187. package/dist/web/workspace/pair/__next._tree.txt +3 -3
  188. package/dist/web/workspace/pair/__next.workspace.pair.__PAGE__.txt +1 -1
  189. package/dist/web/workspace/pair/__next.workspace.pair.txt +1 -1
  190. package/dist/web/workspace/pair/__next.workspace.txt +3 -3
  191. package/dist/web/workspace/pair.html +1 -1
  192. package/dist/web/workspace/pair.txt +30 -22
  193. package/dist/web/workspace/remote/__next._full.txt +30 -22
  194. package/dist/web/workspace/remote/__next._head.txt +1 -1
  195. package/dist/web/workspace/remote/__next._index.txt +12 -7
  196. package/dist/web/workspace/remote/__next._tree.txt +3 -3
  197. package/dist/web/workspace/remote/__next.workspace.remote.__PAGE__.txt +1 -1
  198. package/dist/web/workspace/remote/__next.workspace.remote.txt +1 -1
  199. package/dist/web/workspace/remote/__next.workspace.txt +3 -3
  200. package/dist/web/workspace/remote.html +1 -1
  201. package/dist/web/workspace/remote.txt +30 -22
  202. package/dist/web/workspace/settings/__next._full.txt +37 -0
  203. package/dist/web/{dev/question → workspace/settings}/__next._head.txt +1 -1
  204. package/dist/web/workspace/settings/__next._index.txt +17 -0
  205. package/dist/web/{dev/question → workspace/settings}/__next._tree.txt +3 -2
  206. package/dist/web/workspace/settings/__next.workspace.settings.__PAGE__.txt +5 -0
  207. package/dist/web/{dev/question/__next.dev.question.txt → workspace/settings/__next.workspace.settings.txt} +1 -1
  208. package/dist/web/workspace/settings/__next.workspace.txt +8 -0
  209. package/dist/web/workspace/settings.html +1 -0
  210. package/dist/web/workspace/settings.txt +37 -0
  211. package/dist/web/workspace/terminal/default/__next._full.txt +30 -24
  212. package/dist/web/workspace/terminal/default/__next._head.txt +1 -1
  213. package/dist/web/workspace/terminal/default/__next._index.txt +12 -7
  214. package/dist/web/workspace/terminal/default/__next._tree.txt +3 -3
  215. package/dist/web/workspace/terminal/default/__next.workspace.terminal.$d$sessionId.__PAGE__.txt +1 -1
  216. package/dist/web/workspace/terminal/default/__next.workspace.terminal.$d$sessionId.txt +1 -1
  217. package/dist/web/workspace/terminal/default/__next.workspace.terminal.txt +1 -1
  218. package/dist/web/workspace/terminal/default/__next.workspace.txt +3 -3
  219. package/dist/web/workspace/terminal/default.html +1 -1
  220. package/dist/web/workspace/terminal/default.txt +30 -24
  221. package/dist/web/workspace/welcome/__next._full.txt +30 -22
  222. package/dist/web/workspace/welcome/__next._head.txt +1 -1
  223. package/dist/web/workspace/welcome/__next._index.txt +12 -7
  224. package/dist/web/workspace/welcome/__next._tree.txt +3 -3
  225. package/dist/web/workspace/welcome/__next.workspace.txt +3 -3
  226. package/dist/web/workspace/welcome/__next.workspace.welcome.__PAGE__.txt +1 -1
  227. package/dist/web/workspace/welcome/__next.workspace.welcome.txt +1 -1
  228. package/dist/web/workspace/welcome.html +1 -1
  229. package/dist/web/workspace/welcome.txt +30 -22
  230. package/dist/web/workspace/workspaces/__next._full.txt +30 -22
  231. package/dist/web/workspace/workspaces/__next._head.txt +1 -1
  232. package/dist/web/workspace/workspaces/__next._index.txt +12 -7
  233. package/dist/web/workspace/workspaces/__next._tree.txt +3 -3
  234. package/dist/web/workspace/workspaces/__next.workspace.txt +3 -3
  235. package/dist/web/workspace/workspaces/__next.workspace.workspaces.__PAGE__.txt +1 -1
  236. package/dist/web/workspace/workspaces/__next.workspace.workspaces.txt +1 -1
  237. package/dist/web/workspace/workspaces.html +1 -1
  238. package/dist/web/workspace/workspaces.txt +30 -22
  239. package/dist/web/workspace.html +1 -1
  240. package/dist/web/workspace.txt +27 -20
  241. package/package.json +5 -5
  242. package/dist/ui/assets/index-D_C1NTm1.js +0 -8
  243. package/dist/ui/assets/index-SHlsPzjb.css +0 -1
  244. package/dist/web/_next/static/chunks/1772-ef73c166e83f5eff.js +0 -1
  245. package/dist/web/_next/static/chunks/1920-5ead25286846df83.js +0 -1
  246. package/dist/web/_next/static/chunks/1968-4d2969f0b7112e0b.js +0 -32
  247. package/dist/web/_next/static/chunks/329-15d3e36af1b2827f.js +0 -1
  248. package/dist/web/_next/static/chunks/556-a8f04c41c5663ee8.js +0 -1
  249. package/dist/web/_next/static/chunks/5587-fc5af8c76df14222.js +0 -1
  250. package/dist/web/_next/static/chunks/6153.8c6b8930e22ceea0.js +0 -1
  251. package/dist/web/_next/static/chunks/6221-cf883148bf8a4c1e.js +0 -11
  252. package/dist/web/_next/static/chunks/7489.24938d89538cd03e.js +0 -1
  253. package/dist/web/_next/static/chunks/8126-0279fc9e17c08aff.js +0 -1
  254. package/dist/web/_next/static/chunks/820-99036fb63c5462c8.js +0 -1
  255. package/dist/web/_next/static/chunks/8534.8c6b8930e22ceea0.js +0 -1
  256. package/dist/web/_next/static/chunks/9121-3d281debd0f3e659.js +0 -1
  257. package/dist/web/_next/static/chunks/app/_global-error/page-2ece09c883187d82.js +0 -1
  258. package/dist/web/_next/static/chunks/app/_not-found/page-9f829d2c4beb1840.js +0 -1
  259. package/dist/web/_next/static/chunks/app/admin/access/page-45f45ad529e5b691.js +0 -5
  260. package/dist/web/_next/static/chunks/app/admin/login/page-382072b5b43d3c29.js +0 -1
  261. package/dist/web/_next/static/chunks/app/admin/ota/page-293c0743bd60f454.js +0 -5
  262. package/dist/web/_next/static/chunks/app/admin/page-fc676dae451dd646.js +0 -5
  263. package/dist/web/_next/static/chunks/app/admin/turn/page-2ab33033fc7f0919.js +0 -5
  264. package/dist/web/_next/static/chunks/app/dev/question/page-bafce0c9fd4e8488.js +0 -1
  265. package/dist/web/_next/static/chunks/app/download/page-a65d1c7fcf6397af.js +0 -1
  266. package/dist/web/_next/static/chunks/app/layout-f1429d22e935695f.js +0 -1
  267. package/dist/web/_next/static/chunks/app/login/page-a5dd37d1cbbb394e.js +0 -1
  268. package/dist/web/_next/static/chunks/app/workspace/browse/page-2ece09c883187d82.js +0 -1
  269. package/dist/web/_next/static/chunks/app/workspace/editor/page-2ece09c883187d82.js +0 -1
  270. package/dist/web/_next/static/chunks/app/workspace/files/page-2ece09c883187d82.js +0 -1
  271. package/dist/web/_next/static/chunks/app/workspace/git/page-2ece09c883187d82.js +0 -1
  272. package/dist/web/_next/static/chunks/app/workspace/layout-d8bb677fa1caa5a7.js +0 -20
  273. package/dist/web/_next/static/chunks/app/workspace/mobile/page-2ece09c883187d82.js +0 -1
  274. package/dist/web/_next/static/chunks/app/workspace/page-2ece09c883187d82.js +0 -1
  275. package/dist/web/_next/static/chunks/app/workspace/pair/page-2ece09c883187d82.js +0 -1
  276. package/dist/web/_next/static/chunks/app/workspace/remote/page-2ece09c883187d82.js +0 -1
  277. package/dist/web/_next/static/chunks/app/workspace/terminal/[sessionId]/page-2ece09c883187d82.js +0 -1
  278. package/dist/web/_next/static/chunks/app/workspace/welcome/page-2ece09c883187d82.js +0 -1
  279. package/dist/web/_next/static/chunks/app/workspace/workspaces/page-2ece09c883187d82.js +0 -1
  280. package/dist/web/_next/static/chunks/main-e10b0dbebb4de0a8.js +0 -5
  281. package/dist/web/_next/static/chunks/next/dist/client/components/builtin/app-error-2ece09c883187d82.js +0 -1
  282. package/dist/web/_next/static/chunks/next/dist/client/components/builtin/forbidden-2ece09c883187d82.js +0 -1
  283. package/dist/web/_next/static/chunks/next/dist/client/components/builtin/not-found-2ece09c883187d82.js +0 -1
  284. package/dist/web/_next/static/chunks/next/dist/client/components/builtin/unauthorized-2ece09c883187d82.js +0 -1
  285. package/dist/web/_next/static/css/1c2cca827fa36d54.css +0 -1
  286. package/dist/web/dev/question/__next._full.txt +0 -29
  287. package/dist/web/dev/question/__next._index.txt +0 -12
  288. package/dist/web/dev/question/__next.dev.question.__PAGE__.txt +0 -9
  289. package/dist/web/dev/question/__next.dev.txt +0 -5
  290. package/dist/web/dev/question.html +0 -1
  291. package/dist/web/dev/question.txt +0 -29
  292. /package/dist/web/_next/static/{55Oo1FQxj9HIxB7QE1XWG → u29HK3zWfDC3mM40skU_h}/_ssgManifest.js +0 -0
@@ -1 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[9121],{9121:(e,t,o)=>{"use strict";o.d(t,{s:()=>m});var a=o(7620),n=o(94245),s=o(33879),r=o(24890);let i=s.dI.map(e=>e.code),l=new Map,d=(e,t)=>{if(!i.includes(e)||e===s.Xn||c.getState().dicts[e]||l.has(e))return;let a=o(49262)(`./${e}.js`).then(o=>{l.delete(e);let a=o.default;return t(t=>({dicts:{...t.dicts,[e]:a}})),a}).catch(()=>{l.delete(e)});l.set(e,a)},c=(0,n.v)(e=>({locale:s.Xn,dicts:{[s.Xn]:r.default},hydrated:!1,hydrate:()=>{let t=function(){try{let e=window.localStorage.getItem(s.zl);if(e&&i.includes(e))return e}catch{}return s.Xn}();d(t,e),e({locale:t,hydrated:!0})},setLocale:t=>{if(i.includes(t)){try{window.localStorage.setItem(s.zl,t)}catch{}d(t,e),e({locale:t})}}}));function p(e,t){if(e)return t.split(".").reduce((e,t)=>null==e?e:e[t],e)}function m(){let{locale:e,dicts:t,hydrated:o,hydrate:n,setLocale:r}=c();(0,a.useEffect)(()=>{o||n()},[o,n]);let i=t[e]||t[s.Xn],l=t[s.Xn];return{t:(0,a.useMemo)(()=>(e,t)=>{var o;return o=p(i,e)??p(l,e)??e,"string"==typeof o&&t?o.replace(/\{(\w+)\}/g,(e,o)=>null!=t[o]?t[o]:`{${o}}`):o},[i,l]),locale:e,setLocale:r,hydrated:o}}},24890:(e,t,o)=>{"use strict";o.r(t),o.d(t,{default:()=>a});let a={common:{statusIdle:"Idle",statusWorking:"Working",statusBlocked:"Needs input",statusDone:"Your turn",statusSleep:"Sleeping",connect:"Connect",disconnect:"Disconnect",loading:"Loading...",cancel:"Cancel",confirm:"Confirm",save:"Save",delete:"Delete",close:"Close",back:"Back",next:"Next",edit:"Edit",rename:"Rename",remove:"Remove",open:"Open",clear:"Clear",yes:"Yes",no:"No",ok:"OK",error:"Error",success:"Success",failed:"Failed",retry:"Retry",refresh:"Refresh",clipboard:"Clipboard",clipboardCopy:"Copy",clipboardEmpty:"Clipboard is empty",search:"Search",create:"Create",new:"New",add:"Add",copy:"Copy",copied:"Copied",promptNotSent:"Prompt didn't reach the host",resend:"Resend",dismiss:"Dismiss",download:"Download",upload:"Upload",enabled:"Enabled",disabled:"Disabled",on:"on",off:"off",minute:"min",hour:"h",day:"d",minutesAgo:"{n} min ago",hoursAgo:"{n} hours ago",daysAgo:"{n} days ago",done:"Done",moveUp:"Move up",moveDown:"Move down"},agentSwitcher:{title:"Your devices",active:"ACTIVE",unnamed:"Untitled",connecting:"Connecting…",unreachable:"Can't reach this device. Is it online?"},hosts:{title:"Hosts",openHost:"Open host",connecting:"Connecting…",lastSeen:"Last seen",online:"Online",offline:"Offline",sessions:"sessions",working:"working",attention:"need you",noSessions:"No sessions",addHost:"Add host",removeHost:"Remove host",removeHostMessage:'Remove "{name}" from your saved hosts? The machine itself is not affected.',disconnectMessage:'Disconnect from "{name}"? Its terminals keep running; the key stays saved.'},login:{tagline:"Access your terminal from anywhere",heroLine1:"Any machine.",heroLine2:"One terminal.",heroLine3:"In your pocket.",featureTerminal:"Terminal",featureDesktop:"Desktop",featureFiles:"Files",termConnected:"host connected",termTunnel:"tunnel established",termReady:"ready",accessKey:"Access Key",placeholder:"sk-xxx... or One-Time Key (ABC123)",rememberKey:"Remember this key",connect:"Connect",connecting:"Connecting...",authenticating:"Authenticating with token...",invalidKeyTail:"Wrong access key — check the last characters and try again.",scanQr:"Scan QR to login",qrScanTitle:"Scan QR Code",qrHint:"Point the camera at the QR code shown on the machine running 9Remote.",qrDetected:"QR Code detected!",qrAuthenticating:"Authenticating...",qrPleaseWait:"Please wait...",qrLibFail:"Failed to load the QR scanner library.",qrInitFail:"Could not start the scanner.",qrCamDenied:"Camera permission denied. Allow camera access and try again.",qrNoCamera:"No camera found on this device.",qrCamBusy:"Camera is in use by another app.",qrCamError:"Could not open the camera.",agentOffline:"This machine isn't running 9remote. Start the host, then try again.",legacyKeyUpdateRequired:"Host update required",legacyKeyUpdateHint:"This device uses an older key format. Update 9remote on that machine to connect:",legacyKeyError:"This access key uses an older format. Please update 9remote to the latest version on your host machine.",updateRequired:"Update required",savedKeys:"Saved Keys",login:"Login",lastLogin:"Last login",namePlaceholder:"Name this key (optional)",rename:"Rename",deleteKeyTitle:"Delete key",deleteKeyConfirm:'Are you sure you want to delete "{name}"?',justNow:"Just now",minutesAgo:"{n}m ago",hoursAgo:"{n}h ago",daysAgo:"{n}d ago",tapToScan:"Tap to scan",orEnterManually:"or enter key manually",addKey:"Add Key",secureTitle:"Secure & Encrypted",secureDesc:"All connections are end-to-end encrypted and secure.",featAccessTitle:"Access Anywhere",featAccessDesc:"Connect from any device, anywhere.",featSecureTitle:"Secure Connection",featSecureDesc:"End-to-end encryption keeps you safe.",featFastTitle:"Fast & Reliable",featFastDesc:"Low latency and high performance.",featSessionsTitle:"Multiple Sessions",featSessionsDesc:"Manage and switch between sessions.",home:"Home",docs:"Docs"},menu:{reloadRestart:"Reload & Restart",restartHost:"Restart 9remote host",restartConfirmTitle:"Restart 9remote host?",restartConfirmMessage:"This restarts the host process (no reinstall). Terminal sessions are preserved. It takes a few seconds.",restartStarting:"Restarting host…",restartRestarting:"Restarting 9remote…",restartDone:"Restarted! Reconnecting…",restartTimeout:"Restart is taking too long",restartTimeoutHint:"Reconnect manually if it doesn't recover.",title:"Menu",language:"Language",theme:"Theme",notifications:"Notifications",webgl:"GPU Render (Faster)",webglHint:"Turn off if text looks wrong",notificationsHint:"Notify when agent finishes",files:"File Explorer",downloading:"Downloading",copying:"Copying",conflictTitle:"File already exists",conflictMessage:"{name} already exists. Replace or skip?",skip:"Skip",skipAll:"Skip all",replace:"Replace",replaceAll:"Replace all",sites:"Remote Browser",terminalSettings:"Terminal Settings",fontSize:"Font Size",terminalTheme:"Terminal Theme",terminalBackground:"Background",bgDim:"Background dim",bgApplyAll:"Apply to all",bgUrlPlaceholder:"Image URL (https://…)",bgSave:"Save",bgSaveFailed:"Could not save background",bgFromDevice:"Choose from device",bgFromUrl:"Paste image URL",bgChange:"Change image",bgAdd:"Add",bgCustomLabel:"Custom",bgDeleteFailed:"Could not delete background",bgCustomTitle:"Custom background",commandNotes:"Command Notes",showButtons:"Quick Buttons",showFolder:"Folder & Git Button",showNote:"Checklist Button",artifactHint:"The AI can preview html, docx, pdf, images and more instantly, beside your terminal.",artifactPanel:"Artifact preview",settingsJarvis:"Jarvis",jarvisToggle:"Jarvis coordinator",jarvisToggleHint:"Show the Jarvis button in the header. Its tools need the MCP switch in Plugins.",jarvisMcpOff:"The MCP switch in Plugins is off - Jarvis will start without its coordinator tools.",community:"Community",rateApp:"Rate App",starChip:"Help me star",installApp:"Install App",upgrade:"Upgrade",upgradeExpires:"Expires",upgradeRestore:"Restore Purchases",codespace:"Codespace",logout:"Logout",settingsGeneral:"General",settingsAgent:"Host",settingsSystem:"System",settingsVoice:"Voice",settingsBrowser:"Browser Use",extGuide1:"Open this link, then turn on Developer mode (top right):",extGuide2:'Click "Load unpacked" and pick this folder:',extGuide3:"Status flips to connected in a few seconds",voiceInput:"Voice Input",preventSleep:"Prevent Sleep",agentSystem:"System",agentAutoStart:"Launch on Startup",agentAutoStartHint:"Start the host when you log in",agentUnlock:"Remote Unlock",agentUnlockHint:"Allow control from the Windows lock screen",agentUnlockStale:"Worker state stale — re-checking",agentUnlockReady:"Running — works on the lock screen",agentLogs:"Logs",agentLogsOpen:"Host Logs",settingsDebug:"Debug",debugSource:"Source",debugLevel:"Level",debugAll:"All",debugHost:"Host",debugWeb:"Web",debugRefresh:"Refresh",debugCopy:"Copy",debugClear:"Clear",debugEmpty:"No logs",agentPower:"Power",agentRestart:"Restart host",agentShutdown:"Shutdown host",agentShutdownConfirmTitle:"Shutdown host?",agentShutdownConfirmMsg:"The host stops and every remote session drops until it is started again on this machine.",settingsAppearance:"Appearance",settingsTerminalTab:"Terminal",settingsMcp:"Plugins",settingsRemote:"Remote",mcpIntro:"Extra abilities you can give your AI coding tools.",mcpTools:"Allow",mcpUnavailable:"Update this host to use MCP.",artifactFormats:"Formats it can show",mcpClients:"Works with",settingsWorkspace:"Workspace",settingsApplication:"Application",settingsAccount:"Account",themeLight:"Light",themeDark:"Dark",reload:"Reload App",remoteDesktop:"Remote Desktop",headerButtons:"Header buttons",settingsButtons:"Buttons",notificationsButton:"Notifications",notificationsButtonHint:"Alerts when a terminal finishes or needs you.",remoteDesktopHint:"Control this machine's screen from your phone.",sitesHint:"Browse the host's Chrome and local sites.",settings:"Settings",enablePush:"Enable Push Notifications",disablePush:"Disable Push Notifications",pushHint:"Enable push notifications to get alerted when AI completes tasks",pushActiveHint:"Push notifications are on for this device. You'll be alerted when AI completes tasks.",versionMismatch:"9remote {version} is outdated",versionMismatchHint:"Some features may not work. Run:",updateNow:"Update now",updating:"Updating… reconnecting",webReloadTitle:"New web version available",webReloadHint:"Reload to get the latest interface.",reloadWeb:"Reload",updateAvailableTitle:"9Remote host update available",updateConfirmTitle:"Update 9remote?",updateConfirmMessage:"This installs the latest version and restarts the connection. It takes about a minute.",updateStarting:"Starting update…",updateInstalling:"Installing new version…",updateTimeout:"Update is taking too long",updateTimeoutHint:"Reload manually if it doesn't recover.",updateRestarting:"Updating 9remote…",updateReconnecting:"Reconnecting…",updateDone:"Updated! Reloading…",version:"Version",orientation:"Screen Orientation",orientationPortrait:"Portrait",orientationLandscape:"Landscape",orientationAuto:"Auto"},workspace:{loading:"Loading...",logoutTitle:"Logout",logoutMessage:"Are you sure you want to logout?",failedCreateSession:"Failed to create session: {error}",failedRenameSession:"Failed to rename session: {error}"},sessions:{headerTitle:"9remote.cc",connected:"Connected",disconnected:"Disconnected",codespaceStopped:"Codespace stopped",placeholder:"Terminal name (optional)",newButton:"+ New",empty:"No active sessions",emptyHint:"Create a new session to get started",created:"Created {time}",deleteTitle:"Delete Session",deleteMessage:'Are you sure you want to delete "{name}"?',editName:"Edit name",sessionActions:"Session actions",maximize:"Maximize",restoreSplit:"Restore split",split:"Split",hidePanel:"Hide panel",showPanel:"Show panel",resumeSession:"Resume session",restartAi:"Restart AI",markRead:"Mark as read",openAsUi:"Open as chat UI",openAsTerminal:"Open as terminal",modeSwitchFailed:"Could not switch this terminal",newTerminal:"New terminal",options:"Options"},agentHistory:{title:"History",empty:"No past conversations here yet",untitled:"Untitled",openNow:"Running",minutesAgo:"{n}m",hoursAgo:"{n}h",daysAgo:"{n}d",showAll:"View all history",searchPlaceholder:"Search conversations…",allAgents:"All agents",delete:"Delete session",deleteTitle:"Delete conversation",deleteMessage:'Delete "{title}"? This permanently deletes the conversation transcript.',noResults:"No matching conversations",searchingAll:"Searching all folders…",searchTruncated:"Newest matches shown — refine the query to search deeper"},workspaces:{title:"Workspaces",newWorkspace:"Add workspace",newWorkspacePrompt:"Workspace name",newFolderName:"Folder name",createFolderTitle:"New folder",defaultName:"New workspace",ungrouped:"No workspace",addTerminal:"New terminal here",moveToWorkspace:"Move to workspace",rename:"Rename workspace",delete:"Remove workspace",emptyWorkspace:"No terminals here",selectFolder:"Choose folder",emptyTagVibe:"code \xb7 now",emptyWordVibe:"VibeCode Now",emptyMetaVibe:"Pick a workspace and start coding \xb7 <b>sessions persist</b>",emptyGoVibe:"Choose workspace",emptyTagPair:"connect \xb7 other pc",emptyWordPair:"Remote Other PC",emptyMetaPair:"terminal \xb7 <b>screen</b> \xb7 files — from web, app or pc",emptyGoPair:"Add another PC",browse:"Browse",recentFolders:"Recent",searchFolders:"Search folders...",parentFolder:"Up one level",drives:"Drives",homeFolder:"Home",hiddenFolders:"Hidden folders",selectNamed:'Choose "{name}"',enterPath:"Type a path and press Enter",pathNotFolder:"That path is not a folder",filterOrPath:"Search, or type a path like /home/me",notADirectory:'"{name}" is not a folder in {dir}',multipleDirMatches:'"{name}" matches several folders in {dir}',invalidPath:"Invalid path",openHere:"New terminal here",tabFiles:"Files",tabGit:"Git",tabTrees:"Trees",refreshRepos:"Rescan repos",onlyChanged:"Only changed files",openFullFiles:"Open full file explorer",emptyTitle:"Nothing open yet",cardWorkspaceTitle:"Workspace",cardWorkspaceDesc:"Open a folder and run terminals in it",cardRemoteTitle:"Remote desktop",cardRemoteDesc:"Control this machine's screen",emptyWordTerminal:"Remote Terminal",emptyWordRemote:"Remote Desktop",emptyTagWorkspace:"workspace \xb7 pty",emptyTagRemote:"remote \xb7 webrtc",emptyMetaWorkspace:"open a folder \xb7 <b>sessions persist</b>",emptyMetaRemote:"control this machine \xb7 <b>low latency</b>",worktrees:"Worktrees",branches:"Branches",newWorktree:"New worktree",worktreeName:"Branch name",worktreeRepoLabel:"Repo to add the worktree in",worktreeNameAscii:"This name can't become a branch — type it in Latin letters.",addWorktree:"Add worktree",removeWorktree:"Remove worktree",removeWorktreeMessage:'Remove worktree at "{path}"?',removeWorktreeFolder:"Folder: {path}",removeWorktreeBranchDelete:"Branch: {branch} (fully merged — deleted too)",removeWorktreeBranchKeep:"Branch: {branch} (not fully merged — kept)",removeWorktreeSessions:"{count} session(s) inside: {names}",removeWorktreeBranch:'Branch "{branch}" is deleted too (when fully merged).',worktreeBranchKept:'Branch "{branch}" kept: not fully merged.',worktreeBusy:"{count} terminal(s) still run in this worktree: {names}",worktreeDirty:"This worktree has modified or untracked files — forcing the removal deletes them for good. Continue?",checkedOut:"checked out",newBranch:"New branch",checkout:"Checkout",searchBranch:"Search branches",worktreePath:"Worktree path",nestedRepos:"{count} repos",showCleanRepos:"Show {count} unchanged repo(s)",showHiddenRepos:"Unhide {count} repo(s)",hideRepo:"Hide this repo",scanDeeper:"Scan subfolders deeper",deleteTitle:"Remove workspace",deleteMessage:'Remove workspace "{name}"? Its terminals are closed. Files on disk are untouched.'},terminal:{quotaNoData:"No quota data",quotaUsageTitle:"usage",back:"Back",menu:"Menu",newTerminal:"New terminal",remoteDesktop:"Remote Desktop",defaultName:"Term",searchAgents:"Search terminal or agent",noAgentsFound:"No match",skipPermissions:"Skip permission prompts",plainShell:"Terminal",nameLabel:"Name (optional)",workspaceRoot:"Workspace root",detachedHead:"detached",browseFolders:"Browse folders…",shell:"Shell"},files:{selectWorkspace:"Select Workspace",recentWorkspaces:"Recent Workspaces",home:"Home",root:"Root",drive:"Drive {letter}",codespaces:"Codespaces",removeRecent:"Remove from recent",removeTitle:"Remove Workspace",removeMessage:'Remove "{name}" from recent workspaces?',setAsWorkspace:"Set as Workspace",openFolder:"Open Folder",newFile:"New File",newFolder:"New Folder",rename:"Rename",delete:"Delete",deleteFile:"Delete File",deleteFolder:"Delete Folder",deleteFileMessage:'Delete "{name}"?',deleteFolderMessage:'Delete folder "{name}" and all its contents?',emptyFolder:"Empty folder",git:"Git",parent:"Parent folder",workspace:"Workspace",failedLoad:"Failed to load: {error}",failedDelete:"Failed to delete: {error}",failedCreate:"Failed to create: {error}",failedRename:"Failed to rename: {error}",enterName:"Enter name",confirmRename:"Rename to:",setWorkspace:"Set Workspace",setAsWorkspaceTitle:"Set as workspace",switchWorkspace:"Switch workspace",searchFiles:"Search files",toggleHidden:"Toggle hidden files",searchPlaceholder:"Search files...",searching:"Searching...",noFilesFound:"No files found",noGitRepo:"No git repository",cannotOpenBinary:"Cannot open binary file",createNew:"Create New",file:"File",folder:"Folder",placeholderFile:"filename.js",placeholderFolder:"folder-name",pickFile:"Choose files",pickFolder:"Choose folder",copyPath:"Copy path",copyRelPath:"Copy Relative Path",copyName:"Copy Filename",delete:"Delete",rename:"Rename",deleteConfirmTitle:"Delete",deleteConfirmMessage:'Delete "{name}"?'},fileKind:{web:"Web pages",document:"Documents",sheet:"Spreadsheets",image:"Images",media:"Audio & video",diagram:"Diagrams",code:"Code & text"},editor:{save:"Save",saving:"Saving...",saved:"Saved",unsaved:"Unsaved changes",close:"Close",discard:"Discard",discardTitle:"Discard Changes",discardMessage:"You have unsaved changes. Discard them?",unsavedTitle:"Save changes to {name}?",unsavedBody:"Your changes will be lost if you don't save them.",failedLoad:"Failed to load file: {error}",failedSave:"Failed to save: {error}",openFull:"Open in full editor",artifact:"Artifact",preview:"Preview",editCode:"Edit code",reload:"Reload",previewFailed:"Preview failed",previewNoRoute:"No LAN or tunnel route to the host",previewBack:"Back",previewForward:"Forward",previewOpenTab:"Open in a new tab",changedOnDisk:"Changed on disk",reloadFromDisk:"Reload",mermaidEmpty:"Nothing to draw",readOnly:"Read only",line:"Line",column:"Column",gitDiff:"Git Diff",typeText:"Type text and insert...",insert:"Insert",statusModified:"Modified",statusAdded:"Added",statusUntracked:"Untracked"},git:{title:"Git",branch:"Branch",changes:"Changes",staged:"Staged",unstaged:"Unstaged",untracked:"Untracked",commit:"Commit",commitAndPush:"Commit & Push",commitSuccess:"Commit successful",pushSuccess:"Push successful",stageFailed:"Failed to stage changes",commitFailed:"Commit failed",pushFailed:"Push failed",pullSuccess:"Pull successful",pullFailed:"Pull failed",stageAllConfirmTitle:"Stage All & Commit",stageAllConfirmMessage:"No changes are staged. Stage all changes and commit?",stageAndCommit:"Stage & Commit",gitActions:"Git actions",commitPlaceholder:"Commit message…",stageAllNote:"Stage all \xb7 {count}",upToDate:"Everything up-to-date",commitMessage:"Commit message",push:"Push",pull:"Pull",fetch:"Fetch",stage:"Stage",stageAll:"Stage All",unstage:"Unstage",discard:"Discard",discardChanges:"Discard Changes",discardMessage:'Discard changes to "{name}"?',noChanges:"No changes",diff:"Diff",pushing:"Pushing...",pulling:"Pulling...",committing:"Committing...",failedCommit:"Failed to commit: {error}",failedPush:"Failed to push: {error}",failedPull:"Failed to pull: {error}",status:"Status",diffTab:"Diff",modified:"Modified",added:"Added",deleted:"Deleted",untrackedTitle:"Untracked",openFile:"Open file",discardChangesTitle:"Discard changes",discardConfirmTitle:"Discard Changes",discardConfirmDelete:'Are you sure you want to delete "{name}"? This cannot be undone.',discardConfirmDiscard:'Are you sure you want to discard changes in "{name}"? This cannot be undone.',addToGitignore:"Add to .gitignore"},fileExplorer:{explorer:"Explorer",search:"Search",sourceControl:"Source Control",settings:"Settings",outline:"Outline",noFolderOpen:"No folder open",uploadingCount:"Uploading {{n}}/{{total}}…",uploadFailedCount:"{{n}} of {{total}} files failed to upload",openFolder:"Open Folder",recentWorkspaces:"Recent Workspaces",openedEditors:"Open Editors",closeEditor:"Close",closeOthers:"Close Others",closeAll:"Close All",closeAllSaved:"Close All Saved",saveAll:"Save All",newFile:"New File",newFolder:"New Folder",refreshExplorer:"Refresh Explorer",collapseAll:"Collapse All",searchInFiles:"Search in files",replaceInFiles:"Replace in files",searchPlaceholder:"Search",replacePlaceholder:"Replace",caseSensitive:"Match Case",wholeWord:"Match Whole Word",useRegex:"Use Regular Expression",filesToInclude:"files to include",filesToExclude:"files to exclude",noResults:"No results found",resultCount:"{count} results in {fileCount} files",replaceAll:"Replace All",replaceConfirmTitle:"Replace in Files",replaceConfirmMessage:"Replace {count} occurrences in {fileCount} files?",commandPalette:"Command Palette",quickOpen:"Quick Open File",typeCommand:"Type a command",typeFileName:"Type a file name",noCommandsFound:"No commands found",workspaceSwitcher:"Switch Workspace",pinWorkspace:"Pin",unpinWorkspace:"Unpin",renameWorkspace:"Rename Workspace",workspaceNamePlaceholder:"Workspace display name",pinned:"Pinned",recent:"Recent",searchWorkspaces:"Search workspaces",welcomeTitle:"Welcome",welcomeSubtitle:"Open a folder to start working",welcomeOpenFolder:"Open Folder",welcomeRecent:"Recent",toggleSidebar:"Toggle Sidebar",togglePanel:"Toggle Panel",togglePanelBottom:"Toggle Bottom Panel",toggleWordWrap:"Toggle Word Wrap",zoomIn:"Zoom In",zoomOut:"Zoom Out",resetZoom:"Reset Zoom",formatDocument:"Format Document",findInFile:"Find",replaceInFile:"Replace",goToLine:"Go to Line",goToFile:"Go to File",revealInOS:"Reveal in Finder/Explorer",openInTerminal:"Open in Terminal",copyPath:"Copy Path",copyRelativePath:"Copy Relative Path",duplicate:"Duplicate",cut:"Cut",paste:"Paste",autoSave:"Auto Save",autoSaveOff:"Off",autoSaveAfterDelay:"After Delay",autoSaveOnFocusChange:"On Focus Change",fontSize:"Font Size",wordWrap:"Word Wrap",language:"Language",encoding:"Encoding",spaces:"Spaces",branch:"Branch",noBranch:"No branch",commitMessage:"Commit Message",commitMessagePlaceholder:"Message (Cmd+Enter to commit)",stage:"Stage",stageAll:"Stage All",unstage:"Unstage",push:"Push",pull:"Pull",sync:"Sync",staged:"Staged Changes",changes:"Changes",untracked:"Untracked",bottomPanelTerminal:"Terminal",bottomPanelOutput:"Output",bottomPanelProblems:"Problems",expandAll:"Expand All",recentFiles:"Recent Files",closedTabReopen:"Reopen Closed Tab",unsavedDot:"●",loadingTree:"Loading...",fileWatcherActive:"Watching for changes"},mobile:{title:"Android Device",refreshDevices:"Refresh devices",pickDevice:"Pick a device to mirror",noDevices:"No Android device found. Start an emulator or attach a device with USB debugging on.",starting:"Starting stream…",stoppingDevice:"Stopping…",streamEnded:"Stream ended",streamFailed:"Stream failed",streamGone:"Device is no longer connected",retry:"Retry",unsupportedBrowser:"This browser cannot decode the video stream. Use Chrome, Edge, or Safari 16.4+.",back:"Back",home:"Home",recents:"Recents",power:"Lock screen",shutdownDevice:"Shut down the emulator",shutdownTitle:"Shut down emulator?",shutdownMessage:"{name} will stop, losing anything running on it. Starting it again takes around 20 seconds.",shutdownConfirm:"Shut down",androidDevice:"Remote Android",androidDeviceHint:"Mirror and control an Android emulator or device.",deviceRunning:"Remote Android — {count} running",rotate:"Rotate",stopped:"Stopped",startDevice:"Start device",stopDevice:"Stop device",switchDevice:"Switch device",lowPower:"Low power mode",lowPowerHint:"No emulator window — much less CPU, fewer frames",noDevicesWithSdk:"No device running. Start an emulator below, or attach a phone with USB debugging on.",phaseLaunching:"Starting emulator…",phaseBooting:"Booting Android…",phaseReady:"Almost ready…",backToScreen:"Back to the device screen",tabApps:"Apps",tabLogs:"Logs",dropApk:"Install an APK",dropApkHint:"Drop a file here, or tap to choose",installing:"Installing…",installedApps:"Installed apps",noApps:"No user apps installed",launch:"Launch",forceStop:"Force stop",clearData:"Clear data",uninstall:"Uninstall",deepLinkPlaceholder:"myapp://path or https://…",filterByApp:"Filter by app",allApps:"All apps",minLevel:"Level",clearLog:"Clear log",pauseLog:"Pause",resumeLog:"Resume",logPaused:"Paused — new lines are not shown",noLogs:"Waiting for log output…",hideNoise:"Hide driver noise",showNoise:"Show driver noise (hidden by default)",modeFloat:"Unpin (float over the page)",modePin:"Pin to the right",resize:"Resize",setupTitle:"Android tooling",setupInstall:"Install",setupExtracting:"Extracting…",setupInstallTo:"Installs to",setupLowDisk:"Not enough disk space at the install location",setupRequires:"Needs {deps} first",setupDepsCmdline:"command line tools",setupDepsJdk:"Java 17",setupDepsEmulator:"emulator",setupBannerHint:"Some Android tools are missing — tap to install",addDevice:"Add device",noDevicesHint:"No device yet — tap + to create one, or plug in a phone with USB debugging on.",presetReady:"Ready — nothing to download",presetDownload:"Android 16 \xb7 ~1.5 GB download","provisionStep_platform-tools":"Downloading adb…",provisionStep_jdk:"Downloading Java…","provisionStep_cmdline-tools":"Downloading SDK tools…",provisionStep_emulator:"Downloading the emulator…",provisionStep_image:"Downloading Android…",provisionStep_create:"Creating the device…",imagesTitle:"System images",imagesSearch:"Search system images…",imagesNone:"No system images match",imageInstall:"Install image",imageRemove:"Remove image",imageRemoveTitle:"Remove system image?",imageRemoveMessage:"{path} will be deleted from the host. AVDs using it will no longer start.",avdCreateTitle:"Create Virtual Device",avdStep1:"Hardware",avdStep2:"System Image",avdStep3:"Name",avdNoProfiles:"No device profiles available",avdNamePlaceholder:"AVD name",avdInstalledBelow:"Installed images are marked",avdMenu:"AVD options",avdWipe:"Wipe data",avdWipeTitle:"Wipe AVD data?",avdWipeMessage:"{name} will lose all apps, accounts and files — back to a fresh device.",avdDelete:"Delete",avdDeleteTitle:"Delete AVD?",avdDeleteMessage:"{name} and its storage on the host will be removed permanently."},remote:{title:"Remote Desktop",connecting:"Connecting...",disconnected:"Disconnected",fullscreen:"Fullscreen",exitFullscreen:"Exit Fullscreen",receivingImage:"Receiving screen…",keyboard:"Keyboard",mouse:"Mouse",fps:"FPS",debug:"Debug",help:"Help",close:"Close",sendKey:"Send Key",helpTitle:"Remote Desktop Help",notAvailable:"Remote desktop is not available",customizeKeys:"Customize keys",back:"Back",resetZoom:"Reset zoom",refresh:"Refresh",rectangleSelection:"Rectangle selection",handMode:"Hand mode",toggleKeyboard:"Toggle native keyboard",hideControls:"Hide controls",showControls:"Show controls",textBatchInput:"Text batch input",extraKeys:"Extra keys",customizeRemoteKeys:"Customize Remote Keys",exitRemote:"Exit remote desktop",debugTitle:"Debug Stats",minimize:"Minimize",transport:"Transport",latency:"Latency",tilesPerSec:"Tiles/sec",bandwidth:"Bandwidth",clearStats:"Clear Stats",lockTitle:"Windows is locked",lockGrantDesc:'Turn on "Unlock PC remotely" in 9remote host on this PC.',lockDesc:"Enter the Windows PIN or password for this computer",lockPlaceholder:"Windows PIN or password",unlock:"Unlock",unlocking:"Unlocking…",unlockFailed:"Unlock failed — check your PIN/password and try again."},remoteHelp:{modePc:"PC / Mouse",modeTrackpad:"Touch \xb7 Trackpad",modeDirect:"Touch \xb7 Direct",mouseTitle:"Mouse",keyboardTitle:"Keyboard",gesturesTrackpadTitle:"Gestures (Trackpad ✋)",gesturesDirectTitle:"Gestures (Direct)",toolbarTitle:"Toolbar",mouseClickKey:"Click / Drag",mouseClickDesc:"Left-click, drag to select/move",mouseRightKey:"Right-click",mouseRightDesc:"Context menu on remote",mouseWheelKey:"Wheel",mouseWheelDesc:"Scroll remote (Shift + Wheel = horizontal)",mouseDoubleKey:"Double-click",mouseDoubleDesc:"Double-click on remote",keyPhysicalKey:"Physical keys",keyPhysicalDesc:"Sent directly (Tab, F-keys, etc. captured)",keyModifierKey:"Ctrl / Alt / Shift / ⌘",keyModifierDesc:"Sticky modifier — combine with next key",trackpadSwipeKey:"1 finger swipe",trackpadSwipeDesc:"Move virtual cursor",trackpadTapKey:"1 finger tap",trackpadTapDesc:"Left-click at cursor",trackpad2TapKey:"2 fingers tap",trackpad2TapDesc:"Right-click at cursor",trackpad2SwipeKey:"2 fingers swipe",trackpad2SwipeDesc:"Scroll at cursor position",trackpadPinchKey:"2 fingers pinch",trackpadPinchDesc:"Zoom canvas",trackpadScrollLockKey:"Hold + drag",trackpadScrollLockDesc:"Hold to lock scroll, drag any direction",directTapKey:"1 finger tap",directTapDesc:"Click at tap position",directLongKey:"1 finger long-press",directLongDesc:"Right-click",directDoubleKey:"1 finger double-tap",directDoubleDesc:"Double-click",directScrollKey:"2 fingers swipe",directScrollDesc:"Scroll remote",directPinchKey:"2 fingers pinch",directPinchDesc:"Zoom canvas",directPanKey:"1 finger drag (zoom>1)",directPanDesc:"Pan canvas",toolbarHandDesc:"Hold left-click (drag mode) — tap again to release",toolbarMouseDirectDesc:"Switch to Direct mode",toolbarMouseTrackpadDesc:"Switch to Trackpad (virtual cursor)",toolbarKeyboardDesc:"Native keyboard / text batch input",toolbarRectDesc:"Rectangle selection mode"},remoteControls:{enterToSend:"Tab or Ctrl+Num to switch tab",typeToSend:"Type text to send...",send:"Send",trackpadMode:"Trackpad mode",directMode:"Direct mode",bottomRow:"Bottom Row",extraPanel:"Extra Panel",exitConfirmMessage:"Are you sure you want to exit the current remote desktop session?"},connection:{retrying:"Reconnecting...",waitingApproval:"Waiting for Approval",approvalDescription:"The 9Remote host needs to approve this device before you can connect.",approvalHint:"Check the terminal on your machine.",rejectedTitle:"Device Rejected",rejectedDescription:"This device was not approved by the 9Remote host.",backToLogin:"Back to Login",failed:"Connection Failed",failedDescription:"Unable to connect after {n} attempts",attemptOf:"Attempt {n} of {total}",pairTab:"Paired Device",pairScanToSignIn:"Scan to sign in",pairOneTimeKey:"One-Time Key",pairPermanentKey:"Permanent Key",pairKeyNotSet:"— not set —",pairExpired:"Expired",pairUnavailable:"Device pairing is only available in the host's local view.",pairGenOneTimeTitle:"New one-time key?",pairGenOneTimeMsg:"Generate a new one-time key? The current one will expire immediately.",pairRegenTitle:"Regenerate permanent key?",pairRegenMsg:"Regenerate permanent key? All existing sessions will be disconnected.",exit:"Exit",cancel:"Cancel",retry:"Retry now"},notifications:{claudeCode:"Claude Code",codex:"Codex",geminiCli:"Gemini CLI",openCode:"OpenCode",title:"Notifications",empty:"No notifications",needsInput:"needs input",badgeTitle:"{blocked} needs input, {done} your turn",replied:"replied",agent:"Agent"},sites:{title:"Sites",localSites:"Local Sites",selectSitePreview:"Select a site to preview",browserNewTab:"New tab",browserAddressPlaceholder:"localhost:3000 or /path",browserNotConnected:"Connect to your host first",portPlaceholder:"port",loadingSites:"Loading Sites...",notConnected:"Not connected to the host",noSitesFound:"No sites found",startServerHint:"Start a local dev server to see it here",siteNamePlaceholder:"Site name",saveTitle:"Save",editNameTitle:"Edit name",removeTitle:"Remove",removePortTitle:"Remove Port",removePortMessage:"Remove port {port} from saved list?",popupBlocked:"Popup blocked! Please allow popups for this site.",startProxyFailed:"Failed to start proxy session for {name}",foundCount:"{n} site{suffix} found",focusOpenedTab:"Focus opened tab",openInNewTab:"Open in new tab",goBack:"Go back",goForward:"Go forward",loadingSite:"Loading...",empty:"No active sites",emptyHint:"Run a local server to see it here",open:"Open",refresh:"Refresh",newTabTitle:"Open local site",errorSwBlocked:"This browser blocked the service worker the site view needs",errorNoBridge:"Connect to your host first",errorNoSession:"Port {port} is no longer open — reopen the site",errorTimeout:"The site did not answer in time",errorNoReply:"No reply from the host",errorGeneric:"The site could not be loaded",browserTab:"Browser",browserPaneNotConnected:"Connect to your host first",browserPaneLocalSites:"Local sites",browserPaneIntroTitle:"Remote browser",browserPaneIntroDesc:"A real Chrome running on your host, streamed to this screen.",browserPaneTipPick:"Open a page, tap Pick, then tap or drag over elements to select them and send to your AI to fix.",browserPaneSearchOrUrl:"Search or type URL",browserPaneLoading:"Connecting to the browser…",browserPaneNoTabs:"No browser tabs open",browserPaneNewTabHint:"Type a URL to open a tab on the host browser",browserPaneReconnect:"Reconnect",browserPaneCopyUrl:"Copy page URL",browserPaneSendText:"Send text",browserPaneLoadError:"Can't reach this page",browserPaneRetry:"Retry",browserPaneCopyAddress:"Copy address",browserCtxCopyLink:"Copy link address",browserCtxCopyUrl:"Copy page URL",browserCtxInspect:"Inspect element",browserCtxHardReload:"Hard reload (ignore cache)",browserCtxImportCookies:"Import cookies",browserPaneSearchFor:"Search",browserCtxOpenNewTab:"Open link in new tab",browserPanePick:"Pick",browserPanePickTitle:"Pick page elements",browserPaneDevice:"Device",browserPaneDeviceTitle:"Device size"},commandNotes:{title:"Command Notes",noSavedCommands:"No saved commands",addFirstBelow:"Add your first command below",clickToCopy:"Click to copy",copiedBang:"Copied!",copy:"Copy",edit:"Edit",delete:"Delete",editCommandPlaceholder:"Edit command...",addCommandPlaceholder:"Add command...",update:"Update",add:"Add",empty:"No notes yet",emptyHint:"Save commands for quick access",add:"Add Note",edit:"Edit Note",delete:"Delete Note",deleteMessage:"Delete this note?",name:"Name",command:"Command",save:"Save",placeholderName:"e.g. Start dev server",placeholderCommand:"e.g. npm run dev"},mobileKeyboard:{pasteHere:"Paste here (Cmd+V)",enterToSend:"{shortcut} to switch tab",typeCommand:"Type command and send...",send:"Send",toggleExtraKeys:"Toggle extra keys",toggleTextInput:"Toggle text input",customizeTerminalKeys:"Customize Terminal Keys",mainBar:"Main Bar",extraPanel:"Extra Panel",fileTooLarge:"File too large (max 5MB)",readFileFailed:"Failed to read file",uploadFailed:"Failed to upload file: {error}"},terminalPane:{scrollToBottom:"Scroll to bottom",refresh:"Refresh terminal",openFolder:"Open folder",openFolderHere:"Open files here",changedFiles:"Changed files",pasteOrType:"Paste or type here",paste:"Paste",note:"Checklist",addToNote:"Add to checklist"},note:{title:"Checklist",placeholder:"No tasks yet",copy:"Copy",clear:"Clear",saved:"Saved",addSuccess:"Added to checklist",copyTodo:"Copy to-do items",multilinePlaceholder:"One task per line…",addLines:"Add each line as an item",copyItem:"Copy — taps stack rows in list order",edit:"Edit",drag:"Drag to reorder",pin:"Pin above the terminal",unpin:"Unpin",expand:"Open the full checklist",allDone:"All done",clearDone:"Clear done",sendHint:"Send to terminal with checklist",addChip:"Add chip",removeChip:"Remove chip",chipPlaceholder:"Chip text…"},pwaGuide:{copyYourKey:"Copy Your Key",copyKeyHint:"Tap the key below to copy — you'll need it to login after installing",tapToCopyApiKey:"Tap to copy API key",copiedBang:"Copied!",copy:"Copy",tapShareButton:"Tap Share Button",tapShareHint:"Tap the share button at the bottom of Safari",addToHome:"Add to Home Screen",addToHomeHint:'Scroll down and tap "Add to Home Screen"',openAppPasteKey:"Open App & Paste Key",openAppPasteKeyHint:"Open the installed app and paste your key to login",openMenu:"Open Menu",openMenuHint:"Tap the menu button (three dots) in Chrome",installApp:"Install App",installAppHint:'Tap "Install app" or "Add to Home screen"',lookInstallIcon:"Look for Install Icon",lookInstallIconHint:"Look for the install icon in the address bar",clickInstallPaste:"Click Install & Paste Key",installNow:"Install Now",installNowHint:"Install 9Remote as an app for quick access",installing:"Installing...",clickInstallPasteHint:"Click install, open the app, and paste your key to login",alternativeHint:'Alternative: Open browser menu → "Install 9Remote" or "Create shortcut"',loadingPlatform:"Loading platform detection...",iosPlatform:"iOS (iPhone/iPad)",androidPlatform:"Android",macosPlatform:"macOS",windowsPlatform:"Windows",desktopPlatform:"Desktop",alreadyInstalled:"Already Installed!",alreadyInstalledHint:"You're already using 9Remote as an installed app",installationGuide:"Installation Guide",installationSteps:"Installation Steps:"},community:{title:"Community",description:"Join the 9Remote community"},pwa:{title:"Install as App",description:"Install 9Remote on your device for the best experience",iosTitle:"iOS Safari",androidTitle:"Android Chrome",desktopTitle:"Desktop"},codespace:{title:"Codespace",name:"Name",status:"Status",running:"Running",autoStart:"Auto Start 9Remote",autoStartHint:"Start 9Remote when codespace opens",stop:"Stop Codespace",stopHint:"Stop to save usage",restartHint:"To restart, go to GitHub",unknown:"Unknown"},history:{title:"Command history",empty:"No commands yet",clearAll:"Clear all",snippets:"Snippets",history:"History",pin:"Pin as snippet",unpin:"Unpin",editSnippet:"Edit snippet",aliasLabel:"Alias",aliasHint:"Type this shortcut then send to run the command",commandLabel:"Command",aliasPlaceholder:"e.g. nrd"},voice:{dictate:"Voice input",language:"Voice language",clear:"Clear",denied:"Microphone blocked — allow mic access in your browser settings",network:"Voice endpoint unreachable — check Voice settings",micTimeout:"Mic did not respond — try again"},shortcuts:{title:"Keyboard shortcuts",menuLabel:"Keyboard shortcuts",switchTerminal:"Switch terminal",switchWorkspace:"Switch workspace",terminalActions:"New / Close terminal",togglePanels:"Toggle side panels",palette:"Search files",help:"Keyboard shortcuts",sessionPrev:"Previous terminal",sessionNext:"Next terminal",workspacePrev:"Previous workspace",workspaceNext:"Next workspace",sessionIndex:"Go to terminal 1-9",closeTerminal:"Close terminal",fitPanes:"Auto-fit panes",toggleFocus:"Toggle terminal / input focus",newTerminal:"New terminal",toggleSidebar:"Toggle sidebar",toggleRightPanel:"Toggle side panel"},appUpdate:{title:"Update required",body:"This version of the app is too old to connect. Update it from the store to continue.",action:"Update app"}}},33879:(e,t,o)=>{"use strict";o.d(t,{Xn:()=>n,dI:()=>a,zl:()=>s});let a=[{code:"en",label:"English",flag:"\uD83C\uDDFA\uD83C\uDDF8",country:"us"},{code:"vi",label:"Tiếng Việt",flag:"\uD83C\uDDFB\uD83C\uDDF3",country:"vn"},{code:"zh",label:"中文",flag:"\uD83C\uDDE8\uD83C\uDDF3",country:"cn"},{code:"es",label:"Espa\xf1ol",flag:"\uD83C\uDDEA\uD83C\uDDF8",country:"es"},{code:"hi",label:"हिन्दी",flag:"\uD83C\uDDEE\uD83C\uDDF3",country:"in"},{code:"ar",label:"العربية",flag:"\uD83C\uDDF8\uD83C\uDDE6",country:"sa"},{code:"pt",label:"Portugu\xeas",flag:"\uD83C\uDDE7\uD83C\uDDF7",country:"br"},{code:"ru",label:"Русский",flag:"\uD83C\uDDF7\uD83C\uDDFA",country:"ru"},{code:"ja",label:"日本語",flag:"\uD83C\uDDEF\uD83C\uDDF5",country:"jp"},{code:"de",label:"Deutsch",flag:"\uD83C\uDDE9\uD83C\uDDEA",country:"de"},{code:"fr",label:"Fran\xe7ais",flag:"\uD83C\uDDEB\uD83C\uDDF7",country:"fr"},{code:"ko",label:"한국어",flag:"\uD83C\uDDF0\uD83C\uDDF7",country:"kr"},{code:"it",label:"Italiano",flag:"\uD83C\uDDEE\uD83C\uDDF9",country:"it"},{code:"tr",label:"T\xfcrk\xe7e",flag:"\uD83C\uDDF9\uD83C\uDDF7",country:"tr"},{code:"id",label:"Bahasa Indonesia",flag:"\uD83C\uDDEE\uD83C\uDDE9",country:"id"},{code:"th",label:"ไทย",flag:"\uD83C\uDDF9\uD83C\uDDED",country:"th"},{code:"pl",label:"Polski",flag:"\uD83C\uDDF5\uD83C\uDDF1",country:"pl"},{code:"nl",label:"Nederlands",flag:"\uD83C\uDDF3\uD83C\uDDF1",country:"nl"},{code:"uk",label:"Українська",flag:"\uD83C\uDDFA\uD83C\uDDE6",country:"ua"},{code:"fa",label:"فارسی",flag:"\uD83C\uDDEE\uD83C\uDDF7",country:"ir"},{code:"ms",label:"Bahasa Melayu",flag:"\uD83C\uDDF2\uD83C\uDDFE",country:"my"},{code:"sv",label:"Svenska",flag:"\uD83C\uDDF8\uD83C\uDDEA",country:"se"},{code:"el",label:"Ελληνικά",flag:"\uD83C\uDDEC\uD83C\uDDF7",country:"gr"},{code:"he",label:"עברית",flag:"\uD83C\uDDEE\uD83C\uDDF1",country:"il"}],n="en",s="9remote_locale"},49262:(e,t,o)=>{var a={"./ar.js":[15714,5714],"./de.js":[67646,7646],"./en.js":[24890],"./es.js":[37369,7369],"./fa.js":[80236,236],"./fr.js":[76485,6485],"./he.js":[20482,482],"./hi.js":[52934,2934],"./id.js":[52488,2488],"./it.js":[23704,3704],"./ja.js":[99736,9736],"./ko.js":[87207,7207],"./ms.js":[4929,4929],"./nl.js":[72427,2427],"./pl.js":[95757,5757],"./pt.js":[2581,2581],"./ru.js":[37812,7812],"./sv.js":[3428,3428],"./th.js":[10101,101],"./tr.js":[41879,1879],"./uk.js":[74129,4129],"./vi.js":[84964,4964],"./zh.js":[43443,3443]};function n(e){if(!o.o(a,e))return Promise.resolve().then(()=>{var t=Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t});var t=a[e],n=t[0];return Promise.all(t.slice(1).map(o.e)).then(()=>o(n))}n.keys=()=>Object.keys(a),n.id=49262,e.exports=n}}]);
@@ -1 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1447,1984,4896,5348,5711,6364,6399,6819,6913,6988,7427,7711,7851,8167,8655,8983],{51680:()=>{}},_=>{_.O(0,[587,1968,7358],()=>_(_.s=51680)),_N_E=_.O()}]);
@@ -1 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[9492],{35230:(e,t,l)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"HTTPAccessErrorFallback",{enumerable:!0,get:function(){return o}});let r=l(54568),n=l(46961);function o({status:e,message:t}){return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("title",{children:`${e}: ${t}`}),(0,r.jsx)("div",{style:n.styles.error,children:(0,r.jsxs)("div",{children:[(0,r.jsx)("style",{dangerouslySetInnerHTML:{__html:"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}),(0,r.jsx)("h1",{className:"next-error-h1",style:n.styles.h1,children:e}),(0,r.jsx)("div",{style:n.styles.desc,children:(0,r.jsx)("h2",{style:n.styles.h2,children:t})})]})})]})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},43136:(e,t,l)=>{(window.__NEXT_P=window.__NEXT_P||[]).push(["/_not-found/page",function(){return l(63496)}])},46961:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"styles",{enumerable:!0,get:function(){return l}});let l={error:{fontFamily:'system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"',height:"100vh",textAlign:"center",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},desc:{display:"inline-block"},h1:{display:"inline-block",margin:"0 20px 0 0",padding:"0 23px 0 0",fontSize:24,fontWeight:500,verticalAlign:"top",lineHeight:"49px"},h2:{fontSize:14,fontWeight:400,lineHeight:"49px",margin:0}};("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},63496:(e,t,l)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return o}});let r=l(54568),n=l(35230),o=function(){return(0,r.jsx)("html",{children:(0,r.jsx)("body",{children:(0,r.jsx)(n.HTTPAccessErrorFallback,{status:404,message:"This page could not be found."})})})};("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)}},e=>{e.O(0,[587,1968,7358],()=>e(e.s=43136)),_N_E=e.O()}]);
@@ -1,5 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1125],{4655:(e,s,t)=>{"use strict";t.d(s,{b:()=>l});var a=t(7620),r=t(79748),n=t(78864),i=t(68795);function l({redirectIfUnauthed:e=!0}={}){let s=(0,r.useRouter)(),{get:t,post:d}=(0,i.Z)(),[c,o]=(0,a.useState)(null),[x,m]=(0,a.useState)(!0),u=(0,a.useCallback)(async()=>{try{let e=await t(n.lb.me);o(e)}catch{o(null),e&&s.replace("/admin/login")}finally{m(!1)}},[t,e,s]);(0,a.useEffect)(()=>{u()},[u]);let p=(0,a.useCallback)(async()=>{await d(n.lb.logout,{}),s.replace("/admin/login")},[d,s]),b=(0,a.useCallback)(e=>Array.isArray(c?.permissions)&&c.permissions.includes(e),[c]);return{me:c,loading:x,logout:p,can:b,refresh:u}}},14337:(e,s,t)=>{"use strict";t.d(s,{A:()=>r});var a=t(54568);function r({size:e="md",text:s,className:t=""}){return(0,a.jsxs)("div",{className:`flex flex-col items-center justify-center gap-3 ${t}`,children:[(0,a.jsx)("div",{className:`animate-spin rounded-full border-brand-500 border-t-transparent ${{sm:"h-4 w-4 border-2",md:"h-8 w-8 border-2",lg:"h-12 w-12 border-b-2"}[e]}`}),s&&(0,a.jsx)("p",{className:"text-brand-500 text-sm font-medium",children:s})]})}},26784:(e,s,t)=>{"use strict";t.d(s,{A:()=>r});var a=t(54568);function r({label:e,type:s="text",value:t,onChange:n,onKeyDown:i,placeholder:l,disabled:d=!1,error:c,className:o="",...x}){let m=c?"ring-1 ring-red-500 focus:ring-2 focus:ring-red-500":"focus:ring-2 focus:ring-brand-500/40",u=`w-full px-4 py-3 bg-surface-2 rounded-brand text-text placeholder-text-muted focus:outline-none transition-all duration-150 ease-out ${m} ${d?"opacity-50 cursor-not-allowed":""} ${o}`;return(0,a.jsxs)("div",{className:"w-full",children:[e&&(0,a.jsx)("label",{className:"block text-sm font-medium text-text mb-2",children:e}),(0,a.jsx)("input",{type:s,value:t,onChange:n,onKeyDown:i,placeholder:l,disabled:d,className:u,...x}),c&&(0,a.jsx)("p",{className:"mt-1 text-sm text-red-400",children:c})]})}},45256:(e,s,t)=>{"use strict";t.d(s,{A:()=>b});var a=t(54568),r=t(14916),n=t(7620),i=t(65587),l=t(79748),d=t(14337),c=t(51467),o=t(46891),x=t(39634),m=t(96605),u=t(4655);let p=[{href:"/admin",label:"Dashboard",icon:m.Hx,exact:!0},{href:"/admin/access",label:"Access",icon:m.zW},{href:"/admin/ota",label:"OTA Updates",icon:m.lP,needsOta:!0},{href:"/admin/turn",label:"TURN Keys",icon:m.kV}];function b({children:e}){let s=(0,l.usePathname)(),{me:t,loading:h,logout:g}=(0,u.b)(),[f,j]=(0,n.useState)(!1);if(h||!t)return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(x.A,{}),(0,a.jsx)(c.A,{children:(0,a.jsx)("div",{className:"card-glass p-8 max-w-sm w-full flex flex-col items-center justify-center",children:(0,a.jsx)(d.A,{size:"lg",text:"Loading admin..."})})})]});let N=(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"p-4 border-b border-border-subtle flex items-center justify-between gap-3",children:[(0,a.jsxs)("div",{className:"flex items-center gap-2.5 min-w-0",children:[(0,a.jsx)("div",{className:"w-6 h-6 shrink-0 rounded-md flex items-center justify-center font-bold text-sm bg-brand-500 text-white",children:"9"}),(0,a.jsxs)("div",{className:"min-w-0",children:[(0,a.jsx)("h1",{className:"text-sm font-bold tracking-tight text-text truncate",children:"9Remote Admin"}),(0,a.jsxs)("div",{className:"flex items-center gap-1.5 mt-0.5",children:[(0,a.jsx)("span",{className:"text-xs text-text-muted truncate",children:t.username}),(0,a.jsx)("span",{className:"text-[10px] font-mono px-1.5 py-0.5 rounded-full bg-surface-2 text-text-muted border border-border-subtle",children:t.modeName||t.modeId})]})]})]}),(0,a.jsx)("button",{onClick:()=>j(!1),className:"md:hidden p-1.5 -mr-1.5 text-text-muted hover:text-text rounded-[6px] hover:bg-surface-2 transition-colors","aria-label":"Close menu",children:(0,a.jsx)(m.X,{size:18})})]}),(0,a.jsxs)("nav",{className:"flex-1 px-3.5 py-3 space-y-0.5 overflow-y-auto",children:[(0,a.jsx)("div",{className:"pl-[3.5px] py-1.5 text-[10px] font-mono uppercase tracking-wider text-text-subtle",children:"Navigation"}),p.filter(e=>!e.needsOta||t.otaEnabled).map(e=>{let t=e.icon,r=e.exact?s===e.href:s.startsWith(e.href);return(0,a.jsxs)(i,{href:e.href,onClick:()=>j(!1),className:`
2
- flex items-center gap-2.5 -ml-3.5 w-[calc(100%+0.875rem)] pl-[17px] pr-3 py-1.5
3
- rounded-[6px] text-xs font-medium text-left transition-colors duration-150
4
- ${r?"bg-surface-3 text-text font-semibold":"text-text-muted hover:bg-surface-2 hover:text-text"}
5
- `,children:[(0,a.jsx)(t,{size:15,className:r?"text-text":"text-text-subtle"}),(0,a.jsx)("span",{className:"flex-1",children:e.label}),r&&(0,a.jsx)("span",{className:"w-1 h-1 rounded-full bg-text-muted"})]},e.href)})]}),(0,a.jsx)("div",{className:"p-3.5 border-t border-border-subtle",children:(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)(o.A,{className:"border border-border-subtle hover:bg-surface-2 rounded-[6px]"}),(0,a.jsxs)("button",{onClick:g,className:"flex-1 flex items-center justify-center gap-2 px-3 py-1.5 rounded-[6px] text-xs font-medium text-text-muted hover:bg-red-500/10 hover:text-danger transition-colors",children:[(0,a.jsx)(m.nU,{size:15}),"Logout"]})]})})]});return(0,a.jsxs)("div",{className:"jsx-b56c084163c9c8c1 min-h-screen text-text relative selection:bg-brand-500/20",children:[(0,a.jsx)(x.A,{}),(0,a.jsxs)("header",{className:"jsx-b56c084163c9c8c1 md:hidden sticky top-0 z-30 flex items-center justify-between px-4 py-2.5 bg-surface/80 backdrop-blur-md border-b border-border-subtle",children:[(0,a.jsx)("button",{onClick:()=>j(!0),"aria-label":"Open menu",className:"jsx-b56c084163c9c8c1 p-1.5 -ml-1.5 text-text-muted hover:text-text rounded-[6px] hover:bg-surface-2",children:(0,a.jsx)(m.W1,{size:20})}),(0,a.jsxs)("div",{className:"jsx-b56c084163c9c8c1 flex items-center gap-2",children:[(0,a.jsx)("div",{className:"jsx-b56c084163c9c8c1 w-6 h-6 rounded-md flex items-center justify-center font-bold text-xs bg-brand-500 text-white",children:"9"}),(0,a.jsx)("h1",{className:"jsx-b56c084163c9c8c1 text-sm font-semibold tracking-tight",children:"9Remote Admin"})]}),(0,a.jsx)(o.A,{className:"rounded-[6px]"})]}),(0,a.jsx)("aside",{className:"jsx-b56c084163c9c8c1 hidden md:flex fixed inset-y-0 left-0 w-60 border-r border-border-subtle bg-surface/80 backdrop-blur-xl flex-col z-20",children:N}),f&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("div",{onClick:()=>j(!1),className:"jsx-b56c084163c9c8c1 md:hidden fixed inset-0 z-40 bg-black/60 backdrop-blur-[2px] fade-in"}),(0,a.jsx)("aside",{style:{animation:"slideInFromLeft 0.22s cubic-bezier(0.22, 1, 0.36, 1) forwards"},className:"jsx-b56c084163c9c8c1 md:hidden fixed inset-y-0 left-0 z-50 w-72 max-w-[85%] bg-surface/95 backdrop-blur-2xl border-r border-border-subtle flex flex-col slide-in-right",children:N})]}),(0,a.jsx)("main",{className:"jsx-b56c084163c9c8c1 md:ml-60 p-4 sm:p-6 lg:p-8 min-h-screen relative z-10 max-w-7xl",children:e}),(0,a.jsx)(r,{id:"b56c084163c9c8c1",children:"@keyframes slideInFromLeft{from{transform:translatex(-100%);opacity:0}to{transform:translatex(0);opacity:1}}"})]})}},51345:(e,s,t)=>{"use strict";t.r(s),t.d(s,{default:()=>g});var a=t(54568),r=t(7620),n=t(45256),i=t(56156),l=t(26784),d=t(96605);let c={ok:"Success",badPassword:"Wrong password",unknownUser:"Unknown user",turnstile:"Captcha failed",locked:"Locked out"};function o({items:e}){return(0,a.jsxs)("section",{className:"space-y-4",children:[(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)(d.ek,{size:16,className:"text-brand-500"}),(0,a.jsx)("h2",{className:"text-base font-semibold tracking-tight text-text",children:"Login Activity"}),(0,a.jsxs)("span",{className:"text-xs text-text-subtle font-mono",children:["last ",e.length]})]}),(0,a.jsx)("div",{className:"card-glass overflow-hidden",children:(0,a.jsx)("div",{className:"max-h-64 overflow-y-auto",children:(0,a.jsxs)("table",{className:"w-full text-sm text-left",children:[(0,a.jsx)("thead",{className:"bg-surface-2/60 border-b border-border-subtle text-[11px] font-mono uppercase tracking-wider text-text-muted",children:(0,a.jsxs)("tr",{children:[(0,a.jsx)("th",{className:"px-4 py-2.5",children:"Time"}),(0,a.jsx)("th",{className:"px-4 py-2.5",children:"User"}),(0,a.jsx)("th",{className:"px-4 py-2.5",children:"IP"}),(0,a.jsx)("th",{className:"px-4 py-2.5 text-right",children:"Result"})]})}),(0,a.jsxs)("tbody",{className:"divide-y divide-border-subtle/50",children:[0===e.length&&(0,a.jsx)("tr",{children:(0,a.jsx)("td",{colSpan:4,className:"px-4 py-8 text-center text-text-muted",children:"No login attempts recorded yet"})}),e.map((e,s)=>(0,a.jsxs)("tr",{className:"hover:bg-surface-2/40 transition-colors",children:[(0,a.jsx)("td",{className:"px-4 py-2.5 text-xs text-text-muted whitespace-nowrap",children:function(e){try{return new Date(e+"Z").toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return e}}(e.createdAt)}),(0,a.jsx)("td",{className:"px-4 py-2.5 font-mono text-xs text-text",children:e.username}),(0,a.jsx)("td",{className:"px-4 py-2.5 font-mono text-xs text-text-muted",children:e.ip}),(0,a.jsx)("td",{className:"px-4 py-2.5 text-right",children:e.ok?(0,a.jsxs)("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[11px] font-medium border bg-emerald-500/10 text-emerald-500 border-emerald-500/20",children:[(0,a.jsx)(d.ek,{size:11})," OK"]}):(0,a.jsxs)("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[11px] font-medium border bg-red-500/10 text-danger border-red-500/20",children:[(0,a.jsx)(d.RI,{size:11})," ",c[e.reason]||e.reason]})})]},s))]})]})})})]})}var x=t(68795),m=t(4655),u=t(78864);let p={username:"",password:"",modeId:""},b={id:"",name:"",permissions:[]};function h(e){if(!e)return"-";try{return new Date(e+"Z").toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return e}}function g(){let{me:e,can:s,loading:t}=(0,m.b)(),{get:c,post:g,patch:f,del:j}=(0,x.Z)(),[N,y]=(0,r.useState)([]),[v,w]=(0,r.useState)([]),[k,A]=(0,r.useState)([]),[C,S]=(0,r.useState)(p),[z,$]=(0,r.useState)(null),[I,M]=(0,r.useState)(b),[D,P]=(0,r.useState)(null),[L,O]=(0,r.useState)(""),R=s(u.Jj.adminManage),T=s(u.Jj.modeManage),V=s(u.Jj.logView),E=[{key:"admins",label:"Admins"},{key:"modes",label:"Modes & Permissions"},...V?[{key:"logins",label:"Login Activity"}]:[]],[U,F]=(0,r.useState)("admins"),W=(0,r.useCallback)(async()=>{let e=[c(u.lb.admins),c(u.lb.modes)];s(u.Jj.logView)&&e.push(c(u.lb.logins));let[t,a,r]=await Promise.all(e);y(t.items||[]),w(a.items||[]),r&&A(r.items||[]),S(e=>({...e,modeId:e.modeId||(a.items||[])[0]?.id||""}))},[s,c]);(0,r.useEffect)(()=>{!t&&e&&W()},[t,e,W]);let J=()=>{$(null),S({...p,modeId:v[0]?.id||""}),O("")},_=async()=>{O("");try{if(z)await f(`${u.lb.admins}/${z}`,{modeId:C.modeId,...C.password?{password:C.password}:{}});else{if(!C.username||!C.password||!C.modeId)return void O("All fields are required");await g(u.lb.admins,C)}J(),W()}catch(e){O(e.message)}},q=async e=>{if(confirm("Delete this admin account?"))try{await j(`${u.lb.admins}/${e}`),W()}catch(e){alert(e.message)}},Z=()=>{P(null),M(b),O("")},K=async()=>{O("");try{if(D)await f(`${u.lb.modes}/${D}`,{name:I.name,permissions:I.permissions});else{if(!I.id||!I.name)return void O("ID and name are required");await g(u.lb.modes,I)}Z(),W()}catch(e){O(e.message)}},X=async e=>{if(confirm(`Delete mode ${e}?`))try{await j(`${u.lb.modes}/${e}`),W()}catch(e){alert(e.message)}},B=(0,a.jsxs)("section",{className:"space-y-4",children:[R&&(0,a.jsxs)("div",{className:"card-glass p-5 sm:p-6 space-y-4",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between border-b border-border-subtle/60 pb-3",children:[(0,a.jsx)("h2",{className:"text-sm font-semibold tracking-tight text-text flex items-center gap-2",children:z?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("span",{className:"text-text-muted",children:"Edit admin:"}),(0,a.jsx)("span",{className:"font-mono text-brand-500 font-bold",children:C.username})]}):(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(d.FW,{size:16,className:"text-brand-500"}),(0,a.jsx)("span",{children:"Create Administrator Account"})]})}),z&&(0,a.jsxs)("button",{onClick:J,className:"text-xs text-text-muted hover:text-text flex items-center gap-1",children:[(0,a.jsx)(d.X,{size:14})," Cancel"]})]}),(0,a.jsxs)("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4",children:[(0,a.jsx)(l.A,{label:"Username",value:C.username,onChange:e=>S({...C,username:e.target.value}),disabled:!!z,placeholder:"operator username"}),(0,a.jsx)(l.A,{label:z?"New Password (optional)":"Password",type:"password",value:C.password,onChange:e=>S({...C,password:e.target.value}),placeholder:z?"Leave blank to keep":"••••••••"}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-xs font-mono uppercase tracking-wider text-text-muted mb-2",children:"Assigned Mode"}),(0,a.jsx)("select",{value:C.modeId,onChange:e=>S({...C,modeId:e.target.value}),className:"w-full px-3 py-2.5 bg-surface-2 border border-border-subtle rounded-xl text-text text-sm focus:outline-none focus:ring-2 focus:ring-brand-500/30 transition-all",children:v.map(e=>(0,a.jsxs)("option",{value:e.id,children:[e.name," (",e.id,")"]},e.id))})]})]}),L&&null!==z&&(0,a.jsx)("p",{className:"text-xs text-danger bg-red-500/10 p-2.5 rounded-lg border border-red-500/20",children:L}),(0,a.jsxs)("div",{className:"flex gap-2 pt-2",children:[(0,a.jsx)(i.A,{variant:"primary",onClick:_,className:"rounded-xl px-4 py-2",children:(0,a.jsxs)("span",{className:"inline-flex items-center gap-1.5 text-xs font-semibold",children:[(0,a.jsx)(d.eM,{size:14}),(0,a.jsx)("span",{children:z?"Update Account":"Create Administrator"})]})}),z&&(0,a.jsx)(i.A,{variant:"secondary",onClick:J,className:"rounded-xl px-4 py-2 text-xs",children:"Cancel"})]})]}),(0,a.jsx)("div",{className:"card-glass overflow-hidden",children:(0,a.jsxs)("table",{className:"w-full text-sm text-left",children:[(0,a.jsx)("thead",{className:"bg-surface-2/60 border-b border-border-subtle text-[11px] font-mono uppercase tracking-wider text-text-muted",children:(0,a.jsxs)("tr",{children:[(0,a.jsx)("th",{className:"px-4 py-3",children:"Username"}),(0,a.jsx)("th",{className:"px-4 py-3",children:"Security Role"}),(0,a.jsx)("th",{className:"px-4 py-3",children:"Created"}),(0,a.jsx)("th",{className:"px-4 py-3",children:"Last Login"}),R&&(0,a.jsx)("th",{className:"px-4 py-3 text-right",children:"Actions"})]})}),(0,a.jsx)("tbody",{className:"divide-y divide-border-subtle/50",children:N.map(s=>{let t=s.id===e?.id;return(0,a.jsxs)("tr",{className:"hover:bg-surface-2/40 transition-colors",children:[(0,a.jsx)("td",{className:"px-4 py-3.5 font-medium text-text",children:(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)("span",{className:"font-mono text-xs",children:s.username}),t&&(0,a.jsx)("span",{className:"text-[10px] font-mono px-1.5 py-0.5 rounded-full bg-brand-500/10 text-brand-500 border border-brand-500/25",children:"you"})]})}),(0,a.jsx)("td",{className:"px-4 py-3.5",children:(0,a.jsx)("span",{className:"px-2 py-0.5 rounded-full text-xs font-medium bg-surface-2 border border-border-subtle text-text",children:s.modeName||s.modeId})}),(0,a.jsx)("td",{className:"px-4 py-3.5 text-xs text-text-muted",children:h(s.createdAt)}),(0,a.jsx)("td",{className:"px-4 py-3.5 text-xs text-text font-medium",children:h(s.lastLoginAt)}),R&&(0,a.jsx)("td",{className:"px-4 py-3.5 text-right",children:(0,a.jsxs)("div",{className:"inline-flex items-center gap-2",children:[(0,a.jsx)("button",{onClick:()=>{$(s.id),S({username:s.username,password:"",modeId:s.modeId}),O("")},className:"text-xs text-brand-500 hover:text-brand-400 font-medium px-2 py-1 rounded hover:bg-brand-500/10 transition-colors",children:"Edit"}),!t&&(0,a.jsx)("button",{onClick:()=>q(s.id),className:"text-text-muted hover:text-danger p-1 rounded hover:bg-red-500/10 transition-colors",title:"Delete admin",children:(0,a.jsx)(d.TB,{size:15})})]})})]},s.id)})})]})})]}),H=(0,a.jsxs)("section",{className:"space-y-4",children:[T&&(0,a.jsxs)("div",{className:"card-glass p-5 sm:p-6 space-y-4",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between border-b border-border-subtle/60 pb-3",children:[(0,a.jsx)("h2",{className:"text-sm font-semibold tracking-tight text-text flex items-center gap-2",children:D?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("span",{className:"text-text-muted",children:"Edit role:"}),(0,a.jsx)("span",{className:"font-mono text-brand-500 font-bold",children:D})]}):(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(d.FW,{size:16,className:"text-brand-500"}),(0,a.jsx)("span",{children:"Create New Security Mode"})]})}),D&&(0,a.jsxs)("button",{onClick:Z,className:"text-xs text-text-muted hover:text-text flex items-center gap-1",children:[(0,a.jsx)(d.X,{size:14})," Cancel"]})]}),(0,a.jsxs)("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[(0,a.jsx)(l.A,{label:"Mode ID",value:I.id,onChange:e=>M({...I,id:e.target.value}),disabled:!!D,placeholder:"e.g. support-lead"}),(0,a.jsx)(l.A,{label:"Display Name",value:I.name,onChange:e=>M({...I,name:e.target.value}),placeholder:"e.g. Support Team Lead"})]}),(0,a.jsx)("div",{className:"space-y-3",children:u.vq.map(e=>(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"text-[10px] font-mono uppercase tracking-wider text-text-subtle mb-1.5",children:e.label}),(0,a.jsx)("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-2",children:e.keys.map(e=>{let s=I.permissions.includes(e);return(0,a.jsxs)("button",{type:"button",onClick:()=>{M(s=>({...s,permissions:s.permissions.includes(e)?s.permissions.filter(s=>s!==e):[...s.permissions,e]}))},title:e,className:`flex items-center justify-between px-3 py-2 rounded-[6px] text-xs border transition-colors text-left ${s?"bg-brand-500/12 text-brand-500 border-brand-500/30":"bg-surface-2/60 text-text-muted border-border-subtle hover:bg-surface-2 hover:text-text"}`,children:[(0,a.jsx)("span",{className:"truncate",children:u.WD[e]||e}),s?(0,a.jsx)(d.aJ,{size:13,className:"text-brand-500 shrink-0 ml-1.5"}):null]},e)})})]},e.label))}),L&&null===D&&(0,a.jsx)("p",{className:"text-xs text-danger bg-red-500/10 p-2.5 rounded-lg border border-red-500/20",children:L}),(0,a.jsxs)("div",{className:"flex gap-2 pt-2",children:[(0,a.jsx)(i.A,{variant:"primary",onClick:K,className:"rounded-xl px-4 py-2",children:(0,a.jsxs)("span",{className:"inline-flex items-center gap-1.5 text-xs font-semibold",children:[(0,a.jsx)(d.eM,{size:14}),(0,a.jsx)("span",{children:D?"Save Changes":"Create Mode"})]})}),D&&(0,a.jsx)(i.A,{variant:"secondary",onClick:Z,className:"rounded-xl px-4 py-2 text-xs",children:"Cancel"})]})]}),(0,a.jsx)("div",{className:"card-glass overflow-hidden",children:(0,a.jsxs)("table",{className:"w-full text-sm text-left",children:[(0,a.jsx)("thead",{className:"bg-surface-2/60 border-b border-border-subtle text-[11px] font-mono uppercase tracking-wider text-text-muted",children:(0,a.jsxs)("tr",{children:[(0,a.jsx)("th",{className:"px-4 py-3",children:"ID"}),(0,a.jsx)("th",{className:"px-4 py-3",children:"Role Name"}),(0,a.jsx)("th",{className:"px-4 py-3",children:"Assigned Permissions"}),T&&(0,a.jsx)("th",{className:"px-4 py-3 text-right",children:"Actions"})]})}),(0,a.jsx)("tbody",{className:"divide-y divide-border-subtle/50",children:v.map(e=>{let s=function(e){try{return"string"==typeof e.permissions?JSON.parse(e.permissions):e.permissions}catch{return[]}}(e);return(0,a.jsxs)("tr",{className:"hover:bg-surface-2/40 transition-colors",children:[(0,a.jsx)("td",{className:"px-4 py-3.5 font-mono text-xs font-semibold text-text",children:e.id}),(0,a.jsxs)("td",{className:"px-4 py-3.5 font-medium text-text",children:[e.name,(0,a.jsxs)("span",{className:"block text-[11px] text-text-muted font-normal",children:[s.length," permissions"]})]}),(0,a.jsx)("td",{className:"px-4 py-3.5",children:(0,a.jsx)("div",{className:"flex flex-wrap gap-1 max-w-md",children:s.map(e=>(0,a.jsx)("span",{title:e,className:"px-2 py-0.5 rounded-[4px] bg-surface-2 border border-border-subtle text-[11px] text-text-muted",children:u.WD[e]||e},e))})}),T&&(0,a.jsx)("td",{className:"px-4 py-3.5 text-right",children:(0,a.jsxs)("div",{className:"inline-flex items-center gap-2",children:[(0,a.jsx)("button",{onClick:()=>{P(e.id),M({id:e.id,name:e.name,permissions:s}),O("")},className:"text-xs text-brand-500 hover:text-brand-400 font-medium px-2 py-1 rounded hover:bg-brand-500/10 transition-colors",children:"Edit"}),(0,a.jsx)("button",{onClick:()=>X(e.id),className:"text-text-muted hover:text-danger p-1 rounded hover:bg-red-500/10 transition-colors",title:"Delete mode",children:(0,a.jsx)(d.TB,{size:15})})]})})]},e.id)})})]})})]});return(0,a.jsx)(n.A,{children:(0,a.jsxs)("div",{className:"space-y-6 max-w-5xl",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h1",{className:"text-xl font-bold tracking-tight text-text",children:"Access Control"}),(0,a.jsx)("p",{className:"text-xs text-text-muted mt-1",children:"Operator accounts, security roles and login audit"})]}),(0,a.jsx)("div",{className:"flex items-stretch border-b border-border-subtle overflow-x-auto scrollbar-none -mb-px",children:E.map(e=>(0,a.jsxs)("button",{onClick:()=>F(e.key),className:`term-tab flex items-center gap-1.5 px-3 py-2 text-xs font-medium whitespace-nowrap cursor-pointer ${U===e.key?"term-tab-active":""}`,children:[U===e.key&&(0,a.jsx)("span",{className:"w-1 h-1 rounded-full bg-text-muted"}),(0,a.jsx)("span",{children:e.label})]},e.key))}),"admins"===U&&B,"modes"===U&&H,"logins"===U&&V&&(0,a.jsx)(o,{items:k})]})})}},51467:(e,s,t)=>{"use strict";t.d(s,{A:()=>r});var a=t(54568);function r({children:e,centered:s=!0,className:t=""}){return(0,a.jsx)("div",{className:`min-h-screen ${s?"flex items-center justify-center p-4":""} ${t}`,children:e})}},56156:(e,s,t)=>{"use strict";t.d(s,{A:()=>r});var a=t(54568);function r({children:e,variant:s="primary",size:t="md",disabled:n=!1,loading:i=!1,onClick:l,className:d="",...c}){let o=`font-semibold rounded-brand transition-all duration-150 ease-out transform active:scale-[0.97] ${{primary:"bg-brand-500 hover:bg-brand-600 disabled:bg-surface-3 disabled:text-text-muted text-white shadow-sm",secondary:"bg-surface-2 hover:bg-surface-3 disabled:bg-surface disabled:text-text-muted text-text",danger:"bg-red-500 hover:bg-red-600 disabled:bg-surface-3 disabled:text-text-muted text-white",success:"bg-green-600 hover:bg-green-700 disabled:bg-surface-3 disabled:text-text-muted text-white"}[s]} ${{sm:"px-3 py-1.5 text-sm",md:"px-4 py-2 text-base",lg:"px-6 py-3 text-lg"}[t]} ${n||i?"cursor-not-allowed":""} ${d}`;return(0,a.jsx)("button",{onClick:l,disabled:n||i,className:o,...c,children:i?(0,a.jsxs)("span",{className:"flex items-center justify-center gap-2",children:[(0,a.jsx)("span",{className:"animate-spin rounded-full h-4 w-4 border-b-2 border-white"}),e]}):e})}},67434:(e,s,t)=>{Promise.resolve().then(t.bind(t,51345))},68795:(e,s,t)=>{"use strict";t.d(s,{Z:()=>n});var a=t(7620);async function r(e,s={}){let t=await fetch(e,{...s,headers:{"Content-Type":"application/json",...s.headers||{}},credentials:"include"}),a=await t.json().catch(()=>({}));if(!t.ok)throw Error(a?.error||`Request failed (${t.status})`);return a}function n(){let e=(0,a.useCallback)(e=>r(e),[]),s=(0,a.useCallback)((e,s)=>r(e,{method:"POST",body:JSON.stringify(s||{})}),[]);return{get:e,post:s,patch:(0,a.useCallback)((e,s)=>r(e,{method:"PATCH",body:JSON.stringify(s||{})}),[]),del:(0,a.useCallback)(e=>r(e,{method:"DELETE"}),[])}}},78864:(e,s,t)=>{"use strict";t.d(s,{GS:()=>c,Jj:()=>a,Qh:()=>i,WD:()=>r,Wm:()=>l,lb:()=>x,rK:()=>o,vq:()=>n,xp:()=>d});let a={sessionView:"session.view",sessionDelete:"session.delete",modeView:"mode.view",modeManage:"mode.manage",adminView:"admin.view",adminManage:"admin.manage",otaView:"ota.view",otaManage:"ota.manage",turnView:"turn.view",turnManage:"turn.manage",logView:"log.view"};Object.values(a);let r={"session.view":"View sessions","session.delete":"Delete sessions","admin.view":"View admins","admin.manage":"Create/edit admins","mode.view":"View modes","mode.manage":"Create/edit modes","ota.view":"View OTA updates","ota.manage":"Manage OTA updates","turn.view":"View TURN keys","turn.manage":"Manage TURN keys","log.view":"View login audit"},n=[{label:"Sessions",keys:["session.view","session.delete"]},{label:"Admins",keys:["admin.view","admin.manage"]},{label:"Modes",keys:["mode.view","mode.manage"]},{label:"OTA & TURN",keys:["ota.view","ota.manage","turn.view","turn.manage"]},{label:"Audit",keys:["log.view"]}],i=18e5,l=20,d=[10,20,50,100],c=["createdAt","lastAccessAt","expiresAt","machineId"],o=[{key:"loyal",label:"Loyal",minMs:6048e5,color:"text-success"},{key:"returning",label:"Returning",minMs:864e5,color:"text-brand-500"},{key:"active",label:"Active",minMs:3e5,color:"text-brand-400"},{key:"new",label:"New",minMs:0,color:"text-text-muted"}],x={login:"/api/admin/login",logout:"/api/admin/logout",me:"/api/admin/me",sessions:"/api/admin/sessions",stats:"/api/admin/stats",modes:"/api/admin/modes",admins:"/api/admin/admins",ota:"/api/admin/ota",turn:"/api/admin/turn",logins:"/api/admin/logins",turnstile:"/api/admin/turnstile"}},79748:(e,s,t)=>{"use strict";var a=t(79796);t.o(a,"usePathname")&&t.d(s,{usePathname:function(){return a.usePathname}}),t.o(a,"useRouter")&&t.d(s,{useRouter:function(){return a.useRouter}}),t.o(a,"useSearchParams")&&t.d(s,{useSearchParams:function(){return a.useSearchParams}})}},e=>{e.O(0,[820,5587,1772,556,587,1968,7358],()=>e(e.s=67434)),_N_E=e.O()}]);
@@ -1 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[2116],{26784:(e,t,s)=>{"use strict";s.d(t,{A:()=>n});var a=s(54568);function n({label:e,type:t="text",value:s,onChange:r,onKeyDown:i,placeholder:l,disabled:o=!1,error:d,className:A="",...c}){let u=d?"ring-1 ring-red-500 focus:ring-2 focus:ring-red-500":"focus:ring-2 focus:ring-brand-500/40",m=`w-full px-4 py-3 bg-surface-2 rounded-brand text-text placeholder-text-muted focus:outline-none transition-all duration-150 ease-out ${u} ${o?"opacity-50 cursor-not-allowed":""} ${A}`;return(0,a.jsxs)("div",{className:"w-full",children:[e&&(0,a.jsx)("label",{className:"block text-sm font-medium text-text mb-2",children:e}),(0,a.jsx)("input",{type:t,value:s,onChange:r,onKeyDown:i,placeholder:l,disabled:o,className:m,...c}),d&&(0,a.jsx)("p",{className:"mt-1 text-sm text-red-400",children:d})]})}},41989:(e,t,s)=>{Promise.resolve().then(s.bind(s,69421))},46891:(e,t,s)=>{"use strict";s.d(t,{A:()=>o});var a=s(54568),n=s(38118),r=s(14652);let i=({size:e=18})=>(0,a.jsxs)("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,a.jsx)("circle",{cx:"12",cy:"12",r:"4"}),(0,a.jsx)("path",{d:"M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"})]}),l=({size:e=18})=>(0,a.jsx)("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:(0,a.jsx)("path",{d:"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"})});function o({className:e="",size:t=18}){let{theme:s,toggleTheme:d}=(0,n.D)(),A="dark"===s;return(0,a.jsx)("button",{type:"button",onClick:()=>{(0,r.e)(),d()},"aria-label":A?"Switch to light theme":"Switch to dark theme",title:A?"Light mode":"Dark mode",className:`p-1.5 rounded-brand transition-colors text-[var(--color-text-muted)] hover:text-[var(--color-text)] hover:bg-[var(--color-surface-2)] ${e}`,children:A?(0,a.jsx)(i,{size:t}):(0,a.jsx)(l,{size:t})})}},51467:(e,t,s)=>{"use strict";s.d(t,{A:()=>n});var a=s(54568);function n({children:e,centered:t=!0,className:s=""}){return(0,a.jsx)("div",{className:`min-h-screen ${t?"flex items-center justify-center p-4":""} ${s}`,children:e})}},56156:(e,t,s)=>{"use strict";s.d(t,{A:()=>n});var a=s(54568);function n({children:e,variant:t="primary",size:s="md",disabled:r=!1,loading:i=!1,onClick:l,className:o="",...d}){let A=`font-semibold rounded-brand transition-all duration-150 ease-out transform active:scale-[0.97] ${{primary:"bg-brand-500 hover:bg-brand-600 disabled:bg-surface-3 disabled:text-text-muted text-white shadow-sm",secondary:"bg-surface-2 hover:bg-surface-3 disabled:bg-surface disabled:text-text-muted text-text",danger:"bg-red-500 hover:bg-red-600 disabled:bg-surface-3 disabled:text-text-muted text-white",success:"bg-green-600 hover:bg-green-700 disabled:bg-surface-3 disabled:text-text-muted text-white"}[t]} ${{sm:"px-3 py-1.5 text-sm",md:"px-4 py-2 text-base",lg:"px-6 py-3 text-lg"}[s]} ${r||i?"cursor-not-allowed":""} ${o}`;return(0,a.jsx)("button",{onClick:l,disabled:r||i,className:A,...d,children:i?(0,a.jsxs)("span",{className:"flex items-center justify-center gap-2",children:[(0,a.jsx)("span",{className:"animate-spin rounded-full h-4 w-4 border-b-2 border-white"}),e]}):e})}},69421:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>h});var a=s(54568),n=s(7620),r=s(79748),i=s(65587),l=s(51467),o=s(56156),d=s(26784),A=s(46891),c=s(39634);function u({siteKey:e,onToken:t}){let s=(0,n.useRef)(null),r=(0,n.useRef)(t);return((0,n.useEffect)(()=>{r.current=t},[t]),(0,n.useEffect)(()=>{if(!e||!s.current)return;let t=null,a=()=>{window.turnstile?.render&&s.current&&(t=window.turnstile.render(s.current,{sitekey:e,callback:e=>r.current(e),"expired-callback":()=>r.current(""),"error-callback":()=>r.current("")}))};if(window.turnstile?.render)a();else{let e=document.createElement("script");e.src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit",e.async=!0,e.onload=a,document.head.appendChild(e)}return()=>{null!=t&&window.turnstile?.remove?.(t)}},[e]),e)?(0,a.jsx)("div",{ref:s,className:"flex justify-center min-h-[33px]","aria-label":"Captcha"}):null}var m=s(96605),x=s(78864);function h(){let e=(0,r.useRouter)(),[t,s]=(0,n.useState)(""),[h,g]=(0,n.useState)(""),[p,b]=(0,n.useState)(""),[f,w]=(0,n.useState)(!1),[v,j]=(0,n.useState)(""),[y,k]=(0,n.useState)("");(0,n.useEffect)(()=>{fetch(x.lb.turnstile).then(e=>e.json()).then(e=>j(e?.siteKey||"")).catch(()=>j(""))},[]);let C=async()=>{if(t&&h){w(!0),b("");try{let s=await fetch(x.lb.login,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:t,password:h,turnstileToken:y}),credentials:"include"}),a=await s.json();if(!s.ok)throw Error(a?.error||"Login failed");e.replace("/admin")}catch(e){b(e.message),k(""),window.turnstile?.reset?.()}finally{w(!1)}}};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(c.A,{}),(0,a.jsx)(l.A,{children:(0,a.jsxs)("div",{className:"card-glass p-8 sm:p-10 max-w-md w-full relative overflow-hidden",children:[(0,a.jsx)("div",{className:"absolute top-0 left-1/2 -translate-x-1/2 w-48 h-1 bg-brand-500/80 rounded-full blur-sm"}),(0,a.jsxs)("div",{className:"flex items-center justify-between mb-8",children:[(0,a.jsxs)("div",{className:"flex items-center gap-3",children:[(0,a.jsx)("div",{className:"w-10 h-10 rounded-xl flex items-center justify-center font-bold text-lg bg-brand-500 text-white shadow-[0_8px_24px_-6px_rgba(255,87,10,0.5)] ring-1 ring-white/20",children:"9"}),(0,a.jsxs)("div",{children:[(0,a.jsx)("span",{className:"text-[11px] font-mono tracking-wider uppercase text-brand-500 font-semibold block",children:"Console"}),(0,a.jsx)("h1",{className:"text-xl font-bold tracking-tight text-text",children:"9Remote Admin"})]})]}),(0,a.jsx)(A.A,{className:"rounded-xl border border-border-subtle"})]}),(0,a.jsxs)("div",{className:"mb-6",children:[(0,a.jsx)("h2",{className:"text-2xl font-bold tracking-tight text-text login-hero-grad",children:"Welcome back"}),(0,a.jsx)("p",{className:"text-xs text-text-muted mt-1",children:"Sign in with administrator credentials to manage node instances"})]}),p&&(0,a.jsxs)("div",{className:"mb-5 p-3 rounded-xl bg-red-500/10 border border-red-500/20 text-danger text-xs flex items-center gap-2",children:[(0,a.jsx)(m.RI,{size:15,className:"shrink-0"}),(0,a.jsx)("span",{children:p})]}),(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsx)(d.A,{label:"Admin Username",value:t,onChange:e=>s(e.target.value),placeholder:"e.g. root",autoFocus:!0,onKeyDown:e=>"Enter"===e.key&&C()}),(0,a.jsx)(d.A,{label:"Password",type:"password",value:h,onChange:e=>g(e.target.value),placeholder:"••••••••",onKeyDown:e=>"Enter"===e.key&&C()}),(0,a.jsx)(u,{siteKey:v,onToken:k}),(0,a.jsx)(o.A,{variant:"primary",onClick:C,disabled:!t||!h||v&&!y,loading:f,className:"w-full py-2.5 rounded-xl shadow-[0_8px_20px_-6px_rgba(255,87,10,0.45)] font-semibold",children:(0,a.jsxs)("span",{className:"inline-flex items-center justify-center gap-2",children:[(0,a.jsx)("span",{children:"Authenticate"}),(0,a.jsx)(m.Qp,{size:16})]})})]}),(0,a.jsxs)("div",{className:"mt-8 pt-5 border-t border-border-subtle flex items-center justify-between text-xs text-text-subtle",children:[(0,a.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,a.jsx)(m.ek,{size:13,className:"text-brand-500"}),(0,a.jsx)("span",{children:"Restricted access"})]}),(0,a.jsx)(i,{href:"/login",className:"hover:text-brand-500 transition-colors",children:"User Login →"})]})]})})]})}},78864:(e,t,s)=>{"use strict";s.d(t,{GS:()=>d,Jj:()=>a,Qh:()=>i,WD:()=>n,Wm:()=>l,lb:()=>c,rK:()=>A,vq:()=>r,xp:()=>o});let a={sessionView:"session.view",sessionDelete:"session.delete",modeView:"mode.view",modeManage:"mode.manage",adminView:"admin.view",adminManage:"admin.manage",otaView:"ota.view",otaManage:"ota.manage",turnView:"turn.view",turnManage:"turn.manage",logView:"log.view"};Object.values(a);let n={"session.view":"View sessions","session.delete":"Delete sessions","admin.view":"View admins","admin.manage":"Create/edit admins","mode.view":"View modes","mode.manage":"Create/edit modes","ota.view":"View OTA updates","ota.manage":"Manage OTA updates","turn.view":"View TURN keys","turn.manage":"Manage TURN keys","log.view":"View login audit"},r=[{label:"Sessions",keys:["session.view","session.delete"]},{label:"Admins",keys:["admin.view","admin.manage"]},{label:"Modes",keys:["mode.view","mode.manage"]},{label:"OTA & TURN",keys:["ota.view","ota.manage","turn.view","turn.manage"]},{label:"Audit",keys:["log.view"]}],i=18e5,l=20,o=[10,20,50,100],d=["createdAt","lastAccessAt","expiresAt","machineId"],A=[{key:"loyal",label:"Loyal",minMs:6048e5,color:"text-success"},{key:"returning",label:"Returning",minMs:864e5,color:"text-brand-500"},{key:"active",label:"Active",minMs:3e5,color:"text-brand-400"},{key:"new",label:"New",minMs:0,color:"text-text-muted"}],c={login:"/api/admin/login",logout:"/api/admin/logout",me:"/api/admin/me",sessions:"/api/admin/sessions",stats:"/api/admin/stats",modes:"/api/admin/modes",admins:"/api/admin/admins",ota:"/api/admin/ota",turn:"/api/admin/turn",logins:"/api/admin/logins",turnstile:"/api/admin/turnstile"}},79748:(e,t,s)=>{"use strict";var a=s(79796);s.o(a,"usePathname")&&s.d(t,{usePathname:function(){return a.usePathname}}),s.o(a,"useRouter")&&s.d(t,{useRouter:function(){return a.useRouter}}),s.o(a,"useSearchParams")&&s.d(t,{useSearchParams:function(){return a.useSearchParams}})},96605:(e,t,s)=>{"use strict";s.d(t,{$o:()=>eE.A,AX:()=>eb.A,Ay:()=>to,BK:()=>e5.A,BZ:()=>Z.A,Bm:()=>B.A,Cp:()=>K.A,Do:()=>l.A,F1:()=>o.A,FE:()=>e1.A,FW:()=>eF.A,Fc:()=>eD.A,GD:()=>D.A,GO:()=>eh.A,Gr:()=>L.A,Gv:()=>ew.A,Hx:()=>er.A,Ir:()=>A.A,J4:()=>e0.A,JG:()=>g.A,JU:()=>G.A,Jl:()=>x.A,Kq:()=>ti.A,LM:()=>ed.A,Lt:()=>N.A,M6:()=>eY.A,MA:()=>d.A,Mr:()=>e_.A,P6:()=>et.A,QR:()=>C.A,Qp:()=>i.A,RI:()=>n.A,TB:()=>e8.A,Ud:()=>q.A,VA:()=>ep.A,Vn:()=>eK.A,W1:()=>ex.A,WE:()=>f.A,We:()=>e4.A,Wn:()=>k.A,X:()=>tr.A,X_:()=>U.A,ZH:()=>O.A,ZU:()=>e9.A,Ze:()=>eV.A,Zr:()=>$.A,_O:()=>te.A,_V:()=>ee.A,a4:()=>ef.A,aJ:()=>m.A,ak:()=>Q.A,bE:()=>e3.A,bd:()=>e6.A,cC:()=>c.A,c_:()=>p.A,dJ:()=>z.A,de:()=>tn.A,dx:()=>H.A,e6:()=>ek.A,e9:()=>ez.A,eM:()=>eG.A,ek:()=>eQ.A,es:()=>ey.A,f2:()=>I.A,f5:()=>S.A,gH:()=>eL.A,h1:()=>eu.A,iU:()=>E.A,jG:()=>eO.A,jj:()=>eg.A,jl:()=>w.A,jz:()=>eM.A,kU:()=>R.A,kV:()=>es.A,kr:()=>eo.A,kt:()=>eB.A,lM:()=>e7.A,lP:()=>ej.A,m0:()=>v.A,mN:()=>X.A,nU:()=>ec.A,qz:()=>J.A,rX:()=>b.A,s3:()=>ea.A,sU:()=>eZ.A,sv:()=>T.A,ue:()=>eC.A,vR:()=>eS.A,vW:()=>eT.A,vd:()=>W.A,vj:()=>eH.A,vv:()=>ei.A,wB:()=>eI.A,wO:()=>eX.A,ww:()=>Y.A,xq:()=>em.A,xv:()=>eP.A,y8:()=>el.A,yQ:()=>h.A,yU:()=>eU.A,yd:()=>r.A,zP:()=>u.A,zW:()=>tt.A});var a=s(54568),n=s(14796),r=s(50683),i=s(30307),l=s(62826),o=s(22061),d=s(46480),A=s(77542),c=s(30824),u=s(8631),m=s(34309),x=s(63322),h=s(34041),g=s(8008),p=s(76265),b=s(17156),f=s(11964),w=s(21411),v=s(1173),j=s(72980),y=s(9901),k=s(3129),C=s(59706),N=s(31381),M=s(40414),P=s(91276),S=s(2099),L=s(26083),R=s(20732),U=s(69724),V=s(93675),O=s(96249),D=s(36293),F=s(16556),_=s(14264),E=s(2939),T=s(74206),z=s(52947),W=s(26463),B=s(45894),G=s(72030),$=s(58588),H=s(10280),K=s(57460),J=s(97380),I=s(80172),q=s(7086),Q=s(83667),X=s(73012),Z=s(19773),Y=s(64529),ee=s(31260),et=s(46396),es=s(86163),ea=s(45258),en=s(81167),er=s(7920),ei=s(68476),el=s(53903),eo=s(58299),ed=s(41956),eA=s(1345),ec=s(76710),eu=s(1778),em=s(81168),ex=s(17212),eh=s(32174),eg=s(6906),ep=s(82099),eb=s(39182),ef=s(23428),ew=s(44073),ev=s(26093),ej=s(15217),ey=s(67310),ek=s(45667),eC=s(63742),eN=s(90466),eM=s(16172),eP=s(63253),eS=s(80367),eL=s(794),eR=s(99348),eU=s(81002),eV=s(21126),eO=s(55769),eD=s(28819),eF=s(67447),e_=s(11344),eE=s(49600),eT=s(14858),ez=s(60527),eW=s(16889),eB=s(19293),eG=s(92534),e$=s(14432),eH=s(23555),eK=s(82797),eJ=s(95740),eI=s(37270),eq=s(4326),eQ=s(35198),eX=s(41684),eZ=s(46548),eY=s(3792),e0=s(87130),e1=s(94411),e2=s(27663),e6=s(87547),e4=s(30774),e5=s(88011),e8=s(44968),e7=s(82791),e9=s(70479),e3=s(96466),te=s(63058),tt=s(96553),ts=s(69458),ta=s(1852),tn=s(39075),tr=s(36645),ti=s(56242);let tl={AlertCircle:n.A,ArrowDown:r.A,ArrowRight:i.A,ArrowUp:l.A,ArrowUpRight:o.A,Ban:d.A,Bell:A.A,Bot:c.A,Bug:u.A,Check:m.A,CheckCircle2:x.A,ChevronDown:h.A,ChevronLeft:g.A,ChevronRight:p.A,ChevronUp:b.A,ChevronsDownUp:f.A,Circle:w.A,ClipboardPaste:v.A,Command:j.A,Compass:y.A,Columns2:k.A,Copy:C.A,CornerDownLeft:N.A,Crown:M.A,Delete:P.A,Download:S.A,ExternalLink:L.A,Eye:R.A,EyeOff:U.A,Facebook:V.A,File:O.A,FileCode:D.A,FileJson:F.A,FilePlus:_.A,FileText:E.A,Files:T.A,Filter:z.A,Folder:W.A,FolderOpen:B.A,FolderPlus:G.A,GitBranch:$.A,GitFork:H.A,Github:K.A,Globe:J.A,GripVertical:I.A,Hand:q.A,HardDrive:Q.A,HelpCircle:X.A,History:Z.A,Home:Y.A,Image:ee.A,ImageOff:et.A,KeyRound:es.A,Keyboard:ea.A,Laptop:en.A,LayoutDashboard:er.A,Link2:ei.A,ListChecks:el.A,Loader2:eo.A,Lock:ed.A,LogIn:eA.A,LogOut:ec.A,Maximize2:eu.A,Minimize2:em.A,Menu:ex.A,Mic:eh.A,MicOff:eg.A,Monitor:ep.A,Moon:eb.A,MoreHorizontal:ef.A,MoreVertical:ew.A,MousePointer2:ev.A,Package:ej.A,Palette:ey.A,PanelLeft:ek.A,PanelLeftClose:eC.A,PanelLeftOpen:eN.A,PanelRight:eM.A,Paperclip:eP.A,Pause:eS.A,Pencil:eL.A,Pi:eR.A,Pin:eU.A,PinOff:eV.A,Play:eO.A,Plug:eD.A,Plus:eF.A,Power:e_.A,PowerOff:eE.A,QrCode:eT.A,RefreshCw:ez.A,Replace:eW.A,RotateCw:eB.A,Save:eG.A,Scissors:e$.A,Search:eH.A,Send:eK.A,SendHorizontal:eJ.A,Settings:eI.A,Share:eq.A,Shield:eQ.A,Smartphone:eX.A,Sparkles:eZ.A,Square:eY.A,SquarePen:e0.A,Star:e1.A,StickyNote:e2.A,Sun:e6.A,Target:e4.A,Terminal:e5.A,Trash2:e8.A,Triangle:e7.A,Type:e9.A,Undo2:e3.A,Upload:te.A,Users:tt.A,Volume2:ts.A,VolumeX:ta.A,Wallpaper:tn.A,X:tr.A,Zap:ti.A};function to({name:e,size:t=20,className:s="",...n}){let r=tl[e];return r?(0,a.jsx)(r,{size:t,className:s,strokeWidth:2,...n}):(console.warn(`Icon "${e}" not found in the icon registry`),null)}}},e=>{e.O(0,[820,5587,1772,587,1968,7358],()=>e(e.s=41989)),_N_E=e.O()}]);
@@ -1,5 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[8535],{4655:(e,t,s)=>{"use strict";s.d(t,{b:()=>i});var a=s(7620),r=s(79748),n=s(78864),l=s(68795);function i({redirectIfUnauthed:e=!0}={}){let t=(0,r.useRouter)(),{get:s,post:d}=(0,l.Z)(),[c,o]=(0,a.useState)(null),[x,m]=(0,a.useState)(!0),u=(0,a.useCallback)(async()=>{try{let e=await s(n.lb.me);o(e)}catch{o(null),e&&t.replace("/admin/login")}finally{m(!1)}},[s,e,t]);(0,a.useEffect)(()=>{u()},[u]);let b=(0,a.useCallback)(async()=>{await d(n.lb.logout,{}),t.replace("/admin/login")},[d,t]),p=(0,a.useCallback)(e=>Array.isArray(c?.permissions)&&c.permissions.includes(e),[c]);return{me:c,loading:x,logout:b,can:p,refresh:u}}},14337:(e,t,s)=>{"use strict";s.d(t,{A:()=>r});var a=s(54568);function r({size:e="md",text:t,className:s=""}){return(0,a.jsxs)("div",{className:`flex flex-col items-center justify-center gap-3 ${s}`,children:[(0,a.jsx)("div",{className:`animate-spin rounded-full border-brand-500 border-t-transparent ${{sm:"h-4 w-4 border-2",md:"h-8 w-8 border-2",lg:"h-12 w-12 border-b-2"}[e]}`}),t&&(0,a.jsx)("p",{className:"text-brand-500 text-sm font-medium",children:t})]})}},45256:(e,t,s)=>{"use strict";s.d(t,{A:()=>p});var a=s(54568),r=s(14916),n=s(7620),l=s(65587),i=s(79748),d=s(14337),c=s(51467),o=s(46891),x=s(39634),m=s(96605),u=s(4655);let b=[{href:"/admin",label:"Dashboard",icon:m.Hx,exact:!0},{href:"/admin/access",label:"Access",icon:m.zW},{href:"/admin/ota",label:"OTA Updates",icon:m.lP,needsOta:!0},{href:"/admin/turn",label:"TURN Keys",icon:m.kV}];function p({children:e}){let t=(0,i.usePathname)(),{me:s,loading:h,logout:f}=(0,u.b)(),[g,j]=(0,n.useState)(!1);if(h||!s)return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(x.A,{}),(0,a.jsx)(c.A,{children:(0,a.jsx)("div",{className:"card-glass p-8 max-w-sm w-full flex flex-col items-center justify-center",children:(0,a.jsx)(d.A,{size:"lg",text:"Loading admin..."})})})]});let N=(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"p-4 border-b border-border-subtle flex items-center justify-between gap-3",children:[(0,a.jsxs)("div",{className:"flex items-center gap-2.5 min-w-0",children:[(0,a.jsx)("div",{className:"w-6 h-6 shrink-0 rounded-md flex items-center justify-center font-bold text-sm bg-brand-500 text-white",children:"9"}),(0,a.jsxs)("div",{className:"min-w-0",children:[(0,a.jsx)("h1",{className:"text-sm font-bold tracking-tight text-text truncate",children:"9Remote Admin"}),(0,a.jsxs)("div",{className:"flex items-center gap-1.5 mt-0.5",children:[(0,a.jsx)("span",{className:"text-xs text-text-muted truncate",children:s.username}),(0,a.jsx)("span",{className:"text-[10px] font-mono px-1.5 py-0.5 rounded-full bg-surface-2 text-text-muted border border-border-subtle",children:s.modeName||s.modeId})]})]})]}),(0,a.jsx)("button",{onClick:()=>j(!1),className:"md:hidden p-1.5 -mr-1.5 text-text-muted hover:text-text rounded-[6px] hover:bg-surface-2 transition-colors","aria-label":"Close menu",children:(0,a.jsx)(m.X,{size:18})})]}),(0,a.jsxs)("nav",{className:"flex-1 px-3.5 py-3 space-y-0.5 overflow-y-auto",children:[(0,a.jsx)("div",{className:"pl-[3.5px] py-1.5 text-[10px] font-mono uppercase tracking-wider text-text-subtle",children:"Navigation"}),b.filter(e=>!e.needsOta||s.otaEnabled).map(e=>{let s=e.icon,r=e.exact?t===e.href:t.startsWith(e.href);return(0,a.jsxs)(l,{href:e.href,onClick:()=>j(!1),className:`
2
- flex items-center gap-2.5 -ml-3.5 w-[calc(100%+0.875rem)] pl-[17px] pr-3 py-1.5
3
- rounded-[6px] text-xs font-medium text-left transition-colors duration-150
4
- ${r?"bg-surface-3 text-text font-semibold":"text-text-muted hover:bg-surface-2 hover:text-text"}
5
- `,children:[(0,a.jsx)(s,{size:15,className:r?"text-text":"text-text-subtle"}),(0,a.jsx)("span",{className:"flex-1",children:e.label}),r&&(0,a.jsx)("span",{className:"w-1 h-1 rounded-full bg-text-muted"})]},e.href)})]}),(0,a.jsx)("div",{className:"p-3.5 border-t border-border-subtle",children:(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)(o.A,{className:"border border-border-subtle hover:bg-surface-2 rounded-[6px]"}),(0,a.jsxs)("button",{onClick:f,className:"flex-1 flex items-center justify-center gap-2 px-3 py-1.5 rounded-[6px] text-xs font-medium text-text-muted hover:bg-red-500/10 hover:text-danger transition-colors",children:[(0,a.jsx)(m.nU,{size:15}),"Logout"]})]})})]});return(0,a.jsxs)("div",{className:"jsx-b56c084163c9c8c1 min-h-screen text-text relative selection:bg-brand-500/20",children:[(0,a.jsx)(x.A,{}),(0,a.jsxs)("header",{className:"jsx-b56c084163c9c8c1 md:hidden sticky top-0 z-30 flex items-center justify-between px-4 py-2.5 bg-surface/80 backdrop-blur-md border-b border-border-subtle",children:[(0,a.jsx)("button",{onClick:()=>j(!0),"aria-label":"Open menu",className:"jsx-b56c084163c9c8c1 p-1.5 -ml-1.5 text-text-muted hover:text-text rounded-[6px] hover:bg-surface-2",children:(0,a.jsx)(m.W1,{size:20})}),(0,a.jsxs)("div",{className:"jsx-b56c084163c9c8c1 flex items-center gap-2",children:[(0,a.jsx)("div",{className:"jsx-b56c084163c9c8c1 w-6 h-6 rounded-md flex items-center justify-center font-bold text-xs bg-brand-500 text-white",children:"9"}),(0,a.jsx)("h1",{className:"jsx-b56c084163c9c8c1 text-sm font-semibold tracking-tight",children:"9Remote Admin"})]}),(0,a.jsx)(o.A,{className:"rounded-[6px]"})]}),(0,a.jsx)("aside",{className:"jsx-b56c084163c9c8c1 hidden md:flex fixed inset-y-0 left-0 w-60 border-r border-border-subtle bg-surface/80 backdrop-blur-xl flex-col z-20",children:N}),g&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("div",{onClick:()=>j(!1),className:"jsx-b56c084163c9c8c1 md:hidden fixed inset-0 z-40 bg-black/60 backdrop-blur-[2px] fade-in"}),(0,a.jsx)("aside",{style:{animation:"slideInFromLeft 0.22s cubic-bezier(0.22, 1, 0.36, 1) forwards"},className:"jsx-b56c084163c9c8c1 md:hidden fixed inset-y-0 left-0 z-50 w-72 max-w-[85%] bg-surface/95 backdrop-blur-2xl border-r border-border-subtle flex flex-col slide-in-right",children:N})]}),(0,a.jsx)("main",{className:"jsx-b56c084163c9c8c1 md:ml-60 p-4 sm:p-6 lg:p-8 min-h-screen relative z-10 max-w-7xl",children:e}),(0,a.jsx)(r,{id:"b56c084163c9c8c1",children:"@keyframes slideInFromLeft{from{transform:translatex(-100%);opacity:0}to{transform:translatex(0);opacity:1}}"})]})}},50158:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>x});var a=s(54568),r=s(7620),n=s(45256),l=s(68795),i=s(4655),d=s(78864),c=s(96605);let o=["","ios","android"];function x(){let{can:e,me:t,loading:s}=(0,i.b)(),{get:x,post:m}=(0,l.Z)(),[u,b]=(0,r.useState)([]),[p,h]=(0,r.useState)(!0),[f,g]=(0,r.useState)(""),[j,N]=(0,r.useState)({runtimeVersion:"",platform:"",channel:""}),[y,v]=(0,r.useState)(null),w=e(d.Jj.otaManage),k=(0,r.useCallback)(async()=>{h(!0),g("");try{let e=new URLSearchParams;j.runtimeVersion&&e.set("runtimeVersion",j.runtimeVersion),j.platform&&e.set("platform",j.platform),j.channel&&e.set("channel",j.channel);let t=await x(`${d.lb.ota}?${e}`);b(t.items||[])}catch(e){g(e.message)}finally{h(!1)}},[x,j.runtimeVersion,j.platform,j.channel]);(0,r.useEffect)(()=>{!s&&t&&k()},[s,t]);let A=async e=>{if(confirm(`Promote #${e.buildNumber} to serving for channel "${e.channel}" (${e.platform}, ${e.runtimeVersion})?`)){v(e.id);try{await m(`${d.lb.ota}/${e.id}/promote`),await k()}catch(e){g(e.message)}finally{v(null)}}};return(0,a.jsx)(n.A,{children:(0,a.jsxs)("div",{className:"space-y-8 max-w-5xl",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsxs)("div",{children:[(0,a.jsxs)("h1",{className:"text-2xl font-bold tracking-tight text-text login-hero-grad flex items-center gap-2.5",children:[(0,a.jsx)(c.lP,{size:24,className:"text-brand-500"}),(0,a.jsx)("span",{children:"OTA Updates"})]}),(0,a.jsx)("p",{className:"text-xs text-text-muted mt-1",children:"Publish, promote and rollback mobile application bundles"})]}),(0,a.jsxs)("button",{onClick:k,disabled:p,className:"inline-flex items-center gap-2 px-3.5 py-1.5 rounded-xl bg-surface-2 hover:bg-surface-3 border border-border-subtle text-xs font-medium text-text transition-colors disabled:opacity-50",children:[(0,a.jsx)(c.e9,{size:13,className:p?"animate-spin text-brand-500":""}),(0,a.jsx)("span",{children:"Refresh"})]})]}),(0,a.jsxs)("div",{className:"card-glass p-4 grid grid-cols-1 sm:grid-cols-4 gap-3",children:[(0,a.jsx)("input",{className:"px-3 py-2 text-xs border border-border-subtle rounded-xl bg-surface-2/80 text-text placeholder:text-text-subtle focus:outline-none focus:ring-2 focus:ring-brand-500/30 font-mono",placeholder:"Runtime (e.g. 0.1.7)",value:j.runtimeVersion,onChange:e=>N({...j,runtimeVersion:e.target.value})}),(0,a.jsx)("select",{className:"px-3 py-2 text-xs border border-border-subtle rounded-xl bg-surface-2/80 text-text focus:outline-none focus:ring-2 focus:ring-brand-500/30",value:j.platform,onChange:e=>N({...j,platform:e.target.value}),children:o.map(e=>(0,a.jsx)("option",{value:e,children:e?e.toUpperCase():"All platforms"},e))}),(0,a.jsx)("input",{className:"px-3 py-2 text-xs border border-border-subtle rounded-xl bg-surface-2/80 text-text placeholder:text-text-subtle focus:outline-none focus:ring-2 focus:ring-brand-500/30 font-mono",placeholder:"Channel (e.g. production)",value:j.channel,onChange:e=>N({...j,channel:e.target.value})}),(0,a.jsx)("button",{onClick:k,className:"px-4 py-2 text-xs font-semibold bg-brand-500 text-white rounded-xl hover:bg-brand-600 shadow-[0_4px_12px_-4px_rgba(255,87,10,0.5)] transition-all",children:"Filter Bundles"})]}),f&&(0,a.jsx)("p",{className:"text-xs text-danger bg-red-500/10 p-3 rounded-xl border border-red-500/20",children:f}),p?(0,a.jsxs)("div",{className:"card-glass p-12 text-center text-text-muted text-xs",children:[(0,a.jsx)(c.e9,{size:20,className:"mx-auto mb-2 animate-spin text-brand-500"}),"Loading updates catalog..."]}):0===u.length?(0,a.jsxs)("div",{className:"card-glass p-12 text-center",children:[(0,a.jsx)("div",{className:"w-12 h-12 rounded-2xl bg-surface-2 flex items-center justify-center mx-auto mb-3 text-text-subtle",children:(0,a.jsx)(c.lP,{size:24})}),(0,a.jsx)("h3",{className:"text-sm font-semibold text-text",children:"No updates published"}),(0,a.jsxs)("p",{className:"text-text-muted text-xs mt-1",children:["Publish an OTA update package with ",(0,a.jsx)("code",{className:"text-brand-500 font-mono px-1.5 py-0.5 rounded bg-surface-2",children:"npm run update"})]})]}):(0,a.jsx)("div",{className:"card-glass overflow-hidden",children:(0,a.jsxs)("table",{className:"w-full text-sm text-left",children:[(0,a.jsx)("thead",{className:"bg-surface-2/60 border-b border-border-subtle text-[11px] font-mono uppercase tracking-wider text-text-muted",children:(0,a.jsxs)("tr",{children:[(0,a.jsx)("th",{className:"px-4 py-3",children:"Build"}),(0,a.jsx)("th",{className:"px-4 py-3",children:"Runtime"}),(0,a.jsx)("th",{className:"px-4 py-3",children:"Platform"}),(0,a.jsx)("th",{className:"px-4 py-3",children:"Channel"}),(0,a.jsx)("th",{className:"px-4 py-3",children:"Published"}),(0,a.jsx)("th",{className:"px-4 py-3",children:"Status"}),w&&(0,a.jsx)("th",{className:"px-4 py-3 text-right",children:"Actions"})]})}),(0,a.jsx)("tbody",{className:"divide-y divide-border-subtle/50",children:u.map(e=>(0,a.jsxs)("tr",{className:"hover:bg-surface-2/40 transition-colors",children:[(0,a.jsxs)("td",{className:"px-4 py-3.5",children:[(0,a.jsxs)("div",{className:"font-medium text-text",children:[(0,a.jsxs)("span",{className:"text-brand-500 font-mono font-bold mr-2",children:["#",e.buildNumber]}),(0,a.jsx)("span",{children:e.message||"(no message)"})]}),(0,a.jsx)("div",{className:"text-[10px] text-text-subtle font-mono mt-0.5",children:e.id.slice(0,8)})]}),(0,a.jsx)("td",{className:"px-4 py-3.5 text-xs font-mono text-text-muted",children:e.runtimeVersion}),(0,a.jsx)("td",{className:"px-4 py-3.5",children:(0,a.jsx)("span",{className:`px-2 py-0.5 rounded-md text-[10px] font-mono font-bold uppercase tracking-wider border ${"ios"===e.platform?"bg-sky-500/10 text-sky-500 border-sky-500/20":"bg-emerald-500/10 text-emerald-500 border-emerald-500/20"}`,children:e.platform})}),(0,a.jsx)("td",{className:"px-4 py-3.5",children:(0,a.jsx)("span",{className:"px-2 py-0.5 rounded-full text-xs font-mono bg-surface-2 border border-border-subtle text-text",children:e.channel})}),(0,a.jsx)("td",{className:"px-4 py-3.5 text-xs text-text-muted font-mono",children:(e=>{if(!e)return"-";try{return new Date(e).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return e}})(e.publishedAt||e.createdAt)}),(0,a.jsx)("td",{className:"px-4 py-3.5",children:e.isServing?(0,a.jsxs)("span",{className:"inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium bg-emerald-500/10 text-emerald-500 border border-emerald-500/20",children:[(0,a.jsx)(c.Jl,{size:13}),(0,a.jsx)("span",{children:"Serving"})]}):(0,a.jsx)("span",{className:"text-xs font-mono text-text-subtle px-2 py-0.5 rounded bg-surface-2",children:e.status})}),w&&(0,a.jsx)("td",{className:"px-4 py-3.5 text-right",children:!e.isServing&&(0,a.jsxs)("button",{onClick:()=>A(e),disabled:y===e.id,className:"inline-flex items-center gap-1 text-xs font-semibold text-brand-500 hover:text-brand-400 px-2.5 py-1 rounded-lg hover:bg-brand-500/10 transition-colors disabled:opacity-50",children:[(0,a.jsx)("span",{children:y===e.id?"Promoting...":"Promote"}),(0,a.jsx)(c.F1,{size:13})]})})]},e.id))})]})})]})})}},51467:(e,t,s)=>{"use strict";s.d(t,{A:()=>r});var a=s(54568);function r({children:e,centered:t=!0,className:s=""}){return(0,a.jsx)("div",{className:`min-h-screen ${t?"flex items-center justify-center p-4":""} ${s}`,children:e})}},56542:(e,t,s)=>{Promise.resolve().then(s.bind(s,50158))},68795:(e,t,s)=>{"use strict";s.d(t,{Z:()=>n});var a=s(7620);async function r(e,t={}){let s=await fetch(e,{...t,headers:{"Content-Type":"application/json",...t.headers||{}},credentials:"include"}),a=await s.json().catch(()=>({}));if(!s.ok)throw Error(a?.error||`Request failed (${s.status})`);return a}function n(){let e=(0,a.useCallback)(e=>r(e),[]),t=(0,a.useCallback)((e,t)=>r(e,{method:"POST",body:JSON.stringify(t||{})}),[]);return{get:e,post:t,patch:(0,a.useCallback)((e,t)=>r(e,{method:"PATCH",body:JSON.stringify(t||{})}),[]),del:(0,a.useCallback)(e=>r(e,{method:"DELETE"}),[])}}},78864:(e,t,s)=>{"use strict";s.d(t,{GS:()=>c,Jj:()=>a,Qh:()=>l,WD:()=>r,Wm:()=>i,lb:()=>x,rK:()=>o,vq:()=>n,xp:()=>d});let a={sessionView:"session.view",sessionDelete:"session.delete",modeView:"mode.view",modeManage:"mode.manage",adminView:"admin.view",adminManage:"admin.manage",otaView:"ota.view",otaManage:"ota.manage",turnView:"turn.view",turnManage:"turn.manage",logView:"log.view"};Object.values(a);let r={"session.view":"View sessions","session.delete":"Delete sessions","admin.view":"View admins","admin.manage":"Create/edit admins","mode.view":"View modes","mode.manage":"Create/edit modes","ota.view":"View OTA updates","ota.manage":"Manage OTA updates","turn.view":"View TURN keys","turn.manage":"Manage TURN keys","log.view":"View login audit"},n=[{label:"Sessions",keys:["session.view","session.delete"]},{label:"Admins",keys:["admin.view","admin.manage"]},{label:"Modes",keys:["mode.view","mode.manage"]},{label:"OTA & TURN",keys:["ota.view","ota.manage","turn.view","turn.manage"]},{label:"Audit",keys:["log.view"]}],l=18e5,i=20,d=[10,20,50,100],c=["createdAt","lastAccessAt","expiresAt","machineId"],o=[{key:"loyal",label:"Loyal",minMs:6048e5,color:"text-success"},{key:"returning",label:"Returning",minMs:864e5,color:"text-brand-500"},{key:"active",label:"Active",minMs:3e5,color:"text-brand-400"},{key:"new",label:"New",minMs:0,color:"text-text-muted"}],x={login:"/api/admin/login",logout:"/api/admin/logout",me:"/api/admin/me",sessions:"/api/admin/sessions",stats:"/api/admin/stats",modes:"/api/admin/modes",admins:"/api/admin/admins",ota:"/api/admin/ota",turn:"/api/admin/turn",logins:"/api/admin/logins",turnstile:"/api/admin/turnstile"}},79748:(e,t,s)=>{"use strict";var a=s(79796);s.o(a,"usePathname")&&s.d(t,{usePathname:function(){return a.usePathname}}),s.o(a,"useRouter")&&s.d(t,{useRouter:function(){return a.useRouter}}),s.o(a,"useSearchParams")&&s.d(t,{useSearchParams:function(){return a.useSearchParams}})}},e=>{e.O(0,[820,5587,1772,556,587,1968,7358],()=>e(e.s=56542)),_N_E=e.O()}]);
@@ -1,5 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[3698],{4655:(e,t,s)=>{"use strict";s.d(t,{b:()=>i});var a=s(7620),l=s(79748),r=s(78864),n=s(68795);function i({redirectIfUnauthed:e=!0}={}){let t=(0,l.useRouter)(),{get:s,post:c}=(0,n.Z)(),[d,o]=(0,a.useState)(null),[x,m]=(0,a.useState)(!0),u=(0,a.useCallback)(async()=>{try{let e=await s(r.lb.me);o(e)}catch{o(null),e&&t.replace("/admin/login")}finally{m(!1)}},[s,e,t]);(0,a.useEffect)(()=>{u()},[u]);let b=(0,a.useCallback)(async()=>{await c(r.lb.logout,{}),t.replace("/admin/login")},[c,t]),h=(0,a.useCallback)(e=>Array.isArray(d?.permissions)&&d.permissions.includes(e),[d]);return{me:d,loading:x,logout:b,can:h,refresh:u}}},8891:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>j});var a=s(54568),l=s(7620),r=s(45256),n=s(96605);let i=[{key:"total",label:"Total",icon:n.BK,color:"text-text",iconColor:"text-text-muted bg-surface-2"},{key:"online",label:"Online (30m)",icon:n.Kq,color:"text-success",iconColor:"text-success bg-emerald-500/10",pulse:!0},{key:"newToday",label:"New (24h)",icon:n.sU,color:"text-brand-500",iconColor:"text-brand-500 bg-brand-500/10"},{key:"retention7d",label:"Retention 7d",icon:n.BZ,color:"text-text",iconColor:"text-text-muted bg-surface-2",suffix:"%"},{key:"stickiness",label:"Stickiness",icon:n.FE,color:"text-amber-500",iconColor:"text-amber-500 bg-amber-500/10",suffix:"%"},{key:"avgLifespanDays",label:"Avg Lifespan",icon:n.kt,color:"text-text",iconColor:"text-text-muted bg-surface-2",suffix:"d"}];function c({stats:e}){return(0,a.jsx)("div",{className:"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-3 sm:gap-4",children:i.map(t=>{let s=t.icon,l=e?.[t.key];return(0,a.jsxs)("div",{className:"card-glass p-4 relative overflow-hidden",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between mb-2",children:[(0,a.jsx)("span",{className:"text-[11px] font-mono tracking-wider uppercase text-text-muted truncate",children:t.label}),(0,a.jsx)("div",{className:`w-7 h-7 rounded-lg flex items-center justify-center ${t.iconColor}`,children:(0,a.jsx)(s,{size:14})})]}),(0,a.jsxs)("div",{className:"flex items-baseline gap-1.5 mt-1",children:[(0,a.jsx)("div",{className:`text-xl sm:text-2xl font-bold tracking-tight font-mono ${t.color}`,children:l??"-"}),null!=l&&t.suffix&&(0,a.jsx)("span",{className:"text-xs font-mono text-text-subtle font-semibold",children:t.suffix})]}),t.pulse&&(0,a.jsxs)("div",{className:"absolute bottom-2 right-2 flex items-center gap-1.5",children:[(0,a.jsxs)("span",{className:"relative flex h-2 w-2",children:[(0,a.jsx)("span",{className:"animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"}),(0,a.jsx)("span",{className:"relative inline-flex rounded-full h-2 w-2 bg-emerald-500"})]}),(0,a.jsx)("span",{className:"text-[10px] font-mono text-emerald-500 font-medium",children:"live"})]})]},t.key)})})}var d=s(78864);let o=[{key:"machineId",label:"Machine ID",sortable:!0},{key:"publicIp",label:"Public IP",sortable:!1},{key:"localIp",label:"Local IP",sortable:!1},{key:"createdAt",label:"Created",sortable:!0},{key:"lastAccessAt",label:"Last Access",sortable:!0},{key:"expiresAt",label:"Expires",sortable:!0}],x=o.filter(e=>e.sortable);function m(e){let t=e?.lastAccessAt||e?.createdAt;return!!t&&Date.now()-new Date(t+"Z").getTime()<d.Qh}function u(e){if(!e)return"-";try{return new Date(e+"Z").toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return e}}function b({session:e}){let{tier:t,ageMs:s}=function(e){let t={tier:d.rK[d.rK.length-1],ageMs:null};if(!e?.createdAt||!e?.lastAccessAt)return t;let s=new Date(e.lastAccessAt+"Z").getTime()-new Date(e.createdAt+"Z").getTime();return{tier:d.rK.find(e=>s>=e.minMs)||t.tier,ageMs:s}}(e),l="loyal"===t.key?"bg-emerald-500/10 text-emerald-500 border-emerald-500/20":"returning"===t.key?"bg-brand-500/10 text-brand-500 border-brand-500/20":"active"===t.key?"bg-amber-500/10 text-amber-500 border-amber-500/20":"bg-surface-2 text-text-muted border-border-subtle";return(0,a.jsxs)("div",{className:"inline-flex items-center gap-1.5",children:[(0,a.jsx)("span",{className:`px-2 py-0.5 rounded-full text-[11px] font-medium border ${l}`,children:t.label}),null!=s&&(0,a.jsx)("span",{className:"text-text-subtle text-[11px] font-mono",children:function(e){if(null==e||e<0)return"-";let t=Math.floor(e/6e4);if(t<1)return"<1m";let s=Math.floor(t/1440),a=Math.floor(t%1440/60),l=t%60;return s>0?`${s}d ${a}h`:a>0?`${a}h ${l}m`:`${l}m`}(s)})]})}function h({items:e,sortBy:t,order:s,onSortChange:l,onDelete:r,canDelete:i}){return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"md:hidden flex items-center justify-between mb-3 text-xs",children:[(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)("span",{className:"text-text-muted",children:"Sort by:"}),(0,a.jsx)("select",{value:t,onChange:e=>l(e.target.value,s),className:"bg-surface-2 border border-border-subtle rounded-lg px-2.5 py-1.5 text-text focus:outline-none",children:x.map(e=>(0,a.jsx)("option",{value:e.key,children:e.label},e.key))})]}),(0,a.jsxs)("button",{onClick:()=>l(t,"asc"===s?"desc":"asc"),className:"flex items-center gap-1 bg-surface-2 hover:bg-surface-3 border border-border-subtle rounded-lg px-2.5 py-1.5 text-text transition-colors","aria-label":"Toggle order",children:[(0,a.jsx)("span",{className:"font-mono uppercase",children:s}),"asc"===s?(0,a.jsx)(n.Do,{size:13}):(0,a.jsx)(n.yd,{size:13})]})]}),(0,a.jsxs)("div",{className:"md:hidden space-y-3",children:[0===e.length&&(0,a.jsxs)("div",{className:"card-glass p-8 text-center text-text-muted flex flex-col items-center justify-center",children:[(0,a.jsx)(n.BK,{size:24,className:"mb-2 text-text-subtle"}),(0,a.jsx)("p",{className:"text-sm",children:"No active sessions found"})]}),e.map(e=>{let t=m(e);return(0,a.jsxs)("div",{className:"card-glass overflow-hidden text-sm",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between px-3.5 py-2.5 bg-surface-2/60 border-b border-border-subtle",children:[(0,a.jsxs)("div",{className:"flex items-center gap-2 min-w-0",children:[(0,a.jsx)("span",{className:"relative flex h-2 w-2",children:t?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("span",{className:"animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"}),(0,a.jsx)("span",{className:"relative inline-flex rounded-full h-2 w-2 bg-emerald-500"})]}):(0,a.jsx)("span",{className:"inline-block w-2 h-2 rounded-full bg-neutral-500/40"})}),(0,a.jsx)("span",{className:"font-mono text-xs font-semibold tracking-tight text-text truncate",children:e.machineId})]}),i&&(0,a.jsx)("button",{onClick:()=>r(e.machineId),className:"text-text-muted hover:text-danger p-1 rounded hover:bg-red-500/10 transition-colors",title:"Delete session",children:(0,a.jsx)(n.TB,{size:15})})]}),(0,a.jsxs)("div",{className:"p-3.5 space-y-2 text-xs",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsx)("span",{className:"text-text-muted",children:"Loyalty"}),(0,a.jsx)(b,{session:e})]}),(0,a.jsxs)("div",{className:"grid grid-cols-2 gap-2 pt-1 border-t border-border-subtle/40",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("span",{className:"text-[10px] uppercase font-mono text-text-subtle block",children:"Public IP"}),(0,a.jsx)("span",{className:"font-mono text-text truncate block",children:e.publicIp||"-"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("span",{className:"text-[10px] uppercase font-mono text-text-subtle block",children:"Local IP"}),(0,a.jsx)("span",{className:"font-mono text-text truncate block",children:e.localIp||"-"})]})]}),(0,a.jsxs)("div",{className:"grid grid-cols-2 gap-2 pt-1 border-t border-border-subtle/40 text-[11px] text-text-muted",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("span",{className:"text-text-subtle block",children:"Created"}),(0,a.jsx)("span",{children:u(e.createdAt)})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("span",{className:"text-text-subtle block",children:"Last Access"}),(0,a.jsx)("span",{className:"text-text",children:u(e.lastAccessAt)})]})]})]})]},e.machineId)})]}),(0,a.jsx)("div",{className:"hidden md:block card-glass overflow-hidden",children:(0,a.jsxs)("table",{className:"w-full text-sm text-left",children:[(0,a.jsx)("thead",{className:"bg-surface-2/60 border-b border-border-subtle text-[11px] font-mono uppercase tracking-wider text-text-muted",children:(0,a.jsxs)("tr",{children:[(0,a.jsx)("th",{className:"px-4 py-3 w-12 text-center",children:"Live"}),(0,a.jsx)("th",{className:"px-4 py-3",children:"Loyalty"}),o.map(e=>(0,a.jsx)("th",{onClick:()=>{var a;return e.sortable&&(a=e.key,void(d.GS.includes(a)&&(t===a?l(a,"asc"===s?"desc":"asc"):l(a,"desc"))))},className:`px-4 py-3 ${e.sortable?"cursor-pointer hover:text-text select-none group":""}`,children:(0,a.jsxs)("span",{className:"inline-flex items-center gap-1.5",children:[e.label,e.sortable&&(0,a.jsx)("span",{className:t===e.key?"text-brand-500":"text-text-subtle opacity-40 group-hover:opacity-100",children:t===e.key&&"asc"===s?(0,a.jsx)(n.Do,{size:12}):(0,a.jsx)(n.yd,{size:12})})]})},e.key)),i&&(0,a.jsx)("th",{className:"px-4 py-3 text-right",children:"Action"})]})}),(0,a.jsxs)("tbody",{className:"divide-y divide-border-subtle/50",children:[0===e.length&&(0,a.jsx)("tr",{children:(0,a.jsxs)("td",{colSpan:o.length+3,className:"px-4 py-12 text-center text-text-muted",children:[(0,a.jsx)(n.BK,{size:28,className:"mx-auto mb-2 text-text-subtle"}),(0,a.jsx)("p",{children:"No active sessions found"})]})}),e.map(e=>{let t=m(e);return(0,a.jsxs)("tr",{className:"hover:bg-surface-2/40 transition-colors",children:[(0,a.jsx)("td",{className:"px-4 py-3 text-center",children:(0,a.jsx)("span",{className:"relative inline-flex h-2 w-2",children:t?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("span",{className:"animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"}),(0,a.jsx)("span",{className:"relative inline-flex rounded-full h-2 w-2 bg-emerald-500"})]}):(0,a.jsx)("span",{className:"inline-block w-2 h-2 rounded-full bg-neutral-500/40"})})}),(0,a.jsx)("td",{className:"px-4 py-3",children:(0,a.jsx)(b,{session:e})}),(0,a.jsx)("td",{className:"px-4 py-3 font-mono text-xs font-medium text-text",children:e.machineId}),(0,a.jsx)("td",{className:"px-4 py-3 font-mono text-xs text-text-muted",children:e.publicIp||"-"}),(0,a.jsx)("td",{className:"px-4 py-3 font-mono text-xs text-text-muted",children:e.localIp||"-"}),(0,a.jsx)("td",{className:"px-4 py-3 text-xs text-text-muted",children:u(e.createdAt)}),(0,a.jsx)("td",{className:"px-4 py-3 text-xs text-text font-medium",children:u(e.lastAccessAt)}),(0,a.jsx)("td",{className:"px-4 py-3 text-xs text-text-muted",children:u(e.expiresAt)}),i&&(0,a.jsx)("td",{className:"px-4 py-3 text-right",children:(0,a.jsx)("button",{onClick:()=>r(e.machineId),className:"text-text-muted hover:text-danger p-1.5 rounded-lg hover:bg-red-500/10 transition-colors",title:"Delete session",children:(0,a.jsx)(n.TB,{size:15})})})]},e.machineId)})]})]})})]})}function p({page:e,pageSize:t,total:s,onPageChange:l,onPageSizeChange:r}){let i=Math.max(1,Math.ceil(s/t));return(0,a.jsxs)("div",{className:"flex flex-wrap items-center justify-between gap-3 mt-4 text-xs text-text-muted",children:[(0,a.jsxs)("div",{className:"flex items-center gap-1.5 font-mono",children:[(0,a.jsx)("span",{children:"Total:"}),(0,a.jsx)("span",{className:"text-text font-semibold px-1.5 py-0.5 rounded bg-surface-2 border border-border-subtle",children:s})]}),(0,a.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,a.jsx)("select",{value:t,onChange:e=>r(parseInt(e.target.value,10)),className:"bg-surface-2 border border-border-subtle rounded-lg px-2.5 py-1 text-text text-xs focus:outline-none",children:d.xp.map(e=>(0,a.jsxs)("option",{value:e,children:[e," / page"]},e))}),(0,a.jsxs)("div",{className:"flex items-center gap-1",children:[(0,a.jsx)("button",{onClick:()=>l(Math.max(1,e-1)),disabled:e<=1,className:"p-1.5 rounded-lg bg-surface-2 hover:bg-surface-3 border border-border-subtle text-text disabled:opacity-30 disabled:cursor-not-allowed transition-colors","aria-label":"Previous page",children:(0,a.jsx)(n.JG,{size:14})}),(0,a.jsxs)("span",{className:"px-2.5 py-1 font-mono text-xs text-text",children:[e," / ",i]}),(0,a.jsx)("button",{onClick:()=>l(Math.min(i,e+1)),disabled:e>=i,className:"p-1.5 rounded-lg bg-surface-2 hover:bg-surface-3 border border-border-subtle text-text disabled:opacity-30 disabled:cursor-not-allowed transition-colors","aria-label":"Next page",children:(0,a.jsx)(n.c_,{size:14})})]})]})]})}var f=s(68795),g=s(4655);function j(){let{can:e,me:t,loading:s}=(0,g.b)(),{get:i,del:o}=(0,f.Z)(),[x,m]=(0,l.useState)(null),[u,b]=(0,l.useState)([]),[j,N]=(0,l.useState)(0),[v,y]=(0,l.useState)(""),[w,k]=(0,l.useState)("lastAccessAt"),[A,C]=(0,l.useState)("desc"),[S,z]=(0,l.useState)(1),[I,P]=(0,l.useState)(d.Wm),[M,T]=(0,l.useState)(!1),D=(0,l.useCallback)(async()=>{T(!0);try{let e=new URLSearchParams({search:v,sortBy:w,order:A,page:String(S),pageSize:String(I)}),[t,s]=await Promise.all([i(`${d.lb.sessions}?${e.toString()}`),i(d.lb.stats)]);b(t.items||[]),N(t.total||0),m(s)}catch(e){console.error(e)}finally{T(!1)}},[i,v,w,A,S,I]);(0,l.useEffect)(()=>{!s&&t&&D()},[s,t,D]);let $=async e=>{confirm(`Delete session ${e}?`)&&(await o(`${d.lb.sessions}/${e}`),D())};return(0,a.jsx)(r.A,{children:(0,a.jsxs)("div",{className:"space-y-8",children:[(0,a.jsxs)("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h1",{className:"text-xl font-bold tracking-tight text-text",children:"System Overview"}),(0,a.jsx)("p",{className:"text-xs text-text-muted mt-1",children:"Real-time telemetry and active host instances"})]}),(0,a.jsxs)("button",{onClick:D,disabled:M,className:"self-start sm:self-auto inline-flex items-center gap-2 px-3.5 py-1.5 rounded-xl bg-surface-2 hover:bg-surface-3 border border-border-subtle text-xs font-medium text-text transition-colors disabled:opacity-50",children:[(0,a.jsx)(n.e9,{size:13,className:M?"animate-spin text-brand-500":""}),(0,a.jsx)("span",{children:"Refresh"})]})]}),(0,a.jsx)("section",{children:(0,a.jsx)(c,{stats:x})}),(0,a.jsxs)("section",{className:"space-y-4",children:[(0,a.jsxs)("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h2",{className:"text-base font-bold tracking-tight text-text",children:"User Activity"}),(0,a.jsx)("p",{className:"text-xs text-text-muted",children:"Connected and registered client sessions"})]}),(0,a.jsxs)("div",{className:"relative w-full sm:w-80",children:[(0,a.jsx)(n.vj,{size:15,className:"absolute left-3.5 top-1/2 -translate-y-1/2 text-text-muted"}),(0,a.jsx)("input",{value:v,onChange:e=>{y(e.target.value),z(1)},placeholder:"Search machineId, IP address...",className:"w-full pl-9 pr-3.5 py-2 bg-surface-2/80 border border-border-subtle rounded-xl text-text text-xs placeholder:text-text-subtle focus:outline-none focus:ring-2 focus:ring-brand-500/30 focus:border-brand-500/40 transition-all font-mono"})]})]}),(0,a.jsx)(h,{items:u,sortBy:w,order:A,onSortChange:(e,t)=>{k(e),C(t),z(1)},onDelete:$,canDelete:e(d.Jj.sessionDelete)}),(0,a.jsx)(p,{page:S,pageSize:I,total:j,onPageChange:z,onPageSizeChange:e=>{P(e),z(1)}})]})]})})}},14337:(e,t,s)=>{"use strict";s.d(t,{A:()=>l});var a=s(54568);function l({size:e="md",text:t,className:s=""}){return(0,a.jsxs)("div",{className:`flex flex-col items-center justify-center gap-3 ${s}`,children:[(0,a.jsx)("div",{className:`animate-spin rounded-full border-brand-500 border-t-transparent ${{sm:"h-4 w-4 border-2",md:"h-8 w-8 border-2",lg:"h-12 w-12 border-b-2"}[e]}`}),t&&(0,a.jsx)("p",{className:"text-brand-500 text-sm font-medium",children:t})]})}},45256:(e,t,s)=>{"use strict";s.d(t,{A:()=>h});var a=s(54568),l=s(14916),r=s(7620),n=s(65587),i=s(79748),c=s(14337),d=s(51467),o=s(46891),x=s(39634),m=s(96605),u=s(4655);let b=[{href:"/admin",label:"Dashboard",icon:m.Hx,exact:!0},{href:"/admin/access",label:"Access",icon:m.zW},{href:"/admin/ota",label:"OTA Updates",icon:m.lP,needsOta:!0},{href:"/admin/turn",label:"TURN Keys",icon:m.kV}];function h({children:e}){let t=(0,i.usePathname)(),{me:s,loading:p,logout:f}=(0,u.b)(),[g,j]=(0,r.useState)(!1);if(p||!s)return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(x.A,{}),(0,a.jsx)(d.A,{children:(0,a.jsx)("div",{className:"card-glass p-8 max-w-sm w-full flex flex-col items-center justify-center",children:(0,a.jsx)(c.A,{size:"lg",text:"Loading admin..."})})})]});let N=(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"p-4 border-b border-border-subtle flex items-center justify-between gap-3",children:[(0,a.jsxs)("div",{className:"flex items-center gap-2.5 min-w-0",children:[(0,a.jsx)("div",{className:"w-6 h-6 shrink-0 rounded-md flex items-center justify-center font-bold text-sm bg-brand-500 text-white",children:"9"}),(0,a.jsxs)("div",{className:"min-w-0",children:[(0,a.jsx)("h1",{className:"text-sm font-bold tracking-tight text-text truncate",children:"9Remote Admin"}),(0,a.jsxs)("div",{className:"flex items-center gap-1.5 mt-0.5",children:[(0,a.jsx)("span",{className:"text-xs text-text-muted truncate",children:s.username}),(0,a.jsx)("span",{className:"text-[10px] font-mono px-1.5 py-0.5 rounded-full bg-surface-2 text-text-muted border border-border-subtle",children:s.modeName||s.modeId})]})]})]}),(0,a.jsx)("button",{onClick:()=>j(!1),className:"md:hidden p-1.5 -mr-1.5 text-text-muted hover:text-text rounded-[6px] hover:bg-surface-2 transition-colors","aria-label":"Close menu",children:(0,a.jsx)(m.X,{size:18})})]}),(0,a.jsxs)("nav",{className:"flex-1 px-3.5 py-3 space-y-0.5 overflow-y-auto",children:[(0,a.jsx)("div",{className:"pl-[3.5px] py-1.5 text-[10px] font-mono uppercase tracking-wider text-text-subtle",children:"Navigation"}),b.filter(e=>!e.needsOta||s.otaEnabled).map(e=>{let s=e.icon,l=e.exact?t===e.href:t.startsWith(e.href);return(0,a.jsxs)(n,{href:e.href,onClick:()=>j(!1),className:`
2
- flex items-center gap-2.5 -ml-3.5 w-[calc(100%+0.875rem)] pl-[17px] pr-3 py-1.5
3
- rounded-[6px] text-xs font-medium text-left transition-colors duration-150
4
- ${l?"bg-surface-3 text-text font-semibold":"text-text-muted hover:bg-surface-2 hover:text-text"}
5
- `,children:[(0,a.jsx)(s,{size:15,className:l?"text-text":"text-text-subtle"}),(0,a.jsx)("span",{className:"flex-1",children:e.label}),l&&(0,a.jsx)("span",{className:"w-1 h-1 rounded-full bg-text-muted"})]},e.href)})]}),(0,a.jsx)("div",{className:"p-3.5 border-t border-border-subtle",children:(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)(o.A,{className:"border border-border-subtle hover:bg-surface-2 rounded-[6px]"}),(0,a.jsxs)("button",{onClick:f,className:"flex-1 flex items-center justify-center gap-2 px-3 py-1.5 rounded-[6px] text-xs font-medium text-text-muted hover:bg-red-500/10 hover:text-danger transition-colors",children:[(0,a.jsx)(m.nU,{size:15}),"Logout"]})]})})]});return(0,a.jsxs)("div",{className:"jsx-b56c084163c9c8c1 min-h-screen text-text relative selection:bg-brand-500/20",children:[(0,a.jsx)(x.A,{}),(0,a.jsxs)("header",{className:"jsx-b56c084163c9c8c1 md:hidden sticky top-0 z-30 flex items-center justify-between px-4 py-2.5 bg-surface/80 backdrop-blur-md border-b border-border-subtle",children:[(0,a.jsx)("button",{onClick:()=>j(!0),"aria-label":"Open menu",className:"jsx-b56c084163c9c8c1 p-1.5 -ml-1.5 text-text-muted hover:text-text rounded-[6px] hover:bg-surface-2",children:(0,a.jsx)(m.W1,{size:20})}),(0,a.jsxs)("div",{className:"jsx-b56c084163c9c8c1 flex items-center gap-2",children:[(0,a.jsx)("div",{className:"jsx-b56c084163c9c8c1 w-6 h-6 rounded-md flex items-center justify-center font-bold text-xs bg-brand-500 text-white",children:"9"}),(0,a.jsx)("h1",{className:"jsx-b56c084163c9c8c1 text-sm font-semibold tracking-tight",children:"9Remote Admin"})]}),(0,a.jsx)(o.A,{className:"rounded-[6px]"})]}),(0,a.jsx)("aside",{className:"jsx-b56c084163c9c8c1 hidden md:flex fixed inset-y-0 left-0 w-60 border-r border-border-subtle bg-surface/80 backdrop-blur-xl flex-col z-20",children:N}),g&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("div",{onClick:()=>j(!1),className:"jsx-b56c084163c9c8c1 md:hidden fixed inset-0 z-40 bg-black/60 backdrop-blur-[2px] fade-in"}),(0,a.jsx)("aside",{style:{animation:"slideInFromLeft 0.22s cubic-bezier(0.22, 1, 0.36, 1) forwards"},className:"jsx-b56c084163c9c8c1 md:hidden fixed inset-y-0 left-0 z-50 w-72 max-w-[85%] bg-surface/95 backdrop-blur-2xl border-r border-border-subtle flex flex-col slide-in-right",children:N})]}),(0,a.jsx)("main",{className:"jsx-b56c084163c9c8c1 md:ml-60 p-4 sm:p-6 lg:p-8 min-h-screen relative z-10 max-w-7xl",children:e}),(0,a.jsx)(l,{id:"b56c084163c9c8c1",children:"@keyframes slideInFromLeft{from{transform:translatex(-100%);opacity:0}to{transform:translatex(0);opacity:1}}"})]})}},51467:(e,t,s)=>{"use strict";s.d(t,{A:()=>l});var a=s(54568);function l({children:e,centered:t=!0,className:s=""}){return(0,a.jsx)("div",{className:`min-h-screen ${t?"flex items-center justify-center p-4":""} ${s}`,children:e})}},68795:(e,t,s)=>{"use strict";s.d(t,{Z:()=>r});var a=s(7620);async function l(e,t={}){let s=await fetch(e,{...t,headers:{"Content-Type":"application/json",...t.headers||{}},credentials:"include"}),a=await s.json().catch(()=>({}));if(!s.ok)throw Error(a?.error||`Request failed (${s.status})`);return a}function r(){let e=(0,a.useCallback)(e=>l(e),[]),t=(0,a.useCallback)((e,t)=>l(e,{method:"POST",body:JSON.stringify(t||{})}),[]);return{get:e,post:t,patch:(0,a.useCallback)((e,t)=>l(e,{method:"PATCH",body:JSON.stringify(t||{})}),[]),del:(0,a.useCallback)(e=>l(e,{method:"DELETE"}),[])}}},78864:(e,t,s)=>{"use strict";s.d(t,{GS:()=>d,Jj:()=>a,Qh:()=>n,WD:()=>l,Wm:()=>i,lb:()=>x,rK:()=>o,vq:()=>r,xp:()=>c});let a={sessionView:"session.view",sessionDelete:"session.delete",modeView:"mode.view",modeManage:"mode.manage",adminView:"admin.view",adminManage:"admin.manage",otaView:"ota.view",otaManage:"ota.manage",turnView:"turn.view",turnManage:"turn.manage",logView:"log.view"};Object.values(a);let l={"session.view":"View sessions","session.delete":"Delete sessions","admin.view":"View admins","admin.manage":"Create/edit admins","mode.view":"View modes","mode.manage":"Create/edit modes","ota.view":"View OTA updates","ota.manage":"Manage OTA updates","turn.view":"View TURN keys","turn.manage":"Manage TURN keys","log.view":"View login audit"},r=[{label:"Sessions",keys:["session.view","session.delete"]},{label:"Admins",keys:["admin.view","admin.manage"]},{label:"Modes",keys:["mode.view","mode.manage"]},{label:"OTA & TURN",keys:["ota.view","ota.manage","turn.view","turn.manage"]},{label:"Audit",keys:["log.view"]}],n=18e5,i=20,c=[10,20,50,100],d=["createdAt","lastAccessAt","expiresAt","machineId"],o=[{key:"loyal",label:"Loyal",minMs:6048e5,color:"text-success"},{key:"returning",label:"Returning",minMs:864e5,color:"text-brand-500"},{key:"active",label:"Active",minMs:3e5,color:"text-brand-400"},{key:"new",label:"New",minMs:0,color:"text-text-muted"}],x={login:"/api/admin/login",logout:"/api/admin/logout",me:"/api/admin/me",sessions:"/api/admin/sessions",stats:"/api/admin/stats",modes:"/api/admin/modes",admins:"/api/admin/admins",ota:"/api/admin/ota",turn:"/api/admin/turn",logins:"/api/admin/logins",turnstile:"/api/admin/turnstile"}},79748:(e,t,s)=>{"use strict";var a=s(79796);s.o(a,"usePathname")&&s.d(t,{usePathname:function(){return a.usePathname}}),s.o(a,"useRouter")&&s.d(t,{useRouter:function(){return a.useRouter}}),s.o(a,"useSearchParams")&&s.d(t,{useSearchParams:function(){return a.useSearchParams}})},83741:(e,t,s)=>{Promise.resolve().then(s.bind(s,8891))}},e=>{e.O(0,[820,5587,1772,556,587,1968,7358],()=>e(e.s=83741)),_N_E=e.O()}]);
@@ -1,5 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[540],{4655:(e,t,s)=>{"use strict";s.d(t,{b:()=>d});var a=s(7620),r=s(79748),l=s(78864),n=s(68795);function d({redirectIfUnauthed:e=!0}={}){let t=(0,r.useRouter)(),{get:s,post:i}=(0,n.Z)(),[c,o]=(0,a.useState)(null),[x,m]=(0,a.useState)(!0),u=(0,a.useCallback)(async()=>{try{let e=await s(l.lb.me);o(e)}catch{o(null),e&&t.replace("/admin/login")}finally{m(!1)}},[s,e,t]);(0,a.useEffect)(()=>{u()},[u]);let b=(0,a.useCallback)(async()=>{await i(l.lb.logout,{}),t.replace("/admin/login")},[i,t]),h=(0,a.useCallback)(e=>Array.isArray(c?.permissions)&&c.permissions.includes(e),[c]);return{me:c,loading:x,logout:b,can:h,refresh:u}}},14337:(e,t,s)=>{"use strict";s.d(t,{A:()=>r});var a=s(54568);function r({size:e="md",text:t,className:s=""}){return(0,a.jsxs)("div",{className:`flex flex-col items-center justify-center gap-3 ${s}`,children:[(0,a.jsx)("div",{className:`animate-spin rounded-full border-brand-500 border-t-transparent ${{sm:"h-4 w-4 border-2",md:"h-8 w-8 border-2",lg:"h-12 w-12 border-b-2"}[e]}`}),t&&(0,a.jsx)("p",{className:"text-brand-500 text-sm font-medium",children:t})]})}},14974:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>b});var a=s(54568),r=s(7620),l=s(45256),n=s(56156),d=s(26784),i=s(96605),c=s(68795),o=s(4655),x=s(78864);let m={keyId:"",secret:"",label:"",scope:"both"},u=["both","dev","prod"];function b(){let{can:e,me:t,loading:s}=(0,o.b)(),{get:b,post:h,patch:p,del:f}=(0,c.Z)(),[g,j]=(0,r.useState)([]),[y,N]=(0,r.useState)(m),[v,w]=(0,r.useState)(!0),[k,C]=(0,r.useState)(!1),[A,S]=(0,r.useState)(""),[T,z]=(0,r.useState)(null),R=e(x.Jj.turnManage),$=(0,r.useCallback)(async()=>{w(!0);try{let e=await b(x.lb.turn);j(e.items||[])}catch(e){S(e.message)}finally{w(!1)}},[b]);(0,r.useEffect)(()=>{!s&&t&&$()},[s,t,$]);let U=async()=>{S(""),C(!0),z(null);try{await h(x.lb.turn,y),z(y.secret),N(m),await $()}catch(e){S(e.message)}finally{C(!1)}},V=async e=>{try{await p(`${x.lb.turn}/${e.id}`,{enabled:!e.enabled}),$()}catch(e){S(e.message)}},D=async(e,t)=>{try{await p(`${x.lb.turn}/${e.id}`,{scope:t}),$()}catch(e){S(e.message)}},O=async e=>{if(confirm("Delete this TURN key? Clients using it fall back to STUN-only."))try{await f(`${x.lb.turn}/${e}`),$()}catch(e){S(e.message)}};return(0,a.jsx)(l.A,{children:(0,a.jsxs)("div",{className:"space-y-8 max-w-5xl",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsxs)("div",{children:[(0,a.jsxs)("h1",{className:"text-2xl font-bold tracking-tight text-text login-hero-grad flex items-center gap-2.5",children:[(0,a.jsx)(i.kV,{size:24,className:"text-brand-500"}),(0,a.jsx)("span",{children:"TURN Keys"})]}),(0,a.jsx)("p",{className:"text-xs text-text-muted mt-1",children:"Rotate Cloudflare TURN credentials for cross-network WebRTC relay"})]}),(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsxs)("a",{href:"https://dash.cloudflare.com/?to=/:account/realtime/turn",target:"_blank",rel:"noreferrer noopener",className:"inline-flex items-center gap-2 px-3.5 py-1.5 rounded-xl bg-brand-500 hover:bg-brand-600 text-white text-xs font-semibold transition-colors shadow-[0_4px_12px_-4px_rgba(255,87,10,0.5)]",children:[(0,a.jsx)(i.Gr,{size:13}),(0,a.jsx)("span",{children:"Create on Cloudflare"})]}),(0,a.jsxs)("button",{onClick:$,disabled:v,className:"inline-flex items-center gap-2 px-3.5 py-1.5 rounded-xl bg-surface-2 hover:bg-surface-3 border border-border-subtle text-xs font-medium text-text transition-colors disabled:opacity-50",children:[(0,a.jsx)(i.e9,{size:13,className:v?"animate-spin text-brand-500":""}),(0,a.jsx)("span",{children:"Refresh"})]})]})]}),(0,a.jsx)("p",{className:"text-xs text-text-muted bg-surface-2/60 border border-border-subtle rounded-xl p-3",children:"Up to 1,000 keys. 1,000 GB/month free per Cloudflare account (shared with SFU) — more keys do not add quota."}),A&&(0,a.jsx)("p",{className:"text-xs text-danger bg-red-500/10 p-3 rounded-xl border border-red-500/20",children:A}),T&&(0,a.jsxs)("div",{className:"card-glass p-4 space-y-2 border border-brand-500/30",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsx)("span",{className:"text-xs font-semibold text-text",children:"Key added — secret stored. Copy it if you need it elsewhere:"}),(0,a.jsx)("button",{onClick:()=>z(null),className:"text-text-muted hover:text-text",children:(0,a.jsx)(i.X,{size:14})})]}),(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)("code",{className:"flex-1 text-[11px] font-mono text-text-muted bg-surface-2 rounded-lg px-3 py-2 break-all",children:T}),(0,a.jsx)("button",{onClick:()=>navigator.clipboard?.writeText(T),className:"p-2 rounded-lg bg-surface-2 hover:bg-surface-3 text-text-muted hover:text-text transition-colors","aria-label":"Copy secret",children:(0,a.jsx)(i.QR,{size:14})})]})]}),R&&(0,a.jsxs)("div",{className:"card-glass p-5 sm:p-6 space-y-4",children:[(0,a.jsxs)("h2",{className:"text-sm font-semibold tracking-tight text-text flex items-center gap-2 border-b border-border-subtle/60 pb-3",children:[(0,a.jsx)(i.FW,{size:16,className:"text-brand-500"}),(0,a.jsx)("span",{children:"Add TURN Key"})]}),(0,a.jsxs)("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[(0,a.jsx)(d.A,{label:"Key ID",value:y.keyId,onChange:e=>N({...y,keyId:e.target.value.trim()}),placeholder:"32-char hex from Cloudflare dashboard"}),(0,a.jsx)(d.A,{label:"API Token / Secret",type:"password",value:y.secret,onChange:e=>N({...y,secret:e.target.value.trim()}),placeholder:"Bearer secret"}),(0,a.jsx)(d.A,{label:"Label",value:y.label,onChange:e=>N({...y,label:e.target.value}),placeholder:"e.g. acc-1 (which Cloudflare account)"}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-xs font-mono uppercase tracking-wider text-text-muted mb-1.5",children:"Scope"}),(0,a.jsx)("select",{className:"w-full px-3 py-2 text-xs border border-border-subtle rounded-xl bg-surface-2/80 text-text focus:outline-none focus:ring-2 focus:ring-brand-500/30",value:y.scope,onChange:e=>N({...y,scope:e.target.value}),children:u.map(e=>(0,a.jsx)("option",{value:e,children:e},e))})]})]}),(0,a.jsxs)("div",{className:"flex items-center gap-3",children:[(0,a.jsx)(n.A,{onClick:U,disabled:k||!y.keyId||!y.secret,children:k?"Validating with Cloudflare...":"Add Key"}),(0,a.jsxs)("span",{className:"text-xs text-text-muted",children:["Scope ",(0,a.jsx)("span",{className:"font-mono",children:"dev"})," = credentials for pages on dev.9remote.cc only."]})]})]}),v?(0,a.jsxs)("div",{className:"card-glass p-12 text-center text-text-muted text-xs",children:[(0,a.jsx)(i.e9,{size:20,className:"mx-auto mb-2 animate-spin text-brand-500"}),"Loading keys..."]}):0===g.length?(0,a.jsxs)("div",{className:"card-glass p-12 text-center",children:[(0,a.jsx)("div",{className:"w-12 h-12 rounded-2xl bg-surface-2 flex items-center justify-center mx-auto mb-3 text-text-subtle",children:(0,a.jsx)(i.kV,{size:24})}),(0,a.jsx)("h3",{className:"text-sm font-semibold text-text",children:"No TURN keys configured"}),(0,a.jsxs)("p",{className:"text-text-muted text-xs mt-1",children:["Clients fall back to the deployed ",(0,a.jsx)("code",{className:"font-mono text-brand-500",children:"TURN_KEY_ID"})," secret, or STUN-only if that is gone."]})]}):(0,a.jsx)("div",{className:"card-glass overflow-x-auto",children:(0,a.jsxs)("table",{className:"w-full text-sm text-left",children:[(0,a.jsx)("thead",{className:"bg-surface-2/60 border-b border-border-subtle text-[11px] font-mono uppercase tracking-wider text-text-muted",children:(0,a.jsxs)("tr",{children:[(0,a.jsx)("th",{className:"px-4 py-3",children:"Key"}),(0,a.jsx)("th",{className:"px-4 py-3",children:"Scope"}),(0,a.jsx)("th",{className:"px-4 py-3",children:"Last Used"}),(0,a.jsx)("th",{className:"px-4 py-3",children:"Status"}),R&&(0,a.jsx)("th",{className:"px-4 py-3 text-right",children:"Actions"})]})}),(0,a.jsx)("tbody",{className:"divide-y divide-border-subtle/50",children:g.map(e=>(0,a.jsxs)("tr",{className:"hover:bg-surface-2/40 transition-colors",children:[(0,a.jsxs)("td",{className:"px-4 py-3.5",children:[(0,a.jsxs)("div",{className:"font-mono text-xs text-text",children:[e.keyId.slice(0,12),"…"]}),(0,a.jsxs)("div",{className:"text-[10px] text-text-subtle font-mono mt-0.5",children:[e.label||"(no label)"," \xb7 secret ",e.secretTail]})]}),(0,a.jsx)("td",{className:"px-4 py-3.5",children:R?(0,a.jsx)("select",{className:"px-2 py-1 text-[11px] font-mono border border-border-subtle rounded-lg bg-surface-2/80 text-text focus:outline-none",value:e.scope,onChange:t=>D(e,t.target.value),children:u.map(e=>(0,a.jsx)("option",{value:e,children:e},e))}):(0,a.jsx)("span",{className:"px-2 py-0.5 rounded-full text-xs font-mono bg-surface-2 border border-border-subtle text-text",children:e.scope})}),(0,a.jsx)("td",{className:"px-4 py-3.5 text-xs text-text-muted font-mono",children:(e=>{if(!e)return"never";try{return new Date(e).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return e}})(e.lastUsedAt)}),(0,a.jsx)("td",{className:"px-4 py-3.5",children:e.enabled?(0,a.jsxs)("span",{className:"inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium bg-emerald-500/10 text-emerald-500 border border-emerald-500/20",children:[(0,a.jsx)(i.aJ,{size:13}),(0,a.jsx)("span",{children:"Active"})]}):(0,a.jsx)("span",{className:"text-xs font-mono text-text-subtle px-2 py-0.5 rounded bg-surface-2",children:"Disabled"})}),R&&(0,a.jsxs)("td",{className:"px-4 py-3.5 text-right whitespace-nowrap",children:[(0,a.jsx)("button",{onClick:()=>V(e),className:"text-xs font-semibold text-brand-500 hover:text-brand-400 px-2.5 py-1 rounded-lg hover:bg-brand-500/10 transition-colors",children:e.enabled?"Disable":"Enable"}),(0,a.jsx)("button",{onClick:()=>O(e.id),className:"ml-1 p-1.5 rounded-lg text-text-muted hover:text-danger hover:bg-red-500/10 transition-colors","aria-label":"Delete key",children:(0,a.jsx)(i.TB,{size:14})})]})]},e.id))})]})})]})})}},26784:(e,t,s)=>{"use strict";s.d(t,{A:()=>r});var a=s(54568);function r({label:e,type:t="text",value:s,onChange:l,onKeyDown:n,placeholder:d,disabled:i=!1,error:c,className:o="",...x}){let m=c?"ring-1 ring-red-500 focus:ring-2 focus:ring-red-500":"focus:ring-2 focus:ring-brand-500/40",u=`w-full px-4 py-3 bg-surface-2 rounded-brand text-text placeholder-text-muted focus:outline-none transition-all duration-150 ease-out ${m} ${i?"opacity-50 cursor-not-allowed":""} ${o}`;return(0,a.jsxs)("div",{className:"w-full",children:[e&&(0,a.jsx)("label",{className:"block text-sm font-medium text-text mb-2",children:e}),(0,a.jsx)("input",{type:t,value:s,onChange:l,onKeyDown:n,placeholder:d,disabled:i,className:u,...x}),c&&(0,a.jsx)("p",{className:"mt-1 text-sm text-red-400",children:c})]})}},45256:(e,t,s)=>{"use strict";s.d(t,{A:()=>h});var a=s(54568),r=s(14916),l=s(7620),n=s(65587),d=s(79748),i=s(14337),c=s(51467),o=s(46891),x=s(39634),m=s(96605),u=s(4655);let b=[{href:"/admin",label:"Dashboard",icon:m.Hx,exact:!0},{href:"/admin/access",label:"Access",icon:m.zW},{href:"/admin/ota",label:"OTA Updates",icon:m.lP,needsOta:!0},{href:"/admin/turn",label:"TURN Keys",icon:m.kV}];function h({children:e}){let t=(0,d.usePathname)(),{me:s,loading:p,logout:f}=(0,u.b)(),[g,j]=(0,l.useState)(!1);if(p||!s)return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(x.A,{}),(0,a.jsx)(c.A,{children:(0,a.jsx)("div",{className:"card-glass p-8 max-w-sm w-full flex flex-col items-center justify-center",children:(0,a.jsx)(i.A,{size:"lg",text:"Loading admin..."})})})]});let y=(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"p-4 border-b border-border-subtle flex items-center justify-between gap-3",children:[(0,a.jsxs)("div",{className:"flex items-center gap-2.5 min-w-0",children:[(0,a.jsx)("div",{className:"w-6 h-6 shrink-0 rounded-md flex items-center justify-center font-bold text-sm bg-brand-500 text-white",children:"9"}),(0,a.jsxs)("div",{className:"min-w-0",children:[(0,a.jsx)("h1",{className:"text-sm font-bold tracking-tight text-text truncate",children:"9Remote Admin"}),(0,a.jsxs)("div",{className:"flex items-center gap-1.5 mt-0.5",children:[(0,a.jsx)("span",{className:"text-xs text-text-muted truncate",children:s.username}),(0,a.jsx)("span",{className:"text-[10px] font-mono px-1.5 py-0.5 rounded-full bg-surface-2 text-text-muted border border-border-subtle",children:s.modeName||s.modeId})]})]})]}),(0,a.jsx)("button",{onClick:()=>j(!1),className:"md:hidden p-1.5 -mr-1.5 text-text-muted hover:text-text rounded-[6px] hover:bg-surface-2 transition-colors","aria-label":"Close menu",children:(0,a.jsx)(m.X,{size:18})})]}),(0,a.jsxs)("nav",{className:"flex-1 px-3.5 py-3 space-y-0.5 overflow-y-auto",children:[(0,a.jsx)("div",{className:"pl-[3.5px] py-1.5 text-[10px] font-mono uppercase tracking-wider text-text-subtle",children:"Navigation"}),b.filter(e=>!e.needsOta||s.otaEnabled).map(e=>{let s=e.icon,r=e.exact?t===e.href:t.startsWith(e.href);return(0,a.jsxs)(n,{href:e.href,onClick:()=>j(!1),className:`
2
- flex items-center gap-2.5 -ml-3.5 w-[calc(100%+0.875rem)] pl-[17px] pr-3 py-1.5
3
- rounded-[6px] text-xs font-medium text-left transition-colors duration-150
4
- ${r?"bg-surface-3 text-text font-semibold":"text-text-muted hover:bg-surface-2 hover:text-text"}
5
- `,children:[(0,a.jsx)(s,{size:15,className:r?"text-text":"text-text-subtle"}),(0,a.jsx)("span",{className:"flex-1",children:e.label}),r&&(0,a.jsx)("span",{className:"w-1 h-1 rounded-full bg-text-muted"})]},e.href)})]}),(0,a.jsx)("div",{className:"p-3.5 border-t border-border-subtle",children:(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)(o.A,{className:"border border-border-subtle hover:bg-surface-2 rounded-[6px]"}),(0,a.jsxs)("button",{onClick:f,className:"flex-1 flex items-center justify-center gap-2 px-3 py-1.5 rounded-[6px] text-xs font-medium text-text-muted hover:bg-red-500/10 hover:text-danger transition-colors",children:[(0,a.jsx)(m.nU,{size:15}),"Logout"]})]})})]});return(0,a.jsxs)("div",{className:"jsx-b56c084163c9c8c1 min-h-screen text-text relative selection:bg-brand-500/20",children:[(0,a.jsx)(x.A,{}),(0,a.jsxs)("header",{className:"jsx-b56c084163c9c8c1 md:hidden sticky top-0 z-30 flex items-center justify-between px-4 py-2.5 bg-surface/80 backdrop-blur-md border-b border-border-subtle",children:[(0,a.jsx)("button",{onClick:()=>j(!0),"aria-label":"Open menu",className:"jsx-b56c084163c9c8c1 p-1.5 -ml-1.5 text-text-muted hover:text-text rounded-[6px] hover:bg-surface-2",children:(0,a.jsx)(m.W1,{size:20})}),(0,a.jsxs)("div",{className:"jsx-b56c084163c9c8c1 flex items-center gap-2",children:[(0,a.jsx)("div",{className:"jsx-b56c084163c9c8c1 w-6 h-6 rounded-md flex items-center justify-center font-bold text-xs bg-brand-500 text-white",children:"9"}),(0,a.jsx)("h1",{className:"jsx-b56c084163c9c8c1 text-sm font-semibold tracking-tight",children:"9Remote Admin"})]}),(0,a.jsx)(o.A,{className:"rounded-[6px]"})]}),(0,a.jsx)("aside",{className:"jsx-b56c084163c9c8c1 hidden md:flex fixed inset-y-0 left-0 w-60 border-r border-border-subtle bg-surface/80 backdrop-blur-xl flex-col z-20",children:y}),g&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("div",{onClick:()=>j(!1),className:"jsx-b56c084163c9c8c1 md:hidden fixed inset-0 z-40 bg-black/60 backdrop-blur-[2px] fade-in"}),(0,a.jsx)("aside",{style:{animation:"slideInFromLeft 0.22s cubic-bezier(0.22, 1, 0.36, 1) forwards"},className:"jsx-b56c084163c9c8c1 md:hidden fixed inset-y-0 left-0 z-50 w-72 max-w-[85%] bg-surface/95 backdrop-blur-2xl border-r border-border-subtle flex flex-col slide-in-right",children:y})]}),(0,a.jsx)("main",{className:"jsx-b56c084163c9c8c1 md:ml-60 p-4 sm:p-6 lg:p-8 min-h-screen relative z-10 max-w-7xl",children:e}),(0,a.jsx)(r,{id:"b56c084163c9c8c1",children:"@keyframes slideInFromLeft{from{transform:translatex(-100%);opacity:0}to{transform:translatex(0);opacity:1}}"})]})}},51467:(e,t,s)=>{"use strict";s.d(t,{A:()=>r});var a=s(54568);function r({children:e,centered:t=!0,className:s=""}){return(0,a.jsx)("div",{className:`min-h-screen ${t?"flex items-center justify-center p-4":""} ${s}`,children:e})}},56156:(e,t,s)=>{"use strict";s.d(t,{A:()=>r});var a=s(54568);function r({children:e,variant:t="primary",size:s="md",disabled:l=!1,loading:n=!1,onClick:d,className:i="",...c}){let o=`font-semibold rounded-brand transition-all duration-150 ease-out transform active:scale-[0.97] ${{primary:"bg-brand-500 hover:bg-brand-600 disabled:bg-surface-3 disabled:text-text-muted text-white shadow-sm",secondary:"bg-surface-2 hover:bg-surface-3 disabled:bg-surface disabled:text-text-muted text-text",danger:"bg-red-500 hover:bg-red-600 disabled:bg-surface-3 disabled:text-text-muted text-white",success:"bg-green-600 hover:bg-green-700 disabled:bg-surface-3 disabled:text-text-muted text-white"}[t]} ${{sm:"px-3 py-1.5 text-sm",md:"px-4 py-2 text-base",lg:"px-6 py-3 text-lg"}[s]} ${l||n?"cursor-not-allowed":""} ${i}`;return(0,a.jsx)("button",{onClick:d,disabled:l||n,className:o,...c,children:n?(0,a.jsxs)("span",{className:"flex items-center justify-center gap-2",children:[(0,a.jsx)("span",{className:"animate-spin rounded-full h-4 w-4 border-b-2 border-white"}),e]}):e})}},61691:(e,t,s)=>{Promise.resolve().then(s.bind(s,14974))},68795:(e,t,s)=>{"use strict";s.d(t,{Z:()=>l});var a=s(7620);async function r(e,t={}){let s=await fetch(e,{...t,headers:{"Content-Type":"application/json",...t.headers||{}},credentials:"include"}),a=await s.json().catch(()=>({}));if(!s.ok)throw Error(a?.error||`Request failed (${s.status})`);return a}function l(){let e=(0,a.useCallback)(e=>r(e),[]),t=(0,a.useCallback)((e,t)=>r(e,{method:"POST",body:JSON.stringify(t||{})}),[]);return{get:e,post:t,patch:(0,a.useCallback)((e,t)=>r(e,{method:"PATCH",body:JSON.stringify(t||{})}),[]),del:(0,a.useCallback)(e=>r(e,{method:"DELETE"}),[])}}},78864:(e,t,s)=>{"use strict";s.d(t,{GS:()=>c,Jj:()=>a,Qh:()=>n,WD:()=>r,Wm:()=>d,lb:()=>x,rK:()=>o,vq:()=>l,xp:()=>i});let a={sessionView:"session.view",sessionDelete:"session.delete",modeView:"mode.view",modeManage:"mode.manage",adminView:"admin.view",adminManage:"admin.manage",otaView:"ota.view",otaManage:"ota.manage",turnView:"turn.view",turnManage:"turn.manage",logView:"log.view"};Object.values(a);let r={"session.view":"View sessions","session.delete":"Delete sessions","admin.view":"View admins","admin.manage":"Create/edit admins","mode.view":"View modes","mode.manage":"Create/edit modes","ota.view":"View OTA updates","ota.manage":"Manage OTA updates","turn.view":"View TURN keys","turn.manage":"Manage TURN keys","log.view":"View login audit"},l=[{label:"Sessions",keys:["session.view","session.delete"]},{label:"Admins",keys:["admin.view","admin.manage"]},{label:"Modes",keys:["mode.view","mode.manage"]},{label:"OTA & TURN",keys:["ota.view","ota.manage","turn.view","turn.manage"]},{label:"Audit",keys:["log.view"]}],n=18e5,d=20,i=[10,20,50,100],c=["createdAt","lastAccessAt","expiresAt","machineId"],o=[{key:"loyal",label:"Loyal",minMs:6048e5,color:"text-success"},{key:"returning",label:"Returning",minMs:864e5,color:"text-brand-500"},{key:"active",label:"Active",minMs:3e5,color:"text-brand-400"},{key:"new",label:"New",minMs:0,color:"text-text-muted"}],x={login:"/api/admin/login",logout:"/api/admin/logout",me:"/api/admin/me",sessions:"/api/admin/sessions",stats:"/api/admin/stats",modes:"/api/admin/modes",admins:"/api/admin/admins",ota:"/api/admin/ota",turn:"/api/admin/turn",logins:"/api/admin/logins",turnstile:"/api/admin/turnstile"}},79748:(e,t,s)=>{"use strict";var a=s(79796);s.o(a,"usePathname")&&s.d(t,{usePathname:function(){return a.usePathname}}),s.o(a,"useRouter")&&s.d(t,{useRouter:function(){return a.useRouter}}),s.o(a,"useSearchParams")&&s.d(t,{useSearchParams:function(){return a.useSearchParams}})}},e=>{e.O(0,[820,5587,1772,556,587,1968,7358],()=>e(e.s=61691)),_N_E=e.O()}]);
@@ -1 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[967],{3844:(e,A,o)=>{"use strict";o.r(A),o.d(A,{default:()=>a});var t=o(54568),i=o(40329);let n=[{question:"Which background should the pane use?",multiSelect:!1,options:[{label:"Keep the global pool",description:"Every pane follows the workspace setting."},{label:"Pin a wallpaper",description:"Only this session gets its own image."},{label:"Solid colour",description:"No image, just the theme surface."}]}],r=[{question:"Which panes should the new layout open?",multiSelect:!0,options:[{label:"Terminal",description:"A shell in the workspace root."},{label:"AI chat",description:"The agent pane for the active engine."},{label:"Files",description:"The explorer panel on the right."}]},{question:"Anything else to note?",options:[{label:"No",description:"Just open them."}]}];function a(){return(0,t.jsxs)("div",{className:"min-h-screen bg-bg p-6 flex flex-col gap-6 max-w-md",children:[(0,t.jsx)(i.J,{questions:n,onResolve:()=>{}}),(0,t.jsx)(i.J,{questions:r,onResolve:()=>{}}),(0,t.jsx)(i.J,{questions:n,answers:'User has answered your questions: "Which background should the pane use?"="Pin a wallpaper".'})]})}},14652:(e,A,o)=>{"use strict";function t(e=10){if(!window.__TAURI__){if(window.ReactNativeWebView&&/Android/i.test(navigator.userAgent)){try{window.ReactNativeWebView.postMessage(JSON.stringify({type:"HAPTIC",style:"selection"}))}catch{}return}if(navigator.vibrate)return void navigator.vibrate(e);if("u">typeof document){if(!("u">typeof navigator&&(/iPad|iPhone|iPod/.test(navigator.userAgent)||window.DEVICE_INFO?.platform==="ios"||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1)))return;let e=document.createElement("div"),A=Math.random().toString(36).slice(2);e.innerHTML=`<input type="checkbox" id="${A}" switch /><label for="${A}"></label>`,e.setAttribute("style","display:none !important;opacity:0 !important;visibility:hidden !important;"),document.body.appendChild(e),e.querySelector("label").click(),setTimeout(()=>e.remove(),100)}}}o.d(A,{e:()=>t})},93696:(e,A,o)=>{Promise.resolve().then(o.bind(o,3844))},96605:(e,A,o)=>{"use strict";o.d(A,{$o:()=>eN.A,AX:()=>ef.A,Ay:()=>Al,BK:()=>e0.A,BZ:()=>$.A,Bm:()=>J.A,Cp:()=>B.A,Do:()=>a.A,F1:()=>l.A,FE:()=>e2.A,FW:()=>eq.A,Fc:()=>eW.A,GD:()=>W.A,GO:()=>eg.A,Gr:()=>U.A,Gv:()=>eb.A,Hx:()=>en.A,Ir:()=>c.A,J4:()=>e6.A,JG:()=>m.A,JU:()=>D.A,Jl:()=>h.A,Kq:()=>Ar.A,LM:()=>es.A,Lt:()=>M.A,M6:()=>eY.A,MA:()=>s.A,Mr:()=>eE.A,P6:()=>eA.A,QR:()=>S.A,Qp:()=>r.A,RI:()=>i.A,TB:()=>e9.A,Ud:()=>Z.A,VA:()=>ew.A,Vn:()=>eB.A,W1:()=>eh.A,WE:()=>v.A,We:()=>e3.A,Wn:()=>k.A,X:()=>An.A,X_:()=>R.A,ZH:()=>_.A,ZU:()=>e8.A,Ze:()=>eT.A,Zr:()=>G.A,_O:()=>Ae.A,_V:()=>ee.A,a4:()=>ev.A,aJ:()=>u.A,ak:()=>K.A,bE:()=>e5.A,bd:()=>e1.A,cC:()=>p.A,c_:()=>w.A,dJ:()=>H.A,de:()=>Ai.A,dx:()=>V.A,e6:()=>ek.A,e9:()=>eH.A,eM:()=>eD.A,ek:()=>eK.A,es:()=>eC.A,f2:()=>X.A,f5:()=>L.A,gH:()=>eU.A,h1:()=>ed.A,iU:()=>N.A,jG:()=>e_.A,jj:()=>em.A,jl:()=>b.A,jz:()=>ex.A,kU:()=>O.A,kV:()=>eo.A,kr:()=>el.A,kt:()=>eJ.A,lM:()=>e7.A,lP:()=>eP.A,m0:()=>y.A,mN:()=>Q.A,nU:()=>ep.A,qz:()=>z.A,rX:()=>f.A,s3:()=>et.A,sU:()=>e$.A,sv:()=>j.A,ue:()=>eS.A,vR:()=>eL.A,vW:()=>ej.A,vd:()=>I.A,vj:()=>eV.A,vv:()=>er.A,wB:()=>eX.A,wO:()=>eQ.A,ww:()=>Y.A,xq:()=>eu.A,xv:()=>eF.A,y8:()=>ea.A,yQ:()=>g.A,yU:()=>eR.A,yd:()=>n.A,zP:()=>d.A,zW:()=>AA.A});var t=o(54568),i=o(14796),n=o(50683),r=o(30307),a=o(62826),l=o(22061),s=o(46480),c=o(77542),p=o(30824),d=o(8631),u=o(34309),h=o(63322),g=o(34041),m=o(8008),w=o(76265),f=o(17156),v=o(11964),b=o(21411),y=o(1173),P=o(72980),C=o(9901),k=o(3129),S=o(59706),M=o(31381),x=o(40414),F=o(91276),L=o(2099),U=o(26083),O=o(20732),R=o(69724),T=o(93675),_=o(96249),W=o(36293),q=o(16556),E=o(14264),N=o(2939),j=o(74206),H=o(52947),I=o(26463),J=o(45894),D=o(72030),G=o(58588),V=o(10280),B=o(57460),z=o(97380),X=o(80172),Z=o(7086),K=o(83667),Q=o(73012),$=o(19773),Y=o(64529),ee=o(31260),eA=o(46396),eo=o(86163),et=o(45258),ei=o(81167),en=o(7920),er=o(68476),ea=o(53903),el=o(58299),es=o(41956),ec=o(1345),ep=o(76710),ed=o(1778),eu=o(81168),eh=o(17212),eg=o(32174),em=o(6906),ew=o(82099),ef=o(39182),ev=o(23428),eb=o(44073),ey=o(26093),eP=o(15217),eC=o(67310),ek=o(45667),eS=o(63742),eM=o(90466),ex=o(16172),eF=o(63253),eL=o(80367),eU=o(794),eO=o(99348),eR=o(81002),eT=o(21126),e_=o(55769),eW=o(28819),eq=o(67447),eE=o(11344),eN=o(49600),ej=o(14858),eH=o(60527),eI=o(16889),eJ=o(19293),eD=o(92534),eG=o(14432),eV=o(23555),eB=o(82797),ez=o(95740),eX=o(37270),eZ=o(4326),eK=o(35198),eQ=o(41684),e$=o(46548),eY=o(3792),e6=o(87130),e2=o(94411),e4=o(27663),e1=o(87547),e3=o(30774),e0=o(88011),e9=o(44968),e7=o(82791),e8=o(70479),e5=o(96466),Ae=o(63058),AA=o(96553),Ao=o(69458),At=o(1852),Ai=o(39075),An=o(36645),Ar=o(56242);let Aa={AlertCircle:i.A,ArrowDown:n.A,ArrowRight:r.A,ArrowUp:a.A,ArrowUpRight:l.A,Ban:s.A,Bell:c.A,Bot:p.A,Bug:d.A,Check:u.A,CheckCircle2:h.A,ChevronDown:g.A,ChevronLeft:m.A,ChevronRight:w.A,ChevronUp:f.A,ChevronsDownUp:v.A,Circle:b.A,ClipboardPaste:y.A,Command:P.A,Compass:C.A,Columns2:k.A,Copy:S.A,CornerDownLeft:M.A,Crown:x.A,Delete:F.A,Download:L.A,ExternalLink:U.A,Eye:O.A,EyeOff:R.A,Facebook:T.A,File:_.A,FileCode:W.A,FileJson:q.A,FilePlus:E.A,FileText:N.A,Files:j.A,Filter:H.A,Folder:I.A,FolderOpen:J.A,FolderPlus:D.A,GitBranch:G.A,GitFork:V.A,Github:B.A,Globe:z.A,GripVertical:X.A,Hand:Z.A,HardDrive:K.A,HelpCircle:Q.A,History:$.A,Home:Y.A,Image:ee.A,ImageOff:eA.A,KeyRound:eo.A,Keyboard:et.A,Laptop:ei.A,LayoutDashboard:en.A,Link2:er.A,ListChecks:ea.A,Loader2:el.A,Lock:es.A,LogIn:ec.A,LogOut:ep.A,Maximize2:ed.A,Minimize2:eu.A,Menu:eh.A,Mic:eg.A,MicOff:em.A,Monitor:ew.A,Moon:ef.A,MoreHorizontal:ev.A,MoreVertical:eb.A,MousePointer2:ey.A,Package:eP.A,Palette:eC.A,PanelLeft:ek.A,PanelLeftClose:eS.A,PanelLeftOpen:eM.A,PanelRight:ex.A,Paperclip:eF.A,Pause:eL.A,Pencil:eU.A,Pi:eO.A,Pin:eR.A,PinOff:eT.A,Play:e_.A,Plug:eW.A,Plus:eq.A,Power:eE.A,PowerOff:eN.A,QrCode:ej.A,RefreshCw:eH.A,Replace:eI.A,RotateCw:eJ.A,Save:eD.A,Scissors:eG.A,Search:eV.A,Send:eB.A,SendHorizontal:ez.A,Settings:eX.A,Share:eZ.A,Shield:eK.A,Smartphone:eQ.A,Sparkles:e$.A,Square:eY.A,SquarePen:e6.A,Star:e2.A,StickyNote:e4.A,Sun:e1.A,Target:e3.A,Terminal:e0.A,Trash2:e9.A,Triangle:e7.A,Type:e8.A,Undo2:e5.A,Upload:Ae.A,Users:AA.A,Volume2:Ao.A,VolumeX:At.A,Wallpaper:Ai.A,X:An.A,Zap:Ar.A};function Al({name:e,size:A=20,className:o="",...i}){let n=Aa[e];return n?(0,t.jsx)(n,{size:A,className:o,strokeWidth:2,...i}):(console.warn(`Icon "${e}" not found in the icon registry`),null)}}},e=>{e.O(0,[820,329,587,1968,7358],()=>e(e.s=93696)),_N_E=e.O()}]);
@@ -1 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[2351],{36284:(e,r,t)=>{"use strict";t.d(r,{default:()=>y});var s=t(54568),o=t(7620),l=t(39634),a=t(85317),n=t(54024),d=t(92673),i=t(71049);let c="9remote_desktop_releases",x=e=>!e.draft&&!e.prerelease&&i.UP.every(r=>e.assets?.some(e=>e.name===r.asset)),m=e=>({tag:e.tag_name,date:(e.published_at||"").slice(0,10)}),b=null,h=null,p=new Set;function u(){for(let e of p)e()}function f(e){return p.add(e),b||function(){if(h)return;let e=function(){try{let e=localStorage.getItem(c);if(!e)return null;let{releases:r,timestamp:t}=JSON.parse(e);if(!Array.isArray(r)||!r.length)return null;return{releases:r,fresh:Date.now()-t<36e5}}catch{return null}}();e&&(b=e.releases,u(),e.fresh)||(h=fetch(d.el).then(e=>e.ok?e.json():null).then(e=>{if(!Array.isArray(e))return;let r=e.filter(x).map(m);if(r.length){b=r,u();try{localStorage.setItem(c,JSON.stringify({releases:r,timestamp:Date.now()}))}catch{}}}).catch(()=>{}).finally(()=>{h=null}))}(),()=>p.delete(e)}let g=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function C({href:e,children:r,primary:t}){return(0,s.jsxs)("a",{href:e,className:"flex items-center justify-center gap-2 px-4 py-2.5 rounded-lg text-[13px] font-semibold border transition-transform hover:scale-[1.02] whitespace-nowrap",style:t?{background:"var(--color-text)",color:"var(--color-bg)",borderColor:"transparent"}:{background:i.CV.bgPanel,color:i.CV.text,borderColor:i.CV.border},children:[r,(0,s.jsx)("svg",{className:"w-3.5 h-3.5 flex-shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:(0,s.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 3v12m0 0l-4-4m4 4l4-4M4 21h16"})})]})}function j({installer:e,tag:r,mine:t,href:o}){return(0,s.jsxs)("div",{className:"p-5 rounded-2xl border flex flex-col transition-all duration-300 hover:-translate-y-0.5",style:{background:i.CV.bgElevated,borderColor:t?i.CV.borderAccent:i.CV.border},children:[(0,s.jsxs)("div",{className:"flex items-center gap-2 mb-2",children:[(0,s.jsx)("span",{className:"text-base font-bold",style:{color:i.CV.text},children:e.os}),(0,s.jsx)("span",{className:"text-[10px] font-mono px-1.5 py-0.5 rounded border",style:{borderColor:i.CV.border,color:i.CV.textMuted},children:r}),t&&(0,s.jsx)("span",{className:"text-[10px] font-mono px-1.5 py-0.5 rounded-full border",style:{borderColor:i.CV.borderAccent,color:i.CV.accent},children:"Your system"})]}),(0,s.jsx)("p",{className:"text-xs mb-4",style:{color:i.CV.textDim},children:e.label}),(0,s.jsx)("div",{className:"mt-auto",children:(0,s.jsxs)(C,{href:o||(0,i.Is)(r,e.asset),primary:t,children:["Download ",e.ext]})})]})}function y(){let e=(0,o.useSyncExternalStore)(()=>()=>{},i.UH,()=>"other"),r=(0,o.useSyncExternalStore)(f,()=>b,()=>null),t=(0,i.Kd)(r||i.Yu).slice(1);return(0,s.jsxs)("div",{className:"min-h-screen overflow-x-hidden safe-area-insets",style:{color:i.CV.text},children:[(0,s.jsx)(l.A,{}),(0,s.jsx)("div",{className:"landing-light","aria-hidden":!0}),(0,s.jsx)(a.A,{}),(0,s.jsx)("main",{className:"relative z-10 pt-28 pb-24 px-4 sm:px-6 lg:px-8",children:(0,s.jsxs)("div",{className:"max-w-5xl mx-auto",children:[(0,s.jsxs)("div",{className:"text-center mb-12",children:[(0,s.jsx)("h1",{className:"text-3xl sm:text-4xl lg:text-5xl font-bold mb-3",style:{color:i.CV.text},children:"Download 9Remote"}),(0,s.jsx)("p",{className:"text-base sm:text-lg max-w-xl mx-auto",style:{color:i.CV.textDim},children:"The host app serves your terminals, screen and files. Install it on the machine you leave running."})]}),(0,s.jsx)("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-3 mb-4",children:i.UP.map(r=>(0,s.jsx)(j,{installer:r,tag:i.Ji.tag,mine:"other"!==e&&r.os.toLowerCase().startsWith(e),href:i.Ji.assets[r.id]||(0,i.Is)(i.Ji.tag,r.asset)},r.id))}),(0,s.jsxs)("div",{className:"p-5 rounded-2xl border mb-16",style:{background:i.CV.bgElevated,borderColor:i.CV.border},children:[(0,s.jsxs)("div",{className:"flex flex-wrap items-center gap-2 mb-2",children:[(0,s.jsx)("span",{className:"text-base font-bold",style:{color:i.CV.text},children:"Linux"}),(0,s.jsx)("span",{className:"text-[10px] font-mono px-1.5 py-0.5 rounded border",style:{borderColor:i.CV.border,color:i.CV.textMuted},children:i.Ji.tag})]}),(0,s.jsxs)("p",{className:"text-xs mb-4",style:{color:i.CV.textDim},children:["Debian/Ubuntu (.deb) or any distro via AppImage (arm64). x64 AppImage: use the CLI ",(0,s.jsx)("code",{children:"npm i -g 9remote"}),"."]}),(0,s.jsx)("div",{className:"flex flex-wrap gap-2",children:[["deb \xb7 x64",i.Ji.assets.debAmd64],["deb \xb7 arm64",i.Ji.assets.debArm64],["AppImage \xb7 arm64",i.Ji.assets.appImageArm64]].map(([e,r])=>(0,s.jsx)("a",{href:r,className:"text-xs font-medium px-3 py-1.5 rounded-lg border transition-colors",style:{background:i.CV.bgPanel,color:i.CV.textDim,borderColor:i.CV.border},children:e},e))})]}),(0,s.jsxs)("section",{className:"mb-16",children:[(0,s.jsx)("h2",{className:"text-[11px] font-mono uppercase tracking-[0.12em] pb-2.5 mb-1 border-b",style:{color:i.CV.textMuted,borderColor:i.CV.border},children:"Older versions"}),t.map(e=>(0,s.jsxs)("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2 py-3.5 border-b",style:{borderColor:i.CV.border},children:[(0,s.jsx)("span",{className:"text-sm font-bold font-mono",style:{color:i.CV.text},children:e.tag}),(0,s.jsx)("span",{className:"text-xs",style:{color:i.CV.textMuted},children:(e=>{let[r,t,s]=e.split("-");return`${g[Number(t)-1]} ${Number(s)}, ${r}`})(e.date)}),(0,s.jsx)("div",{className:"flex flex-wrap gap-2 ml-auto",children:i.UP.map(r=>(0,s.jsx)("a",{href:(0,i.Is)(e.tag,r.asset),className:"text-xs font-medium px-3 py-1.5 rounded-lg border transition-colors",style:{background:i.CV.bgPanel,color:i.CV.textDim,borderColor:i.CV.border},children:r.short},r.id))})]},e.tag))]}),(0,s.jsxs)("section",{className:"text-center",children:[(0,s.jsx)("h2",{className:"text-lg font-bold mb-2",style:{color:i.CV.text},children:"On a phone or tablet?"}),(0,s.jsx)("p",{className:"text-sm mb-4",style:{color:i.CV.textDim},children:"9Remote is a client on mobile — pair it with a host using the QR code."}),(0,s.jsxs)("div",{className:"flex flex-wrap justify-center gap-3",children:[(0,s.jsx)("a",{href:i.od,target:"_blank",rel:"noopener noreferrer",className:"text-sm font-semibold px-4 py-2 rounded-lg border",style:{background:i.CV.bgPanel,color:i.CV.text,borderColor:i.CV.border},children:"App Store"}),(0,s.jsx)("a",{href:i.JN,target:"_blank",rel:"noopener noreferrer",className:"text-sm font-semibold px-4 py-2 rounded-lg border",style:{background:i.CV.bgPanel,color:i.CV.text,borderColor:i.CV.border},children:"Google Play"}),(0,s.jsx)("a",{href:i.rl,target:"_blank",rel:"noopener noreferrer",className:"text-sm font-semibold px-4 py-2 rounded-lg border",style:{background:i.CV.bgPanel,color:i.CV.textDim,borderColor:i.CV.border},children:"All releases on GitHub"})]})]})]})}),(0,s.jsx)(n.A,{})]})}},40612:(e,r,t)=>{Promise.resolve().then(t.bind(t,36284))},46891:(e,r,t)=>{"use strict";t.d(r,{A:()=>d});var s=t(54568),o=t(38118),l=t(14652);let a=({size:e=18})=>(0,s.jsxs)("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,s.jsx)("circle",{cx:"12",cy:"12",r:"4"}),(0,s.jsx)("path",{d:"M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"})]}),n=({size:e=18})=>(0,s.jsx)("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:(0,s.jsx)("path",{d:"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"})});function d({className:e="",size:r=18}){let{theme:t,toggleTheme:i}=(0,o.D)(),c="dark"===t;return(0,s.jsx)("button",{type:"button",onClick:()=>{(0,l.e)(),i()},"aria-label":c?"Switch to light theme":"Switch to dark theme",title:c?"Light mode":"Dark mode",className:`p-1.5 rounded-brand transition-colors text-[var(--color-text-muted)] hover:text-[var(--color-text)] hover:bg-[var(--color-surface-2)] ${e}`,children:c?(0,s.jsx)(a,{size:r}):(0,s.jsx)(n,{size:r})})}}},e=>{e.O(0,[5587,1772,1920,587,1968,7358],()=>e(e.s=40612)),_N_E=e.O()}]);
@@ -1 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[7177],{36629:(e,t,a)=>{"use strict";a.d(t,{default:()=>l});var r=a(7620);function l(){let[e,t]=(0,r.useState)(!1),[a,l]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{let e=window.matchMedia("(pointer: coarse) and (max-width: 900px)"),a=window.matchMedia("(orientation: landscape)"),r=()=>{t(e.matches),l(a.matches)};return r(),e.addEventListener("change",r),a.addEventListener("change",r),()=>{e.removeEventListener("change",r),a.removeEventListener("change",r)}},[]),(0,r.useEffect)(()=>{let t=!!window.ReactNativeWebView||/9Remote-Mobile/i.test(navigator.userAgent);if(!e||t)return;let a=!1;return(async()=>{try{await window.screen?.orientation?.lock?.("portrait"),a=!0}catch{}})(),()=>{a&&window.screen?.orientation?.unlock?.()}},[e]),null}},38118:(e,t,a)=>{"use strict";a.d(t,{D:()=>s,ThemeProvider:()=>o});var r=a(54568),l=a(7620),c=a(86377);let n=(0,l.createContext)({theme:c.SS,setTheme:()=>{},toggleTheme:()=>{}}),u=e=>{if("u"<typeof document)return;let t=document.documentElement;t.classList.remove("light","dark"),t.classList.add(e),t.style.colorScheme=e;try{let t=window.__TAURI__?.window?.getCurrentWindow?.();t&&(t.setTheme?.(e)?.catch?.(()=>{}),t.setBackgroundColor?.("light"===e?"#e7e7e9":"#2a2a2a")?.catch?.(()=>{}))}catch{}},i=e=>{if(window.ReactNativeWebView)try{window.ReactNativeWebView.postMessage(JSON.stringify({type:"THEME_CHANGE",theme:e}))}catch(e){}};function o({children:e}){let[t,a]=(0,l.useState)(c.SS);(0,l.useEffect)(()=>{let e=localStorage.getItem(c.AQ)||localStorage.getItem("9remote-theme"),t=c.$.includes(e)?e:c.SS;a(t),u(t),i(t)},[]);let s=(0,l.useCallback)(e=>{c.$.includes(e)&&(a(e),u(e),i(e),localStorage.setItem(c.AQ,e),localStorage.setItem("9remote-theme",e))},[]),F=(0,l.useCallback)(()=>{s("dark"===t?"light":"dark")},[t,s]);return(0,r.jsx)(n.Provider,{value:{theme:t,setTheme:s,toggleTheme:F},children:e})}let s=()=>(0,l.useContext)(n)},74255:(e,t,a)=>{Promise.resolve().then(a.bind(a,5092)),Promise.resolve().then(a.bind(a,22546)),Promise.resolve().then(a.bind(a,87341)),Promise.resolve().then(a.t.bind(a,10594,23)),Promise.resolve().then(a.t.bind(a,36138,23)),Promise.resolve().then(a.t.bind(a,10918,23)),Promise.resolve().then(a.t.bind(a,76944,23)),Promise.resolve().then(a.bind(a,82355)),Promise.resolve().then(a.bind(a,36629)),Promise.resolve().then(a.bind(a,88654)),Promise.resolve().then(a.bind(a,38118))},76944:()=>{},82355:(e,t,a)=>{"use strict";a.d(t,{default:()=>s});var r=a(54568),l=a(7620),c=a(9121);let n=/9Remote-Mobile\/(\d+(?:\.\d+){0,2})/i,u=/^\d+(?:\.\d+){0,2}$/,i={android:"market://details?id=cc.remote9.app",ios:"itms-apps://apps.apple.com/app/id6796664210"};function o(){return"u"<typeof navigator?"android":window.DEVICE_INFO?.platform?window.DEVICE_INFO.platform:/iPhone|iPad|iPod/i.test(navigator.userAgent)||/^iP/.test(navigator.platform||"")||window.webkit?.messageHandlers?"ios":"android"}function s(){let{t:e}=(0,c.s)(),[t,a]=(0,l.useState)(!1);if((0,l.useEffect)(()=>{let e=navigator.userAgent;if(!window.ReactNativeWebView&&!n.test(String(e||"")))return;let t=o(),r=!1;return(async()=>{try{let l=await fetch(`/api/version?platform=${t}&_t=${Date.now()}`);if(!l.ok||r)return;let c=await l.json(),i=c?.minAppVersion;if(r||!i)return;let o=function(e,t){let a=t?.version;if("string"==typeof a&&u.test(a))return a;let r=n.exec(String(e||""));return r?r[1]:null}(e,window.DEVICE_INFO);(null===o||function(e,t){if(!u.test(String(e))||!u.test(String(t)))return!1;let a=String(e).split(".").map(Number),r=String(t).split(".").map(Number);for(let e=0;e<3;e++){let t=(a[e]||0)-(r[e]||0);if(0!==t)return t<0}return!1}(o,i))&&a(!0)}catch{}})(),()=>{r=!0}},[]),!t)return null;let s=i[o()]||i.android;return(0,r.jsxs)("div",{className:"fixed inset-0 z-[300] flex flex-col items-center justify-center gap-4 bg-[#0b0d0c] px-8 text-center",children:[(0,r.jsx)("span",{className:"material-symbols-rounded text-[56px] text-[#E56A4A]",children:"system_update_alt"}),(0,r.jsx)("h2",{className:"text-lg font-semibold text-white",children:e("appUpdate.title")}),(0,r.jsx)("p",{className:"max-w-xs text-sm text-white/60",children:e("appUpdate.body")}),(0,r.jsx)("a",{href:s,className:"mt-2 rounded-brand bg-[#E56A4A] px-6 py-2.5 text-sm font-semibold text-white",children:e("appUpdate.action")})]})}},86377:(e,t,a)=>{"use strict";a.d(t,{$:()=>r,AQ:()=>c,In:()=>s,SS:()=>l,aC:()=>u,g4:()=>o});let r=["dark","light"],l="dark",c="app_theme_v2";function n(e){return{background:e.bg,foreground:e.text,cursor:e.accent||e.peach||e.blue,cursorAccent:e.bg,selectionBackground:e.surface1,black:e.surfaceDim||e.bg,red:e.red,green:e.green,yellow:e.yellow,blue:e.blue,magenta:e.mauve,cyan:e.teal,white:e.subtext0||e.text,brightBlack:e.overlay0,brightRed:e.red,brightGreen:e.green,brightYellow:e.yellow,brightBlue:e.blue,brightMagenta:e.mauve,brightCyan:e.teal,brightWhite:e.text}}let u={dark:n({bg:"#1A1A1A",surface0:"#232323",surface1:"#2A2A2A",surfaceDim:"#101010",overlay0:"#5C5C5C",text:"#FFFFFF",subtext0:"#A0A0A0",red:"#FF8080",green:"#99FFE4",yellow:"#FFC799",blue:"#B0B0B0",mauve:"#FFD1A8",teal:"#66DDCC",peach:"#FFC799",accent:"#FFC799"}),light:n({bg:"#F5F5F5",surface0:"#E8E8E8",surface1:"#DDDDDD",surfaceDim:"#EFEFEF",overlay0:"#999999",text:"#1A1A1A",subtext0:"#5A5A5A",red:"#D9534F",green:"#2A9D8F",yellow:"#E07A3C",blue:"#6B6B6B",mauve:"#C97B5A",teal:"#3A9B8E",peach:"#E07A3C",accent:"#E07A3C"})},i={catppuccinMocha:n({bg:"#181825",surface0:"#31324A",surface1:"#45475A",surfaceDim:"#1E1E2E",overlay0:"#6C708E",text:"#CDD6F4",subtext0:"#A6ADC8",red:"#F38BA8",green:"#A6E3A1",yellow:"#F9E2AF",blue:"#89B4FA",mauve:"#CBA7F7",teal:"#94E2D5",peach:"#FAB387",accent:"#89B4FA"}),monokaiPro:n({bg:"#2D2A2E",surface0:"#353034",surface1:"#3D383C",surfaceDim:"#221F22",overlay0:"#72696A",text:"#FFF1F3",subtext0:"#C8C5C8",red:"#FD6883",green:"#ADDA78",yellow:"#F9CC6C",blue:"#F38D70",mauve:"#A8A9EB",teal:"#85DACC",peach:"#F38D70",accent:"#A8A9EB"}),gruvboxMaterial:n({bg:"#282828",surface0:"#3C3836",surface1:"#504945",surfaceDim:"#1D2021",overlay0:"#928374",text:"#D4BE98",subtext0:"#A89984",red:"#EA6962",green:"#A9B665",yellow:"#D8A657",blue:"#7DAEA3",mauve:"#D3869B",teal:"#89B482",peach:"#E78A4E",accent:"#E78A4E"}),dracula:n({bg:"#282A36",surface0:"#44475A",surface1:"#6272A4",surfaceDim:"#282A36",overlay0:"#6272A4",text:"#F8F8F2",subtext0:"#D2D2DC",red:"#FF5555",green:"#50FA7B",yellow:"#F1FA8C",blue:"#8BE9FD",mauve:"#FF79C6",teal:"#8BE9FD",peach:"#FFB86C",accent:"#BD93F9"}),everforest:n({bg:"#2D353B",surface0:"#343F44",surface1:"#3D484D",surfaceDim:"#232A2E",overlay0:"#7A8478",text:"#D3C6AA",subtext0:"#9DA9A0",red:"#E67E80",green:"#A7C080",yellow:"#DBBC7F",blue:"#7FBBB3",mauve:"#D699B6",teal:"#83C092",peach:"#E69875",accent:"#A7C080"}),linear:n({bg:"#08090A",surface0:"#0F1011",surface1:"#141516",surfaceDim:"#010102",overlay0:"#3E3E44",text:"#F7F8F8",subtext0:"#B4B4B8",red:"#F34E52",green:"#27A644",yellow:"#E4F222",blue:"#8FA6FF",mauve:"#8B5CF6",teal:"#02B8CC",peach:"#F7BF8B",accent:"#5E6AD2"}),synthwave:n({bg:"#262335",surface0:"#241B2F",surface1:"#34294F",surfaceDim:"#171520",overlay0:"#9D8BCA",text:"#FFFFFF",subtext0:"#FFFFFF99",red:"#FE4450",green:"#72F1B8",yellow:"#FEDE5D",blue:"#03EDF9",mauve:"#FF7EDB",teal:"#03EDF9",peach:"#F97E72",accent:"#FF7EDB"}),poimandres:n({bg:"#1B1E28",surface0:"#303340",surface1:"#3A4050",surfaceDim:"#14161F",overlay0:"#506477",text:"#E4F0FB",subtext0:"#A6ACCD",red:"#D0679D",green:"#5DE4C7",yellow:"#FFFAC2",blue:"#ADD7FF",mauve:"#F087BD",teal:"#5DE4C7",peach:"#F087BD",accent:"#5DE4C7"}),ayuMirage:n({bg:"#1F2430",surface0:"#212733",surface1:"#272D3A",surfaceDim:"#161B26",overlay0:"#686868",text:"#CBCCC6",subtext0:"#9A9B95",red:"#F08778",green:"#53BF97",yellow:"#FDCC60",blue:"#60B8D6",mauve:"#EC7171",teal:"#98E6CA",peach:"#FFA759",accent:"#FFCC66"}),githubDarkDimmed:n({bg:"#22272E",surface0:"#2D333B",surface1:"#373E47",surfaceDim:"#1C2128",overlay0:"#545D68",text:"#CDD9E5",subtext0:"#909DAB",red:"#F47067",green:"#57AB5A",yellow:"#C69026",blue:"#539BF5",mauve:"#B083F0",teal:"#39C5CF",peach:"#DAAA3F",accent:"#539BF5"}),palenight:n({bg:"#292D3E",surface0:"#313553",surface1:"#3A3F5F",surfaceDim:"#1F2233",overlay0:"#676E95",text:"#D0D0D0",subtext0:"#A0A0C0",red:"#E05252",green:"#2BE8A8",yellow:"#FFCB6B",blue:"#3FD0E0",mauve:"#C792EA",teal:"#3FD0E0",peach:"#FFCB6B",accent:"#82AAFF"}),nordDark:n({bg:"#2E3440",surface0:"#3B4252",surface1:"#434C5E",surfaceDim:"#232831",overlay0:"#4C566A",text:"#ECEFF4",subtext0:"#D8DEE9",red:"#BF616A",green:"#A3BE8C",yellow:"#EBCB8B",blue:"#81A1C1",mauve:"#B48EAD",teal:"#88C0D0",peach:"#D08770",accent:"#88C0D0"}),horizon:n({bg:"#1C1E26",surface0:"#232530",surface1:"#2E303E",surfaceDim:"#16161C",overlay0:"#6B6F8A",text:"#E0E0E0",subtext0:"#C5C8DA",red:"#E95678",green:"#29D398",yellow:"#FAB795",blue:"#26BBD9",mauve:"#EE64AC",teal:"#59E1E3",peach:"#FAB795",accent:"#EE64AC"}),kanagawaDragon:n({bg:"#181616",surface0:"#1D1C1C",surface1:"#252424",surfaceDim:"#0D0C0C",overlay0:"#7A6F7A",text:"#C5C9C5",subtext0:"#A6A69C",red:"#C4746E",green:"#87A987",yellow:"#E6C384",blue:"#8BA4B0",mauve:"#938AA9",teal:"#7AA89F",peach:"#FFA066",accent:"#8BA4B0"}),catppuccinLatte:n({bg:"#EFF1F5",surface0:"#CCD0DA",surface1:"#BCC0CC",surfaceDim:"#E6E9EF",overlay0:"#9CA0B0",text:"#4C4F69",subtext0:"#6C6F85",red:"#D20F39",green:"#40A02B",yellow:"#DF8E1D",blue:"#1E66F5",mauve:"#8839EF",teal:"#179299",peach:"#FE640B",accent:"#1E66F5"}),gruvboxLight:n({bg:"#FBF1C7",surface0:"#EBDBB2",surface1:"#D5C4A1",surfaceDim:"#F2E5BC",overlay0:"#928374",text:"#3C3836",subtext0:"#504945",red:"#9D0006",green:"#79740E",yellow:"#B57614",blue:"#076678",mauve:"#8F3F71",teal:"#427B58",peach:"#AF3A03",accent:"#B57614"}),githubLight:n({bg:"#FFFFFF",surface0:"#F6F8FA",surface1:"#EAEEF2",surfaceDim:"#EFF2F5",overlay0:"#8C959F",text:"#24292F",subtext0:"#57606A",red:"#CF222E",green:"#1A7F37",yellow:"#9A6700",blue:"#0969DA",mauve:"#8250DF",teal:"#1B7C83",peach:"#BC4C00",accent:"#0969DA"}),everforestLight:n({bg:"#FDF6E3",surface0:"#F4F0D9",surface1:"#EFEBD4",surfaceDim:"#E6E2CC",overlay0:"#9DA9A0",text:"#5C6A72",subtext0:"#7A8478",red:"#F85552",green:"#8DA101",yellow:"#DFA000",blue:"#3A94C5",mauve:"#DF69BA",teal:"#35A77C",peach:"#F57D3A",accent:"#8DA101"}),ayuLight:n({bg:"#FCFCFC",surface0:"#F3F3F3",surface1:"#E8E8E8",surfaceDim:"#F7F7F7",overlay0:"#C1C1C1",text:"#5C6166",subtext0:"#8A8F94",red:"#E7666A",green:"#80AB24",yellow:"#EBA54D",blue:"#4196DF",mauve:"#9870C3",teal:"#51B891",peach:"#E78F4D",accent:"#FF8552"}),tokyoDay:n({bg:"#D6D8DF",surface0:"#C8CBD4",surface1:"#B5B8C5",surfaceDim:"#E1E3EA",overlay0:"#9699AE",text:"#343B58",subtext0:"#565C70",red:"#C24242",green:"#41A6B5",yellow:"#8F5E15",blue:"#2959AA",mauve:"#7B43BA",teal:"#006C86",peach:"#D68910",accent:"#2959AA"}),roseDawn:n({bg:"#FAF4ED",surface0:"#F2E9E1",surface1:"#E9DDD2",surfaceDim:"#F5EBE0",overlay0:"#9893A5",text:"#576279",subtext0:"#797593",red:"#B4637A",green:"#618774",yellow:"#EA9D34",blue:"#286983",mauve:"#907AA9",teal:"#56949F",peach:"#D7827E",accent:"#D7827E"}),lavenderMist:n({bg:"#F6F3FB",surface0:"#EAE5F5",surface1:"#DDD6EE",surfaceDim:"#F0ECF8",overlay0:"#9B95B8",text:"#4A4467",subtext0:"#6B6491",red:"#C95D77",green:"#5FA17A",yellow:"#D9A441",blue:"#5B7FBE",mauve:"#8B7AB8",teal:"#5FA6A8",peach:"#D08A66",accent:"#8B7AB8"}),mintCream:n({bg:"#ECF6F0",surface0:"#DCEEE3",surface1:"#C9E3D2",surfaceDim:"#E2F1E9",overlay0:"#7FA396",text:"#2F4A40",subtext0:"#4E6B5F",red:"#C76B6B",green:"#3FA17A",yellow:"#C9A93E",blue:"#4A8DB8",mauve:"#9B6FA8",teal:"#3FA17A",peach:"#D58560",accent:"#3FA17A"})},o=[{key:"catppuccinMocha",label:"Catppuccin Mocha",mode:"dark"},{key:"monokaiPro",label:"Monokai Pro",mode:"dark"},{key:"dracula",label:"Dracula",mode:"dark"},{key:"everforest",label:"Everforest",mode:"dark"},{key:"gruvboxMaterial",label:"Gruvbox Material",mode:"dark"},{key:"linear",label:"Linear",mode:"dark"},{key:"synthwave",label:"Synthwave '84",mode:"dark"},{key:"poimandres",label:"Poimandres",mode:"dark"},{key:"ayuMirage",label:"Ayu Mirage",mode:"dark"},{key:"githubDarkDimmed",label:"GitHub Dimmed",mode:"dark"},{key:"palenight",label:"Palenight",mode:"dark"},{key:"nordDark",label:"Nord",mode:"dark"},{key:"horizon",label:"Horizon",mode:"dark"},{key:"kanagawaDragon",label:"Kanagawa Dragon",mode:"dark"},{key:"catppuccinLatte",label:"Catppuccin Latte",mode:"light"},{key:"gruvboxLight",label:"Gruvbox Light",mode:"light"},{key:"githubLight",label:"GitHub Light",mode:"light"},{key:"everforestLight",label:"Everforest Light",mode:"light"},{key:"ayuLight",label:"Ayu Light",mode:"light"},{key:"tokyoDay",label:"Tokyo Day",mode:"light"},{key:"roseDawn",label:"Rose Dawn",mode:"light"},{key:"lavenderMist",label:"Lavender Mist",mode:"light"},{key:"mintCream",label:"Mint Cream",mode:"light"}];function s(e,t){let a="light"===e?i.everforestLight:i.palenight;return t&&"default"!==t&&o.find(a=>a.key===t&&a.mode===e)&&i[t]||a}},88654:(e,t,a)=>{"use strict";a.d(t,{default:()=>n});var r=a(54568),l=a(7620);let c=()=>()=>{};function n({id:e,html:t}){return(0,l.useSyncExternalStore)(c,()=>!1,()=>!0)?(0,r.jsx)("script",{id:e,dangerouslySetInnerHTML:{__html:t}}):null}}},e=>{e.O(0,[5675,1317,6221,9121,587,1968,7358],()=>e(e.s=74255)),_N_E=e.O()}]);