chore: bump version to 1.0.1, add CHANGELOG, restart UX (UI modal + nodemon trigger), config/filters fixes, Docker ownership and compose docs

This commit is contained in:
Inside4ndroid
2025-09-17 11:35:15 +01:00
parent 484ea4bb3f
commit e489a1b613
79 changed files with 334 additions and 11769 deletions
+31
View File
@@ -1,5 +1,36 @@
# Changelog # Changelog
All notable changes to this project will be documented in this file.
## [1.0.1] - 2025-09-17
### Added
- Admin UI: Restart Server button (below Logout) with a themed confirmation modal. The UI polls `/api/health` and auto-reloads when the server is back.
- Sidebar divider under Logout/Restart for clarity.
### Changed
- Exclude Codecs presets:
- Introduced "None" (default) → `{ "excludeDV": false, "excludeHDR": false }`.
- "All" → `{ "excludeDV": true, "excludeHDR": true }`.
- Persist and render presets reliably after Save / Reload.
- Minimum Quality: Clear All now resets to `"all"` and selects the All preset in the UI.
- Clear All: Now fully resets TMDB keys, FebBox cookies, providers, and filters; added a themed confirmation modal with optional "Don't ask again" preference.
- Live Config: Hide legacy `tmdbApiKey` (only show `tmdbApiKeys`).
- Restart behavior:
- Local dev: Nodemon watches `restart.trigger`; backend writes it before a clean exit to force a restart.
- Docker: Compose uses `restart: unless-stopped`; Docker restarts the container after restart endpoint triggers exit.
- Dockerfile: Ensure non-root `app` user owns `/app` for writing overrides and restart marker.
- package.json scripts: Simplified to `start`, `start:dev`, and `lint`; both start scripts are nodemon-based and watch `restart.trigger`.
### Fixed
- Provider matrix re-renders immediately after Clear All (no page refresh needed).
- Handling of Exclude Codecs "ALL" previously not persisting correctly.
## [1.0.0] - 2025-09-16
- Initial stable release.
[1.0.1]: https://github.com/Inside4ndroid/TMDB-Embed-API/compare/v1.0.0...v1.0.1# Changelog
## [1.0.0] - 2025-09-16 ## [1.0.0] - 2025-09-16
### Added ### Added
+2
View File
@@ -39,6 +39,8 @@ COPY --from=build /app/README.md ./
# Expose port (documentational; runtime can override) # Expose port (documentational; runtime can override)
EXPOSE 8787 EXPOSE 8787
# Ensure runtime user owns app directory for writes (overrides, restart marker)
RUN chown -R app:app /app
USER app USER app
# Labels / metadata # Labels / metadata
+11 -6
View File
@@ -6,7 +6,7 @@
<img src="https://img.shields.io/badge/Node.js-18%2B-brightgreen?style=flat" /> <img src="https://img.shields.io/badge/Node.js-18%2B-brightgreen?style=flat" />
<img src="https://img.shields.io/badge/Status-Active-success?style=flat" /> <img src="https://img.shields.io/badge/Status-Active-success?style=flat" />
<img src="https://img.shields.io/badge/License-MIT-blue?style=flat" /> <img src="https://img.shields.io/badge/License-MIT-blue?style=flat" />
<img src="https://img.shields.io/badge/Version-1.0.0-informational?style=flat" /> <img src="https://img.shields.io/badge/Version-1.0.1-informational?style=flat" />
<img src="https://img.shields.io/docker/pulls/inside4ndroid/tmdb-embed-api?label=Docker%20Pulls&style=flat" /> <img src="https://img.shields.io/docker/pulls/inside4ndroid/tmdb-embed-api?label=Docker%20Pulls&style=flat" />
</p> </p>
@@ -53,11 +53,11 @@ npm install
# 2. (Optional) Copy example env if you want an initial TMDB key # 2. (Optional) Copy example env if you want an initial TMDB key
cp .env.example .env # then edit TMDB_API_KEY= cp .env.example .env # then edit TMDB_API_KEY=
# 3. Start API (production style) # 3. Start API with automatic restarts (recommended for local dev)
node apiServer.js npm start
# Or with automatic restarts (if you add a dev script) # Or production-style single run
# npm run dev:api # node apiServer.js
# 4. Open the Admin UI (login page) in browser # 4. Open the Admin UI (login page) in browser
http://localhost:8787/ http://localhost:8787/
@@ -142,6 +142,11 @@ If both `TMDB_API_KEY` and `TMDB_API_KEYS` are provided, rotation uses the array
```bash ```bash
docker compose pull # if using an external registry (future) docker compose pull # if using an external registry (future)
docker compose up -d --build docker compose up -d --build
### Restart from Admin UI
The Admin panel includes a Restart Server control.
- Local (nodemon): the backend writes a `restart.trigger` file and exits; nodemon detects the change and restarts automatically.
- Docker Compose: the container exits and is restarted by `restart: unless-stopped`.
``` ```
### Healthcheck ### Healthcheck
@@ -188,7 +193,7 @@ Saving in the UI writes only changed keys. Setting a field to empty removes the
| Quality / Filters | Min quality presets & codec exclusion JSON | | Quality / Filters | Min quality presets & codec exclusion JSON |
| Keys | Add/remove TMDB API keys (rotated randomly) | | Keys | Add/remove TMDB API keys (rotated randomly) |
| FebBox / PStream | Manage FebBox cookies powering Showbox provider | | FebBox / PStream | Manage FebBox cookies powering Showbox provider |
| Advanced | Provider toggles, cache & validation flags, proxy paths | | Advanced | Provider toggles, cache & validation flags |
| Server Status | Live metrics, provider functional checks | | Server Status | Live metrics, provider functional checks |
| Live Config | View merged + override JSON snapshots | | Live Config | View merged + override JSON snapshots |
+26 -1
View File
@@ -66,8 +66,11 @@ function recordLoginSuccess(ip){
loginAttempts.delete(ip); loginAttempts.delete(ip);
} }
// Guard against premature process.exit from imported legacy modules // Guard against premature process.exit from imported legacy modules, but allow controlled restarts
const realProcessExit = process.exit.bind(process);
let allowControlledExit = false;
process.exit = function(code){ process.exit = function(code){
if (allowControlledExit) return realProcessExit(code);
console.warn('[diagnostic] Intercepted process.exit with code', code, new Error('exit trace').stack); console.warn('[diagnostic] Intercepted process.exit with code', code, new Error('exit trace').stack);
// keep process alive for debugging // keep process alive for debugging
}; };
@@ -198,6 +201,28 @@ app.post('/api/config', (req,res) => {
res.json({ success: ok, merged: config }); res.json({ success: ok, merged: config });
}); });
// Restart endpoint (requires auth via session cookie on /config.html UI)
app.post('/api/restart', (req,res) => {
const sess = getSession(req);
if(!sess) return res.status(401).json({ success:false, error:'UNAUTHORIZED' });
res.json({ success:true, message:'RESTARTING' });
// Give the response a moment to flush
setTimeout(()=>{
try {
const fs = require('fs');
const restartMarker = require('path').join(process.cwd(), 'restart.trigger');
fs.writeFileSync(restartMarker, String(Date.now()));
console.warn('[control] wrote restart.trigger to notify nodemon');
} catch (e) {
console.warn('[control] failed to write restart marker:', e.message);
}
console.warn('[control] restarting process by exit(0)');
// Let nodemon detect the file change and restart the app
allowControlledExit = true;
realProcessExit(0);
}, 300);
});
// --- Basic informational endpoints --- // --- Basic informational endpoints ---
app.get('/api/health', (req, res) => { app.get('/api/health', (req, res) => {
res.json({ ok: true, service: 'tmdb-embed-api', time: new Date().toISOString() }); res.json({ ok: true, service: 'tmdb-embed-api', time: new Date().toISOString() });
+3
View File
@@ -16,6 +16,8 @@ services:
volumes: volumes:
# Persist runtime overrides (created by the admin UI) # Persist runtime overrides (created by the admin UI)
- user_config_data:/app/utils/user-config.json - user_config_data:/app/utils/user-config.json
# Allow restart trigger file (optional; stored in container FS)
# - restart_marker:/app/restart.trigger
restart: unless-stopped restart: unless-stopped
healthcheck: healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:8787/api/health || exit 1"] test: ["CMD-SHELL", "wget -qO- http://localhost:8787/api/health || exit 1"]
@@ -25,3 +27,4 @@ services:
retries: 3 retries: 3
volumes: volumes:
user_config_data: user_config_data:
# restart_marker:
+3 -4
View File
@@ -1,12 +1,11 @@
{ {
"name": "tmdb-embed-api", "name": "tmdb-embed-api",
"version": "1.0.0", "version": "1.0.1",
"description": "Standalone streaming embed source aggregation API (TMDB ID in, streams out)", "description": "Standalone streaming embed source aggregation API (TMDB ID in, streams out)",
"main": "apiServer.js", "main": "apiServer.js",
"scripts": { "scripts": {
"start": "node apiServer.js", "start": "nodemon --watch restart.trigger apiServer.js",
"start:api": "node --watch apiServer.js", "start:dev": "nodemon --watch restart.trigger --ignore providers/.cache --ignore **/tmdb-embed-showbox-cache apiServer.js",
"dev:api": "nodemon --ignore providers/.cache --ignore **/tmdb-embed-showbox-cache apiServer.js",
"lint": "eslint . --ext .js" "lint": "eslint . --ext .js"
}, },
"dependencies": { "dependencies": {
@@ -1,14 +0,0 @@
{
"data": [
"https://hubcloud.one/drive/eeltgk7tefggdkw",
"https://hubdrive.space/file/2839373447",
"https://hubcloud.one/drive/zm1uzufz8wh1zmv",
"https://hubdrive.space/file/6441436585",
"https://hubcloud.one/drive/dm1sbdubufkkdsv",
"https://hubdrive.space/file/3875373190",
"https://hubcloud.one/drive/wev1xt17dypotb1",
"https://hubdrive.space/file/4216265302",
"https://hubcloud.one/drive/mrhza1jqmajrjko",
"https://hubdrive.space/file/2736804525"
]
}
@@ -1,14 +0,0 @@
{
"data": [
"https://hubcloud.one/drive/2rc17eosl11jalt",
"https://hubdrive.space/file/30320495116",
"https://hubcloud.one/drive/lb82vul8vwzw8lz",
"https://hubdrive.space/file/24320017865",
"https://hubcloud.one/drive/ls4j4srjsh228ks",
"https://hubdrive.space/file/8303893568",
"https://hubcloud.one/drive/cds5rdggp8pwxds",
"https://hubdrive.space/file/8032803119",
"https://hubcloud.one/drive/gb655ffb5nmzg3g",
"https://hubdrive.space/file/2836399263"
]
}
@@ -1,20 +0,0 @@
{
"data": [
"https://hubdrive.space/file/5855904942",
"https://hubdrive.space/file/5855904942",
"https://hubdrive.space/file/27692865336",
"https://hubdrive.space/file/27692865336",
"https://hubdrive.space/file/6521988586",
"https://hubdrive.space/file/6521988586",
"https://hubdrive.space/file/9974112091",
"https://hubdrive.space/file/9974112091",
"https://hubdrive.space/file/8806133211",
"https://hubdrive.space/file/8806133211",
"https://hubdrive.space/file/6167785635",
"https://hubdrive.space/file/6167785635",
"https://hubdrive.space/file/10054935010",
"https://hubdrive.space/file/10054935010",
"https://hubdrive.space/file/4750964205",
"https://hubdrive.space/file/4750964205"
]
}
@@ -1 +0,0 @@
[]
@@ -1,3 +0,0 @@
{
"data": null
}
@@ -1,64 +0,0 @@
{
"data": [
{
"quality": "720p",
"driveseedRedirectLinks": [
{
"server": "✅ Fast Server (G-Drive)",
"url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtlZnl5UDZCUGpyd1B0aW1WK01GOERRK0V6MDJ5MFNGbGh1Q1h4Y3VYckNXSDZ2MlIxMDVYMnRyeDMydFBNdWNEajRSbDZXMWlzRjNMaVhMdnhDZkVqK1lkeEFrTFVKcnpBemFRSUJ4NStWTE51aHJIM1pOSUlMK3NxMDMwcUVpZXlPR0dPL2tzQmlWUDFmNkhGR0RSbg==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=Z1JOMXJJbTVlVFFIdXcvQ2xRMFZ5ZEtGekMrZk1ISkY1b3d4MUhray8yM2xPVHRGK00zTWtmekhYcjJRQXBLYw=="
},
{
"server": "🚀 Google Drive (Server 2)",
"url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEpaWllxaHVJQ3JtNmZUb1cyMy92NkpPRWdIekdtNjNwTDJRTEh0Z3Mva1JYTUthaStDUVp3UzlRa0hqVVlyQjZWdExtZG1wTitoMmRzVXpyWHZRZ0tPaFpVR3lQcmFzUVBSb2hkdE1wWlB6d0s5ZGsyb2UwOCtGRWZKQS9wKzhaZVRrTjBCendhZVV3YksrOGNXZkdJdg==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=UkZYTyswOUlYWnRkd3c4UFg5TWEyNkxMRXdFakZNL05CMjYxcElpOGxOZWxJUEVMQXo4b2V6alh0RWJTemJEcg=="
}
]
},
{
"quality": "1080p",
"driveseedRedirectLinks": [
{
"server": "✅ Fast Server (G-Drive)",
"url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtYaWxrRmU5aEVETnNSaE0veXJXN1VnYXJjZTVyQ2hVNUtzbk85MDI0OC9Edm9EUWVpWHNMYU0rRXp0ZGpUWTdFZG5VQzR6T0x3UmgvUEY5R1lFc2lrRFkxK3B3N1A1V0htN3h3eDJyaTY5REJSK1RjVm00MkNnRk9XQW12eCtRWE5seWxFZC9uelNXWUNOSXpBbllkaw==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=QXhGREliQjNpZitEWFJZY01qdXc4cmt4SnRMNGlGcit0eGNkbDNySHUybnVWZjIycElLZ0VTNGdMV3A1S1lKVw=="
},
{
"server": "🚀 Google Drive (Server 2)",
"url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZElqd1lDTmJPOWRrK2tMc0ZTMENiQTFtRkZkUVBZVjArQ1d4NFhvdzhNcnhsalBHbm82dnVTY3ppS1Jla3RWTHVxMmxuemhzWUdEczdnMElYS3lEN1Y4WEp2bXdxb3FndWFJKzVHRWE1Y1ljR3dkamZQR0U4czV3Y0ZKcUVvSFVRVVdIQ1RITnBtTGIvelVIeXljQWd5Sg==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=ZXV0eEdJYlhJcFhad0FSeDQxWFRGajZGZ3NDZG9BQTQ1c0JvWVUyMnFBMjJIam5zdUE4UnE2dlIwRjVVYVBERg=="
}
]
},
{
"quality": "720p",
"driveseedRedirectLinks": [
{
"server": "✅ Fast Server (G-Drive)",
"url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZExIOWo1MEtyUTN4L3dUeW8wbzc3VUFXODNBRFZSaFBpUHNwdTZ4aEF2YVJUdVlodzI0Q0pFU1hnQ0ZaUUFHOVNsaEsrWFI0RkY0SFFhYTEyWjFBdFNwNGlHczdNaXpEOS9qeXdVT2dsMU10anpscjVnN21IdmpCcVoyY2x4djJzVzZXb3ZkM0FxM2Q1SXdvR0o5Q3cvNg==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=K1U1RnhlTVdFc25JakJLVFZlTzlaN0w3V2VFRnVlelBLQWRaOVVpVXNBZWFwWksvREw0QmxWQjFCS0pDYWlXOQ=="
},
{
"server": "🚀 Google Drive (Server 2)",
"url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZExqUmh2aXFIeEJDWjQwZkpVVUpZWWZUQzZzeVh4L3VMblgyR1F4eGJjSDc1OVBRQ2VxeHZyb21acHh5SzNvRkhneXBPTmdhSGgvTEh4QnNKMlJoVUJSUnpvempYdExaZUZkcWQ5VnN2TXFqRzJwYXRvSDF4bk1iTXZ1UlZ0R0JtQjhXYmNEQVE0emhmVlFOR1NLODh1eA==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=aExxTjRHZk4wY1ZjNDJ2VHhzcjdrcVBweHBJbWhGNitYN1ZlUGR4Z0gxalR1T2orZFBFdTRLMnRuUndiVE5IQg=="
}
]
},
{
"quality": "1080p",
"driveseedRedirectLinks": [
{
"server": "✅ Fast Server (G-Drive)",
"url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtPNXdWSEEvK1RsbzRDdDJlY0xTd0xlY1FDbHJhK0RjdUlWKzlmZkl6dG1IRWFkTStReXlSUGtXNHhGWG5jZEJDc2ZnUytzK281d3E4VXJVcFdNN0lxZVVjK2F4Y2hhVDAvL2pJRXVHNGMybk5tQW1uSkh5d2p5VlFqTDdaWGdLcUwzMGF6aFNibjkwZTVHd2l5eXRPTg==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=Y08zbk11amZCd3NacmxONVJZYlNNN3FIaklVU0lSSXp6VWhVUTkxVzlpWEJWNVFSOXQ5MTFUWmQvUFNCSzQ0WA=="
},
{
"server": "🚀 Google Drive (Server 2)",
"url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEozOWlUeUxnd2JuT1l5WHNvQlNVUWpNeGNzTEplSExmN2R4ZDNQVm55Y243VHFicHBVREVZUHQraVZJUmxLeVFYVFArb0Y0ejc2MEUzRE1sL2tsRStKdUNwMW1GSEdkZ0ZrR09Bdzl0ZzN5M3ErU1RCTGdFV1F5UVNiOEtqRVlRcmNNckFZQ0xSbW5vbTRMdW1TOVg5UQ==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=Vk5abDBBaEhiaE9rNE8xTHNwR1BZQVZZUTJ0Qjc2bzFzdHVhVUV5VWdPVnNHOWl0ek40S1FxZ1U3YmUwWTdVNg=="
}
]
}
]
}
@@ -1,224 +0,0 @@
{
"data": [
{
"quality": "Season 1 {Hindi-English} 720p 10Bit Esubs [340MB] - Episode Links",
"driveseedRedirectLinks": [
{
"server": "Episode 1",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEw0Y0tZeDhyUmtkbTFtM0tEay90aGM0TmVJNFdxTGk2MVpORURBQUNNaHRKOGJKZlRkdXNnZzMwb1JPaXRrN0VoV1hReFZyNzNUWFBsQ2R6aGkzKy80VXloNGtQZmllUkhMbGdmcXd0Y01LbVRPd1Foc283eFhQL1VKR3pocGZWZEp0bUJTM1VYRzNGTzYxU0VSd0hwbg==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=UnRjNmRSQ3pLV29ONnRUS0kvYmY3RjV6OTRGUCtpbzRLWE81ejgvM0hrYUMzMjM0cEpnSEh3OGVUTGxXY3BrRQ=="
},
{
"server": "Episode 2",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZElRaTlRd1loWlRLNFhDL3UxeEZxRFl5VW93a3h4eTVyYWNRUFJMYnJoTnFzbHZpQ2hFejZEc1N3RHJYd05UODlnN29MZURUN2tRTTdUQVg2cEZGcVBuUHJLNEpPaVpzREd6d0ZyNzBHRzFrc3F0aktLYW1zaEhTM3FaSnRBTjF6b2x0aU5NU2FMdU40aTA0dkxMdzVQTg==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=bkd6amRlRWE0UlhxV0dqRlo4b1B3TmVCZklXTWRMWnNRbXlDYWdFTnJYWHFIQ2lqOWl5K0pCT2pMaWdXQzdpbw=="
},
{
"server": "Episode 3",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtLYmtEYjdWVllPYjZLMm1TMXNZaFl2WXdKUk1kbkR5d0Z3Ylo3TTRNSEo4VWxrZnFQVEMvTzduTDhjNG1ITm4zTVdHc3pzdlhMVFVOOHpOSnNWLzMyOHg0SDdFNi9nSThJaFczRkFMV21NVWZ6Nk0ybUNvejQxanF2OWZZUHhBREY2cWNVcCtyMm1XeDBBdFpYWFFlRQ==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=azkzOHJGMHR2T2YzRUhwWU8raUJuam9MVzZ2UWNXdUNkVVNMdjgrN3FBM1JEVkhJZFlZajcrd1JERENQQ3pCRA=="
},
{
"server": "Episode 4",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEw5L1JZVWZxK09QMWtxbEFWU2ppdUx2SmhKQVFrK0FNNEY0NkJsUDJjZlprQTI3eTlBRW5kaEpQSlN1Vks5RzRUMFBVL0FvQ1hJa2J2R2JIV2ovYUNNVkdZYm9hQjNPY2hLTVZyZml4SUQ0YmROUDFOZm5HbVc1SWpvaXRPZHM0d1ZFMDFUOFBPR0VGRW5qdy9RbTNDSw==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=QVdhWE5rVkhmV3B3dHJKTUQzNEd2VDM3cVJNMW9pN05qQUNDTnJ3ZGR2WmVKR2FVS25heUlob0ZOSnlUUS9TUA=="
},
{
"server": "Episode 5",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZExsVjhoaC83WDZCSDZvUlo2bEtOOTNmUmNzUjlmaHlKS01GK2VmcHVTOGQ5RUlEOFhLTnBtdk9LTHRmSTJjU3NLZHdyZEg0a0Z1ZjFCUGxHbzJ2WGo5TDhmNnhyUTR4WkR4MG9hc3EyOTZadkYzN00xYXRqTGt5YnQrZGFVTUdkWktxV3JJcDdubGpoSVN0SkZzdWZ3dQ==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=Qy9GNFN3U2loNWsyRFVGUUh3RnpmbSs1UURJTVllOEJzNDdwOVhHcUxUci9rZWdOS1JIS0xmVGw5L3QxWGZzSg=="
},
{
"server": "Episode 6",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtGTjA3WlR0MUwvODZqckhBQWFOVUNCUWtQaUVZbzFxTmx6UWpOUFJxMnVCcitiWEtpdGtiSEJSNW5iUG5XSkxwWFZ6a1g2b3BkbFJmN1JYblIweW1xY2R6ZjEvSW9xRU5xZnZTQlRpS3lnU0d1NThhdTZhMFAvUGdYQzl0TWprSkRLa1RwTzVJd1N0N1p0NkhLdkp0cQ==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=WjhBd0J6a09PUWVYeDlaRG5yNU5qcE5KM09ITks2d2NqTkM1UGxtR0c2T2VBTEhnanByRVdBanN0MzJyNDk4UQ=="
},
{
"server": "Episode 7",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZExRVlYyVkpzdWxBWUo3bzBzcWs5d3R3dHNXOWxqUHVlWFdkTlgxSGhaUS9FU1E4NXdCS3laSVlSZUlQTDBFWkxnMGkxOUkzdklmellSR2RyTk9uSXpTWk0vWC9jYkVHdFlQOThjZUs5ckNTNGRraGlFYnRmQ3FhcDdIdEF4ZFdEdjQ0MHJPTytZVUFLRTZVdkhMb2ZUUQ==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=ZjJqSGRoWUtpMW56VlhwTUpzWFVWSTdMazRDSnZJQlQzb0p6dXdTbU1xc2ZrK0FxMzNHSUQzS0hIMDhuS1NUOQ=="
},
{
"server": "Episode 8",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEkzdVZ2UWpRV01CWWJhczc1VUZiM1A0aWlGSHNPbzFnNmNudkdnUXU2QVVUUTBDUGJjTEJIQ2tMSHAzeExiR2dEbXVYaWNZdWtuUFVFUklFbWFLeWNNb2VDRXJ3aVdubmN0UE14bG5NbTV5TkF3VWtWS2RFU2s3WkszRVJpVEVuY055VjNtNWJLVzhSUHV4U1BDMVJnVQ==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=Tng3MmRaUWFERkFaR3ZnR0ZaSzJDaklkMVZudWFFSkE2TGxEREpDYVFUV2J2M1FpNjc1ZHVQajJtT21QZ2t1TA=="
},
{
"server": "Episode 9",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEp6eS9jcnJib1hHeGRwY0RYbHJoMGhSMTlDNUZvSSt0RUlvK2tjRloraWt4Mm5MYUl1MktxbHU5Ry9pS0FuL21TYkphTnZEaXJGdkx6RG9YR3VwaVVpT2g3UkFhUTZjS1Z1eGZaLzhiWjBtUmlYeWFQL1JWbUMwQmdBRnRkYkRhanhqSjJ0aXNJUTRGQy9LRmk4a3V6WA==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=bDZiZXNON0lNTjRCS0tDbDRlb1dRRTk5NCt1V2ZUV1piNGZ3eExZQVFPRVYweEVkWHMzOEJUUGxlOXRLa0RpbA=="
},
{
"server": "Episode 10",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEpFZ1Q4elA2S2x2aTZzQ2tvNXBiMVBHclRJbFMraTBPRHVjQUt0SU8raEg2RWlpZ25leFhlQnNialIyQUJWWWlQMEtWUFJsdTM0Z2NmNGJWOGNLcXRDSzhKNlNUa01WK1grTTRBaGdVT1I2VTE3UEZ6ZDVLVjFkVjdVZFZQU1AxaUtqdVRnNnhNT2tZL1JMMExTcEY0Kw==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=OWRIYzFabCtGM1gzQ3RPRlJreFo5Ykt4MHVKeFYwTW5SRndaQ3NqOEg0UzRiQ2FDZlJ0d0ZEcDA3cTQxSHZzNA=="
}
]
},
{
"quality": "Season 1 {Hindi-English} 720p x264 Esubs [500MB] - Episode Links",
"driveseedRedirectLinks": [
{
"server": "Episode 1",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZElNMHVBSFVUOGhqOUdXMGtDeDRzeVMrSHlPblJSSFlEMi9ZY2R3OFNXNGJRRk1MelNBRTR6NGlPU2ozVXd4cFFRaFM1MlV4QXVlTWhTK2F2akZNaTBoYmc2ZFRoRmYvcnJDdUJZdDY2RGlFZFM5ZzdRNmF5WUZRU0xVYjNTS1dIUWZ1S1JXcS8rQXBMTGNnVTRmSE9MMg==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=c2RhVDROL3JOZG5GV3RoWndtbi9RMHFnN1YrSDF6eUtuSlA4WWR5ZXdOV0pIaGcvNC9BTWN4cURMSTlRRzR4WA=="
},
{
"server": "Episode 2",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZElzOHFpOW9YeGlEenVtQkpZUjhkaGFobmhVYnZRLzJDRTQ5SHNBRlowTis1QnpTOXFub1E3ZHE5cGpoUFhDVU1hbHNCbms5YXprWTh0N05UR09vOUN3TWI2WXFGUGh3SkdGUUFzSURPZlFMU3lvbk9LRW91T0xKZ1U5SGMyOUxsSFkySmlyZzBSYVBkbHBiS2dsblpMLw==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=WjJOc2dvVG8yTTlocmRzTXdEZ3NqWTNQa1hOd1ZnRFU1RnV5aWRpR3djaXFZK1IwVXYzYWxLa3lBUDRpSmkrQQ=="
},
{
"server": "Episode 3",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEp3RHNXZUxnK3l2VVVoL2hpLzdBckpCRTF2b1k2ZldidEhJMlpGc213Q0dUb3BIUlMwSW9ibmFtalBKSk9PQXJSRWZ3L3E3Yk1QdVA3NGloN21KVWo2L3hIaWV3QStmWGk3c0tWMS9neVRTU2swalV1bHhFM0ROeVFudTR4T00wSWVPNmpjR0dQK0U5NFl3SWNGRHZHRA==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=YXN0eGVCaVRhL0hndU1JVTFqa3NRQlR0UE9YdEdEY1ZMOGxzRG8wbjQybldkWFc2MkR5MjR3WE9XS3QzZ2tZUA=="
},
{
"server": "Episode 4",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtlSkVSTnJrbWVpZU9GK0lYTXVwV0xBMEtPaU9FTFNwaFJVNlBYWG4zMzYxazRqSkV2c2I2Q2FaSnBWVXNEZFRjMEg5bnVubEFDbnk3VUhxVXh6Sk9lWWhWejFvWmlUeXhrNjBXZ24vcU5pNVdMZ0JvNDZvUHZMS0hid3JYOVJYSENzem9BVUI0dHdCc2RpVjZUTXB1Rg==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=Q3IydEdlS0NXbUdkeSttRXdqWk9aZFZGcFVpME9wQXVFMTRKTGpKci9qR2lIKzVOSmlzNHV2VUF1NFF1ekJKZA=="
},
{
"server": "Episode 5",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtZMi8rMURQS1IydSs2UzRmZzBxbTV6cUR5NGxXN0pxVzFzZHhteTN4dG92MUlpZlU0dFBOTTgyRGRiSS9wZStzdmR4SngyVHNkV3kwZkVuS1phTDNBNzZJR2VRQWJ4NmM5MkxISHdvRkZXd3FwcVF6NjhJY2RwR0FRMzlsb2c4WkFaN1BLcUFKcldwVFVnNmpvVDF1cw==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=OWhTdjhaaS9uU2hSSzJTc2V1c0lGQmtFZHZ6eHRjKzFLQmhNNmlUSFJtVEc5dGVEdEFYQkF2aE1weFQrNTU5Rw=="
},
{
"server": "Episode 6",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZExFVkQ1Wm5Uc3pRcElVTW9rUE5IVXNHU3Ura0dXRVUzMHNrOWYreFU1WGRxd2wxd1RYYnJ5VnJadjRlM2tPcFVYdmE2dEVkZTRpU1h2TGVBVWhJQ1ZHaDZ4WnNDbVBFNVliWVNwQytPeGF5OEZLWndaZFNTbm1ORFVhZzY1NjhpZitIZ2NLZmYweVFwUnFGTyt4dkFaSA==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=TTlaUm9vQXRjMVg2SXprZlFISDRrVDBpdzNwTUxyeG5RekVoWUp3Y3FGK214SFdTVTdkTzJBMDFHMU8xQ1VXdw=="
},
{
"server": "Episode 7",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEplNERKdG0wYk1xSzRGdVY2cFNQYmN1RTJCTU5BMXUrdFcvN3NsNG9ieWtUMjZaU2FDMytPZWp5V0lkeTBzZkhiZVhaRitwOVB5RWl2R3ZDT3BNTGNBOHFLSzZSN2c0ZmkrVWpQZlhVTWlncXBWVHE5MlpFMmI2a3BKSWhTVVdYeHYzRzJpdllXM0tHU2xRQ2tkb2VqWA==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=SFNGTGpTZE1wTU1DSUwrK3FiOStyU2pzV1V2MWY5NGNyVmVnQ1FRZWRmSGxuQUFVSElGNGVXbU9NNHdTR3hRUw=="
},
{
"server": "Episode 8",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEs2SHp3TDFJcmxUQjBUNGlNYUorck5VMGdqbFlhZFhVRHk3YlRYdlRaVXJWZWtMenEybW8xWU1oNjgrNmJZNXp1cUVDd1BTVjBkbDJKZzh5bzgzamVITGF5Y0szamJwbW9paVYvSTA4OVpWVnV1V2dTZHpoVFJCbWg3R3UrUnd5VWx6VXhOYk95SEE1MXhPMHBnT2xVcQ==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=SmFzM2NEaTBkSjBBNW1MQkJEYlArdUJSUldGYWhxUlJoL1hQOVNPNUR2NnkycTl2aXhSN3FrMGhDcVJZTW4vVg=="
},
{
"server": "Episode 9",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEl3TVBneUl4Nnc4MDIvQUFCSWk5R1RzSklPS2hjMFZXVncyZGFMYUlZNEFZQzhTNkxFVVhzNDFKREVkQ01TaGJGZWlMNEhZY21vMUVNN0U5cVpicXpaV0g3RG1rUi93clhWcmlubWgvWlBLRGJQdUpOOUlYUWhXMkFubU9OMjRBVk9lMnp2YUtBQlNobDRNWVdBOTdmRQ==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=djU0OCtyWkdrMC9vRmNnbHdGektUVG5PdUlEaXNKUG9jL0JrV0t3ZzZnUklKUWQ2M3pkYXAxOS9oaU9tYkpmRQ=="
},
{
"server": "Episode 10",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZExySXZEUkJUaktxSWlWd3BXOHp1d0tvMlZGekxHa2ZCK3lpYkpzTVVEc2FKcTZjbXl6L2ljaGlCNThSRzVFUEZnUmg5ejd0cm1rZTh4QkRSVmNJd2hVS0wwRW9vYmJicXNVamZRTldDU0V0VGZBTjhmUzhVUm85TnNhbTcrQTRWalVBdUpWbkIwSnhmOHRWTzl4ZVN1bA==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=aEZoSFlxZHRiK0F0OWtCSmxDOVRZdFE1VnlwaUZnOWozYUg2WDNNd0lzcnJ4bjNzVlY5akZ6TmI2NmNNNURrNw=="
}
]
},
{
"quality": "Season 1 {Hindi-English} 1080p 10Bit Esubs [970MB] - Episode Links",
"driveseedRedirectLinks": [
{
"server": "Episode 1",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEptWXBMMVZiYzVaZFYwYXp5emZBUjlkcmp5eG9PT1hYQjR2czJ1ME5MVmRyK2JtT0ZXci9uY1NVVEIvTFZ0WjVtUTR3ZzRqSFgwS3hhaWhseHpYWVFzOXpENS9ySlJ3U3AwbkRQdGR5cTVML1p0dzRVcys1V2oxUllZNU1CUXgxN3QxeUgvN01PYjNTN0JncE1nMmhxTA==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=VlFVOVp3RThlc1phanBHdURQdm9HVVo2ZytmT1JqVGxkR0lqUS9ZUXBaLzE3RlhaL2JNbkxQcVV4SkJvNWY2dQ=="
},
{
"server": "Episode 2",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZExrc3ZYTXpxNWJoRFJFSWVjTFFTWXB4TWdaTUlhbFJUTW5MVEJhSm1oWDA5SmJLNGhxcjNnbFlHS1o3ZUZZVlE1U1BGaC9CWUlOTmhyWjZYazNsOHZudHkvQTBmNzFXd2NWcnpaUHlrQy96RWYrQ1dBVUVJdmtXelRnNis2ZFM3ZFI5N1FTdVd6VnlPZUF3Znp4ckZJaA==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=czB5SG9hL0ZLaXY4dEJMdy9yQVZvckZTUmNaOU5MWW0yZjgxR3BZeUpIWUFxWHhNOGFwcDU0K1ZJYVdQL0ViUg=="
},
{
"server": "Episode 3",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZExFWGtXbkhCbUFBN1Z1ZEZJRXEvQ1BNVUZuZkczWXFVVjVFWjBoc3FqTDlrVklPT0VMNkRTbGpOenA2K3pzTWV2cnpqeUNBb2hsT0FvVmJmZDlSdFYxZkhaZGhPTldVakpBVzlQeXJsVTRMWXZDaHJIdzU2N3RPMDV5M1ZDaCtGQkFneE56QWp4Sk5QWndBUDY1QmZ6Zw==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=K1VYdWloUnluSThFeFJiQkxkWS85VFJvT1JkMyt1MUNDYUZTUkthYXdzMDdDUS83WEZ3VXdiOU9SakRTODg0OQ=="
},
{
"server": "Episode 4",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtlV0Z0ejRaQS9vT0dwMWNGZzhQR2RlSnR2Y09PQy9BTlc3RGVSMjUwMEVJT0lVV2oremZsV0JSd0s1SThqTFJIbEk0SERxM2pDQUZTTEV5R3dsVXk0WnNUbXIrNHl5YmdhS00yRWJRSUpnbDllUzRDWVlZalRjcEZZcGd3UmdvRitabnNTcHlZVWJBZWtTYzlTcjNxMQ==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=dXZEZFVPeXNnbzkzNjJPMFM5K1dkbGZGNXY5RzZZODYrRTlsZ2lCYzl5UkhWRTZXYTlBbjYvV0RiQUFLNFhoUA=="
},
{
"server": "Episode 5",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEsrVkd1SkIyNnBnTVp2ZEJTcGJTMGNLem1Ja0JuMHlDUHQ1QTJYa20zVWdwL0I4VFhkaVNEdWNDZ2l2RkphWG1OQmYrWmhnRVhVL0V0RDBNRHZhNFNyU0JqWlV6K1FiMmxFVCs5N2p2YlV4eEh2RHUra0lrOGtkY3hRL1k2Sm1qZmlxRkROWEJ5cWw5bVMzYjMrbWt0Yw==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=TUNyZGxZb1NRN3lseTZGRjFFRnhuY0dLUEhNL3VBN0txMElqVWF3eDJrS3ZXUy9GUHIxTXB6ZUduRlB5eHRITQ=="
},
{
"server": "Episode 6",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEwxdklkdSttMFBENTBOTGlkOHE2Qm5zbU1VUlM1WFFqSnB6NkRRd2xTY2F2WVpaNGkzY0xzelZ1Wk9RNXZRTUR0MTJWWDRCZm82bUd2T1RDUllzZzcxNER0cXQyTzlaTlhNWmVCaENhcnRqeDRCM01rbU5UdmpweVl4cnVuWWFjK3NncnBlVlRiTHEvbHZYL3JzSTEwaQ==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=bzJpL3ptZ1V3UTJEMHRrcGJqVlVEeDJOdFp6S2pGY3VFSjd6ZUNXSmZKT0N5L1pGZFFkMGtnbW0vZlRsN2swbg=="
},
{
"server": "Episode 7",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZElVS0FUQWdMcm5hVTE4Njh5NlVBMTFzMjJxcEsya0ZzT1pRMkZ6N092bWZUbTg5UHJPV1pPdm9YQ0tpNnNJNldnU01BOWppaUdTaW5zWVhQaU9qMXFiMVVISzZZNG8rTzY3WjI4Y2JQZStudzRGa3MxSmtKbWJXRTg0dmp2M0NENTNJaGtYZlUvNzhNemt2RFFsTEhlKw==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=S213TDNGWVduQzE5SnVvS3Y2VWtLeWlkTmpNMlEzMUswb3NiQ1ZUL3h2RGorcXNmQm0xTjBWRzJwSTdxVWkzVQ=="
},
{
"server": "Episode 8",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEl4bG05d2IzR05OLzNhY3VXYjVwL2xtZWNvanhmYVVCVk9mcklVdi96RW5xUW8wODMwZ1YwOEJibjgwaVZreU1ndGgxbzhJUUF4TTNXN2kvRVR5Sm9kY0VDdTlhenp0OGk5M1d1UzhhQTRhWHRNOUo0djNiQzFzNDExMXRuL05zb1Q2Y3ZhckJmcTV6QmhqOGxDRkUvOA==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=SmJudHFnUjBpTnFUUjhDYWZuaU4vSXBrN2xzUUYyb0ZiN3ZTeGlTS1N4UzF4Q0xLc2VHK1FoK1ZGSkQ5dXU5TQ=="
},
{
"server": "Episode 9",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEx1akRqKzRTOXIzNUVzbE1VVEtNSGt4OVJDV0xnTTkyVlo0S09udFcrbmU0cko4R1NWM2hGWmV6UXRvV01lQ3hxN1V3L3VKY3Q3YlMxazRZRHBNRSs4Y1RRQ2owZ1VjelJESGp3WXRiRGdmcGVOc21YVlhuT21QQW94MFhONy9KWTcyVnVtNnExTUlKTHlKNlQ0d1NIUQ==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=dHNReW9XQTM2emQra05ET3FZbmFrNEN4RzloUkdxQW9sYW16K0NTU2MvTWg2VUxpZTBnYTZNYW92bmdEZmtEdA=="
},
{
"server": "Episode 10",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtpYTJKdlJ3c1F4R3grd1FDV3JpWnhPbEdyWjV2RnhQT2VEQWY4SXE1K0NVajI1aFgvK011am5JUWdPaXo5K0gvRVZGWDJiaGZUZDJPVEZKRWpOOE1oUE03NlgveFlLamNLMXA2UE9seWJma3cwanZmWDFtTy9XVnZyck9DbHRPdVczSVB6K3g2TEI5aCtEa0RnM1pjQg==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=Q3Y5TXdaMVpSNHpsVTRnWGpDMncxeVIrNXMxOVVmOGdNUXJadFcyb05GL2FPRFdweWlDNUZiS2srcGxTL2x5aw=="
}
]
},
{
"quality": "Season 1 {Hindi-English} 1080p x264 Esubs [1.2GB] - Episode Links",
"driveseedRedirectLinks": [
{
"server": "Episode 1",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZExZWXo0Mzh6anRBc1k2OWljeXFiYkdXSHEyV1lYMFdDVk10VTNkNkJCanZoSEtWd2g3aFYxdERITkx6OUlsalErYWRKcGtCVFNUbjFGVWEyLzNva251a2tmODhYZUZOallmN21TVFBVaTEzSWhwbGlVV2ZvSGtSTTBqZk5uMm9hdENIZmI5VjBwRXVSY2xrajQ5Ni9ZVQ==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=KytGSDUxVkV2Y2RSRUxoTXhwWnNYNlJBa3JWU29EeEs3cFFCZkxOTWQ4Vy9rVkZXV0pOMHU1NEJ5S2JvbVY2VA=="
},
{
"server": "Episode 2",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEx5ME9yM1lWdHIvTGNRejJnSDB1Y0hGVXg5UXMxblU4VEh4aVFBUVFVNk5US3FEYXVEdW1iaEN3NkdyN2FyaDNucGxGbThtQ3VSa0IxN1hmWElsditkRUJpei9aWVA0RWpHd1dOQWQyOVM4Sk1FTzQyYlRYZ2V6eHUrTjVDWVZlTmFmdG5yMjAwdnoyUGs1VHhwWGZYMA==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=VEdRMXJPeHVSZXJTckY0eUxjdDJ1TThKQVNvVUUySWRxdjBwUjNDRGU5SUc5TnlHZzRobWhmay9DOG9Bdnd6OQ=="
},
{
"server": "Episode 3",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEpwRStQMTBhangzQkU1MW9lcXB1RUlzMHh1WTBrdmVjaHpqMlpuYkEraDlUQ0gybmV1WlVjQ3cwd3p1ZDM5MmZhV0NIUEpoWWM2dGZxczRIZnZNQkV5VmVZMVF6VWd2STFUM3E1WWdBb2swUCtUUmZzMEoxSTY5OG1Xa29RRlR4bjF4RzBBeHlsSkxGY3hrM0s2WHBEdQ==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=NDRCaWx1RTM3SWNmN3QrSE9iQ0pKQUJoNzh6VGVlYVBKdmZVUDcwVXJGOGJ6TzIycDI5cnVNY0NzU1lwc1Znbg=="
},
{
"server": "Episode 4",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEwrN2w0MHdjTHpTenJzRjByVlU5eUh1WEhCbDhaYzc5M2I0S1lsS3Z6Qy94OEtkaU1ybnlmNFV1VkFaVVUwMHUwSmkzZzJ1ZjNydkRYQTNFdWpMUWI0cit0S0JHT1Fwd1VibFNxRUNoL0NJVjBBTGpiTGFBUFhvcGQxY2xJT0VnU1o3ejQrQnNzZFVqdHR0MGhHTjRpNA==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=a21MUG5FTFFlZURiZXRRaU5kS0pZYWNodFlMWUl0K09CU080WDhhMnFWbEp0YnF5d0lSaGRJRGw2U2d0bDIxNw=="
},
{
"server": "Episode 5",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEpDaTVoNkQvOVI4UnRNRzF3S3BYOWgrV25md0xnUzhINHZQbDZyV0xOallqb1FOeVRWaVpjWExvY0hFejhKVjFxVjJvb3Z2SUc2ZWNiaVowYWdxZVFOVWl3SXV6UlIyaWloOGFmTGx6SGdLWjNBWGZ6N2JRVGVPNDlWSlNpcHN3YkhuMEFpM3hzdjU3cHE1TTd5NzJqRQ==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=MUMzWENQeGFWUzhlOXpWNkQ0ekNqR0RuQUJPNG5xZktiSlZnbFFodkJpczY4Mm4vbTB0dUU1ZERWcjhvSVhWRg=="
},
{
"server": "Episode 6",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEpnd2pDOTBlVWhhUTZzOEJRTWhERVlTWkJ2Z0J1MTRFRisxdGczQ2VXSTY4dmNyeDRxMi9UU1Y2ckRsRllnL0wzN0MrZFVKZWVsQmYxdjFMYmhhVjd5SnplL003bnFlbXRFLzJZSjJSWjR4SVNPUlpULzZNYWd0TG9NWWhmemk2MzZqcHd5Qk9wVENRd0JxeHRzRlRmQg==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=WHByMlZFUCtUVkhMSkFEaTY5UmtmNWQzRWxuRVVsZWZWNzJmVEE5dlg5NjgzUXlKeDNVbnZmVCt2VjZFNnZ0dw=="
},
{
"server": "Episode 7",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEowUFJJRWdlWHl6TGZnUXJuczZhL3RPdVV4R1ZzTEJydE1xTUJxTXFSSmtaWkoxd2lReEl5bER1cmRBQ0ZETisrSHZ3MEp3QXRnRVZCd1dPdEMyWHltUGgwUURMbnhvbEFzY0xZMjhLUWIvMi9FOGNkR20vdnhDOFd4U0s4dXdzTkJxODBJbi9IRzJmVitPTXYxZUZGQQ==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=VXQzT3VWZ3R3NStPYXlOTDBNSjNEYkpVYmJnM1k1VTg1WXpldUEzMEZoWWtJWXdVUncrUEduWCtWeEp1Qi9nUA=="
},
{
"server": "Episode 8",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEpJNzhNdUxFQmM4bXA5Qm51eU14RDdFZzVhSEwwNE1weHZPajRzSEJwQk51djJsVnZJZGZQY1JZQmRvdHdjZ1RyS1RMUVRGZEVwYzdndUE3dUpudDAvMkV2bEo3NW0xRmRLMjVjWHJRR2I1Z2NyVVZPSTQvWkxZQi9neEtPZG4ybXRNdk9xaGUxNVdSNUpyMUhLNmVPUw==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=dTJYSExoSXBjTGZkTTBjZWNINUNuVFVLMlZEazR2SWE2cjdpWFVzd09VY1FpRFFjTytOWVV6MGt4a2pCazgxZg=="
},
{
"server": "Episode 9",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEpJSTROcHA5UmV4cXhjYTFmQVMvZUNKZmNtV2lHYnpHakFiaEJLSDRseUdYa3BNdmN6R3loOUEvYlViNlExS3JnM0ZPK1JpSzY1SHpuN2s2MDZuYkh0a256YnhyUnQxU2VaWlVDV1Y5cVo1VUlnMGxIWmRaY2I0TUR1SHJUQ0pvUUNrdys4VWp0TWhha0p2bSs5TjQ2WQ==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=enB3enJJeE9HeG04cXBoVkJhL1V3ZWQyVlpPU0Q3NHRXUWJiWmlFVGdCZlN0UGtaalFwYnNsMkh5Mm0xT29jRg=="
},
{
"server": "Episode 10",
"url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtraXJtMzcwWWYzL3F5M2YzcjRFOUxIenVQY3dvTld6Sk9pakxocHpaSDEyNDNOVHZ2WUVUNnRCZTIxVEgwbTBQZzRJSU1BbkozSEpJa0FXbzdPSFlNZzREUVlsaUNDa0Nxak1CSlVlSUN4ZE1kWUNvU2hwVjVwdVJvSjFqcGNPaXplakE5c1lxM0pnNXh5OFEvc09ZVg==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=QmpLVFI1c3U2bnM3bTEwQU4wV3E1WnFMa3RxMVhscS9la2NqQUhjTmhjdXZXVEx5Mm9Xa1lsNjlSVVpZajdvYQ=="
}
]
}
]
}
@@ -1,64 +0,0 @@
{
"data": [
{
"quality": "720p",
"driveseedRedirectLinks": [
{
"server": "✅ Fast Server (G-Drive)",
"url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtpNjQ1ZFhZeDl4NlZVcm9rQ2lsL0hCM0k3VytEUzRpWWMvZ1FBZlNqRDhrTE5wQVdjeHNQYzJiRG5FMDJWd3lGSXc1LzFPT0hVWFlaWTBZOGw3aDN0V1lkNDVpK0NZVjFXLzh0UGZLSzUydUU2VW83U1YwRWJvdkhVMnh1MVk0Sk9tUm9Ra2FHWVpCQXZpS3R1RGdlNA==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=MkR2QTY2K0pua0xqOS9xa0pmNVIycmNiTndtQzBxbGJ5VU5vVnU0eTh3RU9ML3AydUlJU214bUV5cGx6Rlc2cw=="
},
{
"server": "🚀 Google Drive (Server 2)",
"url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEo1Qm4wbW1FSnJlWkpuWWoya0JZU3VPbXVCMTdlOFNlTEpycW9nUUpPN1Ric0lnbm5mVGQxS1FGdGFjbHZ5WHN1VllwMS93QXdoNzdYdE15Z1VuQkl5TStmTUpaVzA2dWdxSEZ2WmhxaFZaS3JML0RxQ1pTNlY2eUdzbjcrMFBBSit3TnlGRmNlamxvQXJISTNNS1Y2RQ==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=RURQY0lpbE1IWlNaZDhkNld1MFFnSEQ4V0xXNFJEeHZNNGFSZ3lnUW54aDZTLzUrRXdhVVRLaEhITno1ejFYdw=="
}
]
},
{
"quality": "1080p",
"driveseedRedirectLinks": [
{
"server": "✅ Fast Server (G-Drive)",
"url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZElqenM4UmhUeEJKTlpncjJnbVR1aldlTmZIb0kzcStJdm9vMGx6UmtGWUtKMjBWMXdYM1o5U3pseEJJMEMvN29McW9qeXZrZTVEa1F1ejlFbUgwRFBJb3dDTTV5TVoyVktJOGk3eEZYUys3Y29sQW5GcmtqaXZEMk9MSk1JWm9JSVlVTWdoSWdVQWNiQnpEYXp6Q054Vw==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=dHV1dW9KeTlVMEM0UERzaVFaRWVTelN2TlVEUG5IUFdsSFdDYk4vZ29WamhPZThPcTBRRk9oc0lhTnppSlN0ag=="
},
{
"server": "🚀 Google Drive (Server 2)",
"url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtSYVErY0dNVXJDenhFZzFHZ05mR0ZOWWJ1eWJCNEgvdWtFRTlwY3orekF4QS84LzR1enRuTnpxMFZLT0ZGYkxVdXNuTHNWUklUUDh0SEkrYlYrbHI5MUFRcUo1UWNRSm93b2FScnA0YVU5T3dFeENHa2xHcjhYSXNBcXpodkE0alpOMW85L0ZoVS9MSzRFY2trS0NnTQ==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=dVNjL3hNRXhseGRrenJhQzFwQ24yekphRXhyL1JtUzBxUXlCTVgzUVNOSHRmbzhKK05BU3FjT0Q3MFhrMzlRYw=="
}
]
},
{
"quality": "720p",
"driveseedRedirectLinks": [
{
"server": "✅ Fast Server (G-Drive)",
"url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEsrRk5KdUcxZG1IblE5T2d2cGowNW9mT2dLd3ZHK0tzeXp1TnJVZGs0cGs1Mmp6d1kyK1lMY1lERitNL2dlNUtlMGJxa0JaYncrRFNzeVlZOEo2QUJLc0RWTGtuRVI2TTZ4Mk1hUVZCQTVlTUo2d3FmcUVrbUFOQnY1RUNFd3J1TmxHTnQvVE5yL1BoNkkwaHVrdVBiZA==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=ZjU4U21qeFVnN2x1RDhVbm55VHFJUWU1b2JHVEljRm96QzcySzV0NFZqRU1HU05uSlN5ck00TUs3bnFRS1ljWg=="
},
{
"server": "🔗 Gdrive Links (Login)",
"url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZExBSThhUFBxd1BlaE81V0UwOCtVUGphK2lFL00xNXJ1OEQyaGJHckRxSi9SelBiNTFMQ3IzNENPWXhoeDg0SjRGMmo4WTFLMVYyOGhRWXVjSDNkajAramZtMHF6dHFpd2NqZGYwWTE3aUxqcGxYbHJyc2xHWUw0anNXUmpUS3E0SFVZc2cyU0RJVEl0Ky92SThreVVLdg==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=Z2luaGp1aXZ4WXkwSnFBU3pyZWxiU21Mb015bldhdTkzd1JTMkY5bU1CVVB3Q05sUTd1NlRKbHZJSUNnanREUA=="
}
]
},
{
"quality": "1080p",
"driveseedRedirectLinks": [
{
"server": "✅ Fast Server (G-Drive)",
"url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEpxbCtGRHB6dmUrTUp2ZUl2R3pHVGhyaDFTVUJCTDhsTnBTbXBmSFRwZ3BVUk5tS0xGRVJJd245eFgzanlKZ0Q4SzlPakFDQzNZZHhBdFVleFNCL1p4UGpxd1hFWUdXNXBWSm5XQ1FQWERXcDE1RSsrTjBVNGVmeHR6aDFwbGNrbkJSL004T1d2dTJ2MHlrYkhGSmlIQg==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=alBtU2J0bGprbXYxbzhJcmwrTXc3ZjhDMFhFV0xxZ25ocUliR2NZbkcxMkp5RER2QmlMNjNBWmxEZXhoeUpaRA=="
},
{
"server": "🔗 Gdrive Links (Login)",
"url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEpPSnl1Ri9xazhmcVUwakZydFg2NFZVUzJRbUxqdjkvSktycFBKWmhML2F5VXpYMCt6c1draXQxVGYvWEhLK0xwNVJVTVZQSlRiWUtHTUd2TmNuSytybHd0czhlcFdwM3cvZnZnZ1YrcmNhTUdDSUxabU1nZ04veXlCYUIrSFIvbkJmSWpmSkFkOFVHTDJMVk5ibkw4Lw==",
"driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=Q0o2RUdsdE9iZDhIYlQwMXlRdjEyMlA1NEVKZkRmRUNYZTcwdjNGa3RPa0xHZ29Na0taTkM4T2ZjWGZmRWxkQw=="
}
]
}
]
}
@@ -1,4 +0,0 @@
{
"showboxUrl": "NO_URL_FOUND",
"timestamp": 1757925353144
}
@@ -1,4 +0,0 @@
{
"showboxUrl": "NO_URL_FOUND",
"timestamp": 1757926777078
}
@@ -1,4 +0,0 @@
{
"showboxUrl": "NO_URL_FOUND",
"timestamp": 1757926668402
}
@@ -1,4 +0,0 @@
{
"showboxUrl": "NO_URL_FOUND",
"timestamp": 1757950186614
}
@@ -1,4 +0,0 @@
{
"result": "NO_MATCH_FOUND",
"timestamp": 1757950186613
}
@@ -1,4 +0,0 @@
{
"result": "NO_MATCH_FOUND",
"timestamp": 1757926668401
}
@@ -1,4 +0,0 @@
{
"result": "NO_MATCH_FOUND",
"timestamp": 1757926777077
}
@@ -1,4 +0,0 @@
{
"result": "NO_MATCH_FOUND",
"timestamp": 1757925353143
}
@@ -1,10 +0,0 @@
{
"id": 1263256,
"titles": [
{
"iso_3166_1": "VN",
"title": "Chàng Happy Gilmore 2",
"type": ""
}
]
}
@@ -1,8 +0,0 @@
{
"id": 1263256,
"imdb_id": "tt31868189",
"wikidata_id": "Q130269576",
"facebook_id": null,
"instagram_id": null,
"twitter_id": null
}
File diff suppressed because it is too large Load Diff
@@ -1,58 +0,0 @@
{
"adult": false,
"backdrop_path": "/x5dVPttNDZaVRTvbk7pYrtGZoZN.jpg",
"belongs_to_collection": {
"id": 1263259,
"name": "Happy Gilmore Collection",
"poster_path": "/7nUOrnZHSgnhagLtydIYbD4rrDY.jpg",
"backdrop_path": "/mhrE9ij30cIvPFVFRXZSwwTchUg.jpg"
},
"budget": 152000000,
"genres": [
{
"id": 35,
"name": "Comedy"
}
],
"homepage": "https://www.netflix.com/title/81696722",
"id": 1263256,
"imdb_id": "tt31868189",
"origin_country": [
"US"
],
"original_language": "en",
"original_title": "Happy Gilmore 2",
"overview": "Happy Gilmore isn't done with golf — not by a long shot. Since his retirement after his first Tour Championship win, Gilmore returns to finance his daughter's ballet classes.",
"popularity": 24.4786,
"poster_path": "/ynT06XivgBDkg7AtbDbX1dJeBGY.jpg",
"production_companies": [
{
"id": 878,
"logo_path": "/s5j0xnTXvglZoz49CUaQclVv3s9.png",
"name": "Happy Madison Productions",
"origin_country": "US"
}
],
"production_countries": [
{
"iso_3166_1": "US",
"name": "United States of America"
}
],
"release_date": "2025-07-25",
"revenue": 0,
"runtime": 118,
"spoken_languages": [
{
"english_name": "English",
"iso_639_1": "en",
"name": "English"
}
],
"status": "Released",
"tagline": "Happy Gilmore returns!",
"title": "Happy Gilmore 2",
"video": false,
"vote_average": 6.673,
"vote_count": 712
}
@@ -1,305 +0,0 @@
{
"id": 1893,
"titles": [
{
"iso_3166_1": "US",
"title": "Star Wars: Episode I",
"type": "working title"
},
{
"iso_3166_1": "US",
"title": "Star Wars I: The Phantom Menace",
"type": "video box title"
},
{
"iso_3166_1": "CZ",
"title": "Skrytá hrozba",
"type": "short title"
},
{
"iso_3166_1": "FR",
"title": "La menace fantôme",
"type": "short title"
},
{
"iso_3166_1": "FI",
"title": "Tähtien sota - episodi I: Pimeä uhka",
"type": "TV title"
},
{
"iso_3166_1": "DK",
"title": "Den usynlige fjende",
"type": "short title"
},
{
"iso_3166_1": "RU",
"title": "Скрытая угроза",
"type": "short title"
},
{
"iso_3166_1": "ES",
"title": "Star Wars: Episodio I - La amenaza fantasma",
"type": ""
},
{
"iso_3166_1": "US",
"title": "The Phantom Menace",
"type": "short title"
},
{
"iso_3166_1": "HK",
"title": "星球大戰前傳:魅影危機",
"type": ""
},
{
"iso_3166_1": "US",
"title": "Star Wars: The Phantom Menace",
"type": "iTunes Title"
},
{
"iso_3166_1": "TW",
"title": "星際大戰首部曲:威脅潛伏",
"type": ""
},
{
"iso_3166_1": "KR",
"title": "스타워즈 에피소드1 보이지 않는 위험",
"type": ""
},
{
"iso_3166_1": "HU",
"title": "Bajlós Árnyak",
"type": ""
},
{
"iso_3166_1": "BR",
"title": "Star Wars: A Ameaça Fantasma",
"type": "short title"
},
{
"iso_3166_1": "NO",
"title": "Star Wars: Episode I - Den skjulte trussel",
"type": ""
},
{
"iso_3166_1": "FR",
"title": "Star Wars - Episode I - La Menace Fantôme",
"type": ""
},
{
"iso_3166_1": "GR",
"title": "Ο Πόλεμος Των Άστρων: Επεισόδιο 1 - Η Αόρατη Απειλή",
"type": ""
},
{
"iso_3166_1": "CA",
"title": "Star Wars : épisode I - La menace fantôme",
"type": ""
},
{
"iso_3166_1": "CZ",
"title": "Hvězdné války: Epizoda I - Skrytá hrozba",
"type": ""
},
{
"iso_3166_1": "KR",
"title": "스타 워즈 에피소드 1, 보이지 않는 위험",
"type": ""
},
{
"iso_3166_1": "FR",
"title": "Star Wars : La menace fantôme",
"type": ""
},
{
"iso_3166_1": "SK",
"title": "Star Wars: Skrytá hrozba",
"type": ""
},
{
"iso_3166_1": "SK",
"title": "Hviezdné vojny: Epizoda I - Skrytá hrozba",
"type": ""
},
{
"iso_3166_1": "RU",
"title": "Звёздные войны: Эпизод I - Скрытая угроза",
"type": ""
},
{
"iso_3166_1": "RU",
"title": "Звёздные войны: Скрытая угроза",
"type": ""
},
{
"iso_3166_1": "UA",
"title": "Зоряні війни: Прихована загроза",
"type": ""
},
{
"iso_3166_1": "IT",
"title": "Star Wars - Episodio I - La minaccia fantasma",
"type": ""
},
{
"iso_3166_1": "DE",
"title": "Star Wars Episode 1 - Die dunkle Bedrohung",
"type": ""
},
{
"iso_3166_1": "JP",
"title": "スター・ウォーズ/ファントム・メナス",
"type": "iTunes title"
},
{
"iso_3166_1": "KR",
"title": "스타워즈 에피소드 1 보이지 않는 위험",
"type": ""
},
{
"iso_3166_1": "US",
"title": "Star Wars: The Phantom Menace (Episode I)",
"type": "Disney+"
},
{
"iso_3166_1": "CN",
"title": "星球大战前传:魅影危机",
"type": ""
},
{
"iso_3166_1": "PL",
"title": "Gwiezdne Wojny I - Mroczne Widmo",
"type": ""
},
{
"iso_3166_1": "TW",
"title": "星球大戰前傳:魅影危機",
"type": ""
},
{
"iso_3166_1": "FR",
"title": "Star Wars, Episode I - La Menace fantôme",
"type": ""
},
{
"iso_3166_1": "CN",
"title": "星球大战1:幽灵的威胁",
"type": ""
},
{
"iso_3166_1": "CN",
"title": "星球大战前传1:幽灵的威胁",
"type": ""
},
{
"iso_3166_1": "CN",
"title": "星球大战前传:幽灵的威胁",
"type": ""
},
{
"iso_3166_1": "CN",
"title": "星球大战:幽灵的威胁",
"type": ""
},
{
"iso_3166_1": "CN",
"title": "星球大战前传1:魅影危机",
"type": ""
},
{
"iso_3166_1": "CN",
"title": "星球大战:魅影危机",
"type": ""
},
{
"iso_3166_1": "FR",
"title": "Star Wars, épisode I : La Menace fantôme",
"type": ""
},
{
"iso_3166_1": "HU",
"title": "Csillagok Háborúja I. - Baljós Árnyak",
"type": ""
},
{
"iso_3166_1": "GE",
"title": "ვარსკვლავური ომები: ფარული საფრთხე (ეპიზოდი I)",
"type": "Disney+"
},
{
"iso_3166_1": "GE",
"title": "ვარსკვლავური ომები: ეპიზოდი I",
"type": ""
},
{
"iso_3166_1": "GE",
"title": "ვარსკვლავური ომები I",
"type": ""
},
{
"iso_3166_1": "GE",
"title": "ვარსკვლავური ომები 1",
"type": "short title"
},
{
"iso_3166_1": "GE",
"title": "ვარსკვლავური ომები: ეპიზოდი I - ფარული საფრთხე",
"type": ""
},
{
"iso_3166_1": "GE",
"title": "ვარსკვლავური ომები: ეპიზოდი 1",
"type": ""
},
{
"iso_3166_1": "IL",
"title": "סטאר וורס פרק I: אימת הפאנטום",
"type": ""
},
{
"iso_3166_1": "VN",
"title": "Chiến Tranh Giữa Các Vì Sao 1: Hiểm Họa Bóng Ma",
"type": ""
},
{
"iso_3166_1": "ES",
"title": "La amenaza fantasma",
"type": "Titulo abreviado"
},
{
"iso_3166_1": "MX",
"title": "Star Wars: La amenaza fantasma",
"type": ""
},
{
"iso_3166_1": "JP",
"title": "スター・ウォーズ/ファントム・メナス (エピソード1)",
"type": ""
},
{
"iso_3166_1": "US",
"title": "Star Wars Episode I - The Phantom Menace",
"type": ""
},
{
"iso_3166_1": "DE",
"title": "Star Wars - Episode 1 - Die dunkle Bedrohung",
"type": ""
},
{
"iso_3166_1": "IL",
"title": "מלחמת הכוכבים 1: אימת הפנטום",
"type": ""
},
{
"iso_3166_1": "SG",
"title": "Star Wars Episode I:The Phantom Menace",
"type": "HK & Singapore Style English Asian Font Set"
},
{
"iso_3166_1": "UZ",
"title": "Yulduzlar jangi-1: Yashirin tahdid",
"type": ""
}
]
}
@@ -1,8 +0,0 @@
{
"id": 1893,
"imdb_id": "tt0120915",
"wikidata_id": "Q165713",
"facebook_id": "StarWars",
"instagram_id": "starwars",
"twitter_id": "starwars"
}
File diff suppressed because it is too large Load Diff
@@ -1,66 +0,0 @@
{
"adult": false,
"backdrop_path": "/wDe8LzwuvHYYiuwyNfxdYQq8ti4.jpg",
"belongs_to_collection": {
"id": 10,
"name": "Star Wars Collection",
"poster_path": "/22dj38IckjzEEUZwN1tPU5VJ1qq.jpg",
"backdrop_path": "/4z9ijhgEthfRHShoOvMaBlpciXS.jpg"
},
"budget": 115000000,
"genres": [
{
"id": 12,
"name": "Adventure"
},
{
"id": 28,
"name": "Action"
},
{
"id": 878,
"name": "Science Fiction"
}
],
"homepage": "http://www.starwars.com/films/star-wars-episode-i-the-phantom-menace",
"id": 1893,
"imdb_id": "tt0120915",
"origin_country": [
"US"
],
"original_language": "en",
"original_title": "Star Wars: Episode I - The Phantom Menace",
"overview": "Anakin Skywalker, a young slave strong with the Force, is discovered on Tatooine. Meanwhile, the evil Sith have returned, enacting their plot for revenge against the Jedi.",
"popularity": 7.5815,
"poster_path": "/6wkfovpn7Eq8dYNKaG5PY3q2oq6.jpg",
"production_companies": [
{
"id": 1,
"logo_path": "/tlVSws0RvvtPBwViUyOFAO0vcQS.png",
"name": "Lucasfilm Ltd.",
"origin_country": "US"
}
],
"production_countries": [
{
"iso_3166_1": "US",
"name": "United States of America"
}
],
"release_date": "1999-05-19",
"revenue": 924317558,
"runtime": 136,
"spoken_languages": [
{
"english_name": "English",
"iso_639_1": "en",
"name": "English"
}
],
"status": "Released",
"tagline": "Every saga has a beginning.",
"title": "Star Wars: Episode I - The Phantom Menace",
"video": false,
"vote_average": 6.566,
"vote_count": 15219
}
@@ -1,110 +0,0 @@
{
"id": 278,
"titles": [
{
"iso_3166_1": "SE",
"title": "Rita Hayworth - nyckel till flykten",
"type": ""
},
{
"iso_3166_1": "CN",
"title": "肖申克的救赎",
"type": "Mandarin title"
},
{
"iso_3166_1": "GE",
"title": "Gaqceva shoushenkidan",
"type": ""
},
{
"iso_3166_1": "AZ",
"title": "Şouşenkdən qaçış",
"type": ""
},
{
"iso_3166_1": "RU",
"title": "Искупление Шоушенком",
"type": ""
},
{
"iso_3166_1": "AZ",
"title": "Shoushenkden Qacish",
"type": ""
},
{
"iso_3166_1": "IR",
"title": "Rastgari Dar Shawshank",
"type": ""
},
{
"iso_3166_1": "IL",
"title": "Homot Shel Tikva",
"type": ""
},
{
"iso_3166_1": "JP",
"title": "Shôshanku no sora ni",
"type": ""
},
{
"iso_3166_1": "RS",
"title": "Бекство из Шошенка",
"type": ""
},
{
"iso_3166_1": "KR",
"title": "쇼생크 탈출",
"type": ""
},
{
"iso_3166_1": "FR",
"title": "Les Évadés",
"type": ""
},
{
"iso_3166_1": "PL",
"title": "Skazani na Shawshank",
"type": ""
},
{
"iso_3166_1": "JP",
"title": "ショーシャンクの空に:1994",
"type": ""
},
{
"iso_3166_1": "IR",
"title": "رستگاری در شاوشنگ",
"type": ""
},
{
"iso_3166_1": "KR",
"title": "쇼생크탈출",
"type": ""
},
{
"iso_3166_1": "BR",
"title": "Um Sonho de Liberdade",
"type": ""
},
{
"iso_3166_1": "TW",
"title": "刺激1995",
"type": ""
},
{
"iso_3166_1": "AM",
"title": "Փախուստ Շոուշենքից",
"type": ""
},
{
"iso_3166_1": "AR",
"title": "Sueño de Libertad",
"type": ""
},
{
"iso_3166_1": "BY",
"title": "Выкупленне з Шаўшэнку",
"type": ""
}
]
}
@@ -1,8 +0,0 @@
{
"id": 278,
"imdb_id": "tt0111161",
"wikidata_id": "Q172241",
"facebook_id": null,
"instagram_id": null,
"twitter_id": null
}
File diff suppressed because it is too large Load Diff
@@ -1,57 +0,0 @@
{
"adult": false,
"backdrop_path": "/pNjh59JSxChQktamG3LMp9ZoQzp.jpg",
"belongs_to_collection": null,
"budget": 25000000,
"genres": [
{
"id": 18,
"name": "Drama"
},
{
"id": 80,
"name": "Crime"
}
],
"homepage": "",
"id": 278,
"imdb_id": "tt0111161",
"origin_country": [
"US"
],
"original_language": "en",
"original_title": "The Shawshank Redemption",
"overview": "Imprisoned in the 1940s for the double murder of his wife and her lover, upstanding banker Andy Dufresne begins a new life at the Shawshank prison, where he puts his accounting skills to work for an amoral warden. During his long stretch in prison, Dufresne comes to be admired by the other inmates -- including an older prisoner named Red -- for his integrity and unquenchable sense of hope.",
"popularity": 31.7568,
"poster_path": "/9cqNxx0GxF0bflZmeSMuL5tnGzr.jpg",
"production_companies": [
{
"id": 97,
"logo_path": "/qv3ih9pR9w2XNKZDsqDqAGuZjqc.png",
"name": "Castle Rock Entertainment",
"origin_country": "US"
}
],
"production_countries": [
{
"iso_3166_1": "US",
"name": "United States of America"
}
],
"release_date": "1994-09-23",
"revenue": 28341469,
"runtime": 142,
"spoken_languages": [
{
"english_name": "English",
"iso_639_1": "en",
"name": "English"
}
],
"status": "Released",
"tagline": "Fear can hold you prisoner. Hope can set you free.",
"title": "The Shawshank Redemption",
"video": false,
"vote_average": 8.7,
"vote_count": 28866
}
@@ -1,25 +0,0 @@
{
"id": 293660,
"titles": [
{
"iso_3166_1": "VN",
"title": "Quái Nhân Deadpool",
"type": ""
},
{
"iso_3166_1": "CN",
"title": "死侍1",
"type": ""
},
{
"iso_3166_1": "ES",
"title": "Deadpool: 1",
"type": "Castellano"
},
{
"iso_3166_1": "DE",
"title": "Deadpool 1",
"type": ""
}
]
}
@@ -1,8 +0,0 @@
{
"id": 293660,
"imdb_id": "tt1431045",
"wikidata_id": "Q19347291",
"facebook_id": "DeadpoolMovie",
"instagram_id": "deadpoolmovie",
"twitter_id": "deadpoolmovie"
}
File diff suppressed because it is too large Load Diff
@@ -1,84 +0,0 @@
{
"adult": false,
"backdrop_path": "/en971MEXui9diirXlogOrPKmsEn.jpg",
"belongs_to_collection": {
"id": 448150,
"name": "Deadpool Collection",
"poster_path": "/30c5jO7YEXuF8KiWXLg9m28GWDA.jpg",
"backdrop_path": "/dTq7mGyAR5eAydR532feWfjJjzm.jpg"
},
"budget": 58000000,
"genres": [
{
"id": 28,
"name": "Action"
},
{
"id": 12,
"name": "Adventure"
},
{
"id": 35,
"name": "Comedy"
}
],
"homepage": "https://www.20thcenturystudios.com/movies/deadpool",
"id": 293660,
"imdb_id": "tt1431045",
"origin_country": [
"US"
],
"original_language": "en",
"original_title": "Deadpool",
"overview": "The origin story of former Special Forces operative turned mercenary Wade Wilson, who, after being subjected to a rogue experiment that leaves him with accelerated healing powers, adopts the alter ego Deadpool. Armed with his new abilities and a dark, twisted sense of humor, Deadpool hunts down the man who nearly destroyed his life.",
"popularity": 15.1616,
"poster_path": "/3E53WEZJqP6aM84D8CckXx4pIHw.jpg",
"production_companies": [
{
"id": 25,
"logo_path": "/qZCc1lty5FzX30aOCVRBLzaVmcp.png",
"name": "20th Century Fox",
"origin_country": "US"
},
{
"id": 431,
"logo_path": "/6dcR1MbRqYgt3jUVYxkHe68GFnZ.png",
"name": "The Donners' Company",
"origin_country": "US"
},
{
"id": 28788,
"logo_path": "/Aqomtf9oh5dKtxBNEagkdlp3aGv.png",
"name": "Genre Films",
"origin_country": "US"
},
{
"id": 7505,
"logo_path": "/837VMM4wOkODc1idNxGT0KQJlej.png",
"name": "Marvel Entertainment",
"origin_country": "US"
}
],
"production_countries": [
{
"iso_3166_1": "US",
"name": "United States of America"
}
],
"release_date": "2016-02-09",
"revenue": 782837347,
"runtime": 108,
"spoken_languages": [
{
"english_name": "English",
"iso_639_1": "en",
"name": "English"
}
],
"status": "Released",
"tagline": "Feel the love.",
"title": "Deadpool",
"video": false,
"vote_average": 7.623,
"vote_count": 31904
}
@@ -1,5 +0,0 @@
{
"tmdbId": "278",
"tmdbType": "movie",
"title": "The Shawshank Redemption"
}
@@ -1,5 +0,0 @@
{
"tmdbId": "1893",
"tmdbType": "movie",
"title": "Star Wars: Episode I - The Phantom Menace"
}
@@ -1,5 +0,0 @@
{
"tmdbId": "1263256",
"tmdbType": "movie",
"title": "Happy Gilmore 2"
}
@@ -1,74 +0,0 @@
{
"data": [
{
"quality": "Unknown Quality",
"size": "Unknown",
"link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzbjJiSzNaUWpVaG5QM1F2NGJZUjhRVT0=",
"rawQuality": "Unknown Quality",
"driveleechRedirectUrl": "https://uhdmovies.eu/1080p-uhd/"
},
{
"quality": "Unknown Quality",
"size": "Unknown",
"link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzaE5qZ1JnMXNxa1hHT1JiL3ZEZ2lNcz0=",
"rawQuality": "Unknown Quality",
"driveleechRedirectUrl": "https://uhdmovies.eu/movies/"
},
{
"quality": "4K | HDR",
"size": "16.68 GB",
"link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2o4SUZUQjVyK3FDd1MyUXhZQlJ3TFJsdTNiUHhwd1Q4QTVGRlpUdGQxNVpPd0E2YmlWVUJ0c0lXZU9Sa0s1eXVuT2prMEd5dTVEc0xCdHl0Q0FZTTd2Nlhad1pLTnZzODg5L2tWRDR5aGp3ZEpZL014N1RRVVZRYUpWRXg5ZjRGQUtGZDZOTHJ0QVp0MitQUDY4WmVqbA==",
"rawQuality": "Happy Glimore 2 (2025).2160p NF WEB-DL HDR 10bit HEVC [Hindi DDP 5.1 + English DDP 5.1] x265 (HHWEB-UHDMovies) [16.68 GB]",
"driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=dWFxZDQrS3RwK2dZZFVoUHBydmRxQVlORUVHQVc0NkFsRm02UDk3ai80YjZHbE85N2dOWWVZcUhrMVh3U2JONA=="
},
{
"quality": "4K",
"size": "11.14 GB",
"link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2dBcGU3S01vY1JIWkxlYnRZUlpscVFDNFIxbEpDeGtTWVFxNCt3dlVsampCNlhrdVJlUXU3VkZCQVZPL0ttd0hPZ2Q3eU5KQ1VGZVI4cW5ZbWxmNUNXWEt0ejRiTUVBQ3FWQ1RZMjBmV2tPMWdZRVNnQURYZjZSWE56cjJUYjNHbnQ1OUZ2NG96VVZUclJlNlZKSGx6YQ==",
"rawQuality": "Happy Glimore 2 (2025).2160p NF WEB-DL SDR 10bit HEVC [Hindi DDP 5.1 + English DDP 5.1] x265 (HHWEB-UHDMovies) [11.14 GB]",
"driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=UHBTVjR3T3IybXRMS0RjY01tK3FHMVJqbGNzdWVEMFczNjkvdjdpWUh2SHl5ekwwVEFnNHFNdllKRFg2Z015TA=="
},
{
"quality": "1080p",
"size": "5.28 GB",
"link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2hiSUN6VHNPMnIyK1o2NHV4VkVpQmVnUmRqUmRoOFh1UkpKZkdhY3JmbWxOeXdMU1c2SVdnb0FwTnh1b2EySDVVZTVOK1hwTVk0RTIwNEgvN21BcEp4STc1OHlpbUV0Ylh6c1pyc0V5VjFQTEttS3luUXZPL0ZTQ3pycTlhYXgwcGpjWDcyZFdENmdKam5DUmxXUmFKcQ==",
"rawQuality": "Happy.Gilmore.2.2025.1080p.NF.WEB-DL.DUAL.DDP5.1.Atmos.H.264-ShiNobi [5.28 GB]",
"driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=cW5YYzgyZ2IwdW9pWmdXakRIMTRad2xkV3l2eGxkSEZtc0FwUE8vSEs4cjJTNEZLVWIvTjZvaUVPeHQrZ3p5bQ=="
},
{
"quality": "1080p",
"size": "5.28 GB",
"link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzdldUTFJiZlVQZVg0V2JWNkRGRU9uM2RPcjB5UTRtWmxvUXF0OUVLWU8yYw==",
"rawQuality": "Happy.Gilmore.2.2025.1080p.NF.WEB-DL.DUAL.DDP5.1.Atmos.H.264-ShiNobi [5.28 GB]",
"driveleechRedirectUrl": "https://uhdmovies.eu/1080p-60fps/"
},
{
"quality": "1080p",
"size": "5.28 GB",
"link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzcGJmM0lkMWZ4Zyt1Q2xiZ3VlQThqcXlHbHQ2ZUNaejFqbElUa1lXZm9PSg==",
"rawQuality": "Happy.Gilmore.2.2025.1080p.NF.WEB-DL.DUAL.DDP5.1.Atmos.H.264-ShiNobi [5.28 GB]",
"driveleechRedirectUrl": "https://uhdmovies.eu/1080p-10bit/"
},
{
"quality": "1080p",
"size": "5.28 GB",
"link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzdlJ5d0FSNm5XZjFtTlkrM3FmOFpLbz0=",
"rawQuality": "Happy.Gilmore.2.2025.1080p.NF.WEB-DL.DUAL.DDP5.1.Atmos.H.264-ShiNobi [5.28 GB]",
"driveleechRedirectUrl": "https://uhdmovies.eu/4k-hdr/"
},
{
"quality": "Unknown Quality",
"size": "Unknown",
"link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzamFGMjVxNDJ0ZTc0RFM2M0pUNFdYTW1tRlNzbVl2Uzk0N3pDSHdoTmZFUQ==",
"rawQuality": "Unknown Quality",
"driveleechRedirectUrl": "https://uhdmovies.eu/2160p-movies/"
},
{
"quality": "Unknown Quality",
"size": "Unknown",
"link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzbDZUM21XeXB0Tzl6TTB6c1BDN0x0cz0=",
"rawQuality": "Unknown Quality",
"driveleechRedirectUrl": "https://uhdmovies.eu/3d-movies/"
}
]
}
@@ -1,25 +0,0 @@
{
"data": [
{
"quality": "4K | DV | BluRay",
"size": "Unknown",
"link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2pvMHJ3OElxMDl5bFcwWjdSL2cvQWZBdGdnVTNZUE5uSUllcDBlZUc0N0FWb25JS2J4bDNLQVRXMTUwYytoRzFodExZa3pDNE00NWVrejVSS1R3bmlyaDZwR2diVkVMUFhLVkRWTlBWazNGNURYNWczYVFEZ080WWNydkNqNHRxajJuUitjdXJEZkZiNnNrRnBrZDlyMg==",
"rawQuality": "Game.of.Thrones.S01.UHD.BluRay.2160p.DV.HEVC.REMUX.[Hindi DD 2.0 – Eng TrueHD.Atmos.7.1]-MSubs~(Tom) FraMeSToR [25 GB/E]",
"driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=OEcxNEtwQ3ZrMFlaSEp2eFY1RGZYa1Mwa1V0NThXVGQ3T1FjZnpOM0NBY2poZjQyRFpRNmgwQ3hhZkxzeFpjRw=="
},
{
"quality": "1080p | BluRay",
"size": "Unknown",
"link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2oycFVobHI5cmZ3OVNWaG5RYWZEQTFyRmVkQWZ4amdycTVjU0J6Vnl1UUl5SmxPR1ZxdmJJWlRXL1doYUVKMitqN1FWdDdKdERiTUI2U3c4TVJ1M1lYdDZpMTd3WTc1bXM1WElFYVZLTGlrODFGbVNaN20wOFYzYzBIZkUyTlQvZWFRbXEvMXVndGh6dG1Ld2FwLy82OA==",
"rawQuality": "Game of Thrones (2011) S01 1080p BluRay [Hindi DD 2.0 + English DTS 5.1] x264-LiNG[AK47] [5 GB/E]",
"driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=eUc0QUdoUmt5VkxGdTNmWk1aOVlndTFwNHZlUHl5RHNIMFBMZjFZdEdXTkc1L2lqWXlQdU96Y3ZFRXl4UTNNbw=="
},
{
"quality": "1080p | BluRay",
"size": "Unknown",
"link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2pSNWFKd3dwNVR2MVpRd3lqN1cwYXFxQVJiaTdHOC9rWmhqcFNVTytydVVBUFFGVEd1aUJ5YjUxLzZFaFgxU1JjU1hFTEpVdDVpMXlGTWVNMmh0aFNWb2d4TzBaTlNaOU9EM3Y4SVM3bllGSmJQR0NvZzg1TWNObEdOOWZoNFVyazhBOGk3emhxZjhGVy9RY3NpYnB6MQ==",
"rawQuality": "Game of Thrones S01 1080p BluRay 10bit HEVC [Hindi DD 2.0 + English AAC 5.1] x265-Joy[AK47] [800 MB/E] [09 GB ZIP]",
"driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=U2lzTnlYK3lhbDg3a0JNb3NsUVZ5OCtLV1FvaysrMG5jRHJOSFpSUllrWW9qNm56UCtYdkRUcmREYlNxVkp4Ng=="
}
]
}
@@ -1,123 +0,0 @@
{
"data": [
{
"quality": "Unknown Quality",
"size": "Unknown",
"link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMza2Z2VFBEdEhydU93VlhXT3JOYXFGaUhtU3FyeGkwbjh6d1RoajJEaW5UbQ==",
"rawQuality": "Unknown Quality",
"driveleechRedirectUrl": "https://uhdmovies.mov/4k-movies/"
},
{
"quality": "Unknown Quality",
"size": "Unknown",
"link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzbUoyR2JpV2JxSXVOcjZLK0dGKzFhNDdlR09GT3JsaHBmcXR6cFVXeEdCYw==",
"rawQuality": "Unknown Quality",
"driveleechRedirectUrl": "https://uhdmovies.mov/2160p-hevc/"
},
{
"quality": "Unknown Quality",
"size": "Unknown",
"link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMza3ZQQ2I2VEZZM3p6ZWFPMDhBQWRoaEh6c21YSjRDQXV5dHNFdGhNZVF3UA==",
"rawQuality": "Unknown Quality",
"driveleechRedirectUrl": "https://uhdmovies.mov/1080p-uhd/"
},
{
"quality": "Unknown Quality",
"size": "Unknown",
"link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzdlNJRWNQTHBvd0ZXZXQ2bXQzQ083ND0=",
"rawQuality": "Unknown Quality",
"driveleechRedirectUrl": "https://uhdmovies.mov/movies/"
},
{
"quality": "4K | HDR | DV | BluRay",
"size": "26GB",
"link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2hGRTRnNzZRQUIrNUIxcWpDMk9xMEVRNXV2bncyNG8reHE3YVJtOUxBbjhvVzRSYTFjd2VsN2drOUlxM2VVVHd1K3YzcmRtSDg5N3FXMVRQY2hPYjhkUUFmcGlNNnVmb1hZMnJEL2R1WHQxb1dhNEJjV0U2RERKYjVEc2ZHOUk5TzZVbXlxanZHVFhFYVRsOUp0LzdYag==",
"rawQuality": "Deadpool (2016) 2160p UHD BluRay DV HDR 10bit HEVC [Hindi DDP 5.1 + English DDP 5.1] x265 (d3g-UHDMovies [26GB]",
"driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=bFZyc1p1MTVRSU94bXo5ZmJzQlJHcDByaGYwcXZSdnZVbm84ZzVQRlFvSVlLQlFOcTAzWHFGUzB5UGh5cERDRw=="
},
{
"quality": "4K | HDR | DV | BluRay",
"size": "6GB",
"link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2llRS9MRS9Md3BGVWZLWDkrQzk3N05kZVd0aFJwNFNJZGJOYjJ2c3U0aXFiVkNpQkxseWhsNkNWemZwYkk2RFRyOWh5VHJiVHFMTGk3ODU0c2xrcG82Yzk3cnJlSEU5R1JwSjBkYk8wN1JkUnJ3dE0wWCtLWHJxUXc3OVBSZEMySTg0azhDMlc4cnVUc3pDUldaQlBGTg==",
"rawQuality": "Deadpool (2016) 2160p UHD BluRay DV HDR 10bit HEVC [Hindi DDP 5.1 + English DDP 5.1] x265 (RARBG-UHDMovies) [6GB]",
"driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=L0VucTlwOXNCdmRjNFJUL01XS2lTNDNuRTNQbGtnYWFpNk5QOUNQSEN1cm1kRUtmUy8rZDhReDUzVEk0N1k2Mw=="
},
{
"quality": "1080p | HDR | DV | BluRay",
"size": "12GB",
"link": "https://tech.unblockedgames.world/?sid=UldoSTVjL3N3QUU0K05LZzlkVXQxaDdNb0pJa0NJcXArK2RjL3RlQ1gvMD0=",
"rawQuality": "Deadpool (2016) 1080p UHD BluRay DV HDR 10bit HEVC [Hindi DDP 5.1 + English DDP 5.1] x265 (NMcT-UHDMovies [12GB]",
"driveleechRedirectUrl": "javascript:void(0);"
},
{
"quality": "1080p | BluRay",
"size": "11GB",
"link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2hBMkpOb2VJRHdGV1ROVTRVc2w5WGJERTNDVlhFUkE3TjdCUWdkcENqZXkwNXFlM1dRK0MwUjJucmpNTjJlUW5sRDZqWXlSamZRa3dHZThVbG9NelErbHA2VXp5eTBlbG1iY0g2NFNGZE1XL2lTSzlyR3VsTHd4YjVGQXF0NTBDSlpuTVhjVmpycGVKNEtGbmlJVVg2VQ==",
"rawQuality": "Deadpool (2016) 1080p UHD BluRay [Hindi DDP 5.1 + English DDP 5.1] x264 (LoRD-UHDMovies) [11GB]",
"driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=NUVMaXZ0dFJJWXd0WlJaWUZyMUpGaDFiRjhRUEt1SXRUT1JPd29JR3NMWEs1ZnNydWl1bjYxeVBCaFp0ZG52dA=="
},
{
"quality": "1080p | BluRay",
"size": "21GB",
"link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2pLSkd1UmpiYmdQRExHQnJZbS9UaEhmTUlYT09LQnI5QXIxR1ZGd3JzRy80SXdMbjB4OW9jR1R1S2llMkRTSk02SWdpdkJtSmVmZlVHZ3JBTHdyUkE2djg0VWdISXhiTXM3Q3NwVFg3R3E3UU5rVDJ0RDlUb290ckNuZDRWczdvVEgrSk40N3FpK3Q2UWE2TlVxa0M3ag==",
"rawQuality": "Deadpool (2016) 1080p BluRay REMUX AVC [Hindi DDP 5.1 + English DDP 5.1] x264 (CC-UHDMovies) [21GB]",
"driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=a3lXeUFGT29ZaVFZZFRua2lqOFZ3ZGF2bFRidFNaTWFqSGVYUWgrajZmMXl5TVVKclZWeHJFc1c1eDFFV2s3eQ=="
},
{
"quality": "1080p | BluRay",
"size": "11.6GB",
"link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2g5N3pSVmlGNnNibnMrdktudm9QWk9STklic3VrRFZBRE5PWXphOExvcUY0Z1BmRno1cFRKRXZIaHBhV3NIRjVYSWZPa0hwbnBJR1pxSEhGME52RllGcUxvdGx0ZVpqdkVyK3BUdmtlbUlJWE9LRVd2MUlQUFZhZnE5ZTErWUVtNTJnNnVKbE83UkpiTURrZ21UeHZzcQ==",
"rawQuality": "Deadpool (2016) 1080p BluRay AVC [Hindi DDP 5.1 + English DTS 5.1] x264 (HDMaNiAcS-UHDMovies) [11.6GB]",
"driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=bEtkV1ZOemMvVkFMdEVFRGtzK1ladkVndWFBYXhWMWVQSWN1aS96S0kvY2w4R0hUWm1MS25RbHIwVVk3N0RNVg=="
},
{
"quality": "1080p | BluRay",
"size": "6GB",
"link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2dYWHN4ODgzeXUrOURvQTVPbHhOVEZUWnJOZzRBdTd5UkhDTmV6bDIyNnFwUFd6VDBMaXdaVFh6U05ZeVl2U3lIMTE3ZjZOTWlEMVgxWFMvTVFHMzBoWHQvK0p1Y3p3UHRsREJjT0w4bVhtekduMnh1dWRKS0NMSTV4bXV6M3dtampiMXlLWDVpdVZLell1WC83b2tnLw==",
"rawQuality": "Deadpool (2016) 1080p BluRay 10bit HEVC [Hindi DDP 5.1 + English AAC 5.1] x265 (BeiTai-UHDMovies) [6GB]",
"driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=OGlEbjNEN1JGVVBueGE5elVCWjY3bTdVYUpPdm5tZGMrTnNna0lsTWIwMzVSQThUbmdQOEE5WkVVbDVRZTFLUg=="
},
{
"quality": "1080p | BluRay",
"size": "2GB",
"link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2dLSjBXTVNJWXVPK0FxeVZrUVZPUDhJMDJLcjRYOXZ4TVZXYlJ5dndpTDNsM0tmbkpQWVJ5em91NU41YndacERXSTNjemxCNE5GVnowM2F5QkYrVlE1SmhQVGcxelZIVjlNNXBONVJLYTcwK0dDNk42cWNMalE3Qk1WY0x1MVA1MFR0NkVGNGZkWkNRZnp6dS85Zml5Yw==",
"rawQuality": "Deadpool (2016) 1080p BluRay 10bit HEVC [Hindi DDP 5.1 + English AAC 5.1] x265 (RARBG-UHDMovies) [2GB]",
"driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=aVl6ZkFvQTZzUHdIUVE4SStONG02YmlONzkydzdVaUY0dDhIdHpxQVpjK2wrNmpUNkhCeHBwZWI3Q3Zwby9HLw=="
},
{
"quality": "1080p | BluRay",
"size": "2GB",
"link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzbVhDeGlwbGZ5alNmd1dGSExtbllZNmlHQU1hd21Fd00xRGV5R081Ym1xSQ==",
"rawQuality": "Deadpool (2016) 1080p BluRay 10bit HEVC [Hindi DDP 5.1 + English AAC 5.1] x265 (RARBG-UHDMovies) [2GB]",
"driveleechRedirectUrl": "https://uhdmovies.mov/1080p-60fps/"
},
{
"quality": "1080p | BluRay",
"size": "2GB",
"link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzbTlTYS9SYXVlWmVCNUpiM3VLMGY5VFpGMUMwRnBhRllXMXFWeUE3Q3dGcA==",
"rawQuality": "Deadpool (2016) 1080p BluRay 10bit HEVC [Hindi DDP 5.1 + English AAC 5.1] x265 (RARBG-UHDMovies) [2GB]",
"driveleechRedirectUrl": "https://uhdmovies.mov/1080p-10bit/"
},
{
"quality": "1080p | BluRay",
"size": "2GB",
"link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzaEtZenp1aENhajVZeG5sTXNFcFVRTT0=",
"rawQuality": "Deadpool (2016) 1080p BluRay 10bit HEVC [Hindi DDP 5.1 + English AAC 5.1] x265 (RARBG-UHDMovies) [2GB]",
"driveleechRedirectUrl": "https://uhdmovies.mov/4k-hdr/"
},
{
"quality": "Unknown Quality",
"size": "Unknown",
"link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzb3U1SmhRbk5yN0NDdGxPcmZNbUx4QkNPcEZ3bnQvM1R0Y1dsV2p1RFFGRQ==",
"rawQuality": "Unknown Quality",
"driveleechRedirectUrl": "https://uhdmovies.mov/2160p-movies/"
},
{
"quality": "Unknown Quality",
"size": "Unknown",
"link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzdFBXM3RQUkFjRkF6T05icGNaL0FKejdzT0FXVGhwVVhCdVFkM294c2w4ag==",
"rawQuality": "Unknown Quality",
"driveleechRedirectUrl": "https://uhdmovies.mov/3d-movies/"
}
]
}
@@ -1 +0,0 @@
Unknown size
@@ -1 +0,0 @@
Unknown size
@@ -1 +0,0 @@
Unknown size
@@ -1 +0,0 @@
Unknown size
@@ -1 +0,0 @@
Unknown size
@@ -1 +0,0 @@
Unknown size
@@ -1 +0,0 @@
Unknown size
@@ -1 +0,0 @@
Unknown size
@@ -1 +0,0 @@
Unknown size
@@ -1 +0,0 @@
Unknown size
@@ -1 +0,0 @@
Unknown size
@@ -1 +0,0 @@
Unknown size
@@ -1 +0,0 @@
Unknown size
@@ -1 +0,0 @@
Unknown size
@@ -1 +0,0 @@
Unknown size
@@ -1 +0,0 @@
Unknown size
@@ -1 +0,0 @@
Unknown size
@@ -1 +0,0 @@
Unknown size
@@ -1 +0,0 @@
Unknown size
@@ -1 +0,0 @@
Unknown size
@@ -1 +0,0 @@
Unknown size
@@ -1 +0,0 @@
Unknown size
+8 -56
View File
@@ -169,8 +169,7 @@ const CACHE_DIR = process.env.SHOWBOX_CACHE_DIR
? process.env.SHOWBOX_CACHE_DIR ? process.env.SHOWBOX_CACHE_DIR
: (process.env.VERCEL ? path.join('/tmp', '.cache') : path.join(require('os').tmpdir(), 'tmdb-embed-showbox-cache')); : (process.env.VERCEL ? path.join('/tmp', '.cache') : path.join(require('os').tmpdir(), 'tmdb-embed-showbox-cache'));
console.log(`Using cache directory: ${CACHE_DIR}`); console.log(`Using cache directory: ${CACHE_DIR}`);
// MODIFICATION: Remove hardcoded SHOWBOX_PROXY_URL, will use environment variable
// const SHOWBOX_PROXY_URL = "https://starlit-valkyrie-39f5ab.netlify.app/?destination=";
// Ensure cache directories exist // Ensure cache directories exist
const ensureCacheDir = async (dirPath) => { const ensureCacheDir = async (dirPath) => {
@@ -1355,8 +1354,7 @@ class ShowBoxScraper {
this.userCookie = userCookie; this.userCookie = userCookie;
// ScraperAPI key support removed // ScraperAPI key support removed
// Initialize proxy rotation counter for this instance
this.proxyCounter = Math.floor(Math.random() * 1000); // Random start to avoid patterns
this.baseHeaders = { this.baseHeaders = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
@@ -1374,31 +1372,7 @@ class ShowBoxScraper {
}; };
} }
// Get the next proxy URL from the rotation
getNextProxy() {
// Read proxy configuration from environment
const useRotatingProxy = process.env.SHOWBOX_USE_ROTATING_PROXY === 'true';
const primaryProxy = process.env.SHOWBOX_PROXY_URL_VALUE;
const alternateProxy = process.env.SHOWBOX_PROXY_URL_ALTERNATE;
// Increment the counter for this instance
this.proxyCounter++;
// ScraperAPI support removed; simple proxy rotation only
// Return direct connection if both proxies are missing
if (!primaryProxy && !alternateProxy) return null;
// If rotation disabled or alternate proxy not set, just use primary proxy
if (!useRotatingProxy || !alternateProxy) return primaryProxy;
// Use modulo to alternate between available proxies
const proxyIndex = this.proxyCounter % 2;
const selectedProxy = proxyIndex === 0 ? primaryProxy : alternateProxy;
console.log(`[Rotating Proxy] Selected proxy ${proxyIndex + 1}/2 for request #${this.proxyCounter}`);
return selectedProxy;
}
async _makeRequest(url, isJsonExpected = false) { async _makeRequest(url, isJsonExpected = false) {
// Removed unused timerLabel variable (profiling optional) // Removed unused timerLabel variable (profiling optional)
@@ -1416,22 +1390,8 @@ class ShowBoxScraper {
} }
// For HTML requests, we don't cache the raw HTML anymore - it's too large and wasteful // For HTML requests, we don't cache the raw HTML anymore - it's too large and wasteful
// Get the next proxy URL from the rotation // Always make direct requests
const selectedProxy = this.getNextProxy(); const requestUrl = url;
let requestUrl = url;
// removed unused isUsingScraperApi flag
if (selectedProxy) {
if (typeof selectedProxy === 'function') {
requestUrl = selectedProxy(url); // Direct transformation
} else if (selectedProxy.trim() !== '') {
// This is a regular proxy URL
requestUrl = `${selectedProxy}${encodeURIComponent(url)}`;
console.log(`ShowBoxScraper: Making request to: ${url} via Proxy: ${selectedProxy}`);
}
} else {
console.log(`ShowBoxScraper: Making direct request to: ${url} (no proxy available)`);
}
// Removed console.time call (timerLabel removed) // Removed console.time call (timerLabel removed)
@@ -1463,7 +1423,7 @@ class ShowBoxScraper {
try { try {
const response = await axios.get(requestUrl, { const response = await axios.get(requestUrl, {
headers: currentHeaders, headers: currentHeaders,
timeout: 30000 // Consider increasing if proxy adds significant latency timeout: 30000
}); });
const responseData = response.data; const responseData = response.data;
@@ -2851,16 +2811,8 @@ const getStreamsFromPStreamAPI = async (imdbId, tmdbType, seasonNum = null, epis
console.log(`[PStream] No ui-token available, making unauthenticated request`); console.log(`[PStream] No ui-token available, making unauthenticated request`);
} }
// Check if proxy should be used // Always use direct API URL
const useProxy = process.env.SHOWBOX_PROXY_URL_VALUE && process.env.SHOWBOX_PROXY_URL_VALUE.trim() !== ''; const finalApiUrl = apiUrl;
let finalApiUrl = apiUrl;
if (useProxy) {
finalApiUrl = `${process.env.SHOWBOX_PROXY_URL_VALUE}${encodeURIComponent(apiUrl)}`;
console.log(`[PStream] Using proxy for request: ${finalApiUrl}`);
} else {
console.log(`[PStream] Making direct request (no proxy configured)`);
}
// Make the request // Make the request
const response = await axios.get(finalApiUrl, { const response = await axios.get(finalApiUrl, {
+2 -7
View File
@@ -35,16 +35,11 @@ const getVidZeeStreams = async (tmdbId, mediaType, seasonNum, episodeNum) => {
let finalApiUrl; let finalApiUrl;
const headers = { const headers = {
'Referer': `https://player.vidzee.wtf/embed/movie/${tmdbId}` // Default for proxy method 'Referer': `https://player.vidzee.wtf/embed/movie/${tmdbId}`
}; };
const timeout = 7000; // Reduced timeout const timeout = 7000; // Reduced timeout
const proxyBaseUrl = process.env.VIDZEE_PROXY_URL || process.env.SHOWBOX_PROXY_URL_VALUE; finalApiUrl = targetApiUrl;
if (proxyBaseUrl) {
finalApiUrl = proxyBaseUrl + encodeURIComponent(targetApiUrl);
} else {
finalApiUrl = targetApiUrl;
}
console.log(`[VidZee] Fetching from server ${sr}: ${targetApiUrl}`); console.log(`[VidZee] Fetching from server ${sr}: ${targetApiUrl}`);
+18 -99
View File
@@ -25,13 +25,6 @@ function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
} }
// --- Proxy Configuration ---
const MOVIESMOD_PROXY_URL = process.env.MOVIESMOD_PROXY_URL;
if (MOVIESMOD_PROXY_URL) {
console.log(`[MoviesMod] Proxy support enabled: ${MOVIESMOD_PROXY_URL}`);
} else {
console.log('[MoviesMod] No proxy configured, using direct connections');
}
// --- Domain Fetching --- // --- Domain Fetching ---
let moviesModDomain = 'https://moviesmod.chat'; // Fallback domain let moviesModDomain = 'https://moviesmod.chat'; // Fallback domain
@@ -92,22 +85,14 @@ const saveToCache = async (key, data) => {
// Initialize cache directory on startup // Initialize cache directory on startup
ensureCacheDir(); ensureCacheDir();
// Proxy wrapper function // Request helper
const makeRequest = async (url, options = {}) => { const makeRequest = async (url, options = {}) => {
if (MOVIESMOD_PROXY_URL) {
// Route through proxy
const proxiedUrl = `${MOVIESMOD_PROXY_URL}${encodeURIComponent(url)}`;
console.log(`[MoviesMod] Making proxied request to: ${url}`);
return axios.get(proxiedUrl, options);
} else {
// Direct request
console.log(`[MoviesMod] Making direct request to: ${url}`); console.log(`[MoviesMod] Making direct request to: ${url}`);
return axios.get(url, options); return axios.get(url, options);
}
}; };
// Helper function to create a proxied session for SID resolution // Helper function to create a session for SID resolution
const createProxiedSession = async (jar) => { const createSession = async (jar) => {
const { wrapper } = await getAxiosCookieJarSupport(); const { wrapper } = await getAxiosCookieJarSupport();
const sessionConfig = { const sessionConfig = {
@@ -134,46 +119,6 @@ const createProxiedSession = async (jar) => {
} }
}; };
// If proxy is enabled, wrap the session methods to use proxy
if (MOVIESMOD_PROXY_URL) {
console.log(`[MoviesMod] Creating SID session with proxy: ${MOVIESMOD_PROXY_URL}`);
const originalGet = session.get.bind(session);
const originalPost = session.post.bind(session);
session.get = async (url, options = {}) => {
const proxiedUrl = `${MOVIESMOD_PROXY_URL}${encodeURIComponent(url)}`;
console.log(`[MoviesMod] Making proxied SID GET request to: ${url}`);
// Extract cookies from jar and add to headers
const cookieString = await getCookiesForUrl(url);
if (cookieString) {
console.log(`[MoviesMod] Adding cookies to proxied request: ${cookieString}`);
options.headers = {
...options.headers,
'Cookie': cookieString
};
}
return originalGet(proxiedUrl, options);
};
session.post = async (url, data, options = {}) => {
const proxiedUrl = `${MOVIESMOD_PROXY_URL}${encodeURIComponent(url)}`;
console.log(`[MoviesMod] Making proxied SID POST request to: ${url}`);
// Extract cookies from jar and add to headers
const cookieString = await getCookiesForUrl(url);
if (cookieString) {
console.log(`[MoviesMod] Adding cookies to proxied request: ${cookieString}`);
options.headers = {
...options.headers,
'Cookie': cookieString
};
}
return originalPost(proxiedUrl, data, options);
};
}
return session; return session;
}; };
@@ -430,8 +375,8 @@ async function resolveTechUnblockedLink(sidUrl) {
const { origin } = new URL(sidUrl); const { origin } = new URL(sidUrl);
const jar = new CookieJar(); const jar = new CookieJar();
// Create session with proxy support // Create session
const session = await createProxiedSession(jar); const session = await createSession(jar);
try { try {
// Step 0: Get the _wp_http value // Step 0: Get the _wp_http value
@@ -679,24 +624,12 @@ async function resolveVideoSeedLink(videoSeedUrl) {
const formData = new FormData(); const formData = new FormData();
formData.append('keys', keys); formData.append('keys', keys);
let apiResponse; const apiResponse = await axios.post(apiUrl, formData, {
if (MOVIESMOD_PROXY_URL) { headers: {
const proxiedApiUrl = `${MOVIESMOD_PROXY_URL}${encodeURIComponent(apiUrl)}`; ...formData.getHeaders(),
console.log(`[MoviesMod] Making proxied POST request to VideoSeed API`); 'x-token': new URL(videoSeedUrl).hostname
apiResponse = await axios.post(proxiedApiUrl, formData, { }
headers: { });
...formData.getHeaders(),
'x-token': new URL(videoSeedUrl).hostname
}
});
} else {
apiResponse = await axios.post(apiUrl, formData, {
headers: {
...formData.getHeaders(),
'x-token': new URL(videoSeedUrl).hostname
}
});
}
if (apiResponse.data && apiResponse.data.url) { if (apiResponse.data && apiResponse.data.url) {
return apiResponse.data.url; return apiResponse.data.url;
@@ -724,27 +657,13 @@ async function validateVideoUrl(url, timeout = 10000) {
try { try {
console.log(`[MoviesMod] Validating URL: ${url.substring(0, 100)}...`); console.log(`[MoviesMod] Validating URL: ${url.substring(0, 100)}...`);
// Use proxy for URL validation if enabled const response = await axios.head(url, {
let response; timeout,
if (MOVIESMOD_PROXY_URL) { headers: {
const proxiedUrl = `${MOVIESMOD_PROXY_URL}${encodeURIComponent(url)}`; 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
console.log(`[MoviesMod] Making proxied HEAD request for validation to: ${url}`); 'Range': 'bytes=0-1' // Just request first byte to test
response = await axios.head(proxiedUrl, { }
timeout, });
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Range': 'bytes=0-1' // Just request first byte to test
}
});
} else {
response = await axios.head(url, {
timeout,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Range': 'bytes=0-1' // Just request first byte to test
}
});
}
// Check if status is OK (200-299) or partial content (206) // Check if status is OK (200-299) or partial content (206)
if (response.status >= 200 && response.status < 400) { if (response.status >= 200 && response.status < 400) {
+1 -1
View File
@@ -227,7 +227,7 @@ async function fetchXprime(ctx) {
return []; return [];
} }
const t0 = Date.now(); const t0 = Date.now();
const streams = await xprime.getXprimeStreams(title, year, mediaType, ctx.season || null, ctx.episode || null, true, null); const streams = await xprime.getXprimeStreams(title, year, mediaType, ctx.season || null, ctx.episode || null);
const durationMs = Date.now() - t0; const durationMs = Date.now() - t0;
console.log(`[registry] xprime fetch duration ${durationMs}ms (title='${title}' year=${year}) returned ${Array.isArray(streams)?streams.length:0}`); console.log(`[registry] xprime fetch duration ${durationMs}ms (title='${title}' year=${year}) returned ${Array.isArray(streams)?streams.length:0}`);
if (!Array.isArray(streams) || !streams.length) return []; if (!Array.isArray(streams) || !streams.length) return [];
+21 -109
View File
@@ -15,13 +15,7 @@ const getAxiosCookieJarSupport = async () => {
return axiosCookieJarSupport; return axiosCookieJarSupport;
}; };
// --- Proxy Configuration --- // All requests are direct
const UHDMOVIES_PROXY_URL = process.env.UHDMOVIES_PROXY_URL;
if (UHDMOVIES_PROXY_URL) {
console.log(`[UHDMovies] Proxy support enabled: ${UHDMOVIES_PROXY_URL}`);
} else {
console.log('[UHDMovies] No proxy configured, using direct connections');
}
// --- Domain Fetching --- // --- Domain Fetching ---
let uhdMoviesDomain = 'https://uhdmovies.email'; // Fallback domain let uhdMoviesDomain = 'https://uhdmovies.email'; // Fallback domain
@@ -91,7 +85,6 @@ const saveToCache = async (key, data) => {
ensureCacheDir(); ensureCacheDir();
// Configure axios with headers to mimic a browser // Configure axios with headers to mimic a browser
// Configure axios instance with optional proxy support
const createAxiosInstance = () => { const createAxiosInstance = () => {
const config = { const config = {
headers: { headers: {
@@ -105,32 +98,15 @@ const createAxiosInstance = () => {
timeout: 30000 timeout: 30000
}; };
// Add proxy configuration if UHDMOVIES_PROXY_URL is set
if (UHDMOVIES_PROXY_URL) {
console.log(`[UHDMovies] Using proxy: ${UHDMOVIES_PROXY_URL}`);
// For proxy URLs that expect the destination URL as a parameter
config.transformRequest = [(data, headers) => {
return data;
}];
}
return axios.create(config); return axios.create(config);
}; };
const axiosInstance = createAxiosInstance(); const axiosInstance = createAxiosInstance();
// Proxy wrapper function // Request helper
const makeRequest = async (url, options = {}) => { const makeRequest = async (url, options = {}) => {
if (UHDMOVIES_PROXY_URL) { console.log(`[UHDMovies] Making direct request to: ${url}`);
// Route through proxy return axiosInstance.get(url, options);
const proxiedUrl = `${UHDMOVIES_PROXY_URL}${encodeURIComponent(url)}`;
console.log(`[UHDMovies] Making proxied request to: ${url}`);
return axiosInstance.get(proxiedUrl, options);
} else {
// Direct request
console.log(`[UHDMovies] Making direct request to: ${url}`);
return axiosInstance.get(url, options);
}
}; };
// Removed unused in-memory cache structure (uhdMoviesCache) // Removed unused in-memory cache structure (uhdMoviesCache)
@@ -738,24 +714,12 @@ async function tryInstantDownload($) {
const formData = new FormData(); const formData = new FormData();
formData.append('keys', keys); formData.append('keys', keys);
let apiResponse; const apiResponse = await axiosInstance.post(apiUrl, formData, {
if (UHDMOVIES_PROXY_URL) { headers: {
const proxiedApiUrl = `${UHDMOVIES_PROXY_URL}${encodeURIComponent(apiUrl)}`; ...formData.getHeaders(),
console.log(`[UHDMovies] Making proxied POST request for Instant Download API to: ${apiUrl}`); 'x-token': new URL(instantDownloadLink).hostname
apiResponse = await axiosInstance.post(proxiedApiUrl, formData, { }
headers: { });
...formData.getHeaders(),
'x-token': new URL(instantDownloadLink).hostname
}
});
} else {
apiResponse = await axiosInstance.post(apiUrl, formData, {
headers: {
...formData.getHeaders(),
'x-token': new URL(instantDownloadLink).hostname
}
});
}
if (apiResponse.data && apiResponse.data.url) { if (apiResponse.data && apiResponse.data.url) {
let finalUrl = apiResponse.data.url; let finalUrl = apiResponse.data.url;
@@ -859,25 +823,12 @@ async function validateVideoUrl(url, timeout = 10000) {
try { try {
console.log(`[UHDMovies] Validating URL: ${url.substring(0, 100)}...`); console.log(`[UHDMovies] Validating URL: ${url.substring(0, 100)}...`);
// Use proxy for URL validation if enabled const response = await axiosInstance.head(url, {
let response; timeout,
if (UHDMOVIES_PROXY_URL) { headers: {
const proxiedUrl = `${UHDMOVIES_PROXY_URL}${encodeURIComponent(url)}`; 'Range': 'bytes=0-1'
console.log(`[UHDMovies] Making proxied HEAD request for validation to: ${url}`); }
response = await axiosInstance.head(proxiedUrl, { });
timeout,
headers: {
'Range': 'bytes=0-1' // Just request first byte to test
}
});
} else {
response = await axiosInstance.head(url, {
timeout,
headers: {
'Range': 'bytes=0-1' // Just request first byte to test
}
});
}
// Check if status is OK (200-299) or partial content (206) // Check if status is OK (200-299) or partial content (206)
if (response.status >= 200 && response.status < 400) { if (response.status >= 200 && response.status < 400) {
@@ -1076,8 +1027,8 @@ const getCookiesForUrl = async (jar, url) => {
return null; return null;
}; };
// Helper function to create a proxied session for SID resolution // Helper function to create a session for SID resolution
const createProxiedSession = async (jar) => { const createSession = async (jar) => {
const { wrapper } = await getAxiosCookieJarSupport(); const { wrapper } = await getAxiosCookieJarSupport();
const sessionConfig = { const sessionConfig = {
@@ -1093,46 +1044,7 @@ const createProxiedSession = async (jar) => {
const session = wrapper(axios.create(sessionConfig)); const session = wrapper(axios.create(sessionConfig));
// If proxy is enabled, wrap the session methods to use proxy
if (UHDMOVIES_PROXY_URL) {
console.log(`[UHDMovies] Creating SID session with proxy: ${UHDMOVIES_PROXY_URL}`);
const originalGet = session.get.bind(session);
const originalPost = session.post.bind(session);
session.get = async (url, options = {}) => {
const proxiedUrl = `${UHDMOVIES_PROXY_URL}${encodeURIComponent(url)}`;
console.log(`[UHDMovies] Making proxied SID GET request to: ${url}`);
// Extract cookies from jar and add to headers
const cookieString = await getCookiesForUrl(jar, url);
if (cookieString) {
console.log(`[UHDMovies] Adding cookies to proxied request: ${cookieString}`);
options.headers = {
...options.headers,
'Cookie': cookieString
};
}
return originalGet(proxiedUrl, options);
};
session.post = async (url, data, options = {}) => {
const proxiedUrl = `${UHDMOVIES_PROXY_URL}${encodeURIComponent(url)}`;
console.log(`[UHDMovies] Making proxied SID POST request to: ${url}`);
// Extract cookies from jar and add to headers
const cookieString = await getCookiesForUrl(jar, url);
if (cookieString) {
console.log(`[UHDMovies] Adding cookies to proxied request: ${cookieString}`);
options.headers = {
...options.headers,
'Cookie': cookieString
};
}
return originalPost(proxiedUrl, data, options);
};
}
return session; return session;
}; };
@@ -1143,8 +1055,8 @@ async function resolveSidToDriveleech(sidUrl) {
const { origin } = new URL(sidUrl); const { origin } = new URL(sidUrl);
const jar = new CookieJar(); const jar = new CookieJar();
// Create session with proxy support // Create session
const session = await createProxiedSession(jar); const session = await createSession(jar);
try { try {
// Step 0: Get the _wp_http value // Step 0: Get the _wp_http value
+1 -12
View File
@@ -1,21 +1,10 @@
#!/usr/bin/env node #!/usr/bin/env node
const cheerio = require('cheerio'); const cheerio = require('cheerio');
// --- Constants --- // --- Constants ---
const VIDSRC_PROXY_URL = process.env.VIDSRC_PROXY_URL;
let BASEDOM = "https://cloudnestra.com"; // This can be updated by serversLoad let BASEDOM = "https://cloudnestra.com"; // This can be updated by serversLoad
const SOURCE_URL = "https://vidsrc.xyz/embed"; const SOURCE_URL = "https://vidsrc.xyz/embed";
// --- Helper: Conditional Proxied Fetch --- // --- Helper: Direct Fetch ---
// This function wraps the native fetch. If VIDSRC_PROXY_URL is set in the environment,
// it routes requests through the proxy. Otherwise, it makes a direct request.
async function fetchWrapper(url, options) { async function fetchWrapper(url, options) {
if (VIDSRC_PROXY_URL) {
const proxiedUrl = `${VIDSRC_PROXY_URL}${encodeURIComponent(url)}`;
console.log(`[VidSrc Proxy] Fetching: ${url} via proxy`);
// Note: The proxy will handle the actual fetching, so we send the request to the proxy URL.
// We pass the original headers in the options, the proxy should forward them.
return fetch(proxiedUrl, options);
}
// If no proxy is set, fetch directly.
console.log(`[VidSrc Direct] Fetching: ${url}`); console.log(`[VidSrc Direct] Fetching: ${url}`);
return fetch(url, options); return fetch(url, options);
} }
+4 -12
View File
@@ -4,7 +4,6 @@ const fs = require('fs').promises;
const path = require('path'); const path = require('path');
const crypto = require('crypto'); const crypto = require('crypto');
const XPRIME_PROXY_URL = process.env.XPRIME_PROXY_URL || null;
const RETRY_DELAY_MS_XPRIME = 1000; const RETRY_DELAY_MS_XPRIME = 1000;
const MAX_RETRIES_XPRIME = 3; const MAX_RETRIES_XPRIME = 3;
@@ -105,7 +104,7 @@ async function fetchStreamSize(url) {
} }
} }
async function getXprimeStreams(title, year, type, seasonNum, episodeNum, useProxy = true) { async function getXprimeStreams(title, year, type, seasonNum, episodeNum) {
if (!title || !year) return []; if (!title || !year) return [];
const encoded = encodeURIComponent(title); const encoded = encodeURIComponent(title);
let apiUrl; let apiUrl;
@@ -116,19 +115,12 @@ async function getXprimeStreams(title, year, type, seasonNum, episodeNum, usePro
apiUrl = `https://backend.xprime.tv/primebox?name=${encoded}&year=${year}&fallback_year=${year}&season=${seasonNum}&episode=${episodeNum}`; apiUrl = `https://backend.xprime.tv/primebox?name=${encoded}&year=${year}&fallback_year=${year}&season=${seasonNum}&episode=${episodeNum}`;
} else return []; } else return [];
console.log(`[Xprime.tv] Fetch attempt '${title}' (${year}) type=${type} useProxy=${useProxy}`); console.log(`[Xprime.tv] Fetch attempt '${title}' (${year}) type=${type}`);
let resJson; let resJson;
try { try {
if (useProxy && XPRIME_PROXY_URL) { const r = await fetchWithRetry(apiUrl, { headers: BROWSER_HEADERS_XPRIME });
const base = XPRIME_PROXY_URL.replace(/\/$/, ''); resJson = await r.json();
const proxied = `${base}/?destination=${encodeURIComponent(apiUrl)}`;
const r = await fetchWithRetry(proxied, { headers: BROWSER_HEADERS_XPRIME });
resJson = await r.json();
} else {
const r = await fetchWithRetry(apiUrl, { headers: BROWSER_HEADERS_XPRIME });
resJson = await r.json();
}
} catch (e) { } catch (e) {
console.error('[Xprime.tv] Fetch failed:', e.message); console.error('[Xprime.tv] Fetch failed:', e.message);
return []; return [];
+40 -9
View File
@@ -12,6 +12,8 @@
<div class="brand">TMDB Embed API</div> <div class="brand">TMDB Embed API</div>
<nav class="nav"> <nav class="nav">
<button class="nav-item" id="logoutBtn" data-action="logout">Logout</button> <button class="nav-item" id="logoutBtn" data-action="logout">Logout</button>
<button class="nav-item" id="restartBtn" type="button">Restart Server</button>
<div class="nav-sep" role="separator" aria-hidden="true"></div>
<button class="nav-item" data-target="panel-status">Server Status</button> <button class="nav-item" data-target="panel-status">Server Status</button>
<button class="nav-item" data-target="panel-core">Core</button> <button class="nav-item" data-target="panel-core">Core</button>
<button class="nav-item" data-target="panel-quality">Quality / Filters</button> <button class="nav-item" data-target="panel-quality">Quality / Filters</button>
@@ -97,8 +99,9 @@
</label> </label>
<textarea name="minQualitiesRaw" class="mini quality-json" placeholder='{"default":"900p"}' disabled></textarea> <textarea name="minQualitiesRaw" class="mini quality-json" placeholder='{"default":"900p"}' disabled></textarea>
</div> </div>
<div class="field codec-group"><label>Exclude Codecs<p class="hint">Preset radios serialize to a simple string. Custom & advanced modes use the JSON fields.</p> <div class="field codec-group"><label>Exclude Codecs<p class="hint">Preset radios serialize to JSON. Advanced lets you edit the JSON directly.</p>
<div class="codec-presets" id="codecPresets"> <div class="codec-presets" id="codecPresets">
<label class="c-item"><input type="radio" name="codecPreset" value="none"> <span>None</span></label>
<label class="c-item"><input type="radio" name="codecPreset" value="all"> <span>All</span></label> <label class="c-item"><input type="radio" name="codecPreset" value="all"> <span>All</span></label>
<label class="c-item"><input type="radio" name="codecPreset" value="dv"> <span>Dolby Vision (DV)</span></label> <label class="c-item"><input type="radio" name="codecPreset" value="dv"> <span>Dolby Vision (DV)</span></label>
<label class="c-item"><input type="radio" name="codecPreset" value="hdr"> <span>HDR / HDR10(+)</span></label> <label class="c-item"><input type="radio" name="codecPreset" value="hdr"> <span>HDR / HDR10(+)</span></label>
@@ -172,20 +175,13 @@
<p class="hint">These settings allow you to customize the behavior of the api and will effect timings.</p> <p class="hint">These settings allow you to customize the behavior of the api and will effect timings.</p>
<div class="field adv-flag-grid" id="advFlags" aria-label="Core Feature Flags"> <div class="field adv-flag-grid" id="advFlags" aria-label="Core Feature Flags">
<label class="adv-flag-item"><input type="checkbox" name="adv_disableCache" value="1" /> <span>Disable Cache</span></label> <label class="adv-flag-item"><input type="checkbox" name="adv_disableCache" value="1" /> <span>Disable Cache</span></label>
<label class="adv-flag-item"><input type="checkbox" name="adv_showboxRotatingProxy" value="1" /> <span>Showbox Rotating Proxy</span></label>
<label class="adv-flag-item"><input type="checkbox" name="adv_disableUrlValidation" value="1" /> <span>Disable URL Validation</span></label> <label class="adv-flag-item"><input type="checkbox" name="adv_disableUrlValidation" value="1" /> <span>Disable URL Validation</span></label>
<label class="adv-flag-item"><input type="checkbox" name="adv_disable4khdhubValidation" value="1" /> <span>Disable 4KHDHub Validation</span></label> <label class="adv-flag-item"><input type="checkbox" name="adv_disable4khdhubValidation" value="1" /> <span>Disable 4KHDHub Validation</span></label>
</div> </div>
<h1>Proxy / Paths</h1> <h1>Paths</h1>
<p class="hint">Provider enable/disable & feature flags apply immediately. Click toggles to enable (highlighted) or disable (dim).</p> <p class="hint">Provider enable/disable & feature flags apply immediately. Click toggles to enable (highlighted) or disable (dim).</p>
<div class="adv-group"> <div class="adv-group">
<div class="field small"><label>Showbox Cache Dir <input type="text" name="adv_showboxCacheDir" placeholder="/data/showbox-cache"/></label></div> <div class="field small"><label>Showbox Cache Dir <input type="text" name="adv_showboxCacheDir" placeholder="/data/showbox-cache"/></label></div>
<div class="field small"><label>Showbox Proxy (Primary) <input type="text" name="adv_showboxProxyPrimary" placeholder="https://proxy.example/"/></label></div>
<div class="field small"><label>Showbox Proxy (Alternate) <input type="text" name="adv_showboxProxyAlternate" placeholder="https://proxy2.example/"/></label></div>
<div class="field small"><label>Xprime Proxy URL <input type="text" name="adv_xprimeProxyUrl" placeholder="https://..."/></label></div>
<div class="field small"><label>VidZee Proxy URL <input type="text" name="adv_vidzeeProxyUrl" placeholder="https://..."/></label></div>
<div class="field small"><label>VidSrc Proxy URL <input type="text" name="adv_vidsrcProxyUrl" placeholder="https://..."/></label></div>
<div class="field small"><label>MoviesMod Proxy URL <input type="text" name="adv_moviesmodProxyUrl" placeholder="https://..."/></label></div>
</div> </div>
</section> </section>
<section id="panel-live" class="panel"> <section id="panel-live" class="panel">
@@ -206,4 +202,39 @@
<span id="validationSummary" class="validation-summary"></span> <span id="validationSummary" class="validation-summary"></span>
</div> </div>
</main> </main>
<!-- Confirmation Modal -->
<div id="confirmReset" class="modal" aria-hidden="true" role="dialog" aria-modal="true" aria-labelledby="confirmResetTitle">
<div class="modal-backdrop"></div>
<div class="modal-window">
<h3 id="confirmResetTitle">Reset All Settings?</h3>
<p class="modal-text">This will remove all overrides, delete all TMDB API keys and FebBox cookies, and restore provider and feature flags to their defaults. This action cannot be undone.</p>
<ul class="modal-list">
<li>Clear TMDB keys and FebBox cookies</li>
<li>Reset provider enable/default selections</li>
<li>Reapply default quality and validation settings</li>
</ul>
<label class="modal-opt"><input type="checkbox" id="confirmResetDontAsk" /> Don't ask again on this device</label>
<div class="modal-actions">
<button type="button" class="danger" data-action="confirm">Reset Everything</button>
<button type="button" data-action="cancel">Cancel</button>
</div>
</div>
</div>
<!-- Restart Confirmation Modal -->
<div id="confirmRestart" class="modal" aria-hidden="true" role="dialog" aria-modal="true" aria-labelledby="confirmRestartTitle">
<div class="modal-backdrop"></div>
<div class="modal-window">
<h3 id="confirmRestartTitle">Restart Server?</h3>
<p class="modal-text">This will stop the server process and attempt to restart it. Active requests will be interrupted. Make sure the app is managed by Docker, PM2, systemd, or another supervisor.</p>
<ul class="modal-list">
<li>Interrupts any in-flight API calls</li>
<li>Server will exit and come back up</li>
<li>UI will auto-reload when available</li>
</ul>
<div class="modal-actions">
<button type="button" class="danger" data-action="confirm">Restart Now</button>
<button type="button" data-action="cancel">Cancel</button>
</div>
</div>
</div>
</body></html> </body></html>
+112 -29
View File
@@ -124,13 +124,14 @@ function fillForm(data){
} }
const excRaw = override.excludeCodecsRaw !== undefined ? override.excludeCodecsRaw : (merged.excludeCodecsRaw || ''); const excRaw = override.excludeCodecsRaw !== undefined ? override.excludeCodecsRaw : (merged.excludeCodecsRaw || '');
let parsed = null; try { if(excRaw && /[\{\[]/.test(excRaw)) parsed = JSON.parse(excRaw); } catch {} let parsed = null; try { if(excRaw && /[\{\[]/.test(excRaw)) parsed = JSON.parse(excRaw); } catch {}
let mode = 'all'; let mode = 'none';
if(parsed){ if(parsed){
const dv = parsed.excludeDV === true; const dv = parsed.excludeDV === true;
const hdr = parsed.excludeHDR === true; const hdr = parsed.excludeHDR === true;
if(dv && !hdr) mode = 'dv'; if(!dv && !hdr) mode = 'none';
else if(dv && hdr) mode = 'all';
else if(dv && !hdr) mode = 'dv';
else if(hdr && !dv) mode = 'hdr'; else if(hdr && !dv) mode = 'hdr';
else if(dv && hdr) mode = 'advanced';
else mode = 'advanced'; else mode = 'advanced';
} else if(excRaw){ } else if(excRaw){
if(/excludeDV":true/.test(excRaw) && !/excludeHDR":true/.test(excRaw)) mode='dv'; if(/excludeDV":true/.test(excRaw) && !/excludeHDR":true/.test(excRaw)) mode='dv';
@@ -167,25 +168,17 @@ function fillForm(data){
['enableVixsrcProvider','adv_enableVixsrc'], ['enableVixsrcProvider','adv_enableVixsrc'],
['disableCache','adv_disableCache'], ['disableCache','adv_disableCache'],
['enablePStreamApi','adv_enablePStream'], ['enablePStreamApi','adv_enablePStream'],
['showboxUseRotatingProxy','adv_showboxRotatingProxy'],
['disableUrlValidation','adv_disableUrlValidation'], ['disableUrlValidation','adv_disableUrlValidation'],
['disable4khdhubUrlValidation','adv_disable4khdhubValidation'] ['disable4khdhubUrlValidation','adv_disable4khdhubValidation']
]; ];
advBools.forEach(([cfgKey, elName])=>{ const el = f.elements[elName]; if(!el) return; const src = (override[cfgKey]!==undefined? override[cfgKey] : merged[cfgKey]); if(el.type==='checkbox'){ el.checked = !!src; } else { el.value = src? 'true':''; } }); advBools.forEach(([cfgKey, elName])=>{ const el = f.elements[elName]; if(!el) return; const src = (override[cfgKey]!==undefined? override[cfgKey] : merged[cfgKey]); if(el.type==='checkbox'){ el.checked = !!src; } else { el.value = src? 'true':''; } });
const advTexts = [ const advTexts = [
['showboxCacheDir','adv_showboxCacheDir'], ['showboxCacheDir','adv_showboxCacheDir']
['showboxProxyPrimary','adv_showboxProxyPrimary'],
['showboxProxyAlternate','adv_showboxProxyAlternate'],
['xprimeProxyUrl','adv_xprimeProxyUrl'],
['vidzeeProxyUrl','adv_vidzeeProxyUrl'],
['vidsrcProxyUrl','adv_vidsrcProxyUrl'],
['moviesmodProxyUrl','adv_moviesmodProxyUrl']
]; ];
advTexts.forEach(([cfgKey, elName])=>{ const el = f.elements[elName]; if(!el) return; const val = override[cfgKey]!==undefined? override[cfgKey] : merged[cfgKey]; el.value = val || ''; }); advTexts.forEach(([cfgKey, elName])=>{ const el = f.elements[elName]; if(!el) return; const val = override[cfgKey]!==undefined? override[cfgKey] : merged[cfgKey]; el.value = val || ''; });
// Sync checkbox style advanced flags // Sync checkbox style advanced flags
const advFlagMap = { const advFlagMap = {
adv_disableCache: 'disableCache', adv_disableCache: 'disableCache',
adv_showboxRotatingProxy: 'showboxUseRotatingProxy',
adv_disableUrlValidation: 'disableUrlValidation', adv_disableUrlValidation: 'disableUrlValidation',
adv_disable4khdhubValidation: 'disable4khdhubUrlValidation' adv_disable4khdhubValidation: 'disable4khdhubUrlValidation'
}; };
@@ -234,7 +227,8 @@ async function save(){
} }
const cPreset = document.querySelector('input[name="codecPreset"]:checked'); const cPreset = document.querySelector('input[name="codecPreset"]:checked');
if(cPreset){ if(cPreset){
if(cPreset.value==='all') payload.excludeCodecsRaw = null; if(cPreset.value==='none') payload.excludeCodecsRaw = JSON.stringify({excludeDV:false,excludeHDR:false});
else if(cPreset.value==='all') payload.excludeCodecsRaw = JSON.stringify({excludeDV:true,excludeHDR:true});
else if(cPreset.value==='dv') payload.excludeCodecsRaw = JSON.stringify({excludeDV:true,excludeHDR:false}); else if(cPreset.value==='dv') payload.excludeCodecsRaw = JSON.stringify({excludeDV:true,excludeHDR:false});
else if(cPreset.value==='hdr') payload.excludeCodecsRaw = JSON.stringify({excludeDV:false,excludeHDR:true}); else if(cPreset.value==='hdr') payload.excludeCodecsRaw = JSON.stringify({excludeDV:false,excludeHDR:true});
else if(cPreset.value==='advanced') { else if(cPreset.value==='advanced') {
@@ -258,20 +252,11 @@ async function save(){
adv_enableVixsrc:'enableVixsrcProvider', adv_enableVixsrc:'enableVixsrcProvider',
adv_disableCache:'disableCache', adv_disableCache:'disableCache',
adv_enablePStream:'enablePStreamApi', adv_enablePStream:'enablePStreamApi',
adv_showboxRotatingProxy:'showboxUseRotatingProxy',
adv_disableUrlValidation:'disableUrlValidation', adv_disableUrlValidation:'disableUrlValidation',
adv_disable4khdhubValidation:'disable4khdhubUrlValidation' adv_disable4khdhubValidation:'disable4khdhubUrlValidation'
}; };
Object.entries(boolMap).forEach(([formName,cfgKey])=>{ const el = f.elements[formName]; if(el) payload[cfgKey] = !!el.checked; }); Object.entries(boolMap).forEach(([formName,cfgKey])=>{ const el = f.elements[formName]; if(el) payload[cfgKey] = !!el.checked; });
const textMap = { const textMap = { adv_showboxCacheDir:'showboxCacheDir' };
adv_showboxCacheDir:'showboxCacheDir',
adv_showboxProxyPrimary:'showboxProxyPrimary',
adv_showboxProxyAlternate:'showboxProxyAlternate',
adv_xprimeProxyUrl:'xprimeProxyUrl',
adv_vidzeeProxyUrl:'vidzeeProxyUrl',
adv_vidsrcProxyUrl:'vidsrcProxyUrl',
adv_moviesmodProxyUrl:'moviesmodProxyUrl'
};
Object.entries(textMap).forEach(([formName,cfgKey])=>{ const el = f.elements[formName]; if(!el) return; const v = el.value.trim(); payload[cfgKey] = v? v : null; }); Object.entries(textMap).forEach(([formName,cfgKey])=>{ const el = f.elements[formName]; if(!el) return; const v = el.value.trim(); payload[cfgKey] = v? v : null; });
const tmdbHidden = f.elements['tmdbApiKeysHidden']; const tmdbHidden = f.elements['tmdbApiKeysHidden'];
if (tmdbHidden){ if (tmdbHidden){
@@ -288,18 +273,92 @@ async function save(){
} catch(e){ setStatus(e.message,true); } } catch(e){ setStatus(e.message,true); }
} }
function openConfirmReset(){
const modal = document.getElementById('confirmReset');
if(!modal) return Promise.resolve(false);
// Respect persisted preference
try {
const skip = localStorage.getItem('ns_confirmReset_skip') === '1';
if (skip) return Promise.resolve(true);
} catch {}
modal.classList.add('show');
return new Promise(resolve => {
const onClick = (e)=>{
const action = e.target?.dataset?.action;
if(action==='confirm'){
try {
const dontAsk = modal.querySelector('#confirmResetDontAsk')?.checked;
if (dontAsk) localStorage.setItem('ns_confirmReset_skip','1');
} catch {}
cleanup(); resolve(true);
}
if(action==='cancel' || e.target===modal.querySelector('.modal-backdrop')){ cleanup(); resolve(false); }
};
function onKey(e){ if(e.key==='Escape'){ cleanup(); resolve(false); } }
function cleanup(){ modal.classList.remove('show'); modal.removeEventListener('click', onClick); document.removeEventListener('keydown', onKey); }
modal.addEventListener('click', onClick);
document.addEventListener('keydown', onKey);
});
}
function openConfirmRestart(){
const modal = document.getElementById('confirmRestart');
if(!modal) return Promise.resolve(false);
modal.classList.add('show');
return new Promise(resolve => {
const onClick = (e)=>{
const action = e.target?.dataset?.action;
if(action==='confirm'){ cleanup(); resolve(true); }
if(action==='cancel' || e.target===modal.querySelector('.modal-backdrop')){ cleanup(); resolve(false); }
};
function onKey(e){ if(e.key==='Escape'){ cleanup(); resolve(false); } }
function cleanup(){ modal.classList.remove('show'); modal.removeEventListener('click', onClick); document.removeEventListener('keydown', onKey); }
modal.addEventListener('click', onClick);
document.addEventListener('keydown', onKey);
});
}
async function clearAll(){ async function clearAll(){
if(!confirm('Remove ALL overrides?')) return; const confirmed = await openConfirmReset();
const payload = { port:null, defaultRegion:null, defaultProviders:[], minQualitiesRaw:null, excludeCodecsRaw:null, febboxCookies:null, if(!confirmed) return;
enableXprimeProvider:null, enable4khdhubProvider:null, enableMoviesmodProvider:null, enableMp4hydraProvider:null, enableVidzeeProvider:null, enableVixsrcProvider:null, // To truly reset to app defaults, we must:
disableCache:null, enablePStreamApi:null, showboxUseRotatingProxy:null, disableUrlValidation:null, disable4khdhubUrlValidation:null, // - Explicitly clear arrays so env fallbacks don't persist
showboxCacheDir:null, showboxProxyPrimary:null, showboxProxyAlternate:null, xprimeProxyUrl:null, vidzeeProxyUrl:null, vidsrcProxyUrl:null, moviesmodProxyUrl:null }; // - Set boolean flags to their default values (rather than null)
// - Null legacy single TMDB key
const payload = {
port: null,
defaultRegion: null,
defaultProviders: [],
minQualitiesRaw: 'all',
excludeCodecsRaw: JSON.stringify({excludeDV:false,excludeHDR:false}),
// Explicit empty arrays ensure override wins over any prior env mirror
febboxCookies: [],
tmdbApiKeys: [],
tmdbApiKey: null,
// Provider enable flags default to true
enableShowboxProvider: true,
enableXprimeProvider: true,
enable4khdhubProvider: true,
enableMoviesmodProvider: true,
enableMp4hydraProvider: true,
enableVidzeeProvider: true,
enableVixsrcProvider: true,
// Other defaults
disableCache: false,
enablePStreamApi: true,
disableUrlValidation: false,
disable4khdhubUrlValidation: false,
showboxCacheDir: null
};
try { try {
const r = await fetch('/api/config',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload)}); const r = await fetch('/api/config',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload)});
const js = await r.json(); const js = await r.json();
if(!js.success) throw new Error(js.error||'Clear failed'); if(!js.success) throw new Error(js.error||'Clear failed');
setStatus('Overrides cleared'); setStatus('All settings reset to defaults');
fillForm(js); fillForm(js);
// Re-render provider matrix immediately so toggles reflect defaults without page refresh
try { renderProviderMatrix(js.merged); } catch {}
validate();
} catch(e){ setStatus(e.message,true); } } catch(e){ setStatus(e.message,true); }
} }
@@ -443,6 +502,30 @@ document.addEventListener('DOMContentLoaded', ()=> {
location.replace('/?loggedOut=1'); location.replace('/?loggedOut=1');
}); });
} }
const restartBtn = document.getElementById('restartBtn');
if(restartBtn){
restartBtn.addEventListener('click', async ()=>{
const ok = await openConfirmRestart();
if(!ok) return;
setStatus('Restarting server…');
try {
const r = await fetch('/api/restart',{ method:'POST' });
if(!r.ok){ const t = await r.text().catch(()=>r.statusText); throw new Error(t||('HTTP '+r.status)); }
// Server will shut down soon; start polling until it comes back
await new Promise(resolve => setTimeout(resolve, 1000));
const start = Date.now();
const timeoutMs = 60_000;
(async function poll(){
try {
const pr = await fetch('/api/health',{ cache:'no-store' });
if(pr.ok){ location.reload(); return; }
} catch {}
if(Date.now()-start > timeoutMs){ setStatus('Restart timed out', true); return; }
setTimeout(poll, 1000);
})();
} catch(e){ setStatus('Restart failed: '+e.message, true); }
});
}
reload(); reload();
const h = location.hash.slice(1); const h = location.hash.slice(1);
navTo(h||'panel-core'); navTo(h||'panel-core');
+15
View File
@@ -129,6 +129,9 @@ body {
.nav-item.theme-toggle { margin-top: 12px; } .nav-item.theme-toggle { margin-top: 12px; }
.nav-item#logoutBtn { border:1px solid var(--danger); color: var(--danger); font-weight:700; } .nav-item#logoutBtn { border:1px solid var(--danger); color: var(--danger); font-weight:700; }
.nav-item#logoutBtn:hover { background: var(--danger); color:#fff; } .nav-item#logoutBtn:hover { background: var(--danger); color:#fff; }
.nav-item#restartBtn { border:1px solid var(--danger); color: var(--danger); font-weight:700; }
.nav-item#restartBtn:hover { background: var(--danger); color:#fff; }
.nav-sep { height: 1px; background: var(--border); margin: 6px 0 8px; opacity: .6; margin-bottom: 1rem; margin-top: 1rem;}
.grow { flex-grow: 1; } .grow { flex-grow: 1; }
.side-footer { font-size: .65rem; opacity: .6; line-height: 1.4; text-align: center;} .side-footer { font-size: .65rem; opacity: .6; line-height: 1.4; text-align: center;}
.main { .main {
@@ -364,3 +367,15 @@ input.invalid, textarea.invalid { border-color: var(--danger)!important; animati
.providers-table .prov-row { border:1px solid var(--border); } .providers-table .prov-row { border:1px solid var(--border); }
.prov-row strong { font-size:.7rem; letter-spacing:.5px; } .prov-row strong { font-size:.7rem; letter-spacing:.5px; }
} }
/* Modal */
.modal { position: fixed; inset: 0; display: none; align-items: center; justify-content: center; z-index: 100; }
.modal.show { display: flex; }
.modal .modal-backdrop { position: absolute; inset:0; background: rgba(0,0,0,.45); backdrop-filter: blur(2px); }
.modal .modal-window { position: relative; z-index: 1; width: min(560px, 94vw); background: var(--bg-alt); color: var(--text); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); padding: 18px 20px; }
.modal .modal-window h3 { margin: 0 0 8px; font-size: 1.05rem; letter-spacing: .5px; }
.modal .modal-text { margin: 0 0 10px; font-size: .85rem; color: var(--text-dim); }
.modal .modal-list { margin: 0 0 14px 18px; padding: 0; color: var(--text-dim); font-size: .8rem; }
.modal .modal-opt { display:flex; align-items:center; gap:8px; margin: 0 0 12px; font-size:.8rem; color: var(--text-dim); }
.modal .modal-opt input { accent-color: var(--primary); }
.modal .modal-actions { display: flex; gap: 10px; justify-content: flex-end; }
+1
View File
@@ -0,0 +1 @@
1758105049325
+13 -17
View File
@@ -78,10 +78,12 @@ function normalizeConfig(base) {
} }
// Ensure dedupe + trim // Ensure dedupe + trim
cfg.tmdbApiKeys = Array.from(new Set(cfg.tmdbApiKeys.map(k=>String(k).trim()).filter(Boolean))); cfg.tmdbApiKeys = Array.from(new Set(cfg.tmdbApiKeys.map(k=>String(k).trim()).filter(Boolean)));
// Do not expose legacy single-key field in merged config output
delete cfg.tmdbApiKey;
// Booleans normalization // Booleans normalization
const boolKeys = [ const boolKeys = [
'enableShowboxProvider','enableXprimeProvider','enable4khdhubProvider','enableMoviesmodProvider','enableMp4hydraProvider','enableVidzeeProvider','enableVixsrcProvider', 'enableShowboxProvider','enableXprimeProvider','enable4khdhubProvider','enableMoviesmodProvider','enableMp4hydraProvider','enableVidzeeProvider','enableVixsrcProvider',
'disableCache','enablePStreamApi','showboxUseRotatingProxy','disableUrlValidation','disable4khdhubUrlValidation' 'disableCache','enablePStreamApi','disableUrlValidation','disable4khdhubUrlValidation'
]; ];
boolKeys.forEach(k=>{ if (cfg[k] === 'true') cfg[k] = true; else if (cfg[k] === 'false') cfg[k] = false; }); boolKeys.forEach(k=>{ if (cfg[k] === 'true') cfg[k] = true; else if (cfg[k] === 'false') cfg[k] = false; });
// Default values if undefined // Default values if undefined
@@ -94,7 +96,7 @@ function normalizeConfig(base) {
if (cfg.enableVixsrcProvider === undefined) cfg.enableVixsrcProvider = true; if (cfg.enableVixsrcProvider === undefined) cfg.enableVixsrcProvider = true;
if (cfg.disableCache === undefined) cfg.disableCache = false; if (cfg.disableCache === undefined) cfg.disableCache = false;
if (cfg.enablePStreamApi === undefined) cfg.enablePStreamApi = true; if (cfg.enablePStreamApi === undefined) cfg.enablePStreamApi = true;
if (cfg.showboxUseRotatingProxy === undefined) cfg.showboxUseRotatingProxy = false; // Proxy features removed; always use direct connections
if (cfg.disableUrlValidation === undefined) cfg.disableUrlValidation = false; if (cfg.disableUrlValidation === undefined) cfg.disableUrlValidation = false;
if (cfg.disable4khdhubUrlValidation === undefined) cfg.disable4khdhubUrlValidation = false; if (cfg.disable4khdhubUrlValidation === undefined) cfg.disable4khdhubUrlValidation = false;
return cfg; return cfg;
@@ -127,14 +129,14 @@ function applyConfigToEnv(cfg){
process.env.DISABLE_4KHDHUB_URL_VALIDATION = cfg.disable4khdhubUrlValidation ? 'true':'false'; process.env.DISABLE_4KHDHUB_URL_VALIDATION = cfg.disable4khdhubUrlValidation ? 'true':'false';
// Showbox specific // Showbox specific
if (cfg.showboxCacheDir) process.env.SHOWBOX_CACHE_DIR = cfg.showboxCacheDir; else delete process.env.SHOWBOX_CACHE_DIR; if (cfg.showboxCacheDir) process.env.SHOWBOX_CACHE_DIR = cfg.showboxCacheDir; else delete process.env.SHOWBOX_CACHE_DIR;
process.env.SHOWBOX_USE_ROTATING_PROXY = cfg.showboxUseRotatingProxy ? 'true':'false'; // Proxy settings removed; ensure legacy envs are cleared
if (cfg.showboxProxyPrimary) process.env.SHOWBOX_PROXY_URL_VALUE = cfg.showboxProxyPrimary; else delete process.env.SHOWBOX_PROXY_URL_VALUE; delete process.env.SHOWBOX_USE_ROTATING_PROXY;
if (cfg.showboxProxyAlternate) process.env.SHOWBOX_PROXY_URL_ALTERNATE = cfg.showboxProxyAlternate; else delete process.env.SHOWBOX_PROXY_URL_ALTERNATE; delete process.env.SHOWBOX_PROXY_URL_VALUE;
// Other provider proxies delete process.env.SHOWBOX_PROXY_URL_ALTERNATE;
if (cfg.xprimeProxyUrl) process.env.XPRIME_PROXY_URL = cfg.xprimeProxyUrl; else delete process.env.XPRIME_PROXY_URL; delete process.env.XPRIME_PROXY_URL;
if (cfg.vidzeeProxyUrl) process.env.VIDZEE_PROXY_URL = cfg.vidzeeProxyUrl; else delete process.env.VIDZEE_PROXY_URL; delete process.env.VIDZEE_PROXY_URL;
if (cfg.vidsrcProxyUrl) process.env.VIDSRC_PROXY_URL = cfg.vidsrcProxyUrl; else delete process.env.VIDSRC_PROXY_URL; delete process.env.VIDSRC_PROXY_URL;
if (cfg.moviesmodProxyUrl) process.env.MOVIESMOD_PROXY_URL = cfg.moviesmodProxyUrl; else delete process.env.MOVIESMOD_PROXY_URL; delete process.env.MOVIESMOD_PROXY_URL;
if (cfg.defaultRegion) process.env.FEBBOX_REGION = cfg.defaultRegion; // alias if (cfg.defaultRegion) process.env.FEBBOX_REGION = cfg.defaultRegion; // alias
} }
@@ -159,14 +161,8 @@ function loadConfig() {
enableVixsrcProvider: process.env.ENABLE_VIXSRC_PROVIDER, enableVixsrcProvider: process.env.ENABLE_VIXSRC_PROVIDER,
disableCache: process.env.DISABLE_CACHE, disableCache: process.env.DISABLE_CACHE,
enablePStreamApi: process.env.ENABLE_PSTREAM_API, enablePStreamApi: process.env.ENABLE_PSTREAM_API,
showboxUseRotatingProxy: process.env.SHOWBOX_USE_ROTATING_PROXY,
showboxCacheDir: process.env.SHOWBOX_CACHE_DIR || null, showboxCacheDir: process.env.SHOWBOX_CACHE_DIR || null,
showboxProxyPrimary: process.env.SHOWBOX_PROXY_URL_VALUE || null, // Proxy/env paths removed; always direct connections
showboxProxyAlternate: process.env.SHOWBOX_PROXY_URL_ALTERNATE || null,
xprimeProxyUrl: process.env.XPRIME_PROXY_URL || null,
vidzeeProxyUrl: process.env.VIDZEE_PROXY_URL || null,
vidsrcProxyUrl: process.env.VIDSRC_PROXY_URL || null,
moviesmodProxyUrl: process.env.MOVIESMOD_PROXY_URL || null,
disableUrlValidation: process.env.DISABLE_URL_VALIDATION, disableUrlValidation: process.env.DISABLE_URL_VALIDATION,
disable4khdhubUrlValidation: process.env.DISABLE_4KHDHUB_URL_VALIDATION disable4khdhubUrlValidation: process.env.DISABLE_4KHDHUB_URL_VALIDATION
}; };
+22 -2
View File
@@ -1,6 +1,26 @@
{ {
"defaultProviders": [], "defaultProviders": [],
"configVersion": 1, "configVersion": 1,
"tmdbApiKeys": [], "tmdbApiKeys": [
"enableShowboxProvider": true "qwfghfgh",
"fghsdfs",
"uygghmng"
],
"enableShowboxProvider": true,
"febboxCookies": [
"gfdgfdgf"
],
"enableXprimeProvider": true,
"enable4khdhubProvider": true,
"enableMoviesmodProvider": true,
"enableMp4hydraProvider": true,
"enableVidzeeProvider": true,
"enableVixsrcProvider": true,
"disableCache": false,
"enablePStreamApi": true,
"disableUrlValidation": false,
"disable4khdhubUrlValidation": false,
"excludeCodecsRaw": "{\"excludeDV\":true,\"excludeHDR\":true}",
"minQualitiesRaw": "1080p",
"port": 3000
} }