torio-cli 1.2.0
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.
- package/LICENSE +21 -0
- package/README.md +98 -0
- package/dist/cli.cjs +18 -0
- package/dist/index.js +14 -0
- package/package.json +74 -0
- package/preview/01_main-page.png +0 -0
- package/preview/02_search-results.png +0 -0
- package/preview/03_seected-result.png +0 -0
- package/preview/04_download-progress.png +0 -0
- package/preview/05_navigation-map.png +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 bairon.dev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# torio
|
|
2
|
+
|
|
3
|
+
torio — это быстрый и бесшовный способ искать торрент-материалы прямо из терминала и сразу скачивать их без лишних шагов.
|
|
4
|
+
|
|
5
|
+
Никакой сложной настройки, никаких всплывающих окон и лишних вкладок. Введите запрос, выберите результат, и torio всё сделает за вас: проверит несколько источников, покажет размеры и сиды, а затем начнёт загрузку в нужную папку.
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<img src="preview/01_main-page.png" alt="Главный экран torio" style="max-width: 960px; width: 100%; height: auto;">
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
## Почему torio
|
|
12
|
+
|
|
13
|
+
- Поиск сразу по нескольким проверенным источникам.
|
|
14
|
+
- Никакой ручной настройки и конфигов для старта.
|
|
15
|
+
- Удобный интерфейс в терминале с клавиатурной навигацией.
|
|
16
|
+
- Загрузка в фоне, поддержка очереди и возобновление прерванных задач.
|
|
17
|
+
- Автоматическое продолжение раздачи после окончания скачивания.
|
|
18
|
+
|
|
19
|
+
<p align="center">
|
|
20
|
+
<img src="preview/02_search-results.png" alt="Результаты поиска в torio" style="max-width: 960px; width: 100%; height: auto;">
|
|
21
|
+
</p>
|
|
22
|
+
|
|
23
|
+
## Как использовать
|
|
24
|
+
|
|
25
|
+
1. Установите Node.js с [nodejs.org](https://nodejs.org).
|
|
26
|
+
2. Откройте терминал.
|
|
27
|
+
3. Запустите:
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
npx torio
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
После запуска вы увидите строку поиска. Можно ввести название фильма, сериала, игры или просто нажать Enter, чтобы открыть подборку. Для навигации используются стрелки, клавиша `d` — для скачивания, а `?` — для справки по горячим клавишам.
|
|
34
|
+
|
|
35
|
+
<p align="center">
|
|
36
|
+
<img src="preview/03_seected-result.png" alt="Выбранный результат в torio" style="max-width: 960px; width: 100%; height: auto;">
|
|
37
|
+
</p>
|
|
38
|
+
|
|
39
|
+
## Что происходит во время загрузки
|
|
40
|
+
|
|
41
|
+
Активные загрузки отображаются сверху с прогрессом, скоростью и оставшимся временем. Когда задача завершена, она перемещается в раздел «Недавно скачано», а все остальные продолжают находиться в очереди.
|
|
42
|
+
|
|
43
|
+
Загрузка не мешает поиску: можно продолжать искать новые торренты, пока текущие выполняются в фоне. После завершения торренты продолжают раздаваться, если вы не отключили эту функцию вручную.
|
|
44
|
+
|
|
45
|
+
<p align="center">
|
|
46
|
+
<img src="preview/04_download-progress.png" alt="Прогресс загрузки в torio" style="max-width: 960px; width: 100%; height: auto;">
|
|
47
|
+
</p>
|
|
48
|
+
|
|
49
|
+
## Поддерживаемые источники
|
|
50
|
+
|
|
51
|
+
torio собирает результаты из нескольких источников, в том числе:
|
|
52
|
+
|
|
53
|
+
| Категория | Источники |
|
|
54
|
+
| --- | --- |
|
|
55
|
+
| Игры | FitGirl, NNM Club, Rutor, Torentino |
|
|
56
|
+
| Фильмы | YTS, The Pirate Bay, 1337x, NNM Club, Rutor |
|
|
57
|
+
| ТВ | EZTV, The Pirate Bay, 1337x, NNM Club, Rutor |
|
|
58
|
+
| Аниме | Nyaa, SubsPlease, Rutor |
|
|
59
|
+
|
|
60
|
+
Если один источник недоступен, torio просто продолжает поиск без него и сообщает об этом.
|
|
61
|
+
|
|
62
|
+
<p align="center">
|
|
63
|
+
<img src="preview/05_navigation-map.png" alt="Карта навигации torio" style="max-width: 960px; width: 100%; height: auto;">
|
|
64
|
+
</p>
|
|
65
|
+
|
|
66
|
+
## Разработка
|
|
67
|
+
|
|
68
|
+
Чтобы запустить torio локально:
|
|
69
|
+
|
|
70
|
+
1. Склонируйте репозиторий.
|
|
71
|
+
2. Установите зависимости:
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
npm install
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
3. Запустите dev-режим:
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
npm run dev
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
4. Для сборки и запуска готовой версии:
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
npm run build
|
|
87
|
+
npx torio
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Перед отправкой pull request обязательно прочитайте [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
91
|
+
|
|
92
|
+
## Конфиденциальность и раздача
|
|
93
|
+
|
|
94
|
+
Все файлы остаются на вашем устройстве. torio не передаёт данные через центральный сервер: обмен идёт напрямую через торрент-сеть. После завершения загрузки раздача может продолжаться по умолчанию, чтобы другие пользователи также могли получить файл. Если вы не хотите поддерживать раздачу, это можно отключить в интерфейсе.
|
|
95
|
+
|
|
96
|
+
## Лицензия
|
|
97
|
+
|
|
98
|
+
Проект распространяется под лицензией MIT. Подробности — в [LICENSE](LICENSE).
|
package/dist/cli.cjs
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var major = parseInt(process.versions.node.split('.')[0], 10);
|
|
5
|
+
if (major < 22) {
|
|
6
|
+
process.stderr.write(
|
|
7
|
+
'\ntorio requires Node.js v22 or later.\n' +
|
|
8
|
+
'You are running v' + process.versions.node + '.\n\n' +
|
|
9
|
+
'Upgrade: https://nodejs.org\n' +
|
|
10
|
+
'With nvm: nvm install 22 && nvm use 22\n\n'
|
|
11
|
+
);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
import('./index.js').catch(function (err) {
|
|
16
|
+
process.stderr.write(String((err && err.message) || err) + '\n');
|
|
17
|
+
process.exit(1);
|
|
18
|
+
});
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{render as Va}from"ink";var es=["udp://tracker.opentrackr.org:1337/announce","udp://open.demonii.com:1337/announce","udp://tracker.openbittorrent.com:6969/announce","udp://tracker.torrent.eu.org:451/announce","udp://exodus.desync.com:6969/announce","udp://open.stealth.si:80/announce","udp://tracker.dler.org:6969/announce"];function ie(t,e){let r=encodeURIComponent(e),o=es.map(n=>`&tr=${encodeURIComponent(n)}`).join("");return`magnet:?xt=urn:btih:${t}&dn=${r}${o}`}var ts=/xt=urn:btih:([a-f0-9]{40}|[a-z2-7]{32})/i,rs="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";function os(t){let e=0,r=0,o="";for(let n of t.toUpperCase()){let s=rs.indexOf(n);if(s===-1)return null;r=r<<5|s,e+=5,e>=8&&(e-=8,o+=(r>>>e&255).toString(16).padStart(2,"0"),r&=(1<<e)-1)}return o.length===40?o:null}function Lr(t){return t.length===32?os(t)??t.toLowerCase():t.toLowerCase()}function rr(t){let e=t.trim();if(!/^magnet:\?/i.test(e))return null;let r=ts.exec(e);if(!r)return null;let o=Lr(r[1]),n=o;try{let s=new URL(e).searchParams.get("dn");s&&(n=s)}catch{}return{infoHash:o,name:n,magnet:e}}var ns=/^([a-f0-9]{40}|[a-z2-7]{32})$/i;function or(t){return ns.test(t.trim())}function At(t){let e=t.trim(),r=rr(e);if(r)return r;if(!or(e))return null;let o=Lr(e);return{infoHash:o,name:o,magnet:ie(o,o)}}function Fr(t){let e=t.filter(o=>o.trim()!=="");if(e.length===0)return{kind:"run"};let r=e[0];return r==="--version"||r==="-v"?{kind:"version"}:r==="--help"||r==="-h"?{kind:"help"}:/^magnet:\?/i.test(r)?{kind:"run",initialMagnet:r}:or(r)?{kind:"run",initialMagnet:r}:/\.torrent$/i.test(r)?{kind:"run",initialTorrent:r}:{kind:"invalid",arg:r}}var nr=`torio \u2014 \u043F\u043E\u0438\u0441\u043A \u0442\u043E\u0440\u0440\u0435\u043D\u0442\u043E\u0432 \u043F\u0440\u044F\u043C\u043E \u0432 \u0442\u0435\u0440\u043C\u0438\u043D\u0430\u043B\u0435
|
|
3
|
+
|
|
4
|
+
\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435
|
|
5
|
+
torio \u043E\u0442\u043A\u0440\u044B\u0442\u044C TUI \u043F\u043E\u0438\u0441\u043A\u0430
|
|
6
|
+
torio "magnet:?xt=..." \u043D\u0430\u0447\u0430\u0442\u044C \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0443 \u043F\u0440\u0438 \u0437\u0430\u043F\u0443\u0441\u043A\u0435
|
|
7
|
+
torio \u043F\u0443\u0442\u044C/\u0434\u043E/\u0444\u0430\u0439\u043B.torrent \u043E\u0442\u043A\u0440\u044B\u0442\u044C .torrent \u0444\u0430\u0439\u043B \u043F\u0440\u0438 \u0437\u0430\u043F\u0443\u0441\u043A\u0435
|
|
8
|
+
torio --version \u043F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0432\u0435\u0440\u0441\u0438\u044E
|
|
9
|
+
|
|
10
|
+
\u043F\u043E\u0441\u043B\u0435 \u043E\u0442\u043A\u0440\u044B\u0442\u0438\u044F: \u043D\u0430\u0431\u0438\u0440\u0430\u0439\u0442\u0435 \u0434\u043B\u044F \u043F\u043E\u0438\u0441\u043A\u0430 \u043F\u043E \u0432\u0441\u0435\u043C \u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u0430\u043C, enter \u0434\u043B\u044F \u0437\u0430\u043F\u0443\u0441\u043A\u0430,
|
|
11
|
+
\u0441\u0442\u0440\u0435\u043B\u043A\u0438 \u0434\u043B\u044F \u043F\u0435\u0440\u0435\u043C\u0435\u0449\u0435\u043D\u0438\u044F, d \u0434\u043B\u044F \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438, ? \u0434\u043B\u044F \u043A\u043B\u0430\u0432\u0438\u0448
|
|
12
|
+
\u043F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0430: \u0437\u0430\u043A\u043B\u044E\u0447\u0430\u0439\u0442\u0435 \u043C\u0430\u0433\u043D\u0435\u0442-\u0441\u0441\u044B\u043B\u043A\u0438 \u0432 \u043A\u0430\u0432\u044B\u0447\u043A\u0438 (\u043E\u043D\u0438 \u0441\u043E\u0434\u0435\u0440\u0436\u0430\u0442 \u0441\u0438\u043C\u0432\u043E\u043B\u044B &)
|
|
13
|
+
`;var Ur="1.0.0";import{useCallback as ve,useEffect as It,useMemo as Ua,useRef as za,useState as oe}from"react";import{Box as Re,Text as Vn,useApp as Ga,useInput as Qa,useStdout as Wa,useStdin as ja}from"ink";import{promises as Dr}from"fs";import{promises as ls}from"fs";import ss from"os";import Me from"path";import is from"env-paths";var zr="torio",Gr=is(zr,{suffix:""}),Pt=process.env.TORIO_STATE_DIR,$t=Pt?Me.join(Pt,"data"):Gr.data,as=Pt?Me.join(Pt,"config"):Gr.config,sr=Me.join(ss.homedir(),"Downloads",zr),ir=Me.join(as,"config.json"),Ge=Me.join($t,"queue.json"),Qe=Me.join($t,"history.json"),We=Me.join($t,"seeds.json"),ar=Me.join($t,"torrents");import{promises as cr}from"fs";import cs from"path";function je(){let t=Promise.resolve();return e=>(t=t.then(e).catch(()=>{}),t)}async function De(t,e){await cr.mkdir(cs.dirname(t),{recursive:!0});let r=`${t}.tmp`;await cr.writeFile(r,JSON.stringify(e,null,2),"utf8"),await cr.rename(r,t)}var Qr={downloadDir:sr,trackers:[]};async function Wr(){let t;try{t=await ls.readFile(ir,"utf8")}catch{return{...Qr,trackers:[]}}try{let e=JSON.parse(t);return{downloadDir:typeof e.downloadDir=="string"&&e.downloadDir?e.downloadDir:sr,trackers:Array.isArray(e.trackers)?e.trackers.filter(o=>typeof o=="string"&&o.length>0):[]}}catch{return{...Qr,trackers:[]}}}var us=je();function jr(t){return us(()=>De(ir,t))}import Vr from"os";import qr from"path";function ds(t,e=Vr.homedir()){let r=t.trim();return r==="~"?e:r.startsWith("~/")||r.startsWith("~\\")?qr.join(e,r.slice(2)):r}function Yr(t,e=Vr.homedir()){let r=ds(t,e);return r?qr.normalize(r):""}import{EventEmitter as vs}from"events";import ms from"webtorrent";function Kr(t){return t instanceof Error?t.message:String(t)}var Ht=class{client=null;torrents=new Map;ensureClient(){return this.client||(this.client=new ms,this.client.on("error",()=>{})),this.client}add(e,r,o,n,s){let i=this.ensureClient(),l=this.torrents.get(e);if(l){this.torrents.delete(e);try{l.destroy()}catch{}}let c=s&&s.length>0?{path:o,announce:s}:{path:o},a;try{a=i.add(r,c)}catch(u){n.onError?.(Kr(u));return}this.torrents.set(e,a),a.on("metadata",()=>{n.onMetadata?.({name:a.name,total:a.length,files:a.files?.length??0,torrentFile:a.torrentFile})}),a.on("done",()=>{n.onDone?.()}),a.on("error",u=>{n.onError?.(Kr(u)),this.torrents.delete(e);try{a.destroy()}catch{}})}listenPort(){return this.client?.torrentPort??null}stats(e){let r=this.torrents.get(e);return r?{progress:r.progress,downloaded:r.downloaded,total:r.length,speed:r.downloadSpeed,uploadSpeed:r.uploadSpeed,uploaded:r.uploaded,peers:r.numPeers,timeRemaining:r.timeRemaining,name:r.name}:null}remove(e){let r=this.torrents.get(e);if(this.torrents.delete(e),r)try{r.destroy()}catch{}}destroy(){this.torrents.clear();let e=this.client;this.client=null,e&&setImmediate(()=>{try{e.destroy()}catch{}})}};import{promises as dt,mkdirSync as Jr,writeFileSync as Xr,renameSync as Zr,existsSync as fs,rmSync as ps}from"fs";import lr from"path";var eo=je();function to(t){return eo(()=>De(Ge,t))}function ro(t){try{Jr(lr.dirname(Ge),{recursive:!0});let e=`${Ge}.sync.tmp`;Xr(e,JSON.stringify(t,null,2),"utf8"),Zr(e,Ge)}catch{}}function hs(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.id=="string"&&typeof e.magnet=="string"}async function oo(){let t;try{t=await dt.readFile(Ge,"utf8")}catch{return[]}try{let e=JSON.parse(t);return Array.isArray(e)?e.filter(hs):[]}catch{return[]}}function no(t){return eo(()=>De(We,t))}function so(t){try{Jr(lr.dirname(We),{recursive:!0});let e=`${We}.sync.tmp`;Xr(e,JSON.stringify(t,null,2),"utf8"),Zr(e,We)}catch{}}function mt(t){return lr.join(ar,`${t}.torrent`)}function io(t){return fs(mt(t))}async function ao(t,e){try{await dt.mkdir(ar,{recursive:!0});let r=mt(t),o=`${r}.tmp`;await dt.writeFile(o,e),await dt.rename(o,r)}catch{}}function Dt(t){try{ps(mt(t),{force:!0})}catch{}}async function co(){let t;try{t=await dt.readFile(We,"utf8")}catch{return[]}try{let e=JSON.parse(t);if(!Array.isArray(e))return[];let r=[];for(let o of e)if(typeof o=="string")r.push({id:o,status:"seeding"});else if(o&&typeof o=="object"){let n=o;typeof n.id=="string"&&(n.status==="seeding"||n.status==="paused")&&r.push({id:n.id,status:n.status})}return r}catch{return[]}}import{promises as gs,mkdirSync as xs,writeFileSync as Ss,renameSync as ys}from"fs";import ws from"path";var ur=500,bs=je();function Ot(t){return bs(()=>De(Qe,t.slice(0,ur)))}function lo(t){try{xs(ws.dirname(Qe),{recursive:!0});let e=`${Qe}.sync.tmp`;Ss(e,JSON.stringify(t.slice(0,ur),null,2),"utf8"),ys(e,Qe)}catch{}}function Ts(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.id=="string"&&typeof e.name=="string"&&typeof e.magnet=="string"}async function uo(){let t;try{t=await gs.readFile(Qe,"utf8")}catch{return[]}try{let e=JSON.parse(t);return Array.isArray(e)?e.filter(Ts).slice(0,ur):[]}catch{return[]}}function Rs(t){return t.total>0&&t.progress<1&&t.speed>0}var Cs=2,Es=1e4,Is=500,mo=500,Nt=class extends vs{items=new Map;engine=new Ht;poll=null;history=[];seeds=new Map;strayHits=new Map;seedStartedAt=new Map;trackers=[];setTrackers(e){this.trackers=e}getItems(){return[...this.items.values()].sort((e,r)=>r.addedAt-e.addedAt)}get activeCount(){let e=0;for(let r of this.items.values())r.status==="downloading"&&e++;return e}has(e){return this.items.has(e)}add(e,r){this.seeds.has(e.id)&&(this.engine.remove(e.id),this.seeds.delete(e.id),this.strayHits.delete(e.id),this.seedStartedAt.delete(e.id),this.persistSeeds());let o=this.items.get(e.id);if(o&&o.status!=="failed")return;let n=o?{...o,status:"downloading",error:void 0,speed:0}:{id:e.id,name:e.name,source:e.source,magnet:e.magnet,dir:r,status:"downloading",progress:0,totalBytes:e.sizeBytes??0,downloadedBytes:0,speed:0,peers:0,addedAt:Date.now()};this.items.set(n.id,n),this.startEngine(n),this.ensurePoll(),this.changed(),this.persist()}startEngine(e){this.engine.add(e.id,e.magnet,e.dir,this.engineHandlers(e.id),this.trackers)}engineHandlers(e){return{onMetadata:r=>{r.torrentFile&&ao(e,r.torrentFile);let o=this.items.get(e);o&&(r.name&&(o.name=r.name),r.total&&(o.totalBytes=r.total),o.files=r.files,this.changed(),this.persist())},onDone:()=>{let r=this.items.get(e);if(r){r.totalBytes&&(r.downloadedBytes=r.totalBytes),this.complete(r);return}this.seeds.has(e)&&(this.strayHits.set(e,0),this.seedStartedAt.delete(e))},onError:r=>{let o=this.items.get(e);if(o){o.status="failed",o.error=r,o.speed=0,o.peers=0,this.changed(),this.persist(),this.maybeStopPoll();return}let n=this.seeds.get(e);n&&(n.status="missing",n.uploadSpeed=0,n.peers=0,this.seedStartedAt.delete(e),this.changed(),this.persistSeeds(),this.maybeStopPoll())}}}complete(e){this.recordHistory(e),this.items.delete(e.id),this.beginSeed(e),this.emit("completed",e.name),this.changed(),this.persist(),this.maybeStopPoll()}beginSeed(e){e.magnet&&(this.seeds.set(e.id,{id:e.id,name:e.name,source:e.source,magnet:e.magnet,dir:e.dir,sizeBytes:e.totalBytes,status:"seeding",uploadSpeed:0,uploaded:0,peers:0}),this.strayHits.set(e.id,0),this.seedStartedAt.set(e.id,Date.now()),this.ensurePoll(),this.persistSeeds())}tick(){let e=!1;for(let o of this.items.values()){if(o.status!=="downloading")continue;let n=this.engine.stats(o.id);n&&(o.progress=Math.min(100,Math.round(n.progress*100)),o.downloadedBytes=n.downloaded,n.total&&(o.totalBytes=n.total),o.speed=n.speed,o.peers=n.peers,o.eta=n.timeRemaining>0&&Number.isFinite(n.timeRemaining)?n.timeRemaining/1e3:void 0,n.name&&(o.name=n.name),e=!0)}let r=Date.now();for(let o of this.seeds.values()){if(o.status!=="seeding")continue;let n=this.engine.stats(o.id);if(!n)continue;if(r-(this.seedStartedAt.get(o.id)??0)>Es&&Rs(n)){let i=(this.strayHits.get(o.id)??0)+1;this.strayHits.set(o.id,i),i>=Cs&&(this.engine.remove(o.id),this.strayHits.delete(o.id),this.seedStartedAt.delete(o.id),o.status="missing",o.uploadSpeed=0,o.peers=0,this.persistSeeds()),e=!0;continue}this.strayHits.set(o.id,0),o.uploadSpeed=n.uploadSpeed,o.uploaded=n.uploaded,o.peers=n.peers,e=!0}e&&this.changed()}ensurePoll(){this.poll||(this.poll=setInterval(()=>this.tick(),Is),this.poll.unref())}maybeStopPoll(){this.activeCount===0&&this.seedingCount===0&&this.poll&&(clearInterval(this.poll),this.poll=null)}pause(e){let r=this.items.get(e);!r||r.status!=="downloading"||(r.status="paused",r.speed=0,r.peers=0,r.eta=void 0,this.engine.remove(e),this.changed(),this.persist(),this.maybeStopPoll())}resume(e){let r=this.items.get(e);!r||r.status!=="paused"||(r.status="downloading",this.startEngine(r),this.ensurePoll(),this.changed(),this.persist())}togglePause(e){let r=this.items.get(e);r&&(r.status==="downloading"?this.pause(e):r.status==="paused"&&this.resume(e))}cancel(e){this.items.has(e)&&(this.engine.remove(e),this.items.delete(e),Dt(e),this.changed(),this.persist(),this.maybeStopPoll())}retry(e){let r=this.items.get(e);!r||r.status!=="failed"||(r.status="downloading",r.error=void 0,this.startEngine(r),this.ensurePoll(),this.changed(),this.persist())}retryFailed(){for(let e of[...this.items.values()])e.status==="failed"&&this.retry(e.id)}getSeed(e){return this.seeds.get(e)}getSeeds(){return[...this.seeds.values()]}get seedingCount(){let e=0;for(let r of this.seeds.values())r.status==="seeding"&&e++;return e}startSeeding(e){if(this.seeds.get(e.id)?.status==="seeding"||this.items.has(e.id))return;let r={id:e.id,name:e.name,source:e.source,magnet:e.magnet,dir:e.dir,sizeBytes:e.sizeBytes,status:"seeding",uploadSpeed:0,uploaded:0,peers:0};if(!e.magnet){this.seeds.set(e.id,{...r,status:"missing"}),this.changed(),this.persistSeeds();return}this.seeds.set(e.id,r),this.strayHits.set(e.id,0),this.seedStartedAt.set(e.id,Date.now());let o=io(e.id)?mt(e.id):e.magnet;this.engine.add(e.id,o,e.dir,this.engineHandlers(e.id),this.trackers),this.ensurePoll(),this.changed(),this.persistSeeds()}stopSeeding(e){let r=this.seeds.get(e);r&&(this.engine.remove(e),this.strayHits.delete(e),this.seedStartedAt.delete(e),r.status==="seeding"&&(r.status="paused",r.uploadSpeed=0,r.peers=0),this.changed(),this.persistSeeds(),this.maybeStopPoll())}toggleSeeding(e){this.seeds.get(e.id)?.status==="seeding"?this.stopSeeding(e.id):this.startSeeding(e)}restoreSeeds(e){for(let r of e){let o=this.history.find(n=>n.id===r.id);o&&(r.status==="seeding"?this.startSeeding(o):this.restorePaused(o))}}restorePaused(e){this.seeds.has(e.id)||(this.seeds.set(e.id,{id:e.id,name:e.name,source:e.source,magnet:e.magnet,dir:e.dir,sizeBytes:e.sizeBytes,status:"paused",uploadSpeed:0,uploaded:0,peers:0}),this.changed())}seedRecords(){let e=[];for(let r of this.seeds.values())r.status==="seeding"?e.push({id:r.id,status:"seeding"}):e.push({id:r.id,status:"paused"});return e}persistSeeds(){return no(this.seedRecords()).catch(()=>{})}restore(e){for(let r of e)this.items.set(r.id,r),r.status==="downloading"&&this.startEngine(r);this.activeCount>0&&this.ensurePoll(),this.changed()}restoreHistory(e){this.history=e.slice(0,mo)}getHistory(){return this.history}recordHistory(e){let r={id:e.id,name:e.name,source:e.source,sizeBytes:e.totalBytes,magnet:e.magnet,dir:e.dir,completedAt:Date.now()};this.history=[r,...this.history.filter(o=>o.id!==e.id)].slice(0,mo),Ot(this.history).catch(()=>{})}removeHistory(e){let r=this.history.filter(o=>o.id!==e);r.length!==this.history.length&&(this.history=r,this.seeds.has(e)&&(this.engine.remove(e),this.seeds.delete(e),this.strayHits.delete(e),this.seedStartedAt.delete(e),this.persistSeeds(),this.maybeStopPoll()),Dt(e),Ot(this.history).catch(()=>{}),this.changed())}clearHistory(){if(this.history.length!==0){for(let e of this.history)Dt(e.id);if(this.history=[],this.seeds.size>0){for(let e of this.seeds.keys())this.engine.remove(e);this.seeds.clear(),this.strayHits.clear(),this.seedStartedAt.clear(),this.persistSeeds(),this.maybeStopPoll()}Ot(this.history).catch(()=>{}),this.changed()}}changed(){this.emit("update")}async persist(){await to(this.getItems()).catch(()=>{})}persistSync(){ro(this.getItems()),lo(this.history),so(this.seedRecords())}suspend(){for(let e of this.items.values())e.status==="downloading"&&(e.speed=0,e.peers=0,e.eta=void 0);this.persistSync(),this.poll&&(clearInterval(this.poll),this.poll=null),this.engine.destroy()}};function fo(t){let e=new Set,r=[];for(let o of t){if(!o?.id||e.has(o.id)||(e.add(o.id),o.status==="completed"))continue;let n=o.status==="failed"?"failed":o.status==="paused"?"paused":"downloading";r.push({...o,status:n,speed:0,peers:0,eta:void 0})}return r}import{promises as Bs}from"fs";import Ms from"parse-torrent";async function po(t){try{let e=await Bs.readFile(t),r=await Ms(new Uint8Array(e)),o=r?.infoHash?.toLowerCase();if(!o)return null;let n=r.name||o;return{infoHash:o,name:n,magnet:ie(o,n)}}catch{return null}}import{spawn as ho}from"child_process";function dr(t,e){return new Promise(r=>{let o="";try{let n=ho(t,e,{windowsHide:!0}),s=setTimeout(()=>{try{n.kill()}catch{}r("")},4e3);s.unref?.(),n.stdout.on("data",i=>o+=i.toString("utf8")),n.on("error",()=>{clearTimeout(s),r("")}),n.on("close",()=>{clearTimeout(s),r(o)})}catch{r("")}})}function mr(t,e,r){return new Promise(o=>{try{let n=ho(t,e,{windowsHide:!0}),s=!1,i,l=c=>{s||(s=!0,clearTimeout(i),o(c))};i=setTimeout(()=>{try{n.kill()}catch{}l(!1)},4e3),i.unref?.(),n.on("error",()=>l(!1)),n.on("close",c=>l(c===0)),n.stdin?.end(r)}catch{o(!1)}})}var ks=[["wl-paste",["--no-newline"]],["xclip",["-selection","clipboard","-o"]],["xsel",["-b"]]],As=[["wl-copy",[]],["xclip",["-selection","clipboard"]],["xsel",["-b","-i"]]];async function go(){if(process.platform==="win32")return(await dr("powershell",["-NoProfile","-Command","Get-Clipboard"])).trim();if(process.platform==="darwin")return(await dr("pbpaste",[])).trim();for(let[t,e]of ks){let r=(await dr(t,e)).trim();if(r)return r}return""}async function xo(t){if(process.platform==="win32")return mr("powershell",["-NoProfile","-Command","Set-Clipboard -Value ([Console]::In.ReadToEnd())"],t);if(process.platform==="darwin")return mr("pbcopy",[],t);for(let[e,r]of As)if(await mr(e,r,t))return!0;return!1}function Ce(t){if(t===void 0||!Number.isFinite(t)||t<=0)return"0 B";let e=["B","KB","MB","GB","TB"],r=t,o=0;for(;r>=1024&&o<e.length-1;)r/=1024,o++;return`${r.toFixed(o===0?0:2)} ${e[o]}`}var Ps={B:1,KIB:1024,MIB:1024**2,GIB:1024**3,TIB:1024**4,KB:1e3,MB:1e6,GB:1e9,TB:1e12};function we(t){let e=t.match(/([\d.]+)\s*([KMGT]?I?B)/i);return e?Math.round(parseFloat(e[1])*(Ps[e[2].toUpperCase()]??1)):0}function ft(t){if(t===void 0||!Number.isFinite(t)||t<=0)return"";let e=["B/s","KB/s","MB/s","GB/s"],r=t,o=0;for(;r>=1024&&o<e.length-1;)r/=1024,o++;return`${r.toFixed(r<10&&o>0?1:0)} ${e[o]}`}function fr(t){if(!Number.isFinite(t)||t<=0)return"0";if(t<1e4)return String(Math.round(t));let e=Math.round(t/1e3);if(e<1e3)return`${e}k`;let r=t/1e6;return r<10?`${r.toFixed(1).replace(/\.0$/,"")}m`:`${Math.round(r)}m`}function pt(t){if(!t||!Number.isFinite(t)||t<=0)return"";let e=Date.now()/1e3-t;if(e<60)return"\u0442\u043E\u043B\u044C\u043A\u043E \u0447\u0442\u043E";let r=Math.floor(e/60);if(r<60)return`${r} \u043C\u0438\u043D. \u043D\u0430\u0437\u0430\u0434`;let o=Math.floor(r/60);if(o<24){let i=r%60;return i>0?`${o} \u0447 ${i} \u043C\u0438\u043D. \u043D\u0430\u0437\u0430\u0434`:`${o} \u0447 \u043D\u0430\u0437\u0430\u0434`}let n=Math.floor(o/24);if(n<30){let i=o%24;return i>0?`${n} \u0434 ${i} \u0447 \u043D\u0430\u0437\u0430\u0434`:`${n} \u0434 \u043D\u0430\u0437\u0430\u0434`}let s=Math.floor(n/30);return s<12?`${s} \u043C\u0435\u0441. \u043D\u0430\u0437\u0430\u0434`:`${Math.floor(s/12)} \u0433. \u043D\u0430\u0437\u0430\u0434`}function So(t){if(t===void 0||!Number.isFinite(t)||t<0)return"";let e=Math.round(t),r=Math.floor(e/86400),o=Math.floor(e%86400/3600),n=Math.floor(e%3600/60),s=e%60;return r>0?[`${r} \u0434`,o>0?`${o} \u0447`:"",n>0?`${n} \u043C\u0438\u043D`:""].filter(Boolean).join(" "):o>0?n>0?`${o} \u0447 ${n} \u043C\u0438\u043D`:`${o} \u0447`:n>0?s>0?`${n} \u043C\u0438\u043D ${s} \u0441\u0435\u043A`:`${n} \u043C\u0438\u043D`:`${s} \u0441\u0435\u043A`}function $s(t){return t<32||t===127||t===65533||t>=8203&&t<=8207||t>=8232&&t<=8238||t===8288||t===65279||t===8205||t===65039||t===8419||t>=9728&&t<=10175||t>=11008&&t<=11263||t>=126976&&t<=131071}function ae(t){let e="";for(let r of t.normalize("NFC"))$s(r.codePointAt(0))||(e+=r);return e.replace(/\s+/g," ").trim()||"\u0411\u0435\u0437 \u043D\u0430\u0437\u0432\u0430\u043D\u0438\u044F"}function K(t,e){return e<=1?t.slice(0,Math.max(0,e)):t.length<=e?t:t.slice(0,e-1)+"\u2026"}import{createContext as Hs,useContext as Ds,useEffect as pr,useState as hr}from"react";var ht=[{key:"all",label:"\u0412\u0441\u0451"},{key:"games",label:"\u0418\u0433\u0440\u044B",group:"Games"},{key:"movies",label:"\u0424\u0438\u043B\u044C\u043C\u044B",group:"Movies"},{key:"tv",label:"\u0422\u0412",group:"TV"},{key:"anime",label:"\u0410\u043D\u0438\u043C\u0435",group:"Anime"}],_t=Hs(null);function J(){let t=Ds(_t);if(!t)throw new Error("\u0425\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435 \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u043E");return t}function Ve(t){let[e,r]=hr(()=>t.getItems());return pr(()=>{let o=null,n=()=>{o||(o=setTimeout(()=>{o=null,r(t.getItems())},200))};return t.on("update",n),n(),()=>{t.off("update",n),o&&clearTimeout(o)}},[t]),e}function Lt(t){let[e,r]=hr(()=>t.getHistory());return pr(()=>{let o=null,n=()=>{o||(o=setTimeout(()=>{o=null,r(t.getHistory())},200))};return t.on("update",n),n(),()=>{t.off("update",n),o&&clearTimeout(o)}},[t]),e}function yo(t){let[e,r]=hr(()=>new Map(t.getSeeds().map(o=>[o.id,o])));return pr(()=>{let o=null,n=()=>{o||(o=setTimeout(()=>{o=null,r(new Map(t.getSeeds().map(s=>[s.id,s])))},200))};return t.on("update",n),n(),()=>{t.off("update",n),o&&clearTimeout(o)}},[t]),e}import{Box as vo,Text as gr}from"ink";var qe=["\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557","\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557"," \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551"," \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551"," \u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D"," \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D"],Ft=Math.max(...qe.map(t=>[...t].length)),wo=new Set([]);var m={accent:"#ff8f40",text:"#bfbdb6",alt:"#5a6378",good:"#aad94c",warn:"#e6b450",bad:"#d95757",bright:"#d2a6ff"},g={done:"\u2714",error:"\u2718",pending:"\u25CC",pointer:"\u25B6",dot:"\xB7",warn:"\u26A0",bar:"\u258C",down:"\u2193",up:"\u2191",peer:"\u25CF",pause:"\u23F8",all:"\u25CE",games:"\u2726",movies:"\u25C6",tv:"\u25B8",anime:"\u2606",library:"\u2630",copy:"\u2442",sort:"\u2195",search:"\u2315",retry:"\u21BB",clear:"\u2715",delete:"\u2715",back:"\u2190",open:"\u21B5",pauseplay:"\u23F8",stop:"\u25A0"},be="#5a6673",X=2,Os={fitgirl:{tag:"FG",color:m.accent},yts:{tag:"YTS",color:m.good},eztv:{tag:"EZTV",color:m.warn},nyaa:{tag:"NYAA",color:m.bright},subsplease:{tag:"SUB",color:"#5a6378"},"tpb-movies":{tag:"TPB",color:"#95e6cb"},"tpb-tv":{tag:"TPB",color:"#95e6cb"},"x1337-movies":{tag:"1337",color:"#f29668"},"x1337-tv":{tag:"1337",color:"#f29668"},"nnm-movies":{tag:"NNM",color:"#f26d78"},"nnm-tv":{tag:"NNM",color:"#f26d78"},"nnm-games":{tag:"NNM",color:"#f26d78"},torentino:{tag:"TRN",color:"#f26d78"},"rutor-movies":{tag:"RTR",color:"#95e6cb"},"rutor-tv":{tag:"RTR",color:"#95e6cb"},"rutor-games":{tag:"RTR",color:"#95e6cb"},"rutor-anime":{tag:"RTR",color:"#95e6cb"}};function ke(t){return(t?Os[t]:void 0)??{tag:"\u2022",color:m.alt}}function bo(t){let e=parseInt(t.slice(1),16);return[e>>16&255,e>>8&255,e&255]}function ce(t,e,r){let[o,n,s]=bo(t),[i,l,c]=bo(e),a=(u,f)=>Math.round(u+(f-u)*r).toString(16).padStart(2,"0");return`#${a(o,i)}${a(n,l)}${a(s,c)}`}var To=[m.accent,m.bright];import{jsx as gt}from"react/jsx-runtime";var Ns="#ffffff",Ro=m.bright,Co="#5a6378",_s="#3a4048",Ls="#aad94c";function Fs(t){return t<.15?ce(Ns,Ro,t/.15):t<.4?ce(Ro,m.accent,(t-.15)/.25):t<.7?ce(m.accent,Co,(t-.4)/.3):ce(Co,_s,(t-.7)/.3)}function Ut(){let t=qe.length;return gt(vo,{flexDirection:"column",children:qe.map((e,r)=>{let o=Math.max(0,r-1),n=Math.max(1,t-1),s=o/(n-1||1),i=[...e],l=Math.max(1,i.length-1);return gt(vo,{children:i.map((c,a)=>{if(c===" ")return gt(gr,{children:" "},a);if(wo.has(`${r},${a}`))return gt(gr,{bold:!0,color:Ls,children:c},a);let f=(a/l+s)/2;return gt(gr,{bold:!0,color:Fs(f),children:c},a)})},r)})})}import{Box as Ye,Text as zt,useInput as Us}from"ink";function xe(t,e,r){return r<=0?0:((t+e)%r+r)%r}function Oe(t,e,r){if(e<=r)return 0;let o=Math.floor(r/2);return Math.max(0,Math.min(t-o,e-r))}function Eo(t,e){return Math.max(5,t-e-2)}import{jsx as Ee,jsxs as js}from"react/jsx-runtime";var zs=ht.map(t=>({key:t.key,label:t.label,icon:g[t.key]})),Gs=[{key:"downloads",label:"\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0438",icon:g.down},{key:"seeding",label:"\u0420\u0430\u0437\u0434\u0430\u0447\u0438",icon:g.up}],Qs=t=>t==="downloads"||t==="seeding",Io=[zs,Gs],Ke=Io.flat(),Ws=5,xr=X+2+Math.max(...Ke.map(t=>t.label.length+(Qs(t.key)?Ws:0)));function Bo(){let{section:t,setSection:e,region:r,setRegion:o,queue:n}=J(),s=r==="sidebar",i=Math.max(0,Ke.findIndex(a=>a.key===t));Ve(n);let l=n.activeCount,c=n.seedingCount;return Us((a,u)=>{u.upArrow||a==="k"?e(Ke[xe(i,-1,Ke.length)].key):u.downArrow||a==="j"?e(Ke[xe(i,1,Ke.length)].key):u.return&&o("content")},{isActive:s}),Ee(Ye,{flexDirection:"column",width:xr,marginRight:1,children:Io.map((a,u)=>Ee(Ye,{flexDirection:"column",marginTop:u>0?1:0,children:a.map(f=>{let d=f.key===t;return js(Ye,{children:[Ee(Ye,{width:X,flexShrink:0,children:d?Ee(zt,{color:s?To[1]:be,bold:s,children:g.bar}):null}),Ee(Ye,{width:2,flexShrink:0,children:Ee(zt,{color:d?s?m.accent:m.alt:void 0,dimColor:!d,children:f.icon})}),Ee(zt,{color:d?s?m.accent:m.alt:void 0,dimColor:!d,bold:d&&s,children:f.label}),(()=>{let x=f.key==="downloads"?l:f.key==="seeding"?c:0;return x>0?Ee(Ye,{flexShrink:0,children:Ee(zt,{dimColor:!0,children:` (${x})`})}):null})()]},f.key)})},u))})}import{Text as Vs}from"ink";import{jsx as qs}from"react/jsx-runtime";function Gt({width:t}){return qs(Vs,{color:be,children:"\u2500".repeat(Math.max(1,t))})}import{Box as Ys,Text as Je}from"ink";import{jsx as xt,jsxs as Mo}from"react/jsx-runtime";function ko({hints:t}){return xt(Ys,{children:xt(Je,{children:t.map((e,r)=>Mo(Je,{children:[r>0?xt(Je,{dimColor:!0,children:" "}):null,e.icon?Mo(Je,{children:[e.icon," "]}):null,xt(Je,{color:m.alt,children:e.keys}),xt(Je,{dimColor:!0,children:` ${e.label}`})]},e.keys+e.label))})})}import{Box as Ze,Text as et}from"ink";var Xe=[{title:"\u041D\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044F",hints:[{keys:"\u2191 \u2193 \u2190 \u2192, h j k l",label:"\u041D\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044F \u043F\u043E \u043A\u043E\u043D\u0442\u0435\u043D\u0442\u0443 \u0438 \u043F\u0430\u043D\u0435\u043B\u044F\u043C"},{keys:"\u21B5",label:"\u041E\u0442\u043A\u0440\u044B\u0442\u044C"},{keys:"tab",label:"\u0421\u043C\u0435\u043D\u0430 \u043F\u0430\u043D\u0435\u043B\u0438"},{keys:"esc",label:"\u041D\u0430\u0437\u0430\u0434"},{keys:"o",label:"\u041F\u0430\u043F\u043A\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043E\u043A"},{keys:"t",label:"\u0414\u043E\u043F. \u0442\u0440\u0435\u043A\u0435\u0440\u044B"},{keys:"q",label:"\u0412\u044B\u0445\u043E\u0434"}]},{title:"\u041F\u043E\u0438\u0441\u043A",hints:[{keys:"/",label:"\u0420\u0435\u0434\u0430\u043A\u0442. \u043F\u043E\u0438\u0441\u043A"},{keys:"\u21B5",label:"\u041F\u043E\u0438\u0441\u043A"},{keys:"s",label:"\u0421\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0430"},{keys:"y",label:"\u041A\u043E\u043F. \u043C\u0430\u0433\u043D\u0435\u0442"},{keys:"m",label:"\u0412\u0441\u0442. \u043C\u0430\u0433\u043D\u0435\u0442"}]},{title:"\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0438",hints:[{keys:"p",label:"\u041F\u0430\u0443\u0437\u0430/\u043F\u0440\u043E\u0434."},{keys:"c",label:"\u041E\u0442\u043C\u0435\u043D\u0430/\u0443\u0434\u0430\u043B\u0435\u043D\u0438\u0435"},{keys:"f",label:"\u041F\u043E\u0432\u0442\u043E\u0440 \u043E\u0448\u0438\u0431\u043A\u0438"},{keys:"d",label:"\u0421\u043A\u0430\u0447\u0430\u0442\u044C \u0441\u043D\u043E\u0432\u0430"},{keys:"x",label:"\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u044C"}]},{title:"\u0420\u0430\u0437\u0434\u0430\u0447\u0438",hints:[{keys:"p",label:"\u041F\u0430\u0443\u0437\u0430/\u043F\u0440\u043E\u0434."},{keys:"c",label:"\u0423\u0434\u0430\u043B\u0438\u0442\u044C"}]}],Sr={keys:"\u2191\u2193\u2190\u2192",label:"\u0414\u0432\u0438\u0436.",icon:g.pointer},Ne={keys:"?",label:"\u041A\u043B\u0430\u0432\u0438\u0448\u0438",icon:g.all},_e={keys:"tab",label:"\u0421\u043C\u0435\u043D\u0430",icon:g.library};function Ao(t,e,r,o){return t==="sidebar"?[Sr,{keys:"\u21B5",label:"\u041E\u0442\u043A\u0440\u044B\u0442\u044C",icon:g.open},_e,Ne,{keys:"q",label:"\u0412\u044B\u0445\u043E\u0434",icon:g.delete}]:e==="seeding"?[{keys:"p",label:o==="seeding"?"\u041F\u0430\u0443\u0437\u0430":o==="missing"?"\u041F\u043E\u0432\u0442\u043E\u0440":"\u041F\u0440\u043E\u0434.",icon:g.pauseplay},{keys:"c",label:"\u0423\u0434\u0430\u043B\u0438\u0442\u044C",icon:g.delete},_e,Ne]:e==="downloads"?r==="paused"?[{keys:"p",label:"\u041F\u0440\u043E\u0434.",icon:g.pauseplay},{keys:"c",label:"\u041E\u0442\u043C\u0435\u043D\u0430",icon:g.stop},_e,Ne]:r==="failed"?[{keys:"f",label:"\u041F\u043E\u0432\u0442\u043E\u0440",icon:g.retry},{keys:"c",label:"\u0423\u0434\u0430\u043B\u0438\u0442\u044C",icon:g.delete},_e,Ne]:r==="recent"?[Sr,{keys:"d",label:"\u0417\u0430\u043D\u043E\u0432\u043E",icon:g.retry},{keys:"c",label:"\u0423\u0434\u0430\u043B\u0438\u0442\u044C",icon:g.delete},{keys:"x",label:"\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u044C",icon:g.clear},_e,Ne]:[{keys:"p",label:"\u041F\u0430\u0443\u0437\u0430",icon:g.pauseplay},{keys:"c",label:"\u041E\u0442\u043C\u0435\u043D\u0430",icon:g.stop},_e,Ne]:[Sr,{keys:"d",label:"\u0421\u043A\u0430\u0447\u0430\u0442\u044C",icon:g.down},{keys:"y",label:"\u041A\u043E\u043F.",icon:g.copy},{keys:"s",label:"\u0421\u043E\u0440\u0442.",icon:g.sort},{keys:"/",label:"\u041F\u043E\u0438\u0441\u043A",icon:g.search},_e,Ne]}import{jsx as Ae,jsxs as Qt}from"react/jsx-runtime";var Ks=ce(m.accent,be,.55),Js=2,Po=2,yr=Xe.map(t=>Math.max(...t.hints.map(e=>e.keys.length))+Js),$o=Xe.map((t,e)=>yr[e]+Math.max(...t.hints.map(r=>r.label.length))),Xs=$o.reduce((t,e)=>t+e,0)+(Xe.length-1)*Po+4,Zs=Math.max(...yr);function Ho(){let{cols:t}=J(),e=t>=Xs;return Qt(Ze,{flexDirection:"column",alignSelf:"flex-start",borderStyle:"round",borderColor:Ks,paddingX:e?1:2,paddingY:1,children:[Ae(et,{bold:!0,color:m.accent,children:"\u041A\u043B\u0430\u0432\u0438\u0448\u0438"}),Ae(Ze,{marginTop:1,flexDirection:e?"row":"column",children:Xe.map((r,o)=>Qt(Ze,{flexDirection:"column",width:e?$o[o]:void 0,marginRight:e&&o<Xe.length-1?Po:0,marginTop:!e&&o>0?1:0,children:[Ae(et,{bold:!0,children:r.title}),r.hints.map(n=>Qt(Ze,{children:[Ae(Ze,{width:e?yr[o]:Zs,flexShrink:0,children:Ae(et,{color:m.alt,children:n.keys})}),Ae(et,{dimColor:!0,children:n.label})]},n.keys+n.label))]},r.title))}),Qt(Ze,{marginTop:1,flexDirection:"column",children:[Ae(et,{dimColor:!0,children:"\u0421\u043A\u0430\u0447\u0430\u043D\u043D\u044B\u0435 \u0444\u0430\u0439\u043B\u044B \u0432\u0441\u0435\u0433\u0434\u0430 \u043E\u0441\u0442\u0430\u044E\u0442\u0441\u044F \u043D\u0430 \u0434\u0438\u0441\u043A\u0435."}),Ae(et,{dimColor:!0,children:"\u041D\u0430\u0436\u043C\u0438\u0442\u0435 ? \u0438\u043B\u0438 esc \u0434\u043B\u044F \u0437\u0430\u043A\u0440\u044B\u0442\u0438\u044F"})]})]})}import{useEffect as Br,useMemo as Mr,useState as Kt}from"react";import{Box as P,Text as T,useInput as kr}from"ink";import{useEffect as ei,useState as ti}from"react";import{Text as wr}from"ink";import{jsx as Oo,jsxs as ri}from"react/jsx-runtime";var Do=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"];function Wt({label:t}){let[e,r]=ti(0);return ei(()=>{let o=setInterval(()=>r(n=>(n+1)%Do.length),80);return o.unref?.(),()=>clearInterval(o)},[]),ri(wr,{children:[Oo(wr,{color:m.accent,children:Do[e]}),t?Oo(wr,{dimColor:!0,children:` ${t}`}):null]})}import{Box as Uo,Text as vr}from"ink";import{useState as No}from"react";import{Text as Pe,useInput as oi}from"ink";import{jsx as tt,jsxs as Lo}from"react/jsx-runtime";function ni(t,e){return e===0?{value:t,cursor:e}:{value:t.slice(0,e-1)+t.slice(e),cursor:e-1}}function si(t,e){let r=e;for(;r>0&&t[r-1]===" ";)r--;for(;r>0&&t[r-1]!==" ";)r--;return{value:t.slice(0,r)+t.slice(e),cursor:r}}function ii(t,e){return{value:t.slice(0,e),cursor:e}}function ai(t,e,r){return{value:t.slice(0,e)+r+t.slice(e),cursor:e+r.length}}var _o=" ";function rt({isDisabled:t=!1,defaultValue:e="",placeholder:r="",onChange:o,onSubmit:n,onExitDown:s,onExitLeft:i}){let[l,c]=No(e),[a,u]=No(e.length);function f(S){c(S.value),u(Math.max(0,Math.min(S.value.length,S.cursor))),S.value!==l&&o?.(S.value)}if(oi((S,y)=>{if(y.downArrow){s?.();return}if(y.upArrow||y.tab||y.ctrl&&S==="c")return;if(y.return){n?.(l);return}if(y.ctrl)switch(S){case"u":f({value:"",cursor:0});return;case"w":f(si(l,a));return;case"k":f(ii(l,a));return;case"a":u(0);return;case"e":u(l.length);return;default:return}if(y.leftArrow){if(a===0){i?.();return}u(a-1);return}if(y.rightArrow){u(Math.min(l.length,a+1));return}if(y.backspace||y.delete){f(ni(l,a));return}if(y.meta||!S)return;let C=S.replace(/\x1b?\[<\d+;\d+;\d+[Mm]/g,"");C&&f(ai(l,a,C))},{isActive:!t}),t)return l?tt(Pe,{children:l}):tt(Pe,{dimColor:!0,children:r});if(l.length===0)return r?Lo(Pe,{children:[tt(Pe,{inverse:!0,children:r[0]}),tt(Pe,{dimColor:!0,children:r.slice(1)})]}):tt(Pe,{inverse:!0,children:_o});let d=l.slice(0,a),x=l[a]??_o,R=a<l.length?l.slice(a+1):"";return Lo(Pe,{children:[d,tt(Pe,{inverse:!0,children:x}),R]})}import{Box as br,Text as Tr}from"ink";import{jsx as jt,jsxs as Fo}from"react/jsx-runtime";function Z({title:t,width:e,focused:r,count:o,height:n,children:s}){let i=r?m.accent:be,l=Math.max(10,e),c=t.charAt(0).toUpperCase()+t.slice(1),a=o?`${c} ${o}`:c,u=Math.max(0,l-5-a.length);return Fo(br,{flexDirection:"column",width:l,children:[Fo(br,{children:[jt(Tr,{color:i,children:"\u256D\u2500 "}),jt(Tr,{bold:!0,color:i,children:a}),jt(Tr,{color:i,children:` ${"\u2500".repeat(u)}\u256E`})]}),jt(br,{width:l,height:n,flexGrow:n?0:1,flexDirection:"column",borderStyle:"round",borderTop:!1,borderColor:i,paddingX:1,overflow:"hidden",children:s})]})}import{jsx as ot,jsxs as ci}from"react/jsx-runtime";function Vt({width:t,value:e,placeholder:r="\u041F\u043E\u0438\u0441\u043A \u0442\u043E\u0440\u0440\u0435\u043D\u0442\u043E\u0432\u2026",editing:o,onSubmit:n,onChange:s,onExitDown:i,onExitLeft:l}){return ot(Z,{title:"\u043F\u043E\u0438\u0441\u043A",width:t,focused:o,height:2,children:ci(Uo,{children:[ot(vr,{color:m.accent,children:`${g.pointer} `}),ot(Uo,{flexGrow:1,minWidth:0,children:o?ot(rt,{defaultValue:e,placeholder:r,onSubmit:n,onChange:s,onExitDown:i,onExitLeft:l}):e?ot(vr,{wrap:"truncate-end",children:e}):ot(vr,{dimColor:!0,children:r})})]})})}import{useEffect as ia,useState as aa}from"react";var L="torio (+https://www.npmjs.com/package/torio)",k=class extends Error{status;constructor(e,r){super(r??`HTTP ${e}`),this.name="HttpError",this.status=e}},li=new Set([408,425,429,500,502,503,504]),ui=5,di=500,mi=2e4;function fi(t){return new Promise(e=>setTimeout(e,t))}function pi(t){return t instanceof Error&&(t.name==="AbortError"||/aborted/i.test(t.message))}function hi(t,e=Date.now()){if(!t)return;let r=t.trim();if(/^\d+$/.test(r))return Number(r)*1e3;let o=Date.parse(r);if(!Number.isNaN(o))return Math.max(0,o-e)}function zo(t,e,r,o,n=Math.random){let s=Math.min(r,e*2**t),i=Math.floor(n()*s);return o!==void 0?Math.max(i,o):i}async function F(t,e={}){let{retries:r=ui,baseMs:o=di,capMs:n=mi,fetchImpl:s=fetch,sleepImpl:i=fi,signal:l,...c}=e,a=l?{...c,signal:l}:c,u;for(let f=0;f<=r;f++){if(l?.aborted)throw new k(0,"aborted");let d;try{d=await s(t,a)}catch(S){if(pi(S)||l?.aborted)throw S;if(u=S,f<r){await i(zo(f,o,n));continue}throw S}if(!li.has(d.status))return d;let x=d.headers.get("server")?.toLowerCase()||"";if(d.status===503&&(x.includes("ddos-guard")||x.includes("cloudflare")))throw new k(d.status,`Request to ${t} blocked by ${x} (HTTP ${d.status}).`);if(f>=r)throw new k(d.status,`Request to ${t} failed after ${r} retries (HTTP ${d.status}).`);let R=hi(d.headers.get("retry-after"));await i(zo(f,o,n,R))}throw u instanceof Error?u:new k(0,"fetchResilient exhausted without a response")}var gi="https://eztvx.to/api/get-torrents";async function xi(t,e={}){if(t.trim())return[];let r=await F(`${gi}?limit=100&page=1`,{headers:{"User-Agent":L},signal:e.signal,retries:1});if(!r.ok)throw new k(r.status,`EZTV returned ${r.status}`);let o=await r.json(),n=[];for(let s of o.torrents??[]){let i=(s.hash??"").toLowerCase(),l=s.title||s.filename||i,c=s.magnet_url||(i?ie(i,l):"");!c||!i||n.push({infoHash:i,name:l,sizeBytes:Number(s.size_bytes??0)||0,seeders:s.seeds??0,leechers:s.peers??0,source:"eztv",magnet:c,added:s.date_released_unix})}return n}var Go={id:"eztv",label:"EZTV",group:"TV",homepage:"https://eztvx.to",search:xi};function fe(t){return t.replace(/�?38;|&/g,"&").replace(/–|—/g,"-").replace(/’|�?39;|'/g,"'").replace(/“|”|"/g,'"').replace(/</g,"<").replace(/>/g,">")}function Qo(t,e){let r=t.split("<item>").slice(1),o=[];for(let n of r){let s=n.match(/href="(magnet:\?xt=urn:btih:[^"]+)"/i);if(!s)continue;let i=fe(s[1]),l=i.match(/urn:btih:([a-zA-Z0-9]+)/)?.[1]?.toLowerCase()??"";if(!l)continue;let c=fe(n.match(/<title>(.*?)<\/title>/)?.[1]??"Unknown Title"),a=n.match(/<pubDate>(.*?)<\/pubDate>/)?.[1]??"",u=a?new Date(a).getTime()/1e3:0;o.push({infoHash:l,name:c,sizeBytes:0,seeders:0,leechers:0,source:e,magnet:i,added:u})}return o}var Si=10,yi=3,wi=2;function Wo(t,e,r){let o=e.trim(),n=o?`${t}/?s=${encodeURIComponent(o)}&feed=rss2`:`${t}/feed/`;return r<=1?n:`${n}${o?"&":"?"}paged=${r}`}async function jo(t,e,r,o){let n=await F(t,{headers:{"User-Agent":L},signal:r.signal,...o!==void 0?{retries:o}:{}});if(!n.ok)throw new k(n.status,`${e} feed returned ${n.status}`);return n.text()}async function Vo(t,e,r,o={}){let n=await jo(Wo(t,r,1),e,o),s=Qo(n,e);if(n.split("<item>").length-1<Si)return s;let l=await Promise.all(Array.from({length:yi-1},(a,u)=>jo(Wo(t,r,u+2),e,o,wi).then(f=>Qo(f,e)).catch(()=>[]))),c=new Set(s.map(a=>a.infoHash));for(let a of l.flat())c.has(a.infoHash)||(c.add(a.infoHash),s.push(a));return s}var qo="https://fitgirl-repacks.site",Yo={id:"fitgirl",label:"FitGirl",group:"Games",homepage:qo,search:(t,e)=>Vo(qo,"fitgirl",t,e)};var yt="https://nnmclub.to",bi="windows-1251",Ti=8;async function Ko(t,e,r=2){let o=await F(t,{headers:{"User-Agent":L},signal:e.signal,retries:r});if(!o.ok)throw new k(o.status,`NNM returned ${o.status}`);let n=await o.arrayBuffer();return new TextDecoder(bi).decode(new Uint8Array(n))}function St(t){return t.replace(/<[^>]+>/g,"").replace(/ /gi," ").replace(/\xa0/g," ").trim()}function vi(t){let e=[],r=/<tr[^>]*>[\s\S]*?<\/tr>/gi,o;for(;(o=r.exec(t))!==null;){let s=o[0].match(/<td[^>]*>[\s\S]*?<\/td>/gi);if(!s||s.length<9)continue;let l=s[1].match(/href="[^"]*viewtopic\.php\?t=(\d+)"[^>]*>(.*?)<\/a>/i);if(!l)continue;let c=l[1],a=fe(St(l[2]));if(!a)continue;let u=St(s[4]),f=Number(u.match(/^(\d+)/)?.[1]??0),d=f>0?f:(()=>{let y=u.match(/([\d.]+\s*[KMGT]I?B)/i);return y?we(y[1]):0})(),x=Number(St(s[5]).match(/(\d+)/)?.[1]??0),R=Number(St(s[6]).match(/(\d+)/)?.[1]??0),S=Number(St(s[8]).match(/^(\d{10})/)?.[1]??0);e.push({name:a,topicId:c,sizeBytes:d,seeders:x,leechers:R,added:S})}return e}async function Ri(t,e){try{let r=`${yt}/forum/viewtopic.php?t=${t}`,n=(await Ko(r,e,1)).match(/href="(magnet:\?xt=urn:btih:[^"<>]+)"/i);return n?fe(n[1]):null}catch{return null}}async function Rr(t,e,r={}){let o=t.trim(),n=`${yt}/forum/tracker.php?f=-1`;o&&(n+=`&nm=${encodeURIComponent(o)}`);let s=await Ko(n,r),i=vi(s),l=o.toLowerCase().split(/\s+/).filter(Boolean),c=l.length?i.filter(f=>l.every(d=>f.name.toLowerCase().includes(d))):i;c.sort((f,d)=>d.seeders-f.seeders);let a=c.slice(0,Ti);return(await Promise.all(a.map(async f=>{let d=await Ri(f.topicId,r),x=d?.match(/urn:btih:([a-zA-Z0-9]+)/i)?.[1]?.toLowerCase();return!d||!x?null:{infoHash:x,name:f.name,sizeBytes:f.sizeBytes,seeders:f.seeders,leechers:f.leechers,source:e,magnet:d,added:f.added||void 0}}))).filter(f=>f!==null)}var Jo={id:"nnm-movies",label:"NNM Club",group:"Movies",homepage:yt,search:(t,e={})=>Rr(t,"nnm-movies",e)},Xo={id:"nnm-tv",label:"NNM Club",group:"TV",homepage:yt,search:(t,e={})=>Rr(t,"nnm-tv",e)},Zo={id:"nnm-games",label:"NNM Club",group:"Games",homepage:yt,search:(t,e={})=>Rr(t,"nnm-games",e)};var Ci="https://nyaa.si/";function nt(t,e){return t.match(new RegExp(`<${e}>(?:<!\\[CDATA\\[)?(.*?)(?:\\]\\]>)?</${e}>`,"s"))?.[1]?.trim()??""}async function Ei(t,e={}){let r=new URLSearchParams({page:"rss",q:t.trim(),c:"0_0",f:"0"}),o=await F(`${Ci}?${r.toString()}`,{headers:{"User-Agent":L},signal:e.signal});if(!o.ok)throw new k(o.status,`Nyaa returned ${o.status}`);let n=await o.text(),s=[];for(let i of n.split("<item>").slice(1)){let l=nt(i,"nyaa:infoHash").toLowerCase(),c=fe(nt(i,"title"));if(!l||!c)continue;let a=Number(nt(i,"nyaa:seeders")),u=Number(nt(i,"nyaa:leechers")),f=nt(i,"pubDate");s.push({infoHash:l,name:c,sizeBytes:we(nt(i,"nyaa:size")),seeders:Number.isFinite(a)?a:0,leechers:Number.isFinite(u)?u:0,source:"nyaa",magnet:ie(l,c),added:f?new Date(f).getTime()/1e3:void 0})}return s}var en={id:"nyaa",label:"Nyaa",group:"Anime",homepage:"https://nyaa.si",search:Ei};var wt="https://rutor.info",Ii={\u042F\u043D\u0432:0,\u0424\u0435\u0432:1,\u041C\u0430\u0440:2,\u0410\u043F\u0440:3,\u041C\u0430\u0439:4,\u0418\u044E\u043D:5,\u0418\u044E\u043B:6,\u0410\u0432\u0433:7,\u0421\u0435\u043D:8,\u041E\u043A\u0442:9,\u041D\u043E\u044F:10,\u0414\u0435\u043A:11};function Bi(t){let e=t.match(/(\d{1,2})\s+([А-Яа-я]{3})\s+(\d{2})/);if(!e)return;let r=e[2].charAt(0).toUpperCase()+e[2].slice(1).toLowerCase(),o=Ii[r];if(o===void 0)return;let n=Number(e[1]),s=2e3+Number(e[3]),i=Math.floor(Date.UTC(s,o,n)/1e3);return Number.isNaN(i)?void 0:i}function Mi(t,e){let r=t.indexOf('<div id="index">');if(r<0)return[];let o=t.slice(r),n=[],s=o.split(/<tr\s+class="(?:gai|tum)">/i).slice(1);for(let i of s){let l=i.indexOf("</tr>"),c=l>=0?i.slice(0,l):i,a=c.match(/href="(magnet:[^"]+)"/i)?.[1];if(!a)continue;let u=a.match(/xt=urn:btih:([a-f0-9]{40})/i)?.[1]?.toLowerCase();if(!u)continue;let f=c.match(/href="(\/torrent\/\d+\/[^"]+)"[^>]*>([^<]+)<\/a>/i);if(!f)continue;let d=fe(f[2].trim()),x=Number(c.match(/<span class="green">.*?(\d+)\s*<\/span>/i)?.[1]??0),R=Number(c.match(/<span class="red">.*?(\d+)\s*<\/span>/i)?.[1]??0),S=c.match(/<td[^>]*align="right"[^>]*>([\d.]+\s*(?:[KMGT]i?B|B))\s*<\/td>/i),y=S?we(S[1]):0,C=c.match(/<td[^>]*>\s*(\d{1,2}\s+[А-Яа-я]{3}\s+\d{2})\s*<\/td>/),M=C?Bi(C[1]):void 0;n.push({infoHash:u,name:d,sizeBytes:y,seeders:x,leechers:R,source:e,magnet:a,added:M})}return n}async function qt(t,e,r={}){let o=t.trim();if(!o)return[];let n=`${wt}/search/0/0/000/0/${encodeURIComponent(o)}`,s=await F(n,{headers:{"User-Agent":L},signal:r.signal,retries:2});if(!s.ok)throw new k(s.status,`Rutor returned ${s.status}`);let i=await s.text();return Mi(i,e)}var tn={id:"rutor-movies",label:"Rutor",group:"Movies",homepage:wt,search:(t,e={})=>qt(t,"rutor-movies",e)},rn={id:"rutor-tv",label:"Rutor",group:"TV",homepage:wt,search:(t,e={})=>qt(t,"rutor-tv",e)},on={id:"rutor-games",label:"Rutor",group:"Games",homepage:wt,search:(t,e={})=>qt(t,"rutor-games",e)},nn={id:"rutor-anime",label:"Rutor",group:"Anime",homepage:wt,search:(t,e={})=>qt(t,"rutor-anime",e)};var ki="https://subsplease.org/api/",Ai=["1080","720","480"];function Pi(t){for(let e of Ai){let r=t.find(o=>o.res===e&&o.magnet);if(r)return r}return t.find(e=>e.magnet)}async function $i(t,e={}){let r=t.trim(),o=new URLSearchParams({tz:"UTC"});r?(o.set("f","search"),o.set("s",r)):o.set("f","latest");let n=await F(`${ki}?${o.toString()}`,{headers:{"User-Agent":L},signal:e.signal});if(!n.ok)throw new k(n.status,`SubsPlease returned ${n.status}`);let s=await n.json();if(!s||Array.isArray(s))return[];let i=[];for(let l of Object.values(s)){let c=Pi(l.downloads??[]);if(!c?.magnet)continue;let a=rr(c.magnet);if(!a)continue;let u=l.show??"Unknown",f=l.episode?` - ${l.episode}`:"",d=c.magnet.match(/[?&]xl=(\d+)/);i.push({infoHash:a.infoHash,name:`${u}${f} [${c.res??"?"}p]`,sizeBytes:d?Number(d[1]):0,seeders:0,leechers:0,source:"subsplease",magnet:a.magnet,added:l.release_date?new Date(l.release_date).getTime()/1e3:void 0})}return i}var sn={id:"subsplease",label:"SubsPlease",group:"Anime",homepage:"https://subsplease.org",search:$i};import Hi from"parse-torrent";var Yt="https://torentino.org",Di=10;function Oi(t){let e=t.match(/(\d{2})\.(\d{2})\.(\d{4})/);if(!e)return 0;let r=Math.floor(Date.UTC(Number(e[3]),Number(e[2])-1,Number(e[1]))/1e3);return Number.isNaN(r)?0:r}function Ni(t){let e=[],r=t.split('<div class="shortstory">').slice(1);for(let o of r){let n=o.match(/href="(\/load\/[^"]+\/(\d+-\d+-\d+-(\d+)))"/);if(!n)continue;let s=n[1],i=Number(n[3]);if(!i)continue;let l=o.match(/<h2>\s*<a[^>]*>([^<]+)<\/a>\s*<\/h2>/);if(!l)continue;let c=l[1].replace(/\s*скачать\s+торрент\s*$/i,"").trim(),a=o.match(/<div class="short_cat">\s*<a[^>]*>([^<]+)<\/a>/),u=a?a[1].trim():"",f=o.match(/\|\s*Дата:\s*([\d.,:\s]+)<\/span>/),d=f?Oi(f[1]):0;e.push({id:i,name:c,path:s,category:u,added:d})}return e}async function _i(t,e){try{let r=await F(`${Yt}${t.path}`,{headers:{"User-Agent":L},signal:e.signal,retries:1});if(!r.ok)return null;let o=await r.text(),n=0,s=o.match(/Место\s+на\s+диске[^<]*<\/b>\s*([^<]+)/i);return s&&(n=we(s[1].trim())),{sizeBytes:n}}catch{return null}}async function Li(t,e){try{let r=await F(`${Yt}/load/0-0-0-${t}-20`,{headers:{"User-Agent":L},signal:e.signal,retries:1});if(!r.ok)return null;let o=await r.arrayBuffer();return(await Hi(new Uint8Array(o)))?.infoHash?.toLowerCase()??null}catch{return null}}var an={id:"torentino",label:"Torentino",group:"Games",homepage:Yt,search:async(t,e={})=>{let r=t.trim();if(!r)return[];let o=new URLSearchParams({do:"search",subaction:"search",a:"2",query:r}),n=await F(`${Yt}/load`,{method:"POST",headers:{"User-Agent":L,"Content-Type":"application/x-www-form-urlencoded"},body:o.toString(),signal:e.signal});if(!n.ok)throw new k(n.status,`Torentino returned ${n.status}`);let s=await n.text(),i=Ni(s).slice(0,Di);return(await Promise.all(i.map(async c=>{let[a,u]=await Promise.all([_i(c,e),Li(c.id,e)]);if(!u)return null;let f=ie(u,c.name);return{infoHash:u,name:c.name,sizeBytes:a?.sizeBytes??0,seeders:0,leechers:0,source:"torentino",magnet:f,added:c.added||void 0}}))).filter(c=>c!==null)}};var Cr="https://apibay.org",Fi=new Set([201,202,207,209]),Ui=new Set([205,208]),zi=`${Cr}/precompiled/data_top100_207.json`,Gi=`${Cr}/precompiled/data_top100_208.json`,Qi="0000000000000000000000000000000000000000";function Wi(t,e){let r=(t.info_hash??"").toLowerCase();if(!r||r===Qi||t.id==="0")return null;let o=t.name||"Unknown",n=Number(t.num_files);return{infoHash:r,name:o,sizeBytes:Number(t.size)||0,seeders:Number(t.seeders)||0,leechers:Number(t.leechers)||0,numFiles:Number.isFinite(n)&&n>0?n:void 0,source:e,magnet:ie(r,o),added:Number(t.added)||void 0}}async function ji(t,e){let r=await F(t,{headers:{"User-Agent":L},signal:e.signal,retries:1});if(!r.ok)throw new k(r.status,`Pirate Bay returned ${r.status}`);let o=await r.json();return Array.isArray(o)?o:[]}async function cn(t,e,r,o,n){let s=t.trim(),i=await ji(s?`${Cr}/q.php?q=${encodeURIComponent(s)}`:r,n),l=[];for(let c of i){if(s&&!e.has(Number(c.category)))continue;let a=Wi(c,o);a&&l.push(a)}return l}var ln={id:"tpb-movies",label:"TPB",group:"Movies",homepage:"https://thepiratebay.org",search:(t,e={})=>cn(t,Fi,zi,"tpb-movies",e)},un={id:"tpb-tv",label:"TPB",group:"TV",homepage:"https://thepiratebay.org",search:(t,e={})=>cn(t,Ui,Gi,"tpb-tv",e)};var Vi=["1337x.to","1337x.st","x1337x.ws","1337xx.to"],qi=8,Yi=new Set(["the","a","an","of","and","or","to"]);function Ki(t){let e=t.indexOf("table-list");if(e<0)return[];let r=[];for(let o of t.slice(e).split(/<tr[\s>]/i).slice(1)){let n=o.match(/href="(\/torrent\/[^"]+)"[^>]*>([^<]+)<\/a>/i);if(!n)continue;let s=o.match(/class="coll-4 size[^"]*">\s*([\d.]+\s*[KMGT]i?B)/i)?.[1]??"";r.push({name:fe(n[2].trim()),path:n[1],seeders:Number(o.match(/class="coll-2 seeds[^"]*">\s*(\d+)/i)?.[1]??0),leechers:Number(o.match(/class="coll-3 leeches[^"]*">\s*(\d+)/i)?.[1]??0),sizeBytes:we(s)})}return r}async function dn(t,e,r){let o=await F(t,{headers:{"User-Agent":L},signal:e.signal,retries:r});if(!o.ok)throw new k(o.status,`1337x returned ${o.status}`);return o.text()}var Ji={jan:0,feb:1,mar:2,apr:3,may:4,jun:5,jul:6,aug:7,sep:8,oct:9,nov:10,dec:11};function Xi(t){let e=t.match(/Date uploaded<\/strong>\s*<span>\s*([A-Za-z]{3})\.?\s+(\d{1,2})[a-z]{2}\s*'(\d{2})/i);if(!e)return;let r=Ji[e[1].toLowerCase()];if(r===void 0)return;let o=Number(e[2]),n=2e3+Number(e[3]),s=Math.floor(Date.UTC(n,r,o)/1e3);return Number.isNaN(s)?void 0:s}async function Zi(t,e,r){try{let o=await dn(`${t}${e}`,r,1),n=o.match(/magnet:\?xt=urn:btih:[^"'<>\s]+/i)?.[0];return n?{magnet:fe(n),added:Xi(o)}:null}catch{return null}}async function mn(t,e,r,o={}){let n=t.trim(),s=n?`/category-search/${encodeURIComponent(n).replace(/%20/g,"+")}/${e}/1/`:`/popular-${e==="Movies"?"movies":"tv"}`,i="",l="",c;for(let y of Vi)try{let C=`https://${y}`;l=await dn(`${C}${s}`,o,2),i=C;break}catch(C){if(o.signal?.aborted)throw C;c=C}if(!i)throw c instanceof Error?c:new k(0,"1337x unreachable");let a=Ki(l),u=n.toLowerCase().split(/\s+/).filter(Boolean),f=u.filter(y=>!Yi.has(y)),d=f.length?f:u,x=d.length?a.filter(y=>{let C=y.name.toLowerCase();return d.every(M=>C.includes(M))}):a;x.sort((y,C)=>C.seeders-y.seeders);let R=x.slice(0,qi);return(await Promise.all(R.map(async y=>{let C=await Zi(i,y.path,o),M=C?.magnet?.match(/urn:btih:([a-zA-Z0-9]+)/i)?.[1]?.toLowerCase();return!C||!M?null:{infoHash:M,name:y.name,sizeBytes:y.sizeBytes,seeders:y.seeders,leechers:y.leechers,source:r,magnet:C.magnet,added:C.added}}))).filter(y=>y!==null)}var fn={id:"x1337-movies",label:"1337x",group:"Movies",homepage:"https://1337x.to",search:(t,e={})=>mn(t,"Movies","x1337-movies",e)},pn={id:"x1337-tv",label:"1337x",group:"TV",homepage:"https://1337x.to",search:(t,e={})=>mn(t,"TV","x1337-tv",e)};var ea=["yts.mx","yts.am","yts.rs"];async function ta(t,e){let r;for(let o of ea)try{let n=await F(`https://${o}/api/v2/list_movies.json?${t.toString()}`,{headers:{"User-Agent":L},signal:e.signal,retries:1});if(n.ok)return await n.json();r=new k(n.status,`YTS returned ${n.status}`)}catch(n){if(e.signal?.aborted)throw n;r=n}throw r instanceof Error?r:new k(0,"YTS unreachable")}async function ra(t,e={}){let r=t.trim(),o=new URLSearchParams({limit:"50"});r?o.set("query_term",r):o.set("sort_by","date_added");let n=await ta(o,e),s=[];for(let i of n.data?.movies??[]){let l=i.title_long||i.title||"Unknown";for(let c of i.torrents??[]){if(!c.hash)continue;let a=c.hash.toLowerCase(),u=[c.quality,c.type].filter(Boolean).join(" "),f=u?`${l} [${u}]`:l;s.push({infoHash:a,name:f,sizeBytes:c.size_bytes??0,seeders:c.seeds??0,leechers:c.peers??0,source:"yts",magnet:ie(a,f),added:i.date_uploaded_unix})}}return s}var hn={id:"yts",label:"YTS",group:"Movies",homepage:"https://yts.mx",search:ra};var ee=[Yo,hn,ln,fn,Go,un,pn,en,sn,Jo,Xo,Zo,an,tn,rn,on,nn],oa=ee[0];function gn(t){return ee.find(e=>e.id===t)??oa}var na=["Games","Movies","TV","Anime"];function xn(){return na.map(t=>({group:t,sources:ee.filter(e=>e.group===t)})).filter(t=>t.sources.length>0)}var Sn=new Map;function sa(t,e){return`${t}::${e.trim().toLowerCase()}`}async function yn(t,e,r={}){let o=sa(t.id,e),n=Sn.get(o);if(n&&Date.now()-n.at<3e5)return n.results;let s=await t.search(e,r);return Sn.set(o,{at:Date.now(),results:s}),s}function ca(t,e){return e?"\u0442\u0430\u0439\u043C-\u0430\u0443\u0442":t instanceof k&&t.status>0?`HTTP ${t.status}`:"\u043D\u0435\u0442 \u043E\u0442\u0432\u0435\u0442\u0430"}var la=25e3;function wn(t){let e={};for(let r of ee)e[r.id]={loading:t,error:null,code:null,count:0};return e}function ua(t){let e=new Map;for(let r of t){let o=e.get(r.infoHash);(!o||r.seeders>o.seeders)&&e.set(r.infoHash,r)}return[...e.values()]}function da(t){return t.sort((e,r)=>r.seeders!==e.seeders?r.seeders-e.seeders:(r.added??0)-(e.added??0))}function ma(){return{results:[],perSource:wn(!1),loading:!1,done:0,total:ee.length}}function bn(t){let[e,r]=aa(ma);return ia(()=>{let o=new AbortController,n=!0,s=[],i=wn(!0),l=0;r({results:[],perSource:{...i},loading:!0,done:0,total:ee.length});for(let c of ee){let a=new AbortController,u=()=>a.abort();o.signal.addEventListener("abort",u);let f=setTimeout(()=>a.abort(),la);yn(c,t,{signal:a.signal}).then(d=>{n&&(s.push(...d),i[c.id]={loading:!1,error:null,code:null,count:d.length})}).catch(d=>{if(!n||o.signal.aborted)return;let x=a.signal.aborted;i[c.id]={loading:!1,error:x?"\u0442\u0430\u0439\u043C-\u0430\u0443\u0442":d instanceof Error?d.message:String(d),code:ca(d,x),count:0}}).finally(()=>{clearTimeout(f),o.signal.removeEventListener("abort",u),n&&(l+=1,r({results:da(ua(s.slice())),perSource:{...i},loading:l<ee.length,done:l,total:ee.length}))})}return()=>{n=!1,o.abort()}},[t]),e}var Er=["none",{field:"size",dir:"asc"},{field:"size",dir:"desc"},{field:"seeders",dir:"asc"},{field:"seeders",dir:"desc"},{field:"source",dir:"asc"},{field:"source",dir:"desc"}];function fa(t,e){return t==="none"||e==="none"?t===e:t.field===e.field&&t.dir===e.dir}function Tn(t){let e=Er.findIndex(r=>fa(r,t));return Er[(e+1)%Er.length]}function Ir(t){return t==="asc"?"\u25B4":"\u25BE"}function vn(t){return t==="none"?"\u043F\u043E \u0443\u043C\u043E\u043B\u0447.":`${t.field} ${Ir(t.dir)}`}function Rn(t,e){let r=t.slice();if(e==="none")return r;let o=e.dir==="asc"?1:-1;switch(e.field){case"size":r.sort((n,s)=>o*(n.sizeBytes-s.sizeBytes)||s.seeders-n.seeders);break;case"seeders":r.sort((n,s)=>o*(n.seeders-s.seeders)||(s.added??0)-(n.added??0));break;case"source":r.sort((n,s)=>o*n.source.localeCompare(s.source)||s.seeders-n.seeders);break}return r}import{Fragment as Jt,jsx as h,jsxs as j}from"react/jsx-runtime";var pa="\u041F\u043E\u0438\u0441\u043A \u0438\u043B\u0438 \u0432\u0441\u0442\u0430\u0432\u044C\u0442\u0435 \u043C\u0430\u0433\u043D\u0435\u0442-\u0441\u0441\u044B\u043B\u043A\u0443\u2026";function st({label:t,value:e}){return j(P,{children:[h(P,{width:9,flexShrink:0,children:h(T,{dimColor:!0,children:t})}),h(P,{flexGrow:1,minWidth:0,children:e})]})}function ha({r:t,width:e}){let r=ke(t.source),o=pt(t.added),n=t.seeders||t.leechers?j(T,{children:[h(T,{color:t.seeders>0?m.good:void 0,bold:t.seeders>0,children:t.seeders}),h(T,{dimColor:!0,children:` \u0441\u0438\u0434\u0435\u0440\u043E\u0432 ${g.dot} ${t.leechers} \u043A\u0430\u0447\u0430\u044E\u0449\u0438\u0445`})]}):h(T,{dimColor:!0,children:"\u043D\u0435\u0438\u0437\u0432."});return j(P,{flexDirection:"column",children:[j(P,{children:[h(P,{flexGrow:1,minWidth:0,children:h(T,{bold:!0,color:m.text,wrap:"truncate-end",children:ae(t.name)})}),h(P,{flexShrink:0,marginLeft:2,children:h(T,{color:r.color,bold:!0,children:r.tag})})]}),h(Gt,{width:e}),j(P,{marginTop:1,flexDirection:"column",children:[h(st,{label:"\u0420\u0430\u0437\u043C\u0435\u0440",value:t.sizeBytes>0?h(T,{color:m.text,children:Ce(t.sizeBytes)}):h(T,{dimColor:!0,children:"\u043D\u0435\u0438\u0437\u0432."})}),h(st,{label:"\u0417\u0434\u043E\u0440\u043E\u0432\u044C\u0435",value:n}),t.numFiles?h(st,{label:"\u0424\u0430\u0439\u043B\u044B",value:h(T,{dimColor:!0,children:String(t.numFiles)})}):null,o?h(st,{label:"\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u043E",value:h(T,{dimColor:!0,children:o})}):null,h(st,{label:"\u0425\u0435\u0448",value:h(T,{color:m.alt,dimColor:!0,wrap:"truncate-end",children:t.infoHash})}),h(st,{label:"\u041C\u0430\u0433\u043D\u0435\u0442",value:h(T,{color:m.alt,dimColor:!0,wrap:"truncate-end",children:t.magnet})})]}),j(P,{marginTop:1,children:[j(T,{children:[g.down," "]}),h(T,{color:m.accent,bold:!0,children:"d"}),h(T,{color:m.text,children:" \u0421\u043A\u0430\u0447\u0430\u0442\u044C"}),h(T,{dimColor:!0,children:` ${g.dot} `}),j(T,{children:[g.copy," "]}),h(T,{color:m.accent,bold:!0,children:"y"}),h(T,{color:m.text,children:" \u041A\u043E\u043F. \u043C\u0430\u0433\u043D\u0435\u0442"}),h(T,{dimColor:!0,children:` ${g.dot} `}),j(T,{children:[g.back," "]}),h(T,{color:m.alt,children:"esc"}),h(T,{dimColor:!0,children:" \u043D\u0430\u0437\u0430\u0434"})]})]})}function Cn(){let{query:t,submitQuery:e,section:r,region:o,setRegion:n,setCaptureMode:s,startDownload:i,copyMagnet:l,contentWidth:c,listRows:a}=J(),u=bn(t),[f,d]=Kt("none"),x=Mr(()=>{let p=ht.find(B=>B.key===r),N=p?.group?u.results.filter(B=>gn(B.source).group===p.group):u.results;return Rn(N,f)},[u.results,r,f]),R=o==="content",[S,y]=Kt("list"),[C,M]=Kt(0),[G,U]=Kt(null);Br(()=>{M(0)},[x]),Br(()=>{if(R)return s(S==="search"?"text":S==="detail"?"esc":"none"),()=>s("none")},[S,R,s]),Br(()=>{R||y("list")},[R]);let D=Math.min(C,Math.max(0,x.length-1)),q=Eo(a,3),O=Math.max(3,q-4),Se=Math.max(1,O-1),ne=p=>i({id:p.infoHash,name:p.name,magnet:p.magnet,source:p.source,sizeBytes:p.sizeBytes}),ye=p=>l({name:p.name,magnet:p.magnet});kr((p,N)=>{if(p==="/"){y("search");return}if(N.upArrow||p==="k"){x.length>0&&D>0?M(D-1):y("search");return}if(x.length!==0)if(N.downArrow||p==="j")M(xe(D,1,x.length));else if(N.pageUp)M(Math.max(0,D-Se));else if(N.pageDown)M(Math.min(x.length-1,D+Se));else if(N.return){let B=x[D];B&&(U(B),y("detail"))}else if(p==="d"){let B=x[D];B&&ne(B)}else if(p==="y"){let B=x[D];B&&ye(B)}else p==="s"&&d(B=>Tn(B))},{isActive:R&&S==="list"}),kr((p,N)=>{N.escape?(y("list"),U(null)):p==="d"&&G?ne(G):p==="y"&&G&&ye(G)},{isActive:R&&S==="detail"}),kr((p,N)=>{N.escape&&y("list")},{isActive:R&&S==="search"});let Y=p=>{y("list"),e(p)},ue=t.trim()==="",se=Mr(()=>Object.values(u.perSource).filter(p=>p.error).length,[u.perSource]),pe=ht.find(p=>p.key===r),de=pe?.group?ee.filter(p=>p.group===pe.group):ee,b=de.length>0&&de.every(p=>u.perSource[p.id]?.error),z=Mr(()=>x.some(p=>p.sizeBytes>0||p.seeders>0),[x]),v=Math.max(2,String(x.length).length),he=p=>{let N=[...new Set(p.map(B=>u.perSource[B.id]?.code).filter(Boolean))];return N.length?` (${N.join(", ")})`:""},ge=p=>p===1?`${p} \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442`:p>=2&&p<=4?`${p} \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0430`:`${p} \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u043E\u0432`,$e=p=>p===1?`${p} \u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A`:p>=2&&p<=4?`${p} \u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u0430`:`${p} \u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u043E\u0432`,Fe=f==="none"?"":` ${g.dot} \u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0430: ${vn(f)}`,ct=()=>{if(u.loading)return x.length>0?h(T,{dimColor:!0,children:`\u043F\u043E\u0438\u0441\u043A\u2026 ${u.done}/${u.total} \u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u043E\u0432${Fe}`}):h(Wt,{label:`${ue?"\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430":"\u041F\u043E\u0438\u0441\u043A"} ${u.done}/${u.total} \u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u043E\u0432`});if(x.length===0){if(se>=u.total){let B=ee.filter(me=>u.perSource[me.id]?.error);return h(T,{color:m.warn,children:`\u041D\u0438 \u043E\u0434\u0438\u043D \u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u0435\u043D. \u0412\u043E\u0437\u043C\u043E\u0436\u043D\u043E, \u043E\u043D\u0438 \u043D\u0435 \u0440\u0430\u0431\u043E\u0442\u0430\u044E\u0442${he(B)}.`})}if(b&&pe){let B=de.filter(He=>u.perSource[He.id]?.error),me=B.length===1?"\u0418\u0441\u0442\u043E\u0447\u043D\u0438\u043A":`\u0412\u0441\u0435 ${B.length} \u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u043E\u0432`;return h(T,{color:m.warn,children:`\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0434\u043E\u0441\u0442\u0443\u0447\u0430\u0442\u044C\u0441\u044F \u0434\u043E ${pe.label.toLowerCase()}. ${me} \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u0435\u043D${he(B)}.`})}return u.results.length>0&&pe?.group?h(T,{dimColor:!0,children:`\u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u043E\u0432 \u043F\u043E ${pe.label.toLowerCase()} \u043F\u043E\u043A\u0430 \u043D\u0435\u0442. \u041F\u043E\u043F\u0440\u043E\u0431\u0443\u0439\u0442\u0435 \u0434\u0440\u0443\u0433\u0443\u044E \u0432\u043A\u043B\u0430\u0434\u043A\u0443 \u0438\u043B\u0438 \u043F\u043E\u0438\u0441\u043A.`}):h(T,{dimColor:!0,children:ue?"\u0421\u0435\u0439\u0447\u0430\u0441 \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u043E\u0432\u043E\u0433\u043E.":`\u041D\u0435\u0442 \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u043E\u0432 \u0434\u043B\u044F "${K(t,28)}".`})}let p=se>0?` (${se} \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u0435\u043D)`:"",N=ue?"\u0441\u0432\u0435\u0436\u0435\u0435 \u0441\u043E \u0432\u0441\u0435\u0445 \u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u043E\u0432":ge(x.length);return h(T,{dimColor:!0,children:`${N}${p}${Fe}`})},lt=(p,N)=>f==="none"||f.field!==p?N:j(Jt,{children:[h(T,{color:m.accent,bold:!0,children:Ir(f.dir)}),N]}),ut=Oe(D,x.length,O),Be=x.slice(ut,ut+O),kt=x.length>0?`(${x.length})`:void 0;return j(P,{flexDirection:"column",children:[h(Vt,{width:c,value:t,editing:S==="search",placeholder:pa,onSubmit:Y,onExitDown:()=>y("list"),onExitLeft:()=>n("sidebar")}),h(P,{marginTop:1,children:h(Z,{title:S==="detail"?"\u0434\u0435\u0442\u0430\u043B\u0438":ue?"\u0441\u0432\u0435\u0436\u0435\u0435":"\u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u044B",width:c,focused:R&&S!=="search",count:S==="detail"?void 0:kt,height:q,children:S==="detail"&&G?h(ha,{r:G,width:Math.max(10,c-4)}):j(Jt,{children:[h(P,{children:ct()}),j(P,{flexDirection:"column",marginTop:x.length>0?1:0,children:[x.length>0?j(P,{children:[h(P,{width:X,flexShrink:0}),h(P,{width:v,flexShrink:0,justifyContent:"flex-end",children:h(T,{bold:!0,dimColor:!0,children:"#"})}),h(P,{flexGrow:1,minWidth:0,marginLeft:1,children:h(T,{bold:!0,dimColor:!0,children:"\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435"})}),z?j(Jt,{children:[h(P,{width:10,flexShrink:0,marginLeft:1,justifyContent:"flex-end",children:h(T,{bold:!0,dimColor:!0,children:lt("size","\u0420\u0430\u0437\u043C\u0435\u0440")})}),h(P,{width:9,flexShrink:0,marginLeft:1,justifyContent:"flex-end",children:h(T,{bold:!0,dimColor:!0,children:lt("seeders","\u0421\u0438\u0434:\u041A\u0430\u0447")})})]}):h(P,{width:12,flexShrink:0,marginLeft:1,justifyContent:"flex-end",children:h(T,{bold:!0,dimColor:!0,children:"\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u043E"})}),h(P,{width:4,flexShrink:0,marginLeft:1,justifyContent:"flex-end",children:h(T,{bold:!0,dimColor:!0,children:lt("source","\u0418\u0441\u0442.")})})]}):null,Be.map((p,N)=>{let B=ut+N,me=B===D&&R&&S==="list",He=ke(p.source);return j(P,{children:[h(P,{width:X,flexShrink:0,children:h(T,{color:m.accent,children:me?g.pointer:""})}),h(P,{width:v,flexShrink:0,justifyContent:"flex-end",children:h(T,{dimColor:!0,children:B+1})}),h(P,{flexGrow:1,minWidth:0,marginLeft:1,children:h(T,{wrap:"truncate-end",color:me?m.accent:void 0,dimColor:!me,bold:me,children:ae(p.name)})}),z?j(Jt,{children:[h(P,{width:10,flexShrink:0,marginLeft:1,justifyContent:"flex-end",children:h(T,{dimColor:!0,children:p.sizeBytes>0?Ce(p.sizeBytes):"-"})}),h(P,{width:9,flexShrink:0,marginLeft:1,justifyContent:"flex-end",children:h(T,{color:p.seeders>0?m.good:void 0,dimColor:p.seeders===0,children:p.seeders||p.leechers?`${fr(p.seeders)}:${fr(p.leechers)}`:"-"})})]}):h(P,{width:12,flexShrink:0,marginLeft:1,justifyContent:"flex-end",children:h(T,{dimColor:!0,children:pt(p.added)||"-"})}),h(P,{width:4,flexShrink:0,marginLeft:1,justifyContent:"flex-end",children:h(T,{color:He.color,dimColor:!me,children:He.tag})})]},p.infoHash)})]})]})})})]})}import{useEffect as wa,useState as ba}from"react";import{Box as Q,Text as te,useInput as Ta}from"ink";import{useEffect as xa,useState as Sa}from"react";import{Text as bt}from"ink";var En="#ffffff";function In(t){return Math.ceil(t+4.5*2)+8}function Bn(t,e){return t*.45%e-4.5}function Mn(t,e){let r=Math.abs(t-e);return r>=4.5?0:.5*(1+Math.cos(Math.PI*r/4.5))*.9}import{jsx as Ar,jsxs as $n}from"react/jsx-runtime";var ya="#5a6378";function kn(t,e,r,o){return t<=.5?ce(e,r,t/.5):ce(r,o,(t-.5)/.5)}function An(t){let e=[];for(let r of t){let o=e[e.length-1];o&&o.color===r?o.len++:e.push({color:r,len:1})}return e}function Pn(t){return t.map((e,r)=>Ar(bt,{color:e.color,children:"\u2588".repeat(e.len)},r))}function Hn({pct:t,width:e,color:r=m.accent,animate:o=!1}){let n=Math.max(0,Math.min(100,t)),s=Math.round(n/100*e),i=Math.max(0,e-s),l=Math.max(1,e-1),[c,a]=Sa(0);xa(()=>{if(!o)return;let R=setInterval(()=>a(S=>S+1),40);return R.unref?.(),()=>clearInterval(R)},[o]);let u=i>0?Ar(bt,{color:be,children:"\u2591".repeat(i)}):null;if(s===0)return Ar(bt,{children:u});if(!o){let R=ce(r,"#000000",.3),S=ce(r,m.text,.35),y=Array.from({length:s},(C,M)=>kn(M/l,R,r,S));return $n(bt,{children:[Pn(An(y)),u]})}let f=In(e),d=Bn(c,f),x=Array.from({length:s},(R,S)=>{let y=kn(S/l,ya,m.accent,m.bright),C=Mn(S,d);return C>0&&(y=ce(y,En,C)),y});return $n(bt,{children:[Pn(An(x)),u]})}import{jsx as A,jsxs as vt}from"react/jsx-runtime";var Tt=2,Xt=2,va="#5a6378";function Ra(t){return t==="failed"?m.bad:t==="paused"?va:m.accent}function Ca(t){return t==="failed"?g.error:t==="paused"?g.pause:g.down}function Ea(t){if(t.status==="downloading"){let e=ft(t.speed)||"\u2026",r=t.eta?` ${So(t.eta)}`:"";return`${t.progress}% ${e} ${g.peer}${t.peers}${r}`}return t.status==="paused"?`\u043F\u0430\u0443\u0437\u0430 ${t.progress}%`:K(t.error||"\u043E\u0448\u0438\u0431\u043A\u0430",28)}function Dn(){let{queue:t,region:e,contentWidth:r,listRows:o,startDownload:n,setDownloadFocus:s}=J(),i=Ve(t),l=Lt(t),c=e==="content",a=i.length+l.length,[u,f]=ba(0),d=Math.min(u,Math.max(0,a-1)),x=d<i.length,R=d-i.length;Ta((b,z)=>{if(z.upArrow||b==="k")f(xe(d,-1,a));else if(z.downArrow||b==="j")f(xe(d,1,a));else if(b==="f")t.retryFailed();else if(b==="x")t.clearHistory();else if(x){let v=i[d];if(!v)return;b==="c"?t.cancel(v.id):b==="p"&&t.togglePause(v.id)}else{let v=l[R];if(!v)return;z.return||b==="d"?n({id:v.id,name:v.name,magnet:v.magnet,source:v.source,sizeBytes:v.sizeBytes}):b==="c"&&t.removeHistory(v.id)}},{isActive:c&&a>0});let S=null;if(c&&a>0)if(!x)S="recent";else{let b=i[d]?.status;(b==="downloading"||b==="paused"||b==="failed")&&(S=b)}wa(()=>(s(S),()=>s(null)),[S,s]);let y=Math.max(5,o-1);if(a===0)return A(Z,{title:"\u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438",width:r,focused:c,height:y,children:A(te,{dimColor:!0,children:"\u0417\u0430\u0433\u0440\u0443\u0437\u043E\u043A \u043F\u043E\u043A\u0430 \u043D\u0435\u0442. \u041D\u0430\u0439\u0434\u0438\u0442\u0435 \u0447\u0442\u043E-\u043D\u0438\u0431\u0443\u0434\u044C \u0438 \u043D\u0430\u0436\u043C\u0438\u0442\u0435 d \u0434\u043B\u044F \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438."})});let C=i.length>0,M=l.length>0,G=M?1:0,U=Math.max(1,y-1),D=C&&M?1:0,I=0,q=0;if(!M)I=Math.max(1,Math.floor(U/Tt));else if(!C)q=Math.max(1,U-G);else{let b=U-G-D;b<Tt+1&&(D=0,b=U-G);let z=Math.max(Tt,Math.floor(b*.55));I=Math.min(i.length,Math.max(1,Math.floor(z/Tt))),q=Math.max(1,b-I*Tt)}let O=Oe(x?d:0,i.length,I),Se=i.slice(O,O+I),ne=Oe(x?0:R,l.length,q),ye=l.slice(ne,ne+q),Y=r-4,ue=2,se=Math.max(8,Math.min(28,Math.floor(Y*.4))),pe=Math.max(6,Y-Xt-X-se-ue),de=C?`(${i.length})`:void 0;return vt(Z,{title:"\u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438",width:r,focused:c,count:de,height:y,children:[Se.map((b,z)=>{let v=O+z===d&&c&&x,he=Ra(b.status),ge=ke(b.source);return vt(Q,{flexDirection:"column",children:[vt(Q,{children:[A(Q,{width:Xt,flexShrink:0,children:A(te,{color:m.accent,bold:!0,children:v?g.pointer:""})}),A(Q,{width:X,flexShrink:0,children:A(te,{color:he,children:Ca(b.status)})}),A(Q,{flexGrow:1,minWidth:0,children:A(te,{wrap:"truncate-end",bold:v,color:v?m.accent:void 0,dimColor:!v,children:ae(b.name)})}),A(Q,{width:10,flexShrink:0,marginLeft:1,justifyContent:"flex-end",children:A(te,{dimColor:!0,children:b.totalBytes>0?Ce(b.totalBytes):"-"})}),A(Q,{width:4,flexShrink:0,marginLeft:1,justifyContent:"flex-end",children:A(te,{color:b.source?ge.color:void 0,dimColor:!b.source||!v,children:b.source?ge.tag:"mag"})})]}),vt(Q,{children:[A(Q,{width:Xt+X,flexShrink:0}),A(Hn,{pct:b.progress,width:se,color:he,animate:b.status==="downloading"}),A(Q,{marginLeft:ue,flexShrink:0,children:A(te,{dimColor:!0,children:K(Ea(b),pe)})})]})]},b.id)}),M?A(Q,{marginTop:D?1:0,children:A(te,{dimColor:!0,children:`\u041D\u0435\u0434\u0430\u0432\u043D\u043E \u0441\u043A\u0430\u0447\u0430\u043D\u043E${l.length>1?` (${l.length})`:""}`})}):null,ye.map((b,z)=>{let v=ne+z===R&&c&&!x,he=ke(b.source),ge=pt(b.completedAt/1e3);return vt(Q,{children:[A(Q,{width:Xt,flexShrink:0,children:A(te,{color:m.accent,bold:!0,children:v?g.pointer:""})}),A(Q,{width:X,flexShrink:0,children:A(te,{color:m.good,dimColor:!v,children:g.done})}),A(Q,{flexGrow:1,minWidth:0,children:A(te,{wrap:"truncate-end",bold:v,color:v?m.accent:void 0,dimColor:!v,children:ae(b.name)})}),A(Q,{width:10,flexShrink:0,marginLeft:1,justifyContent:"flex-end",children:A(te,{dimColor:!0,children:b.sizeBytes>0?Ce(b.sizeBytes):"-"})}),A(Q,{width:12,flexShrink:0,marginLeft:1,justifyContent:"flex-end",children:A(te,{dimColor:!0,children:ge||"-"})}),A(Q,{width:4,flexShrink:0,marginLeft:1,justifyContent:"flex-end",children:A(te,{color:b.source?he.color:void 0,dimColor:!b.source||!v,children:b.source?he.tag:"mag"})})]},b.id)})]})}import{useEffect as Ia,useState as Ba}from"react";import{Box as V,Text as re,useInput as Ma}from"ink";import{jsx as $,jsxs as Rt}from"react/jsx-runtime";var On=2,Nn=10,Pr=14,_n=4,ka="#5a6378";function Aa(t){return t?t.status==="seeding"?{icon:g.up,color:m.good}:t.status==="paused"?{icon:g.pause,color:ka}:{icon:g.warn,color:m.warn}:{icon:g.done,color:m.good}}function Pa(t){return t?t.status==="seeding"?{text:`${g.up}${ft(t.uploadSpeed)||"0 B/s"} ${g.peer}${t.peers}`,color:m.good,dim:!1}:t.status==="paused"?{text:"\u043F\u0430\u0443\u0437\u0430",dim:!0}:{text:"\u0444\u0430\u0439\u043B \u0443\u0434\u0430\u043B\u0451\u043D",color:m.warn,dim:!1}:{text:"\u0433\u043E\u0442\u043E\u0432\u043E",dim:!0}}function Ln(){let{queue:t,region:e,contentWidth:r,listRows:o,setNotice:n,setSeedFocus:s}=J(),i=Lt(t),l=yo(t),c=e==="content",a=i.length,[u,f]=Ba(0),d=Math.min(u,Math.max(0,a-1)),x=c&&a>0?l.get(i[d]?.id??"")?.status??"idle":null;Ia(()=>(s(x),()=>s(null)),[x,s]),Ma((I,q)=>{if(q.upArrow||I==="k")f(xe(d,-1,a));else if(q.downArrow||I==="j")f(xe(d,1,a));else if(I==="p"){let O=i[d];if(!O)return;t.toggleSeeding(O),t.getSeed(O.id)?.status==="missing"&&n(`${g.warn} \u0424\u0430\u0439\u043B \u0431\u043E\u043B\u044C\u0448\u0435 \u043D\u0435 \u043D\u0430 \u0434\u0438\u0441\u043A\u0435.`)}else if(I==="c"){let O=i[d];O&&t.removeHistory(O.id)}},{isActive:c&&a>0});let R=Math.max(5,o-1),S=t.seedingCount;if(a===0)return $(Z,{title:"\u0440\u0430\u0437\u0434\u0430\u0447\u0438",width:r,focused:c,height:R,children:$(re,{dimColor:!0,children:"\u041F\u043E\u043A\u0430 \u043D\u0438\u0447\u0435\u0433\u043E. \u0420\u0430\u0437\u0434\u0430\u0447\u0438 \u043D\u0430\u0447\u0438\u043D\u0430\u044E\u0442\u0441\u044F \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438 \u043F\u043E\u0441\u043B\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u0438\u044F \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438."})});let y=0,C=0,M=0;for(let I of l.values())M+=I.uploaded,I.status==="seeding"&&(y+=I.uploadSpeed,C+=I.peers);let G=Math.max(1,R-2),U=Oe(d,a,G),D=i.slice(U,U+G);return Rt(Z,{title:"\u0440\u0430\u0437\u0434\u0430\u0447\u0438",width:r,focused:c,count:S>0?`(${S})`:void 0,height:R,children:[$(V,{children:S>0?Rt(re,{color:m.good,children:[g.up," ",ft(y)||"0 B/s",$(re,{dimColor:!0,children:` ${g.dot} ${C} \u043F\u0438\u0440\u043E\u0432 ${g.dot} ${Ce(M)} \u0440\u043E\u0437\u0434\u0430\u043D\u043E`})]}):$(re,{dimColor:!0,children:"\u0420\u0430\u0437\u0434\u0430\u0447\u0438 \u043D\u0430\u0447\u0438\u043D\u0430\u044E\u0442\u0441\u044F \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438. \u041D\u0430\u0436\u043C\u0438\u0442\u0435 p \u0434\u043B\u044F \u043F\u0430\u0443\u0437\u044B \u0438\u043B\u0438 \u0432\u043E\u0437\u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F."})}),Rt(V,{flexDirection:"column",marginTop:1,children:[Rt(V,{children:[$(V,{width:On,flexShrink:0}),$(V,{width:X,flexShrink:0}),$(V,{flexGrow:1,minWidth:0,marginLeft:1,children:$(re,{bold:!0,dimColor:!0,children:"\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435"})}),$(V,{width:Nn,flexShrink:0,marginLeft:1,justifyContent:"flex-end",children:$(re,{bold:!0,dimColor:!0,children:"\u0420\u0430\u0437\u043C\u0435\u0440"})}),$(V,{width:Pr,flexShrink:0,marginLeft:1,justifyContent:"flex-end",children:$(re,{bold:!0,dimColor:!0,children:"\u0421\u0442\u0430\u0442\u0443\u0441"})}),$(V,{width:_n,flexShrink:0,marginLeft:1,justifyContent:"flex-end",children:$(re,{bold:!0,dimColor:!0,children:"\u0418\u0441\u0442."})})]}),D.map((I,q)=>{let O=U+q===d&&c,Se=l.get(I.id),ne=Aa(Se),ye=Pa(Se),Y=ke(I.source);return Rt(V,{children:[$(V,{width:On,flexShrink:0,children:$(re,{color:m.accent,bold:!0,children:O?g.pointer:""})}),$(V,{width:X,flexShrink:0,children:$(re,{color:ne.color,dimColor:!Se&&!O,children:ne.icon})}),$(V,{flexGrow:1,minWidth:0,marginLeft:1,children:$(re,{wrap:"truncate-end",bold:O,color:O?m.accent:void 0,dimColor:!O,children:ae(I.name)})}),$(V,{width:Nn,flexShrink:0,marginLeft:1,justifyContent:"flex-end",children:$(re,{dimColor:!0,children:I.sizeBytes>0?Ce(I.sizeBytes):"-"})}),$(V,{width:Pr,flexShrink:0,marginLeft:1,justifyContent:"flex-end",children:$(re,{color:ye.color,dimColor:ye.dim,children:K(ye.text,Pr)})}),$(V,{width:_n,flexShrink:0,marginLeft:1,justifyContent:"flex-end",children:$(re,{color:I.source?Y.color:void 0,dimColor:!I.source||!O,children:I.source?Y.tag:"mag"})})]},I.id)})]})]})}import{useEffect as $a}from"react";function $r(){let{queue:t}=J();Ve(t);let e=t.activeCount;return $a(()=>{let r=e>0?`\u2193${e} \xB7 torio`:"torio";process.stdout.write(`\x1B]0;${r}\x07`),process.platform==="win32"&&(process.title=r)},[e]),null}import{Box as Ct,Text as le,useInput as Ha,useStdin as Da}from"ink";import{jsx as W,jsxs as Fn}from"react/jsx-runtime";var Oa=xn().map(t=>t.group.toLowerCase()).join(` ${g.dot} `);function Un(){let{submitQuery:t,quitAll:e,cols:r,rows:o}=J(),{isRawModeSupported:n}=Da();Ha((l,c)=>{(c.escape||c.ctrl&&l==="c")&&e()},{isActive:n});let s=r>=Ft+2,i=Math.max(24,Math.min(r-6,62));return Fn(Ct,{height:Math.max(1,o-1),flexDirection:"column",justifyContent:"center",alignItems:"center",children:[s?W(Ut,{}):W(le,{bold:!0,color:m.accent,children:"torio"}),W(Ct,{marginTop:2,children:W(le,{color:m.text,children:"\u0422\u043E\u0440\u0440\u0435\u043D\u0442-\u043A\u043B\u0438\u0435\u043D\u0442 \u043F\u0440\u044F\u043C\u043E \u0432 \u0442\u0435\u0440\u043C\u0438\u043D\u0430\u043B\u0435."})}),W(Ct,{children:W(le,{dimColor:!0,children:Oa})}),W(Ct,{marginTop:1,width:i,children:W(Vt,{width:i,value:"",editing:!0,placeholder:"\u041F\u043E\u0438\u0441\u043A \u0438\u043B\u0438 \u0432\u0441\u0442\u0430\u0432\u044C\u0442\u0435 \u043C\u0430\u0433\u043D\u0435\u0442-\u0441\u0441\u044B\u043B\u043A\u0443\u2026",onSubmit:t})}),W(Ct,{marginTop:1,children:Fn(le,{children:[W(le,{color:m.alt,children:"\u21B5"}),W(le,{dimColor:!0,children:" \u043F\u043E\u0438\u0441\u043A"}),W(le,{dimColor:!0,children:` ${g.dot} `}),W(le,{dimColor:!0,children:"\u043F\u0443\u0441\u0442\u043E "}),W(le,{color:m.alt,children:"\u21B5"}),W(le,{dimColor:!0,children:" \u043E\u0431\u0437\u043E\u0440"}),W(le,{dimColor:!0,children:` ${g.dot} `}),W(le,{color:m.alt,children:"^c"}),W(le,{dimColor:!0,children:" \u0432\u044B\u0445\u043E\u0434"})]})})]})}import{Box as Zt,Text as it,useInput as Na}from"ink";import{jsx as Ie,jsxs as Hr}from"react/jsx-runtime";function zn({width:t,value:e,onSubmit:r,onCancel:o}){return Na((n,s)=>{s.escape&&o()}),Hr(Zt,{flexDirection:"column",width:t,children:[Ie(Z,{title:"\u043F\u0430\u043F\u043A\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043E\u043A",width:t,focused:!0,height:2,children:Hr(Zt,{children:[Ie(it,{color:m.accent,children:`${g.pointer} `}),Ie(Zt,{flexGrow:1,minWidth:0,children:Ie(rt,{defaultValue:e,placeholder:"~/Downloads/torio",onSubmit:r})})]})}),Hr(Zt,{marginTop:1,children:[Ie(it,{color:m.alt,children:"\u21B5"}),Ie(it,{dimColor:!0,children:" \u0441\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C"}),Ie(it,{dimColor:!0,children:` ${g.dot} `}),Ie(it,{color:m.alt,children:"esc"}),Ie(it,{dimColor:!0,children:" \u043E\u0442\u043C\u0435\u043D\u0430"})]})]})}import{Box as Et,Text as Le,useInput as La}from"ink";var _a=/^(udp|https?|wss?):\/\//i;function Gn(t){let e=new Set,r=[];for(let o of t.split(/[\s,]+/)){let n=o.trim();!n||!_a.test(n)||e.has(n)||(e.add(n),r.push(n))}return r}function Qn(t){return t.join(", ")}import{jsx as Te,jsxs as er}from"react/jsx-runtime";function Wn({width:t,value:e,onSubmit:r,onCancel:o}){return La((n,s)=>{s.escape&&o()}),er(Et,{flexDirection:"column",width:t,children:[Te(Z,{title:"\u0434\u043E\u043F. \u0442\u0440\u0435\u043A\u0435\u0440\u044B",width:t,focused:!0,height:2,children:er(Et,{children:[Te(Le,{color:m.accent,children:`${g.pointer} `}),Te(Et,{flexGrow:1,minWidth:0,children:Te(rt,{defaultValue:Qn(e),placeholder:"udp://tracker.example:1337/announce, https://...",onSubmit:n=>r(Gn(n))})})]})}),er(Et,{marginTop:1,flexDirection:"column",children:[er(Et,{children:[Te(Le,{color:m.alt,children:"\u21B5"}),Te(Le,{dimColor:!0,children:" \u0441\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C"}),Te(Le,{dimColor:!0,children:` ${g.dot} `}),Te(Le,{color:m.alt,children:"esc"}),Te(Le,{dimColor:!0,children:" \u043E\u0442\u043C\u0435\u043D\u0430"})]}),Te(Le,{dimColor:!0,children:"\u0420\u0430\u0437\u0434\u0435\u043B\u044F\u0439\u0442\u0435 \u0437\u0430\u043F\u044F\u0442\u044B\u043C\u0438 \u0438\u043B\u0438 \u043F\u0440\u043E\u0431\u0435\u043B\u0430\u043C\u0438. \u041F\u0443\u0441\u0442\u043E = \u043F\u0443\u0441\u0442\u043E\u0439 \u0441\u043F\u0438\u0441\u043E\u043A. \u0414\u043B\u044F \u043D\u043E\u0432\u044B\u0445 \u0437\u0430\u0433\u0440\u0443\u0437\u043E\u043A."})]})]})}import{useEffect as Fa}from"react";function jn(){Fa(()=>{let{stdout:t,stdin:e}=process;t.write("\x1B[?1000h\x1B[?1006h");let r=o=>{let n=o.toString("utf8"),s=/\x1b\[<(64|65);\d+;\d+[Mm]/g,i;for(;(i=s.exec(n))!==null;){let l=i[1]==="64"?"\x1B[A":"\x1B[B";process.nextTick(()=>e.emit("data",Buffer.from(l)))}};return e.prependListener("data",r),()=>{t.write("\x1B[?1000l\x1B[?1006l"),e.removeListener("data",r)}},[])}import{jsx as _,jsxs as Bt}from"react/jsx-runtime";function qn({initialMagnet:t,initialTorrent:e,onQuit:r}={}){jn();let{exit:o}=Ga(),{isRawModeSupported:n}=ja(),{stdout:s}=Wa(),[i,l]=oe({rows:s?.rows??24,cols:s?.columns??80});It(()=>{if(!s)return;let w={rows:s.rows??24,cols:s.columns??80},E=()=>{let H={rows:s.rows??24,cols:s.columns??80};H.rows===w.rows&&H.cols===w.cols||((H.rows<w.rows||H.cols<w.cols)&&s.write("\x1B[2J\x1B[H"),w=H,l(H))};return s.on("resize",E),()=>{s.off("resize",E)}},[s]);let c=i.rows,a=i.cols,[u,f]=oe(null),[d,x]=oe(null),[R,S]=oe("splash"),[y,C]=oe(""),[M,G]=oe("all"),[U,D]=oe("content"),[I,q]=oe("none"),[O,Se]=oe(null),[ne,ye]=oe(null),[Y,ue]=oe(!1),[se,pe]=oe(!1),[de,b]=oe(!1),[z,v]=oe(null),he=za(!1);It(()=>{if(he.current)return;he.current=!0;let w=!0;return(async()=>{let E=await Wr(),H=new Nt;if(H.setTrackers(E.trackers),H.restore(fo(await oo())),H.restoreHistory(await uo()),H.restoreSeeds(await co()),!w){H.suspend();return}x(E),f(H);let ze=t?At(t):e?await po(e):null;ze&&(await Dr.mkdir(E.downloadDir,{recursive:!0}).catch(()=>{}),H.add({id:ze.infoHash,name:ze.name,magnet:ze.magnet},E.downloadDir),S("browser"),G("downloads"),D("content"))})(),()=>{w=!1}},[t,e]),It(()=>{if(!u)return;let w=E=>v(`${g.done} ${K(ae(E),40)}`);return u.on("completed",w),()=>{u.off("completed",w)}},[u]),It(()=>()=>{u?.suspend()},[u]);let ge=ve(()=>{u?.persistSync(),r?r():o()},[u,r,o]),$e=ve(w=>{x(w),u?.setTrackers(w.trackers),jr(w)},[u]),Fe=ve(()=>{pe(!1)},[]),ct=ve(()=>{b(!1)},[]),lt=ve(w=>{if(ct(),!d)return;if(w.length===d.trackers.length&&w.every((H,ze)=>H===d.trackers[ze])){v("\u0422\u0440\u0435\u043A\u0435\u0440\u044B \u0431\u0435\u0437 \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0439.");return}$e({...d,trackers:w}),v(w.length===0?"\u0414\u043E\u043F. \u0442\u0440\u0435\u043A\u0435\u0440\u044B \u043E\u0447\u0438\u0449\u0435\u043D\u044B.":`\u0421\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u043E ${w.length} \u0442\u0440\u0435\u043A\u0435\u0440${w.length===1?"":"\u043E\u0432"}.`)},[d,$e,ct]),ut=ve(w=>{Fe();let E=Yr(w);if(!d||!E||E===d.downloadDir){d&&E&&E===d.downloadDir&&v("\u041F\u0430\u043F\u043A\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043E\u043A \u0431\u0435\u0437 \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0439.");return}(async()=>{try{await Dr.mkdir(E,{recursive:!0})}catch{v(`\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u043F\u0430\u043F\u043A\u0443: ${K(E,48)}`);return}$e({...d,downloadDir:E}),v(`\u041F\u0430\u043F\u043A\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043E\u043A: ${K(E,48)}`)})()},[d,$e,Fe]),Be=ve(w=>{!d||!u||(Dr.mkdir(d.downloadDir,{recursive:!0}).catch(()=>{}),u.add(w,d.downloadDir),v(`\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u043E: ${K(ae(w.name),40)}`),G("downloads"),D("content"))},[d,u]),kt=ve(w=>{(async()=>{if(await xo(w.magnet)){v(`\u041C\u0430\u0433\u043D\u0435\u0442 \u0441\u043A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u043D: ${K(ae(w.magnet),60)}`);return}v(`\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0441\u043A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043C\u0430\u0433\u043D\u0435\u0442 \u0434\u043B\u044F ${K(ae(w.name),32)}.`)})()},[]),p=ve(w=>{let E=w.trim();if(E){let H=At(E);if(H){Be({id:H.infoHash,name:H.name,magnet:H.magnet}),S("browser");return}}C(E),S("browser"),M==="downloads"&&G("all"),D("content")},[M,Be]),N=ve(async()=>{let w=(await go()).trim();if(!w){v("\u0411\u0443\u0444\u0435\u0440 \u043E\u0431\u043C\u0435\u043D\u0430 \u043F\u0443\u0441\u0442.");return}let E=w.match(/magnet:\?xt=urn:btih:[^\s"'<>]+/i)?.[0],H=At(E??w);if(H){Be({id:H.infoHash,name:H.name,magnet:H.magnet}),S("browser");return}v("\u041C\u0430\u0433\u043D\u0435\u0442-\u0441\u0441\u044B\u043B\u043A\u0430 \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u0430 \u0432 \u0431\u0443\u0444\u0435\u0440\u0435 \u043E\u0431\u043C\u0435\u043D\u0430.")},[Be]);It(()=>{if(!z)return;let w=setTimeout(()=>v(null),4e3);return()=>clearTimeout(w)},[z]);let B=c<18,me=!B,He=c>=12,Xn=qe.length+(me?1:0)+(B?0:1)+(He?1:0),Or=Math.max(6,c-1-Xn),Nr=Math.max(4,Or),_r=Math.max(24,a-xr-3),Zn=Math.max(10,a-2),Ue=Ua(()=>!u||!d?null:{config:d,setConfig:$e,queue:u,view:R,setView:S,query:y,submitQuery:p,section:M,setSection:G,region:Y||se||de?"help":U,setRegion:D,captureMode:I,setCaptureMode:q,downloadFocus:O,setDownloadFocus:Se,seedFocus:ne,setSeedFocus:ye,startDownload:Be,copyMagnet:kt,notice:z,setNotice:v,quitAll:ge,listRows:Nr,compact:B,contentWidth:_r,cols:a,rows:c},[u,d,R,y,p,M,U,Y,se,de,I,O,ne,Be,kt,z,Nr,B,_r,a,c,$e,ge]);return Qa((w,E)=>{if(E.ctrl&&w==="c"){ge();return}if(!(se||de)&&I!=="text"){if(Y){ue(!1);return}if(w==="?"){ue(!0);return}if(w==="o"){ue(!1),pe(!0);return}if(w==="t"){ue(!1),b(!0);return}if(w==="m"){N();return}if(E.tab){D(U==="sidebar"?"content":"sidebar");return}if(E.rightArrow||w==="l"){U==="sidebar"&&D("content");return}if(E.leftArrow||w==="h"){U==="content"&&D("sidebar");return}if(E.escape){if(I==="esc")return;if(U==="content"){D("sidebar");return}S("splash");return}if(w==="q"){ge();return}}},{isActive:n&&R==="browser"&&!!Ue}),Ue?R==="splash"?Bt(_t.Provider,{value:Ue,children:[_($r,{}),_(Un,{})]}):Bt(_t.Provider,{value:Ue,children:[_($r,{}),Bt(Re,{flexDirection:"column",height:c-1,paddingX:1,children:[_(Re,{marginTop:1}),Bt(Re,{justifyContent:"space-between",children:[a>=Ft+2?_(Ut,{}):_(Vn,{bold:!0,color:m.accent,children:"torio"}),z?_(Vn,{color:m.good,children:z}):null]}),me?_(Gt,{width:Zn}):null,Y?_(Re,{marginTop:1,children:_(Ho,{})}):null,se?_(Re,{marginTop:1,children:_(zn,{width:Math.max(24,Math.min(a-4,62)),value:Ue.config.downloadDir,onSubmit:ut,onCancel:Fe})}):null,de?_(Re,{marginTop:1,children:_(Wn,{width:Math.max(24,Math.min(a-4,78)),value:Ue.config.trackers,onSubmit:lt,onCancel:ct})}):null,Bt(Re,{height:Or,marginTop:B?0:1,display:Y||se||de?"none":"flex",overflow:"hidden",children:[_(Bo,{}),_(Re,{flexGrow:1,flexDirection:"column",children:M==="downloads"?_(Dn,{}):M==="seeding"?_(Ln,{}):_(Cn,{})})]}),He?_(Re,{display:Y||se||de?"none":"flex",children:_(ko,{hints:Ao(U,M,O,ne)})}):null]})]}):_(Re,{height:c,justifyContent:"center",alignItems:"center",children:_(Wt,{label:"\u0417\u0430\u043F\u0443\u0441\u043A torio"})})}import{jsx as qa}from"react/jsx-runtime";var at=Fr(process.argv.slice(2));at.kind==="help"&&(console.log(nr),process.exit(0));at.kind==="version"&&(console.log(`torio v${Ur}`),process.exit(0));at.kind==="invalid"&&(console.error(`\u043E\u0448\u0438\u0431\u043A\u0430: \u043D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043D\u044B\u0439 \u0430\u0440\u0433\u0443\u043C\u0435\u043D\u0442 '${at.arg}'
|
|
14
|
+
`),console.error(nr),process.exit(1));process.stdout.write("\x1B[?1049h\x1B[?25l\x1B[22;0t\x1B]0;torio\x07");process.platform==="win32"&&(process.title="torio");var Yn=!1;function Mt(){Yn||(Yn=!0,process.stdout.write("\x1B[?1000l\x1B[?1006l\x1B[?25h\x1B[23;0t\x1B[?1049l"))}var Kn=!1;function tr(t=0){Kn&&(Mt(),process.exit(t)),Kn=!0;try{Jn?.unmount()}catch{}Mt(),process.exit(t)}var Jn=Va(qa(qn,{initialMagnet:at.initialMagnet,initialTorrent:at.initialTorrent,onQuit:()=>tr(0)}),{exitOnCtrlC:!1});Jn.waitUntilExit().then(()=>tr(0)).catch(t=>{Mt(),console.error(t),process.exit(1)});process.on("SIGINT",()=>tr(0));process.on("SIGTERM",()=>tr(0));process.on("exit",Mt);process.on("uncaughtException",t=>{Mt(),console.error(t),process.exit(1)});
|
package/package.json
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "torio-cli",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "A sleek, zero-setup torrent finder and downloader that lives right in your terminal.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"torio": "./dist/cli.cjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"preview"
|
|
12
|
+
],
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=22"
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"dev": "tsx src/index.tsx",
|
|
18
|
+
"build": "tsup",
|
|
19
|
+
"postbuild": "node scripts/postbuild.cjs",
|
|
20
|
+
"start": "node dist/index.js",
|
|
21
|
+
"typecheck": "tsc --noEmit",
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"verify:seeding": "tsx scripts/verify-seeding.ts",
|
|
24
|
+
"previews": "tsx scripts/render-previews.tsx",
|
|
25
|
+
"prepublishOnly": "npm run build"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"torrent",
|
|
29
|
+
"torrent-client",
|
|
30
|
+
"torrent-search",
|
|
31
|
+
"downloader",
|
|
32
|
+
"magnet",
|
|
33
|
+
"magnet-links",
|
|
34
|
+
"p2p",
|
|
35
|
+
"webtorrent",
|
|
36
|
+
"seeding",
|
|
37
|
+
"tui",
|
|
38
|
+
"terminal",
|
|
39
|
+
"cli",
|
|
40
|
+
"ink",
|
|
41
|
+
"zero-configuration",
|
|
42
|
+
"zero-setup",
|
|
43
|
+
"fitgirl"
|
|
44
|
+
],
|
|
45
|
+
"author": "y-tretyakov",
|
|
46
|
+
"license": "MIT",
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "git+https://github.com/y-tretyakov/torio.git"
|
|
50
|
+
},
|
|
51
|
+
"homepage": "https://github.com/y-tretyakov/torio#readme",
|
|
52
|
+
"bugs": {
|
|
53
|
+
"url": "https://github.com/y-tretyakov/torio/issues"
|
|
54
|
+
},
|
|
55
|
+
"publishConfig": {
|
|
56
|
+
"access": "public"
|
|
57
|
+
},
|
|
58
|
+
"dependencies": {
|
|
59
|
+
"env-paths": "^4.0.0",
|
|
60
|
+
"ink": "^7.0.5",
|
|
61
|
+
"parse-torrent": "^11.0.21",
|
|
62
|
+
"react": "^19.2.7",
|
|
63
|
+
"webtorrent": "^2.4.1"
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@types/node": "^25.9.2",
|
|
67
|
+
"@types/react": "^19.2.17",
|
|
68
|
+
"ink-testing-library": "^4.0.0",
|
|
69
|
+
"tsup": "^8.5.1",
|
|
70
|
+
"tsx": "^4.22.4",
|
|
71
|
+
"typescript": "^6.0.3",
|
|
72
|
+
"vitest": "^4.1.8"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|