@coflyn/mori 0.0.0-stage β 1.0.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/CHANGELOG.md +21 -0
- package/LICENSE +674 -0
- package/README.md +146 -2
- package/bundle.js +11 -0
- package/engine.js +1201 -0
- package/index.js +1545 -0
- package/package.json +47 -4
- package/scrapers-version.json +7 -0
package/README.md
CHANGED
|
@@ -1,3 +1,147 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<h1 align="center">@coflyn/mori</h1>
|
|
3
|
+
<p align="center"><strong>Universal Media Downloader CLI</strong></p>
|
|
4
|
+
<p align="center"><em>Save anything, from anywhere. No watermarks. No tracking.</em></p>
|
|
5
|
+
</p>
|
|
2
6
|
|
|
3
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://www.npmjs.com/package/@coflyn/mori"><img src="https://img.shields.io/npm/v/@coflyn/mori?style=flat-square&color=blue" alt="NPM Version"></a>
|
|
9
|
+
<a href="https://www.npmjs.com/package/@coflyn/mori"><img src="https://img.shields.io/npm/dm/@coflyn/mori?style=flat-square&color=green" alt="NPM Downloads"></a>
|
|
10
|
+
<a href="https://github.com/coflyn/Mori"><img src="https://img.shields.io/badge/License-GPL--3.0-blue?style=flat-square" alt="License"></a>
|
|
11
|
+
<a href="https://github.com/coflyn/Mori"><img src="https://img.shields.io/badge/GitHub-coflyn%2FMori-black?style=flat-square&logo=github" alt="GitHub"></a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
Command-line interface for **[Mori](https://github.com/coflyn/Mori)**. Download watermark-free videos, high-resolution photos, music, playlists, and compile albums into PDF across 16 platforms directly from your terminal.
|
|
17
|
+
|
|
18
|
+
## β‘ Quick Start
|
|
19
|
+
|
|
20
|
+
Run instantly without global installation via `npx`:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Interactive REPL mode
|
|
24
|
+
npx @coflyn/mori
|
|
25
|
+
|
|
26
|
+
# Download any link directly
|
|
27
|
+
npx @coflyn/mori https://www.tiktok.com/@user/video/123456789
|
|
28
|
+
|
|
29
|
+
# Download audio only (MP3)
|
|
30
|
+
npx @coflyn/mori https://youtu.be/dQw4w9WgXcQ -a
|
|
31
|
+
|
|
32
|
+
# Compile photo carousel into a single PDF album
|
|
33
|
+
npx @coflyn/mori https://www.instagram.com/p/C_abc123/ -p
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Or install globally:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install -g @coflyn/mori
|
|
40
|
+
mori
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## π Supported Platforms (16)
|
|
46
|
+
|
|
47
|
+
| Platform | Capabilities |
|
|
48
|
+
| :------------------------ | :---------------------------------------------------------- |
|
|
49
|
+
| **TikTok** | No-watermark video (HD/1080p), MP3 audio, slide photos |
|
|
50
|
+
| **Instagram** | Reels, stories, posts, photos, carousels |
|
|
51
|
+
| **YouTube** | MP4 video, MP3 audio, full playlists & albums |
|
|
52
|
+
| **Twitter / X** | All resolutions, GIFs, MP4 video |
|
|
53
|
+
| **Spotify** | Single tracks, full albums & playlists to MP3 (128β320kbps) |
|
|
54
|
+
| **Apple Music** | Tracks, albums, and playlists to high-quality MP3 |
|
|
55
|
+
| **Pinterest** | Original full-resolution images, video pins |
|
|
56
|
+
| **Facebook** | Public reels & HD videos |
|
|
57
|
+
| **Threads** | Videos and photo carousels |
|
|
58
|
+
| **Reddit** | Videos with synced audio, multi-image galleries |
|
|
59
|
+
| **Bilibili** | High-definition DASH video & audio streams |
|
|
60
|
+
| **Douyin** | Watermark-free videos & photo carousels |
|
|
61
|
+
| **RedNote (Xiaohongshu)** | High-res photos and videos |
|
|
62
|
+
| **Pixiv** | Artwork galleries and animated Ugoira |
|
|
63
|
+
| **Bandcamp** | Individual songs and full discographies |
|
|
64
|
+
| **TeraBox** | Direct stream extraction |
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## π οΈ CLI Options
|
|
69
|
+
|
|
70
|
+
```text
|
|
71
|
+
USAGE:
|
|
72
|
+
mori [URL] [OPTIONS]
|
|
73
|
+
npx @coflyn/mori [URL] [OPTIONS]
|
|
74
|
+
|
|
75
|
+
OPTIONS:
|
|
76
|
+
-o, --output <dir> Custom download destination (default: ~/Downloads/Mori)
|
|
77
|
+
-s, --server <1|2> Select scraper server engine (1 = Default, 2 = Mirror)
|
|
78
|
+
-a, --audio Extract and download audio stream only (MP3/M4A)
|
|
79
|
+
-p, --pdf Compile multi-photo posts directly into a single PDF album
|
|
80
|
+
-c, --clip Auto-detect and download URL from system clipboard
|
|
81
|
+
-y, --yes Auto-confirm and download best available stream
|
|
82
|
+
-i, --info Inspect and display media metadata only (no download)
|
|
83
|
+
-u, --update Check and apply latest OTA scraper patches
|
|
84
|
+
-h, --help Show help and usage documentation
|
|
85
|
+
-v, --version Display CLI version
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## π¬ Interactive Shell & Slash Commands
|
|
91
|
+
|
|
92
|
+
Launch `mori` without arguments to enter the interactive CLI shell:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
mori
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Inside the interactive prompt, type `/` to access built-in tools:
|
|
99
|
+
|
|
100
|
+
| Command | Aliases | Description |
|
|
101
|
+
| :--------------- | :------------ | :--------------------------------------------------------------------------------- |
|
|
102
|
+
| `/clip` | `/paste` | Auto-detect and download media link currently on system clipboard |
|
|
103
|
+
| `/audio [url]` | `/mp3` | Extract and download audio stream only (MP3/M4A) |
|
|
104
|
+
| `/pdf [url]` | β | Compile photo carousel or gallery directly into a single PDF album |
|
|
105
|
+
| `/batch` | β | Bulk-download multiple links at once (space or newline separated) |
|
|
106
|
+
| `/play [num]` | β | Open and play downloaded MP4/MP3 media in your default system player |
|
|
107
|
+
| `/history [num]` | β | View download history, re-download (`/history <num>`), or purge (`/history clear`) |
|
|
108
|
+
| `/delete [num]` | `/del`, `/rm` | Remove item from history with prompt to delete file from disk |
|
|
109
|
+
| `/open` | β | Open download folder in your OS file manager (Finder / File Explorer) |
|
|
110
|
+
| `/dir [path]` | β | View or set default download destination folder permanently |
|
|
111
|
+
| `/server` | β | Select default scraper engine (`auto`, `1`, `2`) |
|
|
112
|
+
| `/info [url]` | `/inspect` | Inspect media details and available streams without downloading |
|
|
113
|
+
| `/retry` | `/again` | Re-download the last processed link |
|
|
114
|
+
| `/ping [host]` | β | Test network latency and packet loss (default: 1.1.1.1) |
|
|
115
|
+
| `/stats` | β | View total files downloaded, disk space used, and platform breakdown |
|
|
116
|
+
| `/platforms` | `/platform` | List all 16 supported media platforms and categories |
|
|
117
|
+
| `/config` | β | Display active configuration, storage paths, and versions |
|
|
118
|
+
| `/update` | `/u` | Check for both CLI package updates (npm) and OTA scraper patches |
|
|
119
|
+
| `/reset` | β | Factory reset Mori configuration, cached scrapers, and history |
|
|
120
|
+
| `/clear` | `/cls` | Clear terminal screen and reprint header |
|
|
121
|
+
| `/help` | `/?` | Display quick command reference guide |
|
|
122
|
+
| `/exit` | `/quit`, `/q` | Exit interactive CLI mode |
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## π Key Features
|
|
127
|
+
|
|
128
|
+
- **16 Platforms Supported**: Save media from TikTok, Instagram, YouTube, Twitter/X, Spotify, Apple Music, Pinterest, Facebook, Threads, Reddit, Bilibili, Douyin, RedNote, Pixiv, Bandcamp, and TeraBox.
|
|
129
|
+
- **Automatic Version Checker**: Fast, non-blocking check on launch alerts you with a notification box whenever a newer CLI release is available on npm.
|
|
130
|
+
- **Dual Update System**: Run `/update` to check for both newer CLI package versions on npm and live OTA scraper engine patches from GitHub.
|
|
131
|
+
- **Multi-Processing Parallel Downloads**: High-speed concurrent downloads for photo galleries and batch links with optimized worker pools.
|
|
132
|
+
- **Single-Row In-Place Updates**: Dynamic in-place terminal spinner without spamming new lines for every photo.
|
|
133
|
+
- **Instant Photo-to-PDF**: Combine multi-image posts and photo carousels into a single, clean PDF file (`-p` / `--pdf`).
|
|
134
|
+
- **Integrated Terminal Player**: Launch and listen/watch downloaded videos and audio directly via `/play <num>`.
|
|
135
|
+
- **History & Disk Sync Deletion**: Keep track of downloaded files, re-download past items, or delete files from disk and history via `/delete <num>`.
|
|
136
|
+
- **Clipboard Detection**: One-command downloads from your clipboard (`-c` / `--clip` or `/clip`).
|
|
137
|
+
- **Dual-Server Redundancy**: Seamlessly switch between primary and mirror servers for platforms like TikTok, Instagram, YouTube, X, and Spotify.
|
|
138
|
+
- **Over-The-Air (OTA) Hot-Patching**: Scrapers update dynamically via GitHub when upstream platform APIs change, without waiting for an NPM package release.
|
|
139
|
+
- **Built-in Network Diagnostics**: Check connection latency and packet loss to download servers using `/ping`.
|
|
140
|
+
- **100% Local & Private**: No analytics, no accounts, and no data telemetry. Configuration and history are stored locally in `~/.mori`.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## π License
|
|
145
|
+
|
|
146
|
+
Licensed under the [GNU General Public License v3.0](https://github.com/coflyn/Mori/blob/main/LICENSE).
|
|
147
|
+
Part of the **[Mori](https://github.com/coflyn/Mori)** project.
|
package/bundle.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
var __MoriCoreScrapers=(()=>{var jt=Object.create;var ct=Object.defineProperty;var zt=Object.getOwnPropertyDescriptor;var Jt=Object.getOwnPropertyNames;var Vt=Object.getPrototypeOf,Xt=Object.prototype.hasOwnProperty;var wt=(t,r)=>()=>{try{return r||t((r={exports:{}}).exports,r),r.exports}catch(e){throw r=0,e}},Gt=(t,r)=>{for(var e in r)ct(t,e,{get:r[e],enumerable:!0})},kt=(t,r,e,l)=>{if(r&&typeof r=="object"||typeof r=="function")for(let c of Jt(r))!Xt.call(t,c)&&c!==e&&ct(t,c,{get:()=>r[c],enumerable:!(l=zt(r,c))||l.enumerable});return t};var D=(t,r,e)=>(e=t!=null?jt(Vt(t)):{},kt(r||!t||!t.__esModule?ct(e,"default",{value:t,enumerable:!0}):e,t)),Zt=t=>kt(ct({},"__esModule",{value:!0}),t);var F=wt((Ae,Tt)=>{Tt.exports=window.__moriDeps.utils});var K=wt((Ue,Rt)=>{Rt.exports=window.__moriDeps.urlUtils});var Mt=wt((Oe,Ct)=>{Ct.exports=window.__moriDeps.core});var _e={};Gt(_e,{_igSource:()=>W,_spSource:()=>X,_ttSource:()=>z,_twSource:()=>J,_ytSource:()=>B,createScraperResult:()=>C,getRequestTimeout:()=>et,parseJsonResponse:()=>At,scrapeAppleMusic:()=>we,scrapeBandcamp:()=>ye,scrapeBilibili:()=>ce,scrapeDouyin:()=>he,scrapeFacebook:()=>ge,scrapeInstagram:()=>ae,scrapePinterest:()=>fe,scrapePixiv:()=>de,scrapeRedNote:()=>ue,scrapeReddit:()=>Se,scrapeSpotify:()=>Lt,scrapeTeraBox:()=>xe,scrapeThreads:()=>me,scrapeTikTok:()=>Kt,scrapeTwitter:()=>oe,scrapeYouTube:()=>Ot,scraperFetch:()=>T,setInstagramSource:()=>ee,setSpotifySource:()=>se,setTikTokSource:()=>Yt,setTwitterSource:()=>ie,setYouTubeSource:()=>Qt});var dt=D(F());function et(){let t=parseInt(localStorage.getItem("mori_request_timeout"),10);return!isNaN(t)&&t>=5&&t<=180?t*1e3:3e4}function At(t,r="Server"){if(typeof t=="object"&&t!==null)return t;if(typeof t=="string"){let e=t.trim();if(e.startsWith("<")||e.startsWith("<!DOCTYPE"))throw new Error(`${r} returned an HTML error page (blocked or rate-limited). Please try another server or check your network connection.`);try{return JSON.parse(e)}catch{throw new Error(`${r} returned an invalid response format.`)}}throw new Error(`${r} returned an empty response.`)}async function T(t,r="Server"){let e=(t.method||(t.data?"POST":"GET")).toUpperCase(),l={...t.headers};!l["User-Agent"]&&!l["user-agent"]&&(l["User-Agent"]=(0,dt.getUserAgent)());let c=localStorage.getItem("mori_header_spoofing")!=="false",n=localStorage.getItem("mori_bypass_ssl")==="true",h=localStorage.getItem("mori_force_ipv4")==="true";if(c){try{let s=new URL(t.url);!l.Referer&&!l.referer&&(l.Referer=`${s.protocol}//${s.hostname}/`)}catch{}!l.Accept&&!l.accept&&(l.Accept="text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8"),!l["Accept-Language"]&&!l["accept-language"]&&(l["Accept-Language"]="en-US,en;q=0.9,id;q=0.8"),!l["Sec-Fetch-Dest"]&&!l["sec-fetch-dest"]&&(l["Sec-Fetch-Dest"]="empty"),!l["Sec-Fetch-Mode"]&&!l["sec-fetch-mode"]&&(l["Sec-Fetch-Mode"]="cors")}let p=localStorage.getItem("mori_doh")||"off";if(p!=="off")try{let s=new URL(t.url),m=s.hostname;if(!/^\d+\.\d+\.\d+\.\d+$/.test(m)&&s.protocol==="https:"){let f=p==="google"?`https://dns.google/resolve?name=${m}&type=A`:`https://cloudflare-dns.com/dns-query?name=${m}&type=A`;fetch(f,{headers:{Accept:"application/dns-json"},signal:AbortSignal.timeout(2e3)}).catch(()=>{})}}catch{}let w={url:t.url,headers:l,connectTimeout:et(),readTimeout:et()};n&&(w.disableSSLValidation=!0),h&&(w.ipv4Only=!0),t.data!==void 0&&(w.data=t.data),t.params!==void 0&&(w.params=t.params),t.responseType!==void 0&&(w.responseType=t.responseType);let i,u=window.__TAURI__?.core?.invoke||window.__TAURI_INTERNALS__?.invoke||window.__TAURI__?.invoke,g=window.MoriMainBridge||window.MoriShareBridge,o=window.Capacitor?.Plugins?.CapacitorHttp||dt.CapacitorHttp;if(g?.httpRequestAsync){let s=t.url;if(t.params){let S=new URLSearchParams(t.params).toString();S&&(s+=(s.includes("?")?"&":"?")+S)}let m={url:s,method:e,headers:l,responseType:t.responseType};t.data!==void 0&&(m.data=typeof t.data=="object"?JSON.stringify(t.data):String(t.data));let f="req_"+Math.random().toString(36).substring(2,11)+"_"+Date.now(),y=await new Promise((S,a)=>{window.__moriNativeCallbacks||(window.__moriNativeCallbacks={});let d=et(),x=setTimeout(()=>{delete window.__moriNativeCallbacks[f],window.__moriShareCallbacks&&delete window.__moriShareCallbacks[f],a(new Error(`${r} request timed out after ${d/1e3}s`))},d+2e3);window.__moriNativeCallbacks[f]=k=>{clearTimeout(x),S(k)},window.__moriShareCallbacks||(window.__moriShareCallbacks=window.__moriNativeCallbacks),g.httpRequestAsync(JSON.stringify(m),f)}),b=JSON.parse(y);if(b.status===0&&b.error)throw new Error(`${r} request failed: ${b.error}`);i={status:b.status,headers:b.headers||{},data:b.data,url:b.url||t.url}}else if(g?.httpRequest){let s=t.url;if(t.params){let b=new URLSearchParams(t.params).toString();b&&(s+=(s.includes("?")?"&":"?")+b)}let m={url:s,method:e,headers:l,responseType:t.responseType};t.data!==void 0&&(m.data=typeof t.data=="object"?JSON.stringify(t.data):String(t.data));let f=g.httpRequest(JSON.stringify(m)),y=JSON.parse(f);if(y.status===0&&y.error)throw new Error(`${r} request failed: ${y.error}`);i={status:y.status,headers:y.headers||{},data:y.data,url:y.url||t.url}}else if(o)e==="POST"?i=await o.post(w):e==="PUT"?i=await o.put(w):e==="DELETE"?i=await o.delete(w):i=await o.get(w),i&&!i.url&&(i.url=t.url);else if(u){let s=t.url;if(t.params){let f=new URLSearchParams(t.params).toString();f&&(s+=(s.includes("?")?"&":"?")+f)}let m;t.data!==void 0&&(typeof t.data=="object"&&!(t.data instanceof FormData)&&!(t.data instanceof URLSearchParams)?l["Content-Type"]?.includes("application/x-www-form-urlencoded")?m=new URLSearchParams(t.data).toString():(m=JSON.stringify(t.data),l["Content-Type"]||(l["Content-Type"]="application/json")):m=String(t.data)),i=await u("tauri_http_request",{url:s,method:e,headers:l,body:m}),i&&!i.url&&(i.url=s)}else{let s=t.url;if(t.params){let a=new URLSearchParams(t.params).toString();a&&(s+=(s.includes("?")?"&":"?")+a)}let m;t.data!==void 0&&(typeof t.data=="object"&&!(t.data instanceof FormData)&&!(t.data instanceof URLSearchParams)?l["Content-Type"]?.includes("application/x-www-form-urlencoded")?m=new URLSearchParams(t.data).toString():(m=JSON.stringify(t.data),l["Content-Type"]||(l["Content-Type"]="application/json")):m=t.data);let f=new AbortController,y=setTimeout(()=>f.abort(),et()),b=await fetch(s,{method:e,headers:l,body:m,signal:f.signal});clearTimeout(y);let S=t.responseType==="arraybuffer"?await b.arrayBuffer():await b.text();i={status:b.status,headers:Object.fromEntries(b.headers.entries()),data:S,url:b.url}}return t.rawResponse?i:t.parseJson!==!1?At(i.data,r):i.data}function C(t,r,e=null){if(t)return{status:!0,result:r};let l={status:!1,message:typeof r=="string"?r:r?.message||"Scraping failed."};return e!=null&&(l.statusCode=e),l}var gt=D(F()),Ut=D(K());function ut(t){return!t||typeof t!="string"?"":t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').replace(/'/g,"'").replace(/&#x([0-9a-fA-F]+);/g,(r,e)=>String.fromCodePoint(parseInt(e,16))).replace(/&#(\d+);/g,(r,e)=>String.fromCodePoint(parseInt(e,10)))}var z=null;function Yt(t){z=t}async function Kt(t){let r=null;try{let e=(0,Ut.getCleanUrl)(t).split("?")[0];if(!/https:\/\/(?:m|www|vm|vt|lite)?\.?tiktok\.com\/((?:.*\b(?:(?:usr|v|embed|user|video|photo)\/|\?shareId=|\&item_id=)(\d+))|\w+)/.test(e))throw new Error("Must be a valid tiktok url.");if(!z)return{requireSource:!0};if(z==="tikdownloader"||z==="snaptik"){let c=await T({url:"https://tikdownloader.io/api/ajaxSearch",method:"POST",headers:{"User-Agent":gt.CHROME_UA,"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8","X-Requested-With":"XMLHttpRequest",Origin:"https://tikdownloader.io",Referer:"https://tikdownloader.io/id"},data:`q=${encodeURIComponent(e)}&vt=id`,rawResponse:!0},"TikDownloader");r=c.status;let n;if(typeof c.data=="string"){let a=c.data.trim();if(a.startsWith("<")||a.startsWith("<!DOCTYPE"))throw new Error("TikDownloader returned an HTML error page (blocked or rate-limited).");try{n=JSON.parse(a)}catch{throw new Error("TikDownloader returned an invalid response format.")}}else n=c.data;if(!n||n.status!=="ok"||!n.data)throw new Error(n?.msg||"TikDownloader extraction failed.");let h=n.data,p="TikTok Content",w=h.match(/<div[^>]*class=["']clearfix["'][^>]*>[\s\S]*?<h3[^>]*>([\s\S]*?)<\/h3>/i)||h.match(/<h3[^>]*>([\s\S]*?)<\/h3>/i);w&&(p=ut(w[1].replace(/<[^>]+>/g,"").trim()));let i="",u=h.match(/<div[^>]*class=["']image-tik[^"']*["'][^>]*>[\s\S]*?<img[^>]+src=["']([^"']+)["']/i)||h.match(/<img[^>]+src=["']([^"']+)["']/i);u&&(i=ut(u[1]));let g=e.match(/@([^\/]+)/),o=g?g[1]:"TikTok User",s=[],m=/<a[^>]+href=["']([^"']+)["'][^>]*class=["'][^"']*tik-button-dl[^"']*["'][^>]*>([\s\S]*?)<\/a>/gi,f;for(;(f=m.exec(h))!==null;){let a=ut(f[1]),d=f[2].replace(/<[^>]+>/g,"").trim().toLowerCase();d.includes("mp4 hd")||d.includes("hd")?s.push({type:"1080p",url:a,isMirror:!1}):d.includes("mp4 [1]")||d.includes("without watermark")||d.includes("mp4")&&!s.some(x=>x.type==="720p")?s.push({type:"720p",url:a,isMirror:!1}):d.includes("mp4 [2]")?s.push({type:"720p",url:a,isMirror:!0}):d.includes("mp3")||d.includes("audio")?s.push({type:"MP3",url:a,isMirror:!1}):(d.includes("photo")||d.includes("foto")||d.includes("image"))&&s.push({type:"PHOTO",url:a,isMirror:!1})}let y=/<div[^>]*class=["'][^"']*(?:image-item|photo-item)[^"']*["'][^>]*>[\s\S]*?<\/div>/gi,b;for(;(b=y.exec(h))!==null;){let a=b[0],d=a.match(/href=["']([^"']+)["']/i),x=a.match(/src=["']([^"']+)["']/i),k=d&&d[1]!=="#"?d[1]:x?x[1]:null;k&&!s.some(U=>U.url===k)&&s.push({type:"PHOTO",url:ut(k),isMirror:!1})}if(s.length===0)throw new Error("No download links found from TikDownloader.");let S={"1080p":1,"720p":2,PHOTO:3,MP3:4};return s.sort((a,d)=>(S[a.type]||99)-(S[d.type]||99)),z=null,C(!0,{title:p,author:o,thumbnail:i,downloads:s,sourceUrl:t})}if(z==="tiktokio"){let c=await T({url:"https://tiktokio.com/api/v1/tk/html",method:"POST",data:{vid:e,prefix:"tiktokio.com"},headers:{"User-Agent":gt.CHROME_UA,"Content-Type":"application/json",Origin:"https://tiktokio.com",Referer:"https://tiktokio.com/"},rawResponse:!0},"TikTokIO");r=c.status;let n=c.data;if(typeof n=="object"&&n!==null&&(n=JSON.stringify(n)),typeof n!="string"&&(n=""),!n||n.includes("Please paste a valid link")||n.includes("Error"))throw new Error("Invalid link or failed to fetch data from tiktokio.");let h="TikTok Content",p=n.match(/<h3[^>]*>([\s\S]*?)<\/h3>/i);p&&(h=p[1].replace(/<[^>]+>/g,"").trim());let w="",i=n.match(/<img[^>]+src=["']([^"']+)["'][^>]*>/i);i&&(w=i[1].replace(/&/g,"&"));let u=n.includes('class="images-grid"')||n.includes('class="image-item"'),g=e.match(/@([^\/]+)/),o=g?g[1]:"Unknown",s=[];if(u){let m=/<div[^>]*class=["'][^"']*image-item[^"']*["'][^>]*>[\s\S]*?<\/div>/gi,f;for(;(f=m.exec(n))!==null;){let S=f[0],a=S.match(/href=["']([^"']+)/i);if(a&&a[1]!=="#"){let d=a[1].replace(/&/g,"&");s.some(x=>x.url===d)||s.push({type:"PHOTO",url:d,isMirror:!1})}else{let d=S.match(/src=["']([^"']+)/i);if(d){let x=d[1].replace(/&/g,"&");s.some(k=>k.url===x)||s.push({type:"PHOTO",url:x,isMirror:!1})}}}let y=/<a[\s\S]*?<\/a>/gi,b;for(;(b=y.exec(n))!==null;){let S=b[0];if(S.includes("download-btn-purple")||S.toLowerCase().includes("mp3")||S.toLowerCase().includes("music")){let a=S.match(/href=["']([^"']+)/i);if(a&&a[1]!=="#"){let d=a[1].replace(/&/g,"&");s.some(x=>x.url===d)||s.push({type:"MP3",url:d,isMirror:!1})}}}}else{let m=/<a[\s\S]*?<\/a>/gi,f,y=0;for(;(f=m.exec(n))!==null;){let b=f[0];if(!b.includes("download-btn"))continue;let S=b.match(/href=["']([^"']+)/i);if(!S||S[1]==="#")continue;let a=S[1].replace(/&/g,"&"),d=b.replace(/<[^>]+>/g,"").trim().toLowerCase();if(d.includes("download watermark")&&!d.includes("without"))continue;let x=!1,k=!1;if(d.includes("mp3")||d.includes("music")||b.includes("download-btn-purple")?k=!0:(d.includes("without watermark")||b.includes("download-btn-blue")||b.includes("download-btn-green"))&&(x=!0),x){y++;let U=b.includes("download-btn-green")||d.includes("(hd)")||d.includes("1080"),R;U?R=s.some(A=>A.type==="1080p")?`VIDEO ${y}`:"1080p":y===1?R="720p":s.some(A=>A.type==="1080p")?s.some(A=>A.type==="720p")?R=`VIDEO ${y}`:R="720p":R="1080p";let $=y>1;s.some(A=>A.url===a)||s.push({type:R,url:a,isMirror:$})}else k&&(s.some(U=>U.url===a)||s.push({type:"MP3",url:a,isMirror:!1}))}}if(s.length===0)throw new Error("No download links found.");return z=null,C(!0,{title:h,author:o,thumbnail:w,downloads:s,sourceUrl:t})}throw new Error("Invalid source selected.")}catch(e){return z=null,C(!1,e.message,r)}}var at=D(F());var Pe=D(Mt()),B=null;function Qt(t){B=t}async function Ot(t){let r=null;try{let e=t.match(/(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?|shorts|live)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/\s]{11})/i),l=t.match(/[?&]list=([^"&?\/\s]+)/i),c=e?.[1],n=l?.[1],h=!!n&&(!c||t.includes("/playlist"));if(!c&&!n)throw new Error("Invalid YouTube URL");if(h)return B=null,await te(n,t);if(!B)return{requireSource:!0};let w=await(async()=>{let i="YouTube Video",u=`https://i.ytimg.com/vi/${c}/hqdefault.jpg`;try{let g=await T({url:`https://www.youtube.com/oembed?url=https://www.youtube.com/watch?v=${c}&format=json`},"YouTube Oembed");g&&(i=g.title||i,u=g.thumbnail_url||u)}catch{}return{title:i,thumbnail:u}})();if(B==="gg"){let i={Origin:"https://media.ytmp3.gg",Referer:"https://media.ytmp3.gg/","User-Agent":at.CHROME_UA,Accept:"application/json, text/plain, */*"},u=async(m,f)=>{try{let y=await T({url:"https://hub.convert1s.com/api/download",method:"POST",headers:{...i,"Content-Type":"application/json"},data:JSON.stringify({url:t,os:"macos",output:{type:m==="mp4"?"video":"audio",format:m,quality:f},audio:{bitrate:"128k"}}),rawResponse:!0},"ytmp3.gg Convert");r=y.status;let b=y.data;if(typeof b=="string"){if(b.trim().startsWith("<"))return null;b=JSON.parse(b)}if(!b||b.error||!b.statusUrl)return null;let S=null,a=0;for(;!S&&a<30;){await new Promise(x=>setTimeout(x,1500));let d=await T({url:b.statusUrl,headers:i},"ytmp3.gg Status");if(a++,d&&d.status==="completed"&&d.downloadUrl){S=d.downloadUrl;break}if(d&&(d.status==="error"||d.status==="failed"))break}return S?{url:S,quality:b.selectedQuality||f}:null}catch{return null}},g=[],o=["720p","360p"];for(let m of o){let f=await u("mp4",m);f&&f.url&&g.push({type:`MP4 ${f.quality||m}`,url:f.url}),await new Promise(y=>setTimeout(y,300))}let s=await u("mp3","");return s&&s.url&&g.push({type:"MP3",url:s.url}),g.length>0?(B=null,C(!0,{...w,downloads:g,sourceUrl:t})):(console.warn("[ytmp3.gg] Failed, falling back to ytmp3.mobi..."),B="mobi",await Ot(t))}if(B==="mobi"){let i={Origin:"https://ytmp3.mobi",Referer:"https://ytmp3.mobi/en8/","User-Agent":at.CHROME_UA,"Sec-Fetch-Dest":"empty","Sec-Fetch-Mode":"cors","Sec-Fetch-Site":"cross-site",Accept:"*/*"},u=async m=>{try{let f=await T({url:`https://a.ymcdn.org/api/v1/init?p=y&23=1llum1n471&_=${Math.random()}`,headers:i},"ytmp3.mobi Init");if(!f||f.error||!f.convertURL)return null;let y=await T({url:`${f.convertURL}&v=${c}&f=${m}&_=${Math.random()}`,headers:i},"ytmp3.mobi Convert");if(!y||y.error)return null;for(;y&&y.redirect>0&&y.redirectURL;)y=await T({url:`${y.redirectURL}&v=${c}&f=${m}&_=${Math.random()}`,headers:i},"ytmp3.mobi Redirect");if(!y||y.error)return null;let b=0,S=y.downloadURL,a=y.progressURL,d=0;for(;b<3&&d<20;){await new Promise(k=>setTimeout(k,1500));let x=await T({url:`${a}&_=${Math.random()}`,headers:i},"ytmp3.mobi Progress");if(!x||x.error||(b=x.progress,x.downloadURL&&(S=x.downloadURL),b>=3))break;d++}return S&&b>=3?(S.startsWith("//")&&(S="https:"+S),S.startsWith("/")&&(S="https://ytmp3.mobi"+S),S):null}catch{return null}},g=await u("mp3"),o=await u("mp4"),s=[];if(o&&s.push({type:"MP4",url:o}),g&&s.push({type:"MP3",url:g}),!s.length)throw new Error("Failed to get download links. Try again.");return B=null,C(!0,{...w,downloads:s,sourceUrl:t})}throw new Error("Invalid source selected")}catch(e){return B=null,C(!1,e.message,r)}}async function te(t,r){let e=`https://www.youtube.com/playlist?list=${t}`,l=await T({url:e,headers:{"User-Agent":at.CHROME_DESKTOP_UA,"Accept-Language":"en-US,en;q=0.9",Cookie:"SOCS=CAESEwgDEgk2MTc4OTU0NzQaAmVuIAEaBgiA_LyaBg; CONSENT=PENDING+999"},rawResponse:!0},"YouTube Playlist"),c=typeof l?.data=="string"?l.data:JSON.stringify(l?.data||""),n=null,h="ytInitialData = ",p=c.indexOf(h);if(p!==-1){let b=p+h.length,S=c.indexOf("<\/script>",b);if(S!==-1){let a=c.substring(b,S).trim();a.endsWith(";")&&(a=a.slice(0,-1));try{n=JSON.parse(a)}catch{}}}if(!n){let b=c.match(/ytInitialData\s*=\s*({.+?});<\/script>/s)||c.match(/var ytInitialData\s*=\s*({.+?});/s);if(b)try{n=JSON.parse(b[1])}catch{}}if(!n)throw new Error("Failed to extract YouTube playlist. The playlist might be private or unavailable.");if(n.alerts)for(let b of n.alerts){let S=b.alertRenderer?.text?.runs?.[0]?.text||b.alertRenderer?.text?.simpleText;if(S&&b.alertRenderer?.type==="ERROR")throw new Error(`YouTube: ${S}`)}let w=n.sidebar?.playlistSidebarRenderer?.items?.[0]?.playlistSidebarPrimaryInfoRenderer,i=n.sidebar?.playlistSidebarRenderer?.items?.[1]?.playlistSidebarSecondaryInfoRenderer,u=(typeof n.metadata?.playlistMetadataRenderer?.title=="string"?n.metadata?.playlistMetadataRenderer?.title:n.metadata?.playlistMetadataRenderer?.title?.runs?.[0]?.text)||w?.title?.runs?.[0]?.text||w?.title?.simpleText||n.header?.playlistHeaderRenderer?.title?.simpleText||n.header?.playlistHeaderRenderer?.title?.runs?.[0]?.text||"YouTube Playlist",g=i?.videoOwner?.videoOwnerRenderer?.title?.runs?.[0]?.text||i?.videoOwner?.videoOwnerRenderer?.title?.simpleText||n.header?.playlistHeaderRenderer?.ownerText?.runs?.[0]?.text||n.header?.playlistHeaderRenderer?.ownerText?.simpleText||"",o=w?.thumbnailRenderer?.playlistVideoThumbnailRenderer?.thumbnail?.thumbnails?.slice(-1)[0]?.url||n.header?.playlistHeaderRenderer?.playlistHeaderBanner?.heroPlaylistThumbnailRenderer?.thumbnail?.thumbnails?.slice(-1)[0]?.url||n.metadata?.playlistMetadataRenderer?.thumbnail?.thumbnails?.slice(-1)[0]?.url||"https://www.youtube.com/img/desktop/yt_1200.png",s=[],m=new Set;function f(b){if(!(!b||typeof b!="object")){if(b.playlistVideoRenderer){let S=b.playlistVideoRenderer,a=S.videoId,d=S.title?.runs?.[0]?.text||S.title?.simpleText||"",x=S.shortBylineText?.runs?.[0]?.text||"",k=S.thumbnail?.thumbnails?.slice(-1)[0]?.url||`https://i.ytimg.com/vi/${a}/hqdefault.jpg`;a&&d&&!m.has(a)&&(m.add(a),s.push({id:a,title:d,author:x,thumb:k}));return}if(b.lockupViewModel){let S=b.lockupViewModel,a=S.contentId||S.rendererContext?.commandContext?.onTap?.innertubeCommand?.watchEndpoint?.videoId,d=S.metadata?.lockupMetadataViewModel?.title?.content||"",x=S.metadata?.lockupMetadataViewModel?.metadata?.contentMetadataViewModel?.metadataRows?.[0]?.metadataParts?.[0]?.text?.content||"",k=S.contentImage?.thumbnailViewModel?.image?.sources?.slice(-1)[0]?.url||`https://i.ytimg.com/vi/${a}/hqdefault.jpg`;a&&d&&!m.has(a)&&(m.add(a),s.push({id:a,title:d,author:x,thumb:k}));return}for(let S of Object.keys(b))S!=="onTap"&&S!=="serviceTrackingParams"&&S!=="clickTrackingParams"&&f(b[S])}}if(f(n),s.length===0)throw new Error("No playable tracks found in YouTube playlist. It may be private or empty.");let y=s.map((b,S)=>{let a=`${(S+1).toString().padStart(String(s.length).length,"0")}. `,d=rt(b.title),x=rt(b.author),k=x?`${x} - ${d}`:d;return{type:`${a}${k} [MP3]`,url:`youtube_resolve:${b.id}|||mp3|||128`,ext:"mp3"}});return C(!0,{title:g?`${rt(g)} - ${rt(u)} (Playlist)`:`${rt(u)} (Playlist)`,thumbnail:s[0]?.thumb||o,downloads:y,sourceUrl:r})}function rt(t){return t?t.replace(/<[^>]+>/g,"").replace(/�?39;/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').trim():""}var Q=D(F()),$t=D(K());var W=null;function ee(t){W=t}function Pt(t,r){let e="";if(t){let l=t.querySelector(".download-items__title, .card-title, .caption, .desc, .post-title, h3, h4, h5, p.card-text, .text-center > p");if(l){let c=l.textContent?.trim().replace(/\s+/g," ");c&&c.length>3&&!c.toLowerCase().includes("download")&&!c.toLowerCase().includes("snapsave")&&!c.toLowerCase().includes("indown")&&!c.toLowerCase().includes("private")&&(e=c)}if(!e){let c=t.querySelectorAll(".download-items__thumb img, .card img, img");for(let n of c){let h=n.getAttribute("alt")?.trim().replace(/\s+/g," ");if(h&&h.length>3&&h.toLowerCase()!=="thumbnail"&&h.toLowerCase()!=="instagram"&&h.toLowerCase()!=="image"&&h.toLowerCase()!=="video"&&!h.toLowerCase().includes("download")){e=h;break}}}}if(!e){let l=r.match(/instagram\.com\/([A-Za-z0-9_.-]+)\/(?:p|reel|reels|tv)\//i),c=r.match(/(?:p|reel|reels|tv)\/([A-Za-z0-9_-]+)/i),n=r.includes("/reel"),h=r.includes("/tv/"),p=n?"Reel":h?"Video":"Post",w=c?c[1]:"",i=l?l[1].toLowerCase():"",u=l&&!["p","reel","reels","tv","stories","share"].includes(i)?`@${l[1]}`:"";u&&w?e=`${u} - Instagram ${p} (${w})`:u?e=`${u} - Instagram ${p}`:w?e=`Instagram ${p} (${w})`:e=`Instagram ${p}`}return e.length>90&&(e=e.substring(0,87)+"..."),e}async function re(t){try{let r=Q.CHROME_UA,e=await T({url:"https://snapsave.app/action.php",method:"POST",data:(0,Q.serializeData)({url:t}),headers:{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8","User-Agent":r,"X-Requested-With":"XMLHttpRequest",Origin:"https://snapsave.app",Referer:"https://snapsave.app/"},rawResponse:!0},"SnapSave");if(!e||!e.data)return console.warn("[SnapSave] res or res.data is empty:",e),null;let l="",c=e.data,n=h=>{if(typeof h!="string")return"";let p="",w=h.indexOf('innerHTML = "');if(w!==-1){let i=w+13,u=h.lastIndexOf('"');if(u>i){let g=h.slice(i,u);try{p=(0,eval)('"'+g+'"')}catch{p=g}}}if(!p){let i=h.indexOf("innerHTML = '");if(i!==-1){let u=i+13,g=h.lastIndexOf("'");if(g>u){let o=h.slice(u,g);try{p=(0,eval)("'"+o+"'")}catch{p=o}}}}if(!p){let i=h.indexOf("<ul class=");if(i!==-1){let u=h.lastIndexOf("</ul>");u>i&&(p=h.slice(i,u+5))}}return p};if(typeof c=="string"&&c.trim().startsWith("<"))l=c;else if(typeof c=="string")try{let h=c.replace(/\beval\s*\(\s*function/g,"(function"),p=(0,eval)(h);l=n(p)||n(c)}catch(h){console.warn("[SnapSave] Unpack JS failed:",h),l=n(c)}if(l){let p=new DOMParser().parseFromString(l,"text/html"),w=new Map,i=(m,f)=>{let y=(m+" "+f).toUpperCase();if(y.includes("PHOTO")||y.includes("GAMBAR")||y.includes("IMAGE")||y.includes("ICON-DLIMAGE"))return!0;if(y.includes("VIDEO")||y.includes("ICON-DLVIDEO"))return!1;try{let b=m.match(/token=([A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+)/);if(b){let a=b[1].split(".")[1].replace(/-/g,"+").replace(/_/g,"/"),d="";if(typeof atob=="function"?d=atob(a):typeof Buffer<"u"&&(d=Buffer.from(a,"base64").toString("utf-8")),/\.(jpe?g|png|webp)(\?|"|$)/i.test(d))return!0;if(/\.(mp4|mkv|mov|webm)(\?|"|$)/i.test(d))return!1}}catch{}return/\.(jpe?g|png|webp)(\?|$)/i.test(m)},u=(m,f,y,b)=>{if(!m||!m.startsWith("http")||m.includes("snapsave.app")||m.includes("play.google.com")||m.includes("facebook.com"))return;let S=m;if(w.has(S))return;let a=i(m,(f||"")+" "+(y||"")),d=b;!d&&m.includes("rapidcdn.app")&&(d=m.replace("/v2?","/thumb?").replace("/download?","/thumb?")),w.set(S,{url:m,type:a?"PHOTO":"MP4",thumbnail:d})},g=p.querySelectorAll(".download-box > li, .download-items, li");(g.length>0?g:[p]).forEach(m=>{let f=m.querySelector(".download-items__thumb img, img"),y=f?f.getAttribute("src"):null;m.querySelectorAll("a.abutton, .download-items__btn a, a[href*='rapidcdn'], a[href*='snapcdn'], a[href*='cdninstagram'], a[href*='fbcdn'], a[href]").forEach(a=>{let d=a.getAttribute("href"),x=a.getAttribute("title")||"",k=a.textContent||"";u(d,x,k,y)}),m.querySelectorAll("select option").forEach(a=>{let d=a.getAttribute("value");if(!d||!d.startsWith("http")||d.includes("snapsave.app"))return;let x=d;if(w.has(x))return;let k=(a.textContent||"").trim()||"HD",U=i(d,k);w.set(x,{url:d,type:U?"PHOTO":"MP4",quality:k&&!k.toLowerCase().includes("hd")?k:void 0,thumbnail:y})})}),w.size===0&&[...l.matchAll(/href=\\?["'](http[^"'\\]+)\\?["']/gi)].map(f=>f[1]).forEach(f=>{u(f,"Download","Download",null)});let s=[...w.values()];if(s.length>0){let m=s[0].thumbnail||s[0].url,f=Pt(p,t);return C(!0,{title:f,thumbnail:m,downloads:s,sourceUrl:t})}}}catch(r){console.warn("[SnapSave] Failed:",r)}return null}async function ae(t){let r=null;try{let e=(0,$t.getCleanUrl)(t).split("?")[0];if(!W)return{requireSource:!0};if(W==="savevid"||W==="downreels"||W==="snapsave"){let l=await re(e);if(l)return W=null,l;throw new Error("Failed to fetch media from Server 2.")}if(W==="indown"){try{let l=Q.CHROME_UA,c=await T({url:"https://indown.net/api/ajaxSearch",method:"POST",data:(0,Q.serializeData)({q:e,vt:"reel",t:"media",lang:"en",v:"v2"}),headers:{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8","User-Agent":l,"X-Requested-With":"XMLHttpRequest",Origin:"https://indown.net",Referer:"https://indown.net/"},rawResponse:!0},"Indown Net");if(c&&c.data){let h=(typeof c.data=="string"?JSON.parse(c.data):c.data).data||"";if(h){let w=new DOMParser().parseFromString(h,"text/html"),i=[],u=new Set,g=(s,m,f)=>{let y=(m+" "+f).toUpperCase();if(y.includes("VIDEO")||y.includes("MP4")||y.includes("REEL"))return!0;if(y.includes("PHOTO")||y.includes("IMAGE")||y.includes("GAMBAR")||y.includes("FOTO"))return!1;try{let b=s.match(/token=([A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+)/);if(b){let a=b[1].split(".")[1].replace(/-/g,"+").replace(/_/g,"/"),d="";if(typeof atob=="function"?d=atob(a):typeof Buffer<"u"&&(d=Buffer.from(a,"base64").toString("utf-8")),/\.(mp4|mov|webm|mkv)(\?|"|$)/i.test(d))return!0;if(/\.(jpe?g|png|webp)(\?|"|$)/i.test(d))return!1}}catch{}return/\.(mp4|mov|webm)(\?|$)/i.test(s)?!0:(/\.(jpe?g|png|webp)(\?|$)/i.test(s),!1)},o=Array.from(w.querySelectorAll(".download-items, .col-md-4, .col-sm-6, .card, .thumbnail"));if(o=o.filter(s=>!o.some(m=>m!==s&&m.contains(s))),o.length===0&&(o=[w]),o.forEach((s,m)=>{let y=s.querySelector("img")?.getAttribute("src")||"",b=Array.from(s.querySelectorAll("a[href*='download'], a.abutton, a.btn, a[href*='snapcdn'], a[href*='rapidcdn'], a[href*='cdninstagram'], a[href*='fbcdn'], a[href^='http']")).filter(A=>{let _=A.getAttribute("href")||"";return!(!_.startsWith("http")||_.includes("indown.net/api")||_.includes("facebook.com")||_.includes("ads")||_==="https://indown.net/"||_==="https://indown.net")});if(b.length===0)return;let a=b.find(A=>{let _=A.getAttribute("href")||"",v=A.textContent||"",M=A.getAttribute("title")||"";return g(_,v,M)})||b[0],d=a.getAttribute("href").replace(/&/g,"&");if(u.has(d))return;u.add(d);let x=a.textContent||"",k=a.getAttribute("title")||"",R=g(d,x,k)?"MP4":"PHOTO",$=y&&y.startsWith("http")?y:R==="PHOTO"?d:null;i.push({type:R,url:d,thumbnail:$||d})}),i.length===0&&Array.from(w.querySelectorAll("a.abutton, a.btn, a[href*='snapcdn'], a[href*='rapidcdn'], a[href*='cdninstagram'], a[href*='fbcdn'], a[href*='download']")).forEach((m,f)=>{let y=m.getAttribute("href");if(!y||!y.startsWith("http")||(y=y.replace(/&/g,"&"),y.includes("indown.net/api")||y.includes("facebook.com")||y.includes("ads")||y==="https://indown.net/")||u.has(y))return;u.add(y);let b=m.textContent||"",S=m.getAttribute("title")||"",d=g(y,b,S)?"MP4":"PHOTO";i.push({type:d,url:y,thumbnail:y})}),i.length>0){let s=i[0].thumbnail||i[0].url,m=Pt(w,e);return W=null,C(!0,{title:m,thumbnail:s,downloads:i,sourceUrl:e})}}}}catch(l){console.warn("[Indown.Net] Request failed:",l)}throw new Error("Media links not found. Post might be private or invalid.")}throw new Error("Invalid source selected.")}catch(e){return W=null,C(!1,e.message,r)}}var H=D(F()),Dt=D(K());var J=null;function ie(t){J=t}async function qt(t){try{let r=t.match(/status(?:es)?\/(\d+)/i);if(!r)return null;let e=await T({url:`https://api.fxtwitter.com/status/${r[1]}`,rawResponse:!0},"FxTwitter Meta"),l=e?.data??e;if(typeof l=="string")try{l=JSON.parse(l)}catch{}if(l?.tweet){let c=l.tweet.media?.videos?.[0]?.thumbnail_url||l.tweet.media?.photos?.[0]?.url||l.tweet.media?.mosaic?.formats?.jpeg||l.tweet.thumbnail_url||null;return{text:l.tweet.text||"",author:l.tweet.author?.name||"",handle:l.tweet.author?.screen_name?`@${l.tweet.author.screen_name}`:"",thumbnail:c}}}catch{}return null}function Et(t,r,e,l,c){let n="";if(t?.text){let h=t.text.replace(/https:\/\/t\.co\/\S+/g,"").replace(/\s+/g," ").trim();if(h){let p=t.author||l;n=p?`${p} - ${h}`:h}}if(!n&&r){let h=r.querySelector(".download__item__info__text, .download__item__text, .tweet-text, .card-text, .desc");if(h){let p=h.textContent?.trim().replace(/\s+/g," ");p&&p.length>3&&!p.toLowerCase().includes("download")&&!p.toLowerCase().includes("video quality")&&(n=l?`${l} - ${p}`:p)}}if(!n){let h=t?.author||l,p=t?.handle||c;h&&p?n=`${h} (${p})`:h&&(n=h)}if(!n){let h=e.match(/(?:twitter|x)\.com\/([A-Za-z0-9_]+)\/status\/(\d+)/i);if(h){let p=h[1]!=="i"?`@${h[1]}`:"",w=h[2];n=p?`${p} - Tweet (${w})`:`Tweet (${w})`}else n="Twitter Post"}return n.length>90&&(n=n.substring(0,87)+"..."),n}async function oe(t){let r=null;try{let e=(0,Dt.getCleanUrl)(t).split("?")[0];if(!J)return{requireSource:!0};let l=(n,h,p="")=>{let w=(n||"")+" "+(h||""),i=(p||"").match(/\/vid\/(\d+x\d+)\//i);if(i)return i[1].toLowerCase();let u=w.match(/(\d+\s*[xXΓ]\s*\d+|\d+\s*p)/i);return u?u[1].replace(/\s+/g,"").replace("\xD7","x").toLowerCase():w.replace(/download|video|mp4|get|premium|for|\$|\d+\.\d+|\:/gi,"").trim()||"MP4"},c=(n,h)=>{if(!n||!n.startsWith("http"))return!0;let p=n.toLowerCase(),w=(h||"").toLowerCase();return!!(p.includes("gumroad.com")||p.includes("aculix.link")||p.includes("circleboom.com")||p.includes("checkout")||p.includes("stripe")||p.includes("buy")||p.includes("premium")||w.includes("$")||w.includes("for $")||w.includes("premium")||w.includes("paywall"))};if(J==="tvd"){let n=e.replace(/https:\/\/(x|fixupx|fxtwitter|vxtwitter|nitter)\.com/g,"https://twitter.com"),h=await T({url:"https://twittervideodownloader.com/",headers:{"User-Agent":H.CHROME_UA},rawResponse:!0},"TVD Main");r=h.status;let p=new DOMParser,w=p.parseFromString(h.data,"text/html"),i=w.querySelector('input[name="csrfmiddlewaretoken"]')?.value,u=w.querySelector('input[name="gql"]')?.value||"",g=(0,H.getCookiesFromHeaders)(h.headers);if(!i)throw new Error("Could not find CSRF token from TwitterVideoDownloader.");let o=await T({url:"https://twittervideodownloader.com/download",method:"POST",data:(0,H.serializeData)({tweet:n,csrfmiddlewaretoken:i,gql:u}),headers:{Cookie:g,"Content-Type":"application/x-www-form-urlencoded","User-Agent":H.CHROME_UA,Referer:"https://twittervideodownloader.com/"},rawResponse:!0},"TVD Download");r=o.status;let s=p.parseFromString(o.data,"text/html"),m=[],f=[],y=k=>{let U=(k||"").match(/(\d+)\s*[xX]\s*(\d+)/);if(U)return parseInt(U[1],10)*parseInt(U[2],10);let R=(k||"").match(/(\d+)\s*p/i);return R?parseInt(R[1],10)*parseInt(R[1],10)*1.77:0};s.querySelectorAll(".card-body a, a.btn-download, a.btn, a.tw-btn, a[href*='video.twimg.com'], a[href*='twimg.com']").forEach(k=>{let U=k.getAttribute("href");if(!U||U==="/"||U.startsWith("#"))return;let R=k.textContent.trim(),A=k.closest(".card-body")?.querySelector(".card-text")?.textContent?.trim()||"",_=`${R} ${A}`;if(c(U,_))return;let v=U.includes("video.twimg.com")||/\.(mp4|m3u8)(\?|$)/i.test(U)||/mp4|video|720|1080|480|360|270/i.test(R),M=U.includes("pbs.twimg.com")||/\.(jpe?g|png|webp)(\?|$)/i.test(U);if(v&&!M){if(!m.some(O=>O.url===U)){let O=l(R,A,U);m.push({type:O,url:U})}}else M&&(f.some(O=>O.url===U)||f.push({type:"PHOTO",url:U}))}),m.sort((k,U)=>y(U.type)-y(k.type));let b=m.length>0?m:f;if(b.length===0)throw new Error("No free video links found on TVD.");let S=await qt(e),a=Et(S,s,e,null,null),d=S?.thumbnail||s.querySelector("img[src*='twimg.com'], img[src*='pbs.twimg.com'], .col-4 img, img.img-fluid, .card img")?.getAttribute("src")||s.querySelector("video")?.getAttribute("poster")||null,x=b.map((k,U)=>({...k,thumbnail:d,isMirror:U>0}));return J=null,C(!0,{title:a,thumbnail:d,downloads:x,sourceUrl:t})}if(J==="savetwt"||J==="tweeload"){let n=e.replace(/https:\/\/(fixupx|fxtwitter|vxtwitter|nitter)\.com/g,"https://x.com"),h=await T({url:"https://savetwt.com/",headers:{"User-Agent":H.CHROME_UA,Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"},rawResponse:!0},"SaveTWT Init");r=h.status;let p=new DOMParser,w=p.parseFromString(h.data,"text/html"),i=w.querySelector('input[name="_token"]')?.value||w.querySelector('meta[name="csrf-token"]')?.getAttribute("content")||h.data.match(/name=["']_token["']\s+value=["']([^"']+)["']/i)?.[1]||h.data.match(/name=["']csrf-token["']\s+content=["']([^"']+)["']/i)?.[1];if(!i)throw new Error("Could not find CSRF token from SaveTWT.");let u=(0,H.getCookiesFromHeaders)(h.headers),g=await T({url:"https://savetwt.com/download",method:"POST",data:(0,H.serializeData)({_token:i,return_locale:"en",url:n}),headers:{Cookie:u,"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json","X-Requested-With":"XMLHttpRequest","User-Agent":H.CHROME_UA,Referer:"https://savetwt.com/",Origin:"https://savetwt.com"},rawResponse:!0},"SaveTWT Post");r=g.status;let o=g.data;if(typeof o=="string")try{o=JSON.parse(o)}catch{}if(!o||!o.redirect)throw new Error("SaveTWT did not return a valid download redirect.");let s=o.redirect;s.startsWith("/")&&(s="https://savetwt.com"+s);let m=(0,H.getCookiesFromHeaders)(g.headers),f=[u,m].filter(Boolean).join("; "),y=await T({url:s,headers:{Cookie:f||u,"User-Agent":H.CHROME_UA,Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",Referer:"https://savetwt.com/"},rawResponse:!0},"SaveTWT Result");r=y.status;let b=p.parseFromString(y.data,"text/html"),S=[],a=[],d=_=>{let v=(_||"").match(/(\d+)\s*[xX]\s*(\d+)/);if(v)return parseInt(v[1],10)*parseInt(v[2],10);let M=(_||"").match(/(\d+)\s*p/i);return M?parseInt(M[1],10)*parseInt(M[1],10)*1.77:0};b.querySelectorAll(".result__quality__table tr, table tr").forEach(_=>{let v=_.querySelector(".result__quality"),M=_.querySelector("a.result__download__button, a[href*='dl.savetwt.com'], a[href*='savetwt.com/d/'], a.btn");if(!M)return;let O=M.getAttribute("href");if(!O||!O.startsWith("http"))return;let E=v?v.textContent.trim():M.getAttribute("aria-label")||"",P=l(E,"",O);S.some(q=>q.url===O)||S.push({type:P,url:O})}),S.length===0&&b.querySelectorAll("a[href*='dl.savetwt.com'], a[href*='/d/v1.']").forEach(_=>{let v=_.getAttribute("href");if(!v||!v.startsWith("http"))return;let M=l(_.getAttribute("aria-label")||_.textContent.trim(),"",v);S.some(O=>O.url===v)||S.push({type:M,url:v})}),S.sort((_,v)=>d(v.type)-d(_.type));let k=S.length>0?S:a;if(k.length===0)throw new Error("No video links found on SaveTWT.");let U=await qt(e),R=Et(U,b,e,null,null),$=U?.thumbnail||b.querySelector("img[src*='twimg.com'], .result__media img")?.getAttribute("src")||null,A=k.map((_,v)=>({..._,thumbnail:$,isMirror:v>0}));return J=null,C(!0,{title:R,thumbnail:$,downloads:A,sourceUrl:t})}throw new Error("Invalid source selected.")}catch(e){return J=null,C(!1,e.message,r)}}var I=D(F());var X=null,pt=null,V=null;function se(t){X=t}function It(t){let r="----WebKitFormBoundary"+Math.random().toString(36).substring(2),e="";for(let[l,c]of Object.entries(t))c!=null&&(e+=`--${r}\r
|
|
2
|
+
Content-Disposition: form-data; name="${l}"\r
|
|
3
|
+
\r
|
|
4
|
+
${c}\r
|
|
5
|
+
`);return e+=`--${r}--\r
|
|
6
|
+
`,{body:e,contentType:`multipart/form-data; boundary=${r}`}}async function Lt(t){if(!X)return{status:!0,requireSource:!0};if(t.match(/spotify\.com\/s\//i))try{let e=await T({url:t,headers:{"User-Agent":"WhatsApp/2.21.19.21 A"},rawResponse:!0},"Spotify Link Resolver");if(e){if(e.url&&!e.url.match(/spotify\.com\/s\//i))t=(0,I.cleanUrl)(e.url);else if(e.data){let l=typeof e.data=="string"?e.data:JSON.stringify(e.data),c=l.match(/<meta property="og:url" content="([^"]+)"/i);if(c&&c[1])t=(0,I.cleanUrl)(c[1]);else{let n=l.match(/<script id="urlSchemeConfig" type="text\/plain">([^<]+)<\/script>/);if(n&&n[1])try{let h=n[1];h=h.padEnd(h.length+(4-h.length%4)%4,"=");let p=JSON.parse(atob(h));p&&p.redirectUrl&&(t=(0,I.cleanUrl)(p.redirectUrl))}catch{}}}}}catch(e){console.warn("Failed to resolve Spotify short link",e)}let r=null;try{if(X==="soundloaders"){let d="https://spotimate.app";try{let x="",k=Date.now();if(pt&&k-pt.time<300*1e3)x=pt.cookies;else{let P=await T({url:d+"/en1",headers:{"User-Agent":I.CHROME_UA,Accept:"*/*"},rawResponse:!0},"SoundLoaders Home");r=P.status,x=(0,I.getCookiesFromHeaders)(P.headers)||"",pt={cookies:x,time:k}}let U="";try{let q=(await T({url:d+"/api/userverify",method:"POST",data:"url="+encodeURIComponent(t),headers:{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8","User-Agent":I.CHROME_UA,"X-Requested-With":"XMLHttpRequest",Referer:d+"/en1",Origin:d,Cookie:x},rawResponse:!0},"SoundLoaders Verify")).data;if(typeof q=="string")try{q=JSON.parse(q)}catch{}q?.success&&q?.token&&(U=q.token)}catch{}let R=It({url:t,cftoken:U}),$=await T({url:d+"/action",method:"POST",data:R.body,headers:{"Content-Type":R.contentType,"User-Agent":I.CHROME_UA,Referer:d+"/en1",Origin:d,Cookie:x},rawResponse:!0},"SoundLoaders Action");r=$.status;let A=$.data;if(typeof A=="string")try{A=JSON.parse(A)}catch{}if(!A||A.success===!1)throw new Error(A?.message||"SoundLoaders returned failure.");let _=A.html||"",v=ne(_);if(v.tracks.length===0)throw new Error("No tracks found from SoundLoaders.");let M=[],O=v.tracks.length>1;for(let P=0;P<v.tracks.length;P++){let q=v.tracks[P],L=O?`${(P+1).toString().padStart(String(v.tracks.length).length,"0")}. `:"",N=q.artist?`${q.artist} - ${q.title}`:q.title;if(P===0&&!O)try{let Z=It({data:q.data,base:q.base||t,token:q.trackToken}),Y=(await T({url:d+"/action/track",method:"POST",data:Z.body,headers:{"Content-Type":Z.contentType,"User-Agent":I.CHROME_UA,Referer:d+"/en1",Origin:d,Cookie:x},rawResponse:!0},"SoundLoaders Download")).data;if(typeof Y=="string")try{Y=JSON.parse(Y)}catch{}let xt=Y?.data||Y?.html||"";(xt?le(xt):[]).forEach(_t=>{M.push({..._t,type:O?`${L}${N} [MP3]`:"MP3"})})}catch{}(M.length===0||O)&&M.push({type:O?`${L}${N} [MP3]`:"MP3",url:`soundloaders_resolve:${q.data}|||${q.trackToken}|||${encodeURIComponent(q.base||t)}`})}if(M.length===0)throw new Error("No download links found from SoundLoaders.");let E=v.type==="playlist"?" (Playlist)":v.type==="album"?" (Album)":"";return X=null,C(!0,{title:v.artist?`${v.artist} - ${v.title}${E}`:`${v.title}${E}`,thumbnail:v.thumbnail,downloads:M,sourceUrl:t})}catch(x){return console.warn("[SoundLoaders] Failed, falling back to SpotiDown...",x),X="spotidown",await Lt(t)}}let e="",l={},c=Date.now(),n=new DOMParser;if(V&&c-V.time<300*1e3)e=V.cookies,l={...V.baseData};else{let d=await T({url:"https://spotidown.app/",headers:{"User-Agent":I.CHROME_UA},rawResponse:!0},"SpotiDown Main");r=d.status,e=(0,I.getCookiesFromHeaders)(d.headers),n.parseFromString(d.data,"text/html").querySelector('form[name="spotifyurl"]')?.querySelectorAll("input").forEach(U=>{let R=U.getAttribute("name"),$=U.getAttribute("value")||"";R&&R!=="url"&&(l[R]=$)}),V={cookies:e,baseData:l,time:c}}let h={...l,url:t};h["g-recaptcha-response"]="dummy_token";let p={"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8","User-Agent":I.CHROME_UA,Origin:"https://spotidown.app",Referer:"https://spotidown.app/","X-Requested-With":"XMLHttpRequest"};e&&(p.Cookie=e);let w=await T({url:"https://spotidown.app/action",method:"POST",data:(0,I.serializeData)(h),headers:p,rawResponse:!0},"SpotiDown Action"),i=(0,I.getCookiesFromHeaders)(w.headers);i&&(e=e?`${e}; ${i}`:i,V&&(V.cookies=e));let u=w.data;if(typeof u=="string")try{u=JSON.parse(u)}catch{}if(u.error)throw V=null,new Error(u.message||"Spotify error");let g=u.data||u,o=n.parseFromString(g,"text/html"),s=o.querySelectorAll('form[name="submitspurl"]'),m=[],f={"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8","User-Agent":I.CHROME_UA,Origin:"https://spotidown.app",Referer:"https://spotidown.app/","X-Requested-With":"XMLHttpRequest"};e&&(f.Cookie=e);let y=s.length>1;for(let d=0;d<s.length;d++){let x=s[d],k={};x.querySelectorAll("input").forEach(_=>{let v=_.getAttribute("name"),M=_.getAttribute("value")||"";v&&(k[v]=M)}),k["g-recaptcha-response"]="dummy_token";let U=(0,I.serializeData)(k),R=y?`${(d+1).toString().padStart(String(s.length).length,"0")}. `:"",$="",A=x.querySelector('input[name="data"]')?.value;if(A)try{let _=JSON.parse(atob(A)),v=_.name||_.title||"",M=_.artist||_.singer||"";M&&v?$=`${M} - ${v}`:v&&($=v)}catch{}if(!$){let _=x.closest(".col-md-4, .col-sm-6, .card, .row, div")||x.parentElement;if(_){let v=_.querySelector("h3, h4, h5, .title, p");v&&v.textContent.trim()&&($=v.textContent.trim())}}if(d===0&&!y)try{let v=(await T({url:"https://spotidown.app/action/track",method:"POST",data:U,headers:f,rawResponse:!0},"SpotiDown Track")).data;if(typeof v=="string")try{v=JSON.parse(v)}catch{}let M=v.data||v,O=n.parseFromString(M,"text/html");O.querySelectorAll("a").forEach(E=>{let P=E.getAttribute("href"),q=E.textContent.trim();if(P&&P.startsWith("http")&&!P.includes("premium.html")&&q!=="Download Another Song"){let L=O.querySelector("h3")?.textContent?.trim()||"",N=O.querySelector("p")?.textContent?.trim()||"",Z=N&&L?`${N} - ${L}`:L||q||"MP3",lt=q.toLowerCase().includes("cover")||P.includes("cover"),Y=lt?"[Cover]":"[MP3]";m.push({type:y?`${R}${Z} ${Y}`:lt?"Cover":"MP3",url:P})}})}catch{}(m.length===0||y)&&m.push({type:y?`${R}${$||"Track "+(d+1)} [MP3]`:"MP3",url:`spotidown_resolve:${U}|||${encodeURIComponent(e||"")}`})}if(m.length===0)throw new Error("No download links found from SpotiDown.");m.sort((d,x)=>{let k=(d.type||"").includes("[Cover]")||(d.type||"").toLowerCase()==="cover",U=(x.type||"").includes("[Cover]")||(x.type||"").toLowerCase()==="cover";return k&&!U?1:!k&&U?-1:0});let b=o.querySelector("h3")?.textContent?.trim()||"Spotify Track",S=o.querySelector("p")?.textContent?.trim(),a=o.querySelector("img")?.getAttribute("src");return X=null,C(!0,{title:S?`${S} - ${b}`:b,thumbnail:a,downloads:m,sourceUrl:t})}catch(e){return X=null,C(!1,e.message,r)}}function ne(t){let r={title:"",artist:"",thumbnail:"",type:"track",tracks:[]},e=t.match(/<img[^>]+src=["'](https:\/\/[^"']*(?:scdn\.co|spotimate|soundloaders)[^"']*)["']/i)||t.match(/<img[^>]+src=["']([^"']+)["'][^>]*class=["'][^"']*rounded-xl[^"']*["']/i);e&&(r.thumbnail=e[1]);let l=t.match(/<h[23][^>]*itemprop=["']name["'][^>]*>([\s\S]*?)<\/h[23]>/i)||t.match(/<h2[^>]*>([\s\S]*?)<\/h2>/i)||t.match(/<h3[^>]*>([\s\S]*?)<\/h3>/i);l&&(r.title=yt(l[1]));let c=t.match(/<p[^>]*><span>([\s\S]*?)<\/span><\/p>/i)||t.match(/<p class="text-sm text-white\/60 mb-8">([\s\S]*?)<\/p>/i);c&&(r.artist=yt(c[1])),(t.includes("playlist-songs")||t.includes("Playlist")||t.includes("dltracks"))&&(r.type=t.includes("Album")?"album":"playlist");let n=/<form[^>]*>([\s\S]*?)<\/form>/gi,h;for(;(h=n.exec(t))!==null;){let p=h[1];if(!p.includes('name="data"')&&!p.includes("name='data'"))continue;let w={data:"",trackToken:"",base:"",title:"",artist:"",thumbnail:""},i=p.match(/<input[^>]+name=["']data["'][^>]+value=["']([^"']*)["']/);i&&(w.data=i[1]);let u=p.match(/<input[^>]+name=["']token["'][^>]+value=["']([^"']*)["']/)||p.match(/<input[^>]+name=["']track_token["'][^>]+value=["']([^"']*)["']/);u&&(w.trackToken=u[1]);let g=p.match(/<input[^>]+name=["']base["'][^>]+value=["']([^"']*)["']/);if(g&&(w.base=g[1]),w.data)try{let o=JSON.parse(atob(w.data));w.title=o.name||o.title||"",w.artist=o.artist||o.singer||"",w.thumbnail=o.cover||""}catch{}if(!w.title){let o=p.match(/>([^<]+)</g);if(o)for(let s of o){let m=s.replace(/[><]/g,"").trim();if(m&&m.length>2&&m!=="Download")if(m.includes(" - ")){let f=m.split(" - ");w.artist=f[0].trim(),w.title=f[1]?.trim()||""}else w.title||(w.title=m)}}!r.thumbnail&&w.thumbnail&&(r.thumbnail=w.thumbnail),!r.title&&w.title&&(r.title=w.title),!r.artist&&w.artist&&(r.artist=w.artist),r.tracks.push(w)}return r}function le(t){let r=[],e=/<a\s[^>]*href=["']([^"']+)["'][^>]*>([\s\S]*?)<\/a>/gi,l;for(;(l=e.exec(t))!==null;){let c=l[1].trim(),n=yt(l[2]);if(c&&c.startsWith("http")&&n!=="Download Another Song"&&!c.includes("tunecable.com")&&!c.includes("premium")){let p=n.toLowerCase().includes("cover")||c.includes("cover")||c.includes("scdn.co")||c.match(/\.(jpg|jpeg|png|webp)(\?.*)?$/i)?"[Cover]":"[MP3]";r.push({type:`${n||"Download"} ${p}`,url:c})}}return r}function yt(t){return t.replace(/<[^>]+>/g,"").replace(/�?39;/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').trim()}var We=D(F()),Ft=D(K());async function ce(t){try{let r=(0,Ft.getCleanUrl)(t);if(r.includes("b23.tv")||r.includes("bili.im"))try{let a=await T({url:r,headers:{"User-Agent":"Bilibili/1.0"},rawResponse:!0},"Bilibili Redirect");if(a?.url&&a.url!==r&&!a.url.includes("b23.tv"))r=a.url;else if(a?.headers?.location||a?.headers?.Location)r=a.headers.location||a.headers.Location;else if(a?.data&&typeof a.data=="string"){let d=a.data.match(/href="([^"]+)"/i)||a.data.match(/https?:\/\/[a-zA-Z0-9.-]*bilibili\.com\/video\/[^\s"'<>]+/i);d&&(r=d[1].replace(/&/g,"&"))}}catch(a){console.error("Bilibili redirect resolve failed:",a)}if(r.includes("bilibili.tv")){try{let a=new URL(r);r=a.origin+a.pathname}catch{}try{let d=new URL(r).pathname.split("/").filter(Boolean),x=null,k="Bilibili.tv Video",U=null,R=d.indexOf("video");if(R!==-1){let v=d[R+1];v&&/^\d+$/.test(v)&&(x={tipo:"video",id:v})}let $=d.indexOf("play");if($!==-1){let v=d.slice($+1).filter(M=>/^\d+$/.test(M));v.length>1?x={tipo:"anime",id:v[1]}:v.length===1&&(x={tipo:"anime",id:null,seasonId:v[0]})}if(!x)throw new Error("Could not parse Bilibili.tv video or episode ID.");let A="";try{A=await T({url:r,parseJson:!1},"Bilibili Metadata"),A=typeof A=="string"?A:"";let v=A.match(/<title>([^<]+)<\/title>/i);v&&(k=v[1].trim());let M=A.match(/<meta\s+property="og:image"\s+content="([^"]+)"/i)||A.match(/<meta\s+name="twitter:image"\s+content="([^"]+)"/i);M&&(U=M[1])}catch(v){console.error("Failed to fetch Bilibili.tv page metadata:",v)}if(x.tipo==="anime"&&!x.id&&x.seasonId){try{let v=await T({url:`https://api.bilibili.tv/intl/gateway/web/v2/ogv/play/episodes?season_id=${x.seasonId}&platform=web&s_locale=en_US`},"Bilibili Episodes");if(v&&v.data&&v.data.sections){for(let M of v.data.sections)if(M.episodes&&M.episodes.length>0){let O=M.episodes[0];x.id=O.episode_id||O.ep_id||O.id,O.title_display&&k==="Bilibili.tv Video"&&(k=O.title_display),O.cover&&!U&&(U=O.cover);break}}}catch(v){console.error("Failed to resolve season episodes:",v)}if(!x.id&&A){let v=A.match(/"episode_id"\s*:\s*"(\d+)"/)||A.match(/"episode_id"\s*:\s*(\d+)/)||A.match(/"ep_id"\s*:\s*(\d+)/);v&&(x.id=v[1])}}let _=[];if(x.tipo==="anime"&&(x.id||x.seasonId))try{let v=x.id?`ep_id=${x.id}`:`season_id=${x.seasonId}`,M=await T({url:`https://api.bilibili.tv/intl/gateway/v2/ogv/playurl?${v}&platform=web&s_locale=en_US`},"Bilibili OGV v2");if(M&&M.data&&M.data.video_info){(M.data.video_info.stream_list||[]).forEach(P=>{let q=P.url||P.url_list?.[0]?.url||P.dash_video?.base_url||P.dash_video?.backup_url?.[0];if(q){let L=q;L.startsWith("http://")&&(L=L.replace("http://","https://"));let N=P.stream_info?.display_desc||P.stream_info?.description||P.desc_words||(P.quality?`${P.quality}p`:"720p");_.push({url:L,type:N,headers:{Referer:"https://www.bilibili.tv/"}})}});let E=M.data.video_info.dash;E&&(E.video&&_.length===0&&E.video.forEach(P=>{let q=P.base_url||P.backup_url?.[0];q&&(q.startsWith("http://")&&(q=q.replace("http://","https://")),_.push({url:q,type:`${P.id||360}p`,headers:{Referer:"https://www.bilibili.tv/"}}))}),E.audio&&E.audio.forEach(P=>{let q=P.base_url||P.backup_url?.[0];q&&(q.startsWith("http://")&&(q=q.replace("http://","https://")),_.push({url:q,type:"MP3",headers:{Referer:"https://www.bilibili.tv/"}}))}))}}catch(v){console.error("OGV v2 API failed:",v)}if(_.length===0&&x.id)try{let v=await T({url:`https://api.bilibili.tv/intl/gateway/web/v2/playurl?aid=${x.id}&platform=web&s_locale=en_US`},"Bilibili PlayURL");v&&v.data&&v.data.playurl&&(v.data.playurl.video||v.data.playurl.durl||[]).forEach(O=>{let E=O.url||O.base_url;E&&(E.startsWith("http://")&&(E=E.replace("http://","https://")),_.push({url:E,type:O.quality?`${O.quality}p`:"720p",headers:{Referer:"https://www.bilibili.tv/"}}))})}catch(v){console.error("Fallback v2 PlayURL failed:",v)}if(_.length>0)return C(!0,{title:k,thumbnail:U,downloads:_,sourceUrl:t})}catch(a){console.error("Bilibili.tv parse error:",a)}}let e=r.match(/(BV[a-zA-Z0-9]+)/i),l=e?e[1]:null,c=r.match(/(?:video\/av|[?&]aid=)(\d+)/i),n=c?c[1]:null;if(!l&&!n)throw new Error("Could not extract Bilibili video ID (BV/AV).");let h=l?`https://api.bilibili.com/x/web-interface/view?bvid=${l}`:`https://api.bilibili.com/x/web-interface/view?aid=${n}`,p={Referer:"https://www.bilibili.com/","User-Agent":"Bilibili/1.0"},w=await T({url:h,headers:{"User-Agent":"Bilibili/1.0"}},"Bilibili View Info");if(!w||w.code!==0||!w.data)throw new Error(w?.message||"Failed to fetch Bilibili video info.");let i=w.data,u=i.title||"Bilibili Video",g=i.pic||null;g&&g.startsWith("http://")&&(g=g.replace("http://","https://"));let o=i.owner?.name||"Bilibili Creator",s=i.bvid||l,m=1;try{let d=new URL(r).searchParams.get("p");d&&/^\d+$/.test(d)&&(m=parseInt(d,10))}catch{}let f=i.cid;if(i.pages&&i.pages.length>0){let a=i.pages.find(d=>d.page===m)||i.pages[0];a&&(f=a.cid||f,i.pages.length>1&&a.part&&(u=`${u} - P${a.page} ${a.part}`))}if(!f)throw new Error("Could not determine Bilibili video stream CID.");let y=[],b=await T({url:`https://api.bilibili.com/x/player/playurl?bvid=${s}&cid=${f}&qn=64&fnval=1`,headers:{"User-Agent":"Bilibili/1.0"}},"Bilibili PlayURL 720p"),S=[];if(b?.code===0&&b?.data?.durl?.[0]?.url){let a=b.data.quality,d=b.data.accept_description||[],x=b.data.accept_quality||[];S=x;let k=x.indexOf(a),U=k!==-1&&d[k]?d[k]:a===64?"720P HD":"Video";y.push({url:b.data.durl[0].url,type:`${U} [MP4]`,headers:p})}if(S.includes(16)&&!y.some(a=>(a.type||"").includes("360P")))try{let a=await T({url:`https://api.bilibili.com/x/player/playurl?bvid=${s}&cid=${f}&qn=16&fnval=1`,headers:{"User-Agent":"Bilibili/1.0"}},"Bilibili PlayURL 360p");a?.code===0&&a?.data?.durl?.[0]?.url&&y.push({url:a.data.durl[0].url,type:"360P SD [MP4]",headers:p})}catch{}if(y.length===0)throw new Error("No playable Bilibili video streams found.");return C(!0,{title:u,thumbnail:g,author:o,downloads:y,sourceUrl:t})}catch(r){return C(!1,r.message)}}var it=D(F());async function de(t){let r=null;try{let e=t.match(/artworks\/(\d+)/)||t.match(/illust_id=(\d+)/);if(!e)throw new Error("Invalid Pixiv URL.");let l=e[1],c=null;try{let i=await T({url:`https://www.pixiv.net/ajax/illust/${l}?lang=en`,headers:{"User-Agent":it.CHROME_UA,Referer:"https://www.pixiv.net/"},rawResponse:!0},"Pixiv Ajax API");r=i.status;let u=i.data;if(typeof u=="string")try{u=JSON.parse(u)}catch{}u&&!u.error&&u.body&&(c=u.body)}catch{}if(!c)try{let i=await T({url:`https://www.pixiv.net/en/artworks/${l}`,headers:{"User-Agent":it.CHROME_UA,"Accept-Language":"en-US,en;q=0.9"},parseJson:!1},"Pixiv Artwork Page");if(i&&typeof i=="string"){let u=i.match(/id="meta-preload-data"\s+content='([^']+)'/i)||i.match(/id="meta-preload-data"\s+content="([^"]+)"/i);if(u&&u[1]){let g=u[1].replace(/"/g,'"').replace(/&/g,"&"),o=JSON.parse(g);o&&o.illust&&o.illust[l]&&(c=o.illust[l])}}}catch(i){console.warn("Could not parse meta-preload-data:",i)}let n=!1;if(c&&(n=String(c.illustType)==="2"||c.illustType==2||String(c.illust_type)==="2"||c.type==="ugoira"||c.urls&&c.urls.original&&c.urls.original.includes("ugoira")),!n)try{let i=await T({url:`https://www.pixiv.net/ajax/illust/${l}/ugoira_meta?lang=en`,headers:{"User-Agent":it.CHROME_UA,Referer:"https://www.pixiv.net/"}},"Pixiv Ugoira Meta");i&&!i.error&&i.body&&(i.body.originalSrc||i.body.frames&&i.body.frames.length>0)&&(n=!0)}catch{}let h=c?.title||c?.illustTitle?`${c.title||c.illustTitle} by ${c.userName||c.userAccount||"Unknown"}`:"Pixiv Artwork",p=[];if(n){let i=null;try{let g=await T({url:`https://www.pixiv.net/ajax/illust/${l}/ugoira_meta?lang=en`,headers:{"User-Agent":it.CHROME_UA,Referer:"https://www.pixiv.net/"}},"Pixiv Ugoira Zip");g&&!g.error&&g.body&&(i=g.body.originalSrc||g.body.src)}catch{}let u=`https://pixiv.re/${l}.gif`;p.push({type:"UGOIRA (MP4)",url:`https://ugoira.com/api/mp4/${l}`,thumbnail:u}),p.push({type:"UGOIRA (GIF)",url:u,thumbnail:u}),p.push({type:"UGOIRA (ZIP)",url:i||`https://i.pximg.net/img-zip-ugoira/img/${l}_ugoira1920x1080.zip`,thumbnail:u})}else{let i=c?.pageCount||1,u=c?.urls?.original;if(u)for(let g=0;g<i;g++){let o=i>1?`PAGE ${g+1}`:"IMAGE",s=u.replace("_p0",`_p${g}`);s=s.replace("i.pximg.net","i.pixiv.re");let m=s;p.push({type:o,url:s,thumbnail:m})}else{p.push({type:"IMAGE / PAGE 1",url:`https://pixiv.re/${l}.jpg`,thumbnail:`https://pixiv.re/${l}.jpg`});for(let g=2;g<=i;g++)p.push({type:`PAGE ${g}`,url:`https://pixiv.re/${l}-${g}.jpg`,thumbnail:`https://pixiv.re/${l}-${g}.jpg`})}}let w=n?`https://pixiv.re/${l}.gif`:c?.urls?.regular?.replace("i.pximg.net","i.pixiv.re")||c?.urls?.original?.replace("i.pximg.net","i.pixiv.re")||`https://pixiv.re/${l}.jpg`;return C(!0,{title:h,thumbnail:w,downloads:p,sourceUrl:t},r)}catch(e){return C(!1,e.message,r)}}var Ht=D(K()),ht=D(F());async function ue(t){try{let r=t.match(/https?:\/\/[^\s]+/i),e=(0,Ht.getCleanUrl)(r?r[0]:t),l=(i,u)=>!!(i&&["\u4F60\u7684\u751F\u6D3B\u5174\u8DA3\u793E\u533A","\u4F60\u8BBF\u95EE\u7684\u9875\u9762\u4E0D\u89C1\u4E86","\u9875\u9762\u4E0D\u89C1\u4E86","404 Not Found","Page Not Found"].some(o=>i.includes(o))||u&&(u.includes("e6214e4fbfae2cf14d634d4296916e8a5eaefdf4")||u.includes("fe-platform"))),c=i=>{if(!i)return null;if(i.noteData?.data?.noteData){let g=i.noteData.data.noteData;if(g.title||g.desc||g.imageList||g.video)return g}if(i.note?.noteDetailMap){let g=i.note.noteDetailMap,o=Object.keys(g);for(let s of o){let m=g[s],f=m?.note||m;if(f&&!Array.isArray(f)&&(f.title||f.desc||f.imageList||f.video))return f}}let u=[i.noteData?.note,i.noteData,i.note?.firstNote,i.feed?.note,i.firstNote];for(let g of u)if(g&&!Array.isArray(g)&&(g.title||g.desc||g.imageList||g.video))return g;return null},n=i=>{let u=typeof i=="string"?i:"",g=u.match(/window\.__INITIAL_STATE__\s*=\s*(\{[\s\S]+?\});?<\/script>/)||u.match(/window\.__INITIAL_DATA__\s*=\s*(\{[\s\S]+?\});?<\/script>/)||u.match(/__INITIAL_STATE__\s*=\s*(\{[\s\S]+?\});?<\/script>/)||u.match(/window\.__PRELOADED_STATE__\s*=\s*(\{[\s\S]+?\});?<\/script>/);if(g)try{let b=g[1].replace(/;\s*$/,"").replace(/:\s*undefined/g,":null"),S=JSON.parse(b),a=c(S);if(a){let d=a.title||a.desc||"RedNote Post",x=a.user?.nickname||a.user?.nickName||"RedNote Creator",k=null,U=[];if(a.imageList&&a.imageList.length>0){let R=a.imageList[0].urlDefault||a.imageList[0].urlOriginal||a.imageList[0].url;R&&(k=R.startsWith("//")?`https:${R}`:R)}if(!l(d,k)){if(a.video&&a.video.media){let R=a.video.media.stream||{},$=null,A=["h264","h265","h266","av1"];for(let _ of A)if(Array.isArray(R[_])&&R[_].length>0){let v=R[_][0];if($=v.masterUrl||v.backupUrls?.[0]||v.url,$)break}if(!$&&a.video.media.video&&($=a.video.media.video.masterUrl),$){let _=$.startsWith("//")?`https:${$}`:$;_.startsWith("http://")&&(_=_.replace("http://","https://")),U.push({url:_,type:"MP4"})}}if(a.imageList&&a.imageList.length>0&&a.imageList.forEach((R,$)=>{let A=R.urlOriginal||R.urlDefault||R.url;A&&(A.startsWith("//")?A=`https:${A}`:A.startsWith("http://")&&(A=A.replace("http://","https://")),U.push({url:A,type:"PHOTO"}))}),U.length>0)return{title:d,author:x,thumbnail:k,downloads:U,sourceUrl:t}}}}catch(b){console.error("RedNote state JSON parse error:",b)}let o=u.match(/<meta\s+property="og:title"\s+content="([^"]+)"/i)||u.match(/<meta\s+name="og:title"\s+content="([^"]+)"/i)||u.match(/<title>([^<]+)<\/title>/i),s=u.match(/<meta\s+property="og:image"\s+content="([^"]+)"/i)||u.match(/<meta\s+name="og:image"\s+content="([^"]+)"/i),m=u.match(/<meta\s+property="og:video"\s+content="([^"]+)"/i)||u.match(/<meta\s+property="og:video:url"\s+content="([^"]+)"/i),f=o?o[1]:"",y=s?s[1]:"";if(y.startsWith("//")&&(y=`https:${y}`),!l(f,y)&&(s||m)){let b=f.replace(/ - (?:ε°ηΊ’δΉ¦|RedNote).*/i,"")||"RedNote Post",S=[];if(m){let a=m[1];a.startsWith("//")&&(a=`https:${a}`),S.push({url:a,type:"MP4"})}if(s&&y&&S.push({url:y,type:"PHOTO"}),S.length>0)return{title:b,author:"RedNote Creator",thumbnail:y||null,downloads:S,sourceUrl:t}}return null},h=null,p=[ht.CHROME_DESKTOP_UA,ht.CHROME_MOBILE_UA];if(e.includes("xhslink.com")||e.includes("xhslink.cn"))for(let i of p)try{let u=await T({url:e,rawResponse:!0,headers:{"User-Agent":i}},"RedNote Redirect"),g=typeof u.data=="string"?u.data:"",o=n(g);if(o)return C(!0,o);let s=u.headers?.location||u.headers?.Location||"",f=`${u.url||""} ${s} ${g}`.match(/\/([a-f0-9]{24})/i);if(f&&(h=f[1]),u.url&&!u.url.includes("xhslink.com")){e=u.url;break}}catch(u){console.error("RedNote redirect resolve failed:",u)}if(!h){let i=e.match(/\/(?:explore|discovery\/item|red_video)\/([a-f0-9]{24})/i)||e.match(/\/([a-f0-9]{24})/i);i&&(h=i[1])}let w=[];e&&!e.includes("xhslink.com")&&!e.includes("xhslink.cn")&&w.push(e),h&&(w.push(`https://www.xiaohongshu.com/explore/${h}`),w.push(`https://www.rednote.com/discovery/item/${h}`),w.push(`https://www.rednote.com/explore/${h}`),w.push(`https://www.xiaohongshu.com/discovery/item/${h}`));for(let i of w)for(let u of p)try{let g=await T({url:i,parseJson:!1,headers:{"User-Agent":u,Cookie:"a1=18a1234567890abcdef1234567890abc; webId=1234567890abcdef","Accept-Language":"zh-CN,zh;q=0.9,en;q=0.8"}},"RedNote Direct HTML"),o=n(g);if(o)return C(!0,o)}catch(g){console.error("RedNote direct HTML fetch failed for",i,g)}throw new Error("RedNote post not found or link has expired.")}catch(r){return C(!1,r.message)}}var Nt=D(K());function mt(t){if(!t||typeof t!="string")return null;let r=t.match(/(?:video|note|share\/(?:video|slides))\b[\/?](\d{15,22})/i)||t.match(/modal_id=(\d{15,22})/i)||t.match(/group_id=(\d{15,22})/i)||t.match(/aweme_id=(\d{15,22})/i)||t.match(/\/(\d{18,20})\b/);return r?r[1]:null}function pe(t){let r=0,e=!1,l=null,c=!1,n=-1;for(let h=0;h<t.length;h++){let p=t[h];if(c){c=!1;continue}if(p==="\\"){c=!0;continue}if(e){p===l&&(e=!1);continue}if(p==='"'||p==="'"){e=!0,l=p;continue}if(p==="{")r++;else if(p==="}"&&(r--,r===0)){n=h+1;break}}if(n!==-1)try{return JSON.parse(t.substring(0,n))}catch{}return null}function bt(t){if(!t||typeof t!="string")return null;let r=["window._ROUTER_DATA =","window._SSR_DATA =","window._RENDER_DATA =","window.__INIT_PROPS__ =","window.SSR_HYDRATED_DATA ="];for(let e of r){let l=t.indexOf(e);if(l===-1)continue;let c=t.substring(l+e.length).trim();if(c.startsWith('"')&&c.includes("%7B"))try{let h=c.match(/^"([^"]+)"/);h&&(c=decodeURIComponent(h[1]))}catch{}else if(c.startsWith("%7B"))try{c=decodeURIComponent(c)}catch{}let n=pe(c);if(n)return n}return null}async function ft(t){try{let r=await T({url:`https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids=${t}`,headers:{"User-Agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 Safari/604.1",Accept:"application/json"},parseJson:!0},"Douyin API");if(r&&r.item_list&&r.item_list.length>0)return r.item_list[0]}catch(r){console.warn("Douyin API fetch error:",r)}return null}function St(t){if(!t)return null;let r=t.loaderData||{};for(let e in r)if(r[e]&&r[e].videoInfoRes){let l=r[e].videoInfoRes.item_list;if(l&&l.length>0)return l[0]}return t.aweme&&t.aweme.detail?t.aweme.detail:t.item_list&&t.item_list.length>0?t.item_list[0]:t.aweme_detail?t.aweme_detail:null}function ot(t,r){let e=t.desc||t.share_info?.share_desc||"Douyin Content",l=t.author?t.author.nickname:"Douyin User",c=[];if(t.images&&t.images.length>0)t.images.forEach(n=>{let h=n.url_list?.[0]||n.download_url_list?.[0];h&&c.push({type:"PHOTO",url:h.replace(/^http:/,"https:"),isMirror:!1})});else{let n=t.video?.play_addr?.url_list?.[0]||t.video?.download_addr?.url_list?.[0]||null;if(!n)throw new Error("No video URL found.");n=n.replace(/^http:/,"https:").replace("playwm","play");let h=null;try{h=new URL(n).searchParams.get("video_id")}catch{}if(!h){let i=n.match(/video_id=([^&]+)/);i&&(h=i[1])}let p=h?`https://aweme.snssdk.com/aweme/v1/play/?video_id=${h}`:n;c.push({type:"MP4",url:p,isMirror:!1},{type:"MP4 (Watermark)",url:n,isMirror:!0});let w=t.music?.play_url?.url_list?.[0]||t.music?.play_url?.uri||null;w&&typeof w=="string"&&w.startsWith("http")&&c.push({type:"MP3",url:w.replace(/^http:/,"https:"),isMirror:!1})}if(c.length===0)throw new Error("No downloadable media found.");return C(!0,{title:e,author:l,thumbnail:t.video?.cover?.url_list?.[0]||t.images?.[0]?.url_list?.[0]||null,downloads:c,sourceUrl:r})}async function he(t){try{if(!t||typeof t!="string")throw new Error("Invalid URL.");let r=(0,Nt.getCleanUrl)(t),e=mt(r);if(e){let p=await ft(e);if(p)return ot(p,t)}e&&r.includes("/share/slides/")&&(r=`https://www.iesdouyin.com/share/video/${e}/`);let l="Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 Safari/604.1",c="";try{let p=await T({url:r,headers:{"User-Agent":l,Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8","Accept-Language":"zh-CN,zh;q=0.9,en;q=0.8"},parseJson:!1,rawResponse:!0},"Douyin");c=typeof p?.data=="string"?p.data:typeof p=="string"?p:"";let w=p?.url||"";if(w&&!e&&(e=mt(w),e)){let i=await ft(e);if(i)return ot(i,t)}if(e&&(r.includes("/share/slides/")||w.includes("/share/slides/"))){let i=await T({url:`https://www.iesdouyin.com/share/video/${e}/`,headers:{"User-Agent":l,Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","Accept-Language":"zh-CN,zh;q=0.9,en;q=0.8"},parseJson:!1},"Douyin Slides to Video");typeof i=="string"&&i.length>0&&(c=i)}}catch(p){console.warn("Douyin initial HTML fetch failed:",p.message)}if(!e&&c&&(e=mt(c),e)){let p=await ft(e);if(p)return ot(p,t)}let n=bt(c),h=St(n);if(!h){let p="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",w=await T({url:r,headers:{"User-Agent":p,Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","Accept-Language":"zh-CN,zh;q=0.9,en;q=0.8"},parseJson:!1,rawResponse:!0},"Douyin Fallback"),i=typeof w?.data=="string"?w.data:typeof w=="string"?w:"";if(e||(e=mt(i)),e){let u=await ft(e);if(u)return ot(u,t);if(i.includes("/share/slides/")||w?.url&&w.url.includes("/share/slides/"))try{let g=await T({url:`https://www.iesdouyin.com/share/video/${e}/`,headers:{"User-Agent":p,Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","Accept-Language":"zh-CN,zh;q=0.9,en;q=0.8"},parseJson:!1},"Douyin Fallback Video");if(typeof g=="string"){let o=bt(g),s=St(o);s&&(h=s)}}catch{}}if(!h){let u=bt(i);h=St(u)}}if(!h)throw new Error("Could not find video data in Douyin page.");return ot(h,t)}catch(r){return C(!1,r.message)}}var st=D(F());async function me(t){try{let i=function(S){try{let a=S.replace(/-/g,"+").replace(/_/g,"/");for(;a.length%4;)a+="=";return decodeURIComponent(escape(atob(a)))}catch{try{let d=S.replace(/-/g,"+").replace(/_/g,"/");for(;d.length%4;)d+="=";return atob(d)}catch{return null}}},r=t.split("?")[0].trim();r=r.replace("threads.com","threads.net");let e=await T({url:"https://threadster.app/",headers:{"User-Agent":st.CHROME_UA},rawResponse:!0},"Threadster Main"),l=(0,st.getCookiesFromHeaders)(e.headers)||"",c=await T({url:"https://threadster.app/download",method:"POST",data:"url="+encodeURIComponent(r),headers:{"Content-Type":"application/x-www-form-urlencoded","User-Agent":st.CHROME_UA,Origin:"https://threadster.app",Referer:"https://threadster.app/",Cookie:l},parseJson:!1},"Threadster Download"),h=new DOMParser().parseFromString(c,"text/html"),p=[],w="";if(h.querySelectorAll("a").forEach(S=>{let a=S.getAttribute("href");if(a&&(a.includes("token=")||a.includes("acxcdn.com"))){let d=a.startsWith("http")?a:`https://threadster.app${a}`,x=a.includes("/image")?"PHOTO":"MP4";try{let U=new URL(d).searchParams.get("token");if(U){let R=U.split(".")[1];if(R){let $=i(R);if($){let A=JSON.parse($);if(A.url){let _=A.url.toLowerCase();_.includes(".jpg")||_.includes(".jpeg")||_.includes(".png")||_.includes(".webp")||a.includes("/image")?x="PHOTO":(_.includes(".mp4")||_.includes(".m3u8")||a.includes("/video"))&&(x="MP4"),!w&&(x==="PHOTO"||_.includes(".jpg")||_.includes(".webp"))&&(w=A.url)}}}}}catch{}p.some(k=>k.url===d)||p.push({type:x,url:d})}}),p.length===0){let S=h.querySelector(".download_result_section .error__msg, .alert-danger, .alert-warning")?.textContent?.trim()||"No download links found. The post may be private, text-only, or removed.";throw new Error(S)}let u="",g=h.querySelector(".download__item__caption__text, .download__item__caption, .card-text, .post-text"),o=g?g.textContent.trim().replace(/\s+/g," "):"";(/please enter a valid threads link/i.test(o)||o.toLowerCase().includes("download"))&&(o="");let s=h.querySelector(".download__item__user_info span, .download__item__user_info"),f=(s?s.textContent.trim():"").match(/@([A-Za-z0-9_.-]+)/),y=t.match(/threads\.(?:net|com)\/@([A-Za-z0-9_.-]+)/i),b=f?f[1].replace(/Β·$/,""):y?y[1]:"";return b&&o?u=`@${b}: ${o}`:o?u=o:b?u=`@${b} - Threads Post`:u="Threads Media",u.length>90&&(u=u.substring(0,87)+"..."),C(!0,{title:u,thumbnail:w||p.find(S=>S.type==="PHOTO")?.url||"",downloads:p,sourceUrl:t})}catch(r){return C(!1,r.message)}}var tt=D(F());async function fe(t){let r=null;try{let e=t;if(e.includes("pin.it"))try{let s=await T({url:e,headers:{"User-Agent":tt.CHROME_UA},rawResponse:!0},"Pinterest Expand Short URL");if(s.data&&typeof s.data=="string"){let m=s.data.match(/<link[^>]+rel="canonical"[^>]+href="([^"]+)"/i);m&&m[1]&&(e=m[1])}}catch{}try{let s=await T({url:e,headers:{"User-Agent":tt.CHROME_UA,Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8","Accept-Language":"en-US,en;q=0.5"},rawResponse:!0},"Pinterest Direct HTML");if(r=s.status,s.data&&typeof s.data=="string"){let m=s.data,f="",y=m.match(/data-test-id=["']pin-title["'][^>]*>([\s\S]*?)<\/h1>/i)||m.match(/<h1[^>]*>([\s\S]*?)<\/h1>/i);if(y&&y[1]){let R=y[1].replace(/<[^>]+>/g,"").trim();R&&!/^pinterest$/i.test(R)&&(f=R)}if(!f){let R=m.match(/<meta[^>]+property="og:title"[^>]+content="([^"]+)"/i)||m.match(/<meta[^>]+content="([^"]+)"[^>]+property="og:title"/i);R&&R[1]&&(f=R[1].replace(/\s*\|\s*Pinterest$/i,"").trim())}if(!f){let R=m.match(/<title>([^<]+)<\/title>/i);R&&R[1]&&(f=R[1].replace(/\s*\|\s*Pinterest$/i,"").trim())}f||(f="Pinterest Pin");let b=[],S=m.match(/https:\/\/(?:v1\.pinimg\.com|7\.pinimg\.com|v\.pinimg\.com)\/[^"'\s]+\.mp4/gi)||m.match(/https:\/\/[^"'\s]+\.mp4[^\s"']*/gi)||[],a=m.match(/https:\/\/i\.pinimg\.com\/originals\/[a-zA-Z0-9\/._-]+\.(?:jpg|jpeg|png|webp)/gi)||[];a.length===0&&(a=m.match(/https:\/\/i\.pinimg\.com\/736x\/[a-zA-Z0-9\/._-]+\.(?:jpg|jpeg|png|webp)/gi)||[]);let d=R=>R.includes("d53b014d86a6b6761bf649a0ed813c2b")||R.includes("/avatars/")||R.includes("/profile/")||R.includes("sprite")||R.includes("placeholder"),x=a.filter(R=>!d(R)),k=[...new Set(S)],U=[...new Set(x)];if(k.forEach(R=>{b.push({type:"MP4",url:R})}),U.forEach(R=>{b.push({type:"PHOTO",url:R})}),b.length>0)return C(!0,{title:f,thumbnail:U[0]||k[0]||"",downloads:b,sourceUrl:t})}}catch(s){console.warn("Direct Pinterest HTML parsing failed, trying PinDown:",s)}let l=await T({url:"https://pindown.io/",headers:{"User-Agent":tt.CHROME_UA},rawResponse:!0},"Pindown Main");r=l.status;let c=(0,tt.getCookiesFromHeaders)(l.headers),n=new DOMParser,p=n.parseFromString(l.data,"text/html").querySelector('input[type="hidden"]:not([name="lang"])'),w=p?.getAttribute("name"),i=p?.getAttribute("value");if(!w||!i)throw new Error("Pinterest token not found.");let u=await T({url:"https://pindown.io/action",method:"POST",data:{url:e,[w]:i,lang:"en"},headers:{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8","X-Requested-With":"XMLHttpRequest",Cookie:c,"User-Agent":tt.CHROME_UA}},"Pindown Action"),g=n.parseFromString(u.html||"","text/html"),o=[];if(g.querySelectorAll(".columns .column").forEach(s=>{let m=s.querySelector(".is-size-6")?.textContent?.trim()||"",f=s.querySelector(".button")?.getAttribute("href");if(f){if(f.includes("file=")&&f.includes("http"))try{let S=f.match(/file=(https?%3A%2F%2F[^&]+|https?:\/\/[^&]+)/i);S&&S[1]&&(f=decodeURIComponent(S[1]))}catch{}let y=f.toLowerCase(),b="PHOTO";y.includes(".mp4")||y.includes("/videos/")||m.toLowerCase().includes("video")?b="MP4":(y.match(/\.(jpg|jpeg|png|webp)/)||y.includes("i.pinimg.com")||m.toLowerCase().includes("image")||m.toLowerCase().includes("photo"))&&(b="PHOTO"),o.push({type:b,url:f})}}),o.length>0)return C(!0,{title:g.querySelector("h3")?.textContent?.trim()||"Pinterest",thumbnail:g.querySelector(".image img")?.getAttribute("src"),downloads:o,sourceUrl:t});throw new Error("No media found for this Pinterest link.")}catch(e){return C(!1,e.message,r)}}var G=D(F());async function we(t){let r=null;try{let e={"User-Agent":G.CHROME_UA,Accept:"application/json, text/javascript, */*; q=0.01","X-Requested-With":"XMLHttpRequest"},l=await T({url:"https://aplmate.com/",headers:{...e,Accept:"text/html"},rawResponse:!0},"Aplmate Main");r=l.status;let c=(0,G.getCookiesFromHeaders)(l.headers),n=await T({url:"https://aplmate.com/action/userverify",method:"POST",data:(0,G.serializeData)({url:t}),headers:{...e,"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8",Cookie:c}},"Aplmate Verify"),h=n.success?n.token:null;if(!h)throw new Error(n.message||"Verification failed.");let p=await T({url:"https://aplmate.com/action",method:"POST",data:(0,G.serializeData)({url:t,"cf-turnstile-response":h}),headers:{...e,"Content-Type":"application/x-www-form-urlencoded",Cookie:c}},"Aplmate Action");if(p.error)throw new Error(p.message||"Action failed.");let w=new DOMParser,i=p.html,u=w.parseFromString(i,"text/html"),g=u.querySelectorAll('form[name="submitapurl"]'),o=[],s=g.length>1;for(let a=0;a<g.length;a++){let d=g[a],x={};d.querySelectorAll("input").forEach(A=>{let _=A.getAttribute("name"),v=A.getAttribute("value")||"";_&&(x[_]=v)});let k=(0,G.serializeData)(x),U=s?`${(a+1).toString().padStart(2,"0")}. `:"",R="",$=d.querySelector('input[name="data"]')?.value;if($)try{let A=JSON.parse(atob($)),_=A.name||A.title||"",v=A.artist||A.singer||"";v&&_?R=`${v} - ${_}`:_&&(R=_)}catch{}if(a===0&&!s)try{let A=await T({url:"https://aplmate.com/action/track",method:"POST",data:k,headers:{...e,"Content-Type":"application/x-www-form-urlencoded",Cookie:c}},"Aplmate Track"),_=A.data||A;w.parseFromString(_,"text/html").querySelectorAll("a").forEach(M=>{let O=M.getAttribute("href"),E=M.textContent.trim();if(O&&(O.includes("/dl?token=")||O.includes("/mp3?token=")||M.classList.contains("abutton"))){if(O.includes("ko-fi.com")||O.includes("premium.html")||E.toLowerCase().includes("another song"))return;let P=O.startsWith("http")?O:"https://aplmate.com"+O;if(o.some(L=>L.url===P))return;let q=E.toLowerCase().includes("cover")||O.includes("cover=")||(()=>{try{let L=new URL(P).searchParams.get("token");if(L){let N=L.split(".")[1];if(N){let Z=N.replace(/-/g,"+").replace(/_/g,"/");return!!JSON.parse(atob(Z)).cover}}}catch{}return!1})();o.push({type:s?`${U}${E||"MP3"} [MP3]`:q?"Cover [HD]":"MP3",url:P,ext:q?"jpg":"mp3"})}}),o.sort((M,O)=>{let E=M.type.includes("Cover"),P=O.type.includes("Cover");return E&&!P?1:!E&&P?-1:0})}catch{}(o.length===0||s)&&o.push({type:s?`${U}${R||"Track "+(a+1)} [MP3]`:"MP3",url:`applemusic_resolve:${k}`,ext:"mp3"})}if(o.length===0)throw new Error("Download links not found.");let m=(()=>{let a=g[0]?.querySelector('input[name="data"]')?.value;if(!a)return null;try{return JSON.parse(atob(a))}catch{return null}})(),f=u.querySelector(".hover-underline")?.textContent?.trim()||u.querySelector("h3")?.textContent?.trim()||m?.name||"Apple Music Content",y=u.querySelector("p")?.textContent?.trim(),b=u.querySelector("img")?.getAttribute("src"),S=g.length>1?t.includes("/playlist/")?" (Playlist)":" (Album)":"";return C(!0,{title:y?`${y} - ${f}${S}`:`${f}${S}`,thumbnail:b,downloads:o,sourceUrl:t})}catch(e){return C(!1,e.message,r)}}var j=D(F());async function ge(t){let r=null;try{let e={"User-Agent":j.CHROME_UA,Origin:"https://snapsave.app",Referer:"https://snapsave.app/id"},l=await T({url:"https://snapsave.app/id",headers:{...e,Accept:"text/html"},rawResponse:!0},"SnapSave Main");r=l.status;let c=(0,j.getCookiesFromHeaders)(l.headers),n=await T({url:"https://snapsave.app/action.php?lang=id",method:"POST",data:(0,j.serializeData)({url:t}),headers:{...e,"Content-Type":"application/x-www-form-urlencoded",Cookie:c},rawResponse:!0},"SnapSave Action");r=n.status;let h=(0,j.decodeSnapSave)(n.data),w=new DOMParser().parseFromString(h,"text/html"),i=[];if(w.querySelectorAll("table tbody tr").forEach(m=>{if(m.classList.contains("render"))return;let f=m.querySelector("td.video-quality"),y=f?f.textContent.trim():m.querySelectorAll("td")[0]?.textContent?.trim(),b=m.querySelector("a.btn-download")||m.querySelector("button")||m.querySelector("a"),S=b?.getAttribute("href")||b?.getAttribute("onclick"),a=(0,j.extractFinalUrl)(S);a&&a.url.startsWith("http")&&!a.isRender&&i.push({type:y||"VIDEO",url:a.url,isRender:!1})}),i.length===0)throw new Error("Could not extract download links.");let u=w.querySelector(".video-preview img")||w.querySelector(".video-preview")||w.querySelector("img:not([src*='logo'])"),g=u?u.getAttribute("src")||u.style.backgroundImage.replace(/url\(['"]?(.*?)['"]?\)/,"$1"):null;g&&g.startsWith("/")&&(g="https://snapsave.app"+g);let o="Facebook Media",s=w.querySelector(".clearfix > h3, .clearfix > p, .clearfix, h3, h4, p.card-text");if(s&&s.textContent.trim()){let m=s.textContent.trim().replace(/\s+/g," ");m.length>3&&!m.toLowerCase().includes("download")&&!m.toLowerCase().includes("snapsave")&&(o=m)}return o.length>90&&(o=o.substring(0,87)+"..."),C(!0,{title:o,thumbnail:g,downloads:i,sourceUrl:t})}catch(e){return C(!1,e.message,r)}}var nt=D(F());function Bt(t){let r="----WebKitFormBoundary"+Math.random().toString(36).substring(2),e="";for(let[l,c]of Object.entries(t))c!=null&&(e+=`--${r}\r
|
|
7
|
+
Content-Disposition: form-data; name="${l}"\r
|
|
8
|
+
\r
|
|
9
|
+
${c}\r
|
|
10
|
+
`);return e+=`--${r}--\r
|
|
11
|
+
`,{body:e,contentType:`multipart/form-data; boundary=${r}`}}async function ye(t){let r=null;try{let e={"User-Agent":nt.CHROME_UA,Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"},l=await T({url:"https://bandcampdownloader.app/",headers:e,rawResponse:!0},"Bandcamp Main");r=l.status;let c=(0,nt.getCookiesFromHeaders)(l.headers)||"",n=await T({url:"https://bandcampdownloader.app/get/token",method:"POST",headers:{...e,"X-BandcampDownloader":"form",Referer:"https://bandcampdownloader.app/",Origin:"https://bandcampdownloader.app",Cookie:c},rawResponse:!0},"Bandcamp Token"),h=(0,nt.getCookiesFromHeaders)(n.headers);h&&(c=c?`${c}; ${h}`:h);let p=n.data;if(typeof p=="string")try{p=JSON.parse(p)}catch{}let w=p?.token;if(!w)throw new Error("CSRF token not found.");let i=Bt({url:t,lang:"en",csrf_token:w}),u=await T({url:"https://bandcampdownloader.app/action",method:"POST",data:i.body,headers:{...e,"Content-Type":i.contentType,Referer:"https://bandcampdownloader.app/",Origin:"https://bandcampdownloader.app",Cookie:c}},"Bandcamp Action");if(u.error)throw new Error(u.message||"Failed to process URL.");if(!u.success||!u.html)throw new Error("No tracks found. Please check the URL.");let g=new DOMParser,s=g.parseFromString(u.html,"text/html").querySelectorAll('form[name="submitapurl"]');if(s.length===0)throw new Error("No tracks found.");let m=s[0].querySelector('input[name="data"]')?.value,f={};if(m)try{f=JSON.parse(atob(m))}catch{}let y=[],b=s.length>1;for(let S=0;S<s.length;S++){let a=s[S],d={};a.querySelectorAll("input").forEach($=>{let A=$.getAttribute("name"),_=$.getAttribute("value");A&&(d[A]=_||"")});let x=Bt({...d,type:"320",csrf_token:w}),k=await T({url:"https://bandcampdownloader.app/action/track",method:"POST",data:x.body,headers:{...e,"Content-Type":x.contentType,Referer:"https://bandcampdownloader.app/",Origin:"https://bandcampdownloader.app",Cookie:c}},"Bandcamp Track");if(!k||k.error)continue;let U=(typeof k=="object"?k.data:k)||"";g.parseFromString(U,"text/html").querySelectorAll("a.abutton, a").forEach($=>{let A=$.getAttribute("href"),_=$.textContent.trim();if(A&&A.includes("/dl?token=")&&!_.toLowerCase().includes("another song")){let v=b?`${(S+1).toString().padStart(String(s.length).length,"0")}. `:"";y.push({type:`${v}${_}`,url:A.startsWith("http")?A:`https://bandcampdownloader.app${A}`})}})}if(y.length===0)throw new Error("Download links not found.");return C(!0,{title:b?f.album||f.name||"Bandcamp Album":f.name||"Bandcamp Track",thumbnail:f.cover||"",downloads:y,sourceUrl:t})}catch(e){return C(!1,e.message,r)}}var vt=D(F());function be(t){if(!t||typeof t!="string")return"";let r=t.match(/https?:\/\/[^\s]+/i),e=r?r[0]:t.trim();return!e.startsWith("http://")&&!e.startsWith("https://")&&(e="https://"+e),e}async function Se(t){let r=null;try{if(!t||typeof t!="string")throw new Error("Invalid URL.");let e=be(t),l=`https://rapidsave.com/info?url=${encodeURIComponent(e)}`,c=await T({url:l,headers:{"User-Agent":vt.CHROME_DESKTOP_UA,Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",Referer:"https://rapidsave.com/"},rawResponse:!0},"RapidSave");r=c.status;let n=typeof c.data=="string"?c.data:"",h=n.match(/class="downloadbutton"[^>]*href="([^"]+)"/i)||n.match(/href="([^"]*sd\.rapidsave\.com\/download\.php[^"]*)"/i)||n.match(/href="([^"]*download\.php\?[^"]*)"/i);if(!h||h[1].startsWith("/")||h[1].includes("reddit-downloader-bot"))throw n.includes("alert-info")&&n.includes("Reddit is limiting")?new Error("Reddit is currently limiting access on RapidSave. Please try again later."):new Error("Could not extract media download link from RapidSave.");let p=h[1].replace(/&/g,"&");try{let f=new URL(p);if(f.hostname.endsWith("reddit.com")&&!f.hostname.includes("redd.it"))throw new Error("This post contains an image gallery or text (RapidSave only supports Reddit video downloads).")}catch(f){if(f.message.includes("RapidSave"))throw f}let w="Reddit Media",i=n.match(/class="text-center">([^<]+)<\/p>/i)||n.match(/<h2>([\s\S]*?)<\/h2>/i)||n.match(/<strong>([\s\S]*?)<\/strong>/i);if(i&&i[1].trim())w=i[1].trim();else{let f=e.match(/comments\/[^\/]+\/([^\/\?#]+)/);f&&f[1]&&(w=decodeURIComponent(f[1].replace(/_/g," ")))}let u="",g=n.match(/<video[^>]+poster="([^">]+)"/i)||n.match(/<img[^>]+class="[^"]*thumbnail[^"]*"[^>]+src="([^">]+)"/i)||n.match(/<img[^>]+src="([^">]+)"[^>]+class="[^"]*thumbnail[^"]*"/i)||n.match(/<img[^>]+src="([^">]*thumbs\.rapidsave\.com[^">]*)"/i)||n.match(/<img[^>]+src="([^">]*(?:preview\.redd\.it|external-preview\.redd\.it|i\.redd\.it|thumbs\.redditmedia\.com)[^">]*)"/i)||n.match(/<meta[^>]+property="og:image"[^>]+content="([^">]+)"/i)||n.match(/<meta[^>]+content="([^">]+)"[^>]+property="og:image"/i)||n.match(/<img[^>]+src="([^">]*(?:rapidsave\.com\/assets\/img\/|assets\/img\/)[^">]*)"/i);if(g&&g[1]){let f=g[1].replace(/&/g,"&").trim();f.startsWith("/")&&(f="https://rapidsave.com"+f),!f.includes("logo")&&!f.includes("icon")&&!f.includes("placeholder")&&(u=f)}if(!u)try{let f=`https://www.reddit.com/oembed?url=${encodeURIComponent(e)}`,y=await T({url:f,headers:{"User-Agent":vt.CHROME_DESKTOP_UA}},"Reddit oEmbed").catch(()=>null);y&&y.thumbnail_url&&(u=y.thumbnail_url)}catch{}let o=null;try{let y=new URL(p).searchParams.get("audio_url");y&&y.startsWith("http")&&(o=y)}catch{}let s=/\.(jpe?g|png|webp|gif)/i.test(p),m=[{type:s?"image":"video",quality:s?"HD Image":"HD Video (with Audio)",url:p,thumbnail:u||""}];return o&&m.push({type:"audio",quality:"Audio Track",url:o,thumbnail:u||""}),C(!0,{title:w,thumbnail:u,type:s?"image":"video",downloads:m,sourceUrl:t})}catch(e){return C(!1,e.message,r)}}var Wt=D(F());function ve(t){if(!t||typeof t!="string")return"";let r=t.match(/https?:\/\/[^\s]+/i),e=r?r[0]:t.trim();return!e.startsWith("http://")&&!e.startsWith("https://")&&(e="https://"+e),e}async function xe(t){let r=null;try{if(!t||typeof t!="string")throw new Error("Invalid URL.");let e=ve(t),n=await T({url:"https://sechno.com/api/terabox",method:"POST",data:{url:e},headers:{"Content-Type":"application/json","User-Agent":Wt.CHROME_DESKTOP_UA,Referer:"https://sechno.com/tools/terabox-downloader"}},"TeraBox (Sechno)");if(!n||!n.success){let o=n?.error||"";throw o.includes("105")?new Error("The TeraBox link is invalid, expired, or deleted (errno 105)."):new Error(o||"Failed to resolve TeraBox link via Sechno.")}let h=Array.isArray(n.files)?n.files:[];if(h.length===0)throw new Error("No files found in TeraBox share.");let p=h.filter(o=>!o.isDir&&(o.downloadUrl||o.streamUrl));if(p.length===0)throw new Error("No downloadable files found in TeraBox share.");let w=[],i=p.length>1,u=n.title||"TeraBox Shared Files";if(i)p.forEach((o,s)=>{let f=`${`${(s+1).toString().padStart(2,"0")}. `}${o.filename||`File_${s+1}`}`,y=o.thumbUrl||o.thumbnail||o.thumbs?.url3||o.thumbs?.url2||o.thumbs?.url1||(/\.(jpe?g|png|webp|gif)/i.test(o.filename||"")?o.downloadUrl:"");o.downloadUrl?w.push({type:f,filename:o.filename,size:o.sizeFormatted||(o.size?`${o.size} B`:""),quality:o.sizeFormatted||"Direct Download",url:o.downloadUrl,thumbnail:y||""}):o.streamUrl&&w.push({type:f,filename:o.filename,size:o.sizeFormatted||(o.size?`${o.size} B`:""),quality:"Stream",url:o.streamUrl,thumbnail:y||""})});else{let o=p[0];o.filename&&(u=o.filename);let s=o.thumbUrl||o.thumbnail||o.thumbs?.url3||o.thumbs?.url2||o.thumbs?.url1||(/\.(jpe?g|png|webp|gif)/i.test(o.filename||"")?o.downloadUrl:"");o.downloadUrl&&w.push({type:"file",filename:o.filename,size:o.sizeFormatted||(o.size?`${o.size} B`:""),quality:o.sizeFormatted?`Direct Download (${o.sizeFormatted})`:"Direct Download",url:o.downloadUrl,thumbnail:s||""}),o.streamUrl&&w.push({type:"video",filename:o.filename,size:o.sizeFormatted||(o.size?`${o.size} B`:""),quality:"Fast Stream (m3u8)",url:o.streamUrl,thumbnail:s||""})}let g=p.find(o=>o.thumbUrl||o.thumbnail||o.thumbs?.url3||o.thumbs?.url2||o.thumbs?.url1)?.thumbUrl||p.find(o=>o.thumbnail)?.thumbnail||p.find(o=>/\.(jpe?g|png|webp|gif)/i.test(o.filename||""))?.downloadUrl||"";return C(!0,{title:u,thumbnail:g,totalFiles:p.length,downloads:w,sourceUrl:t})}catch(e){return C(!1,e.message,r)}}return Zt(_e);})();
|