# Vyla Ecosystem - Complete Full Documentation Digest
# Source: https://vyla.cc
# Generated for AI/LLM context extraction and offline research.
# Timestamp: 2026-11-14T20:30:00Z
#
# This file consolidates all documentation guides, API references, architecture specifications,
# and troubleshooting workflows across the Vyla Ecosystem into a single readable document.

================================================================================
FILE: start-here/introduction.md
================================================================================

# Vyla Entertainment

<p class="page-description">A community-built, decentralized media ecosystem and developer platform focused on privacy, user sovereignty, and self-hosted streaming infrastructure.</p>

<img class="vyla-banner" src="/src/assets/images/devices.webp" alt="The Vyla Ecosystem across Desktop, Android, and Android TV devices" loading="lazy" decoding="async" fetchpriority="low" />

## What is Vyla?

**Vyla** is an open-source, modular media ecosystem built on a simple foundation: **users and developers should have absolute sovereignty over their media experience.**

Unlike centralized streaming platforms that lock users into closed walled gardens, proprietary codecs, and telemetry tracking, Vyla separates the entire media stack into distinct, reusable layers:

1. **Client Frontends**: Native applications for Desktop (Windows, macOS, Linux), Mobile (Android), and Television (Android TV / Google TV).
2. **Scraper & Resolver SDK**: A high-performance Node.js scraping engine (`@vyla-entertainment/sdk`) aggregating over 60 distributed upstream providers with automatic jitter buffering and HLS playback verification.
3. **Stream API Gateway**: A self-hostable HTTP and Server-Sent Events (SSE) microservice proxy delivering low-latency progressive playback manifests, subtitle tracks, and media downloads.

:::callout-note
**Core Policy**: Vyla does not host, upload, store, or distribute video files or copyrighted media. The ecosystem provides client applications and self-hosted scraping tools that resolve publicly accessible links on demand.
:::

---

## Ecosystem Architecture at a Glance

The Vyla Ecosystem is designed around modularity. Each component functions autonomously or seamlessly interconnects with other components:

| Layer | Components | Core Capabilities |
| :--- | :--- | :--- |
| **User Interfaces** | **Vyla Home**, **Vyla Go**, **Vyla TV** | Desktop Tauri v2 with embedded sidecar, Android mobile client with WebGL shaders, and native Android TV (Jetpack Compose + ExoPlayer). |
| **Distribution Gateway** | **Stream API** | Node.js cluster gateway, SSE progressive source emitter, M3U8 playlist & key rewriting proxy, and 120-byte fake-image obfuscation stripper. |
| **Resolver Engine** | **Vyla SDK** (`@vyla-entertainment/sdk`) | 60+ modular source scrapers, two-phase stream verification (`verifyStream` / `verifyPlayable`), manga TLS-fingerprinted extraction, and subtitle normalization. |

---

## The Vyla Component Matrix

| Component | Platform / Tech Stack | Primary Responsibility | Documentation |
| :--- | :--- | :--- | :--- |
| **Vyla Home** | Tauri v2, Node.js Sidecar, Rust | Full desktop control center, automatic updates, Discord RPC | [Vyla Home Guide](/products/home) |
| **Vyla Go** | Tauri v2 Mobile, WebGL Shaders | Android mobile runtime, automated payload download, background playback | [Vyla Go Guide](/products/go) |
| **Vyla TV** | Kotlin, Jetpack Compose, ExoPlayer | 10-foot Leanback television UI, D-pad navigation, 4K/HDR streaming | [Vyla TV Guide](/products/tv) |
| **Stream API** | Node.js, Cluster Workers, SSE | Self-hosted HTTP streaming gateway, M3U8 proxy, segment stripper | [Stream API Overview](/stream-api/overview) |
| **Vyla SDK** | Node.js (ESM), TLS Client, Cheerio | Multi-provider video resolver, subtitle extractor, manga engine | [SDK Overview](/sdk) |
| **Custom Player** | HLS.js, Video.js, HTML5 | Custom web and native playback integration layer | [Build a Player](/products/player) |

---

## Core Principles

- **Zero Centralized Telemetry**: Vyla frontends never require mandatory tracking, user account creation, or proprietary telemetry services.
- **Failover by Design**: Video resolution queries multiple providers concurrently with randomized jitter. If one upstream host goes down or throttles, the client seamlessly shifts to the next viable candidate.
- **Progressive Delivery**: Stream API delivers media metadata instantly, followed by source candidates streamed over Server-Sent Events (SSE) as each scraper resolves. Players start playback within 3 to 8 seconds without waiting for the slowest source.
- **Local Sovereignty**: Every part of Vyla can be self-hosted locally on your laptop, home server, NAS, or virtual private server (VPS).

---

## Where to Begin

Select your path based on your role:

:::code-group
<!-- tab: End Users -->
- **On Desktop (Windows, macOS, Linux)?** Download and run [Vyla Home](/products/home).
- **On Android Phone or Tablet?** Install the native [Vyla Go APK](/products/go).
- **On Android TV, Google TV, or Fire TV?** Install the [Vyla TV APK](/products/tv).
- **Need help with setup?** Read the [Troubleshooting Guide](/resources/troubleshooting).

<!-- tab: Backend Developers -->
- **Embedding scrapers in a Node.js project?** Check out the [SDK Quickstart](/sdk/vyla-sdk/quickstart) and [Complete API Reference](/sdk/vyla-sdk/reference).
- **Want to author a new provider?** Follow the [Contributing a Source Guide](/sdk/vyla-sdk/contributing).
- **Integrating Manga discovery?** Read the [Manga SDK Documentation](/sdk/vyla-sdk/manga).

<!-- tab: Frontend & App Developers -->
- **Connecting a web or mobile player?** Read [Paths & Playback Events](/stream-api/reference/paths) and the [Client Integration Guide](/guides/integrations).
- **Building fallback strategies?** Study the [Error Handling Guide](/guides/error-handling).
- **Self-hosting the streaming gateway?** Read the [Self-Hosting Guide](/stream-api/deployment/self-hosting).

---

## Legal Notice & DMCA Compliance

Vyla is self-hosted software intended for personal educational and development use. All stream resolution and scraper logic interacts with publicly available web sources. Rights holders can review our takedown policies in the [DMCA Policy](/misc/project/dmca).

================================================================================
FILE: start-here/architecture.md
================================================================================

# Architecture & System Design

<p class="page-description">Deep architectural breakdown of the Vyla Ecosystem: component boundaries, communication protocols, video delivery pipelines, and failover topologies.</p>

## High-Level Architecture

The Vyla architecture cleanly separates **presentation**, **gateway mediation**, and **content resolution**. This decoupling ensures that any individual layer can be replaced, scaled, or run independently.

| Architecture Tier | Components | Protocols & Interfaces | Core Responsibilities |
| :--- | :--- | :--- | :--- |
| **Presentation Tier** | Vyla Home, Vyla Go, Vyla TV, Third-Party Web Players | SSE (HTTP/1.1), REST (JSON), HLS / DASH | Render user interface, manage local state, execute video playback via HLS.js or ExoPlayer Media3. |
| **Gateway Tier** | Stream API (`server.js`) | Node.js Cluster IPC, HTTP/REST, SSE, Reverse Proxy | Expose public endpoints, manage 1,500-entry in-memory cache, rewrite M3U8 playlists & AES keys, strip 120-byte obfuscation masks. |
| **Resolver Tier** | Vyla SDK (`@vyla-entertainment/sdk`) | Direct ESM function calls, HTTP/HTTPS scrapers | Scrape 60+ upstream providers concurrently, enforce random jitter delays, run two-phase stream validation. |
| **Upstream Hosts** | Public Third-Party CDNs & Video Hosts | Encrypted TLS/HTTPS, M3U8, MP4 | Deliver raw media segments and video assets. |

---

## Component Boundaries & Responsibilities

### 1. Vyla Home (Desktop)
- **Runtime Environment**: Built on [Tauri v2](https://v2.tauri.app/) using Rust and an embedded Node.js sidecar service.
- **IPC Protocol**: Communicates with the sidecar process via standard input/output (`stdin`/`stdout`) passing JSON-RPC messages.
- **Responsibilities**:
  - Manages application lifecycle, window management, and native system tray.
  - Automatically checks, verifies cryptographic signatures (`update-signing.pem`), and extracts delta updates from GitLab releases.
  - Houses the local `ServiceManager` and `Patcher` for offline and local service fallback.
  - Dispatches Discord Rich Presence activity updates (`discord-rpc.js`).
  - Persists configuration and cache to platform-specific AppData locations.

### 2. Vyla Go (Mobile)
- **Runtime Environment**: Tauri v2 for Android (`tauri-android`) targeting ARM64 (`aarch64`) and x86_64 architectures.
- **Responsibilities**:
  - Touch-optimized interface utilizing WebGL hardware shaders and glassmorphism styling.
  - Automated resource management: fetches, unpacks, and hot-patches runtime assets directly from remote releases without requiring full APK reinstallations for minor script updates.
  - Background playback coordination and media notification integration.

### 3. Vyla TV (Leanback)
- **Runtime Environment**: Native Android application written in Kotlin utilizing Jetpack Compose and Google's [ExoPlayer (Media3)](https://developer.android.com/media/media3/exoplayer).
- **Responsibilities**:
  - Strictly optimized for D-pad remote controls, 10-foot viewing distances, and Android TV / Google TV operating systems.
  - Native HLS stream parsing, hardware-accelerated 4K/HDR decoding, playback speed manipulation, audio track selection, and subtitle overlay.
  - Local client storage for user favorites, watch progress resume, and TMDB catalog browsing.

### 4. Stream API (Gateway)
- **Runtime Environment**: Node.js microservice utilizing the native `cluster` module for multi-core process forking.
- **Responsibilities**:
  - Acts as an HTTP/SSE bridge for clients that cannot run the Node.js SDK directly (e.g. mobile apps, TV apps, browser frontends).
  - Emits real-time playback events (`meta`, `source`, `done`) over Server-Sent Events.
  - Proxies HLS media streams (`/api?url=...`), automatically rewriting playlist chunk URIs and AES encryption key endpoints to bypass browser CORS and network restrictions.
  - Strips obfuscation masks (e.g. 120-byte fake PNG/JPEG headers used by ByteDance/TikTok-based content delivery networks).
  - Caches verified results for 5 minutes (TTL = 300,000 ms) in a shared inter-process memory map.

### 5. Vyla SDK (`@vyla-entertainment/sdk`)
- **Runtime Environment**: Pure ES Module Node.js library.
- **Responsibilities**:
  - Houses the core provider scraping modules (60+ scrapers in `src/sources/`).
  - Implements jitter scheduling, retry backoff, and custom header injection (`User-Agent`, `Referer`, `Origin`).
  - Performs two-phase verification on resolved candidate URLs.
  - Houses the Manga resolver engine leveraging `node-tls-client` to bypass TLS fingerprint blocking on `atsu.moe`.

---

## Playback Data Flow: Step-by-Step

Understanding how a media stream is discovered, verified, and played:

1. **Client Establishes SSE Connection**  
   The viewer selects a title (e.g., TMDB ID `155`), and the client initiates an HTTP Server-Sent Events handshake:
   ```http
   GET /movie?id=155 HTTP/1.1
   Host: api.vyla.cc
   Accept: text/event-stream
   ```

2. **Stream API Emits Initial Metadata**  
   Stream API validates the identifier, queries TMDB for metadata and artwork, queries subtitle providers, and immediately delivers a `meta` event:
   ```json
   data: {"type": "meta", "meta": {"title": "The Dark Knight", "year": 2008}, "subtitles": [{"lang": "English", "url": "..."}]}
   ```

3. **SDK Initiates Concurrent Provider Queries**  
   The SDK filters active provider scrapers from configuration, applies randomized per-source jitter (0–500 ms) to avoid burst-rate triggers, and initiates upstream HTTP scraping requests concurrently.

4. **Two-Phase Stream Verification**  
   - **Phase A (`verifyStream`)**: Executes an HTTP `HEAD` or range `GET` request against candidate stream URLs. Responses with status $\ge 400$ are discarded immediately.
   - **Phase B (`verifyPlayable`)**: Downloads and parses the master HLS manifest (`#EXT-X-STREAM-INF`), validates chunk resolution, and tests segment availability.

5. **Progressive Source Delivery**  
   As each provider scraper completes two-phase verification, Stream API immediately pushes a `source` event over the active SSE stream:
   ```json
   data: {"type": "source", "source": "vidlink", "url": "https://api.vyla.cc/api?url=...", "quality": "1080p", "type": "hls"}
   ```

6. **Instant Client Playback**  
   The client media player (ExoPlayer, HLS.js, or AVPlayer) immediately begins playback upon receiving the first valid source event (typically within 3–8 seconds). Subsequent incoming sources are enqueued into a client-side fallback list.

7. **Stream Completion**  
   Once all configured source scrapers have either returned verified streams or reached their timeout thresholds (typically 15–25 seconds), Stream API emits the completion event and closes the connection:
   ```json
   data: {"type": "done", "total": 4}
   ```

---

## The HLS Proxy & De-Obfuscation Mechanics

Many upstream streaming hosts employ strict CORS restrictions, IP-bound tokens, or binary header obfuscation. Vyla resolves this transparently:

### Playlist & Key Rewriting
When a stream URL is proxied through `/api?url=<URL>&<param>=1`, the gateway:
1. Requests the upstream playlist with provider-mandated `Referer` and `Origin` headers.
2. Intercepts `#EXT-X-KEY:METHOD=AES-128,URI="..."` and rewrites the key URI to route through the proxy.
3. Rewrites all chunk lines (`.ts` / `.m4s`) so that browser audio/video fetch calls pass through the proxy with valid `Access-Control-Allow-Origin: *` headers.

### Byte-Mask Stripping
Certain modern providers mask `.ts` video chunks as fake image files (`image/png`, `image/jpeg`, `letsgocdn`, or TikTok CDN formats) by prepending a 120-byte image header before the MPEG-TS sync byte (`0x47`):
```
[ 120-byte Fake PNG Header (0x89 0x50 0x4E 0x47...) ] + [ MPEG-TS Payload (0x47...) ]
```
When Stream API detects these signatures via regular expressions (`TIKTOK_REGEX`, `STRIP_REGEX`), it slices off the first 120 bytes:
```javascript
const stripped = (full[0] === 0x89 || full[0] === 0xFF || full[0] === 0x00)
    ? full.subarray(120)
    : full;
```
The resulting clean MPEG-TS stream is delivered to players with `Content-Type: video/MP2T`, enabling seamless playback across all platforms.

---

## Deployment Topologies

Choose the deployment architecture that fits your infrastructure:

| Topology | Components Used | Best For | Security & Networking |
| :--- | :--- | :--- | :--- |
| **All-in-One Desktop** | Vyla Home | Casual users wanting local playback on a single PC | Fully local, runs on localhost, zero open ports |
| **Living Room TV** | Vyla TV + Hosted Stream API | Smart TVs, Chromecast, NVIDIA Shield | TV connects over LAN/WAN to a secure Stream API gateway |
| **Private Family Server** | Stream API on VPS/NAS | Multi-device households streaming across phones, PCs, and TVs | Run behind Nginx/Caddy with TLS, enable API key protection |
| **Custom Platform** | SDK in Node.js backend | Developers building bespoke streaming web applications | Complete control over DB, auth, caching, and playback logic |

================================================================================
FILE: concepts/providers.md
================================================================================

# Provider Architecture & Mechanics

<p class="page-description">How Vyla SDK sources are structured, scheduled, verified, proxied, and cached across the ecosystem.</p>

## Overview

At the heart of the Vyla ecosystem is the **Provider Layer**. Rather than relying on a single upstream video host, Vyla SDK aggregates over 60 independent, community-maintained scraping resolvers.

Each provider operates with distinct upstream mechanics, domain rotations, rate-limiting policies, and security defenses. This document explains how Vyla orchestrates these disparate sources into a unified, high-reliability streaming pipeline.

---

## Provider Configuration Interface

In `@vyla-entertainment/sdk`, each provider is declared in `src/config.js` via the `SourceConfig` interface:

```typescript
export interface SourceConfig {
    key: string;              // Unique source identifier (e.g. "vidlink", "vixsrc")
    label: string;            // Human-readable display label
    sourceFile: string;       // Scraper module filename in src/sources/
    proxyParam: string;       // Query parameter used for HLS proxy routing
    timeout: number;          // Total milliseconds allowed before source abort
    sourcesTimeout?: number;  // Secondary timeout for multi-server extraction
    jitter: number;           // Maximum randomized startup delay in ms
    retries: number;          // Number of automatic retry attempts on error
    multiUrl: boolean;        // Returns multiple stream candidate URLs if true
    skipProxy?: boolean;      // If true, returns direct upstream URLs without proxy
    skipVerify?: boolean;     // If true, bypasses verification checks
    verifyHeaders?: boolean;  // Injects custom headers into verification probes
    disabled?: boolean;       // If true, provider is completely excluded
    cdnHeaders?: {            // Custom headers injected for specific CDN patterns
        pattern: RegExp;
        headers: { Referer: string; Origin: string; };
    }[];
}
```

---

## The Query Pipeline

When a client requests a title (`getStream()` in SDK or `/movie` / `/tv` in Stream API), the engine executes the following pipeline:

| Pipeline Stage | Operation | Purpose & Verification |
| :--- | :--- | :--- |
| **1. Source Filtering** | `SOURCES.filter(!disabled)` | Excludes disabled scrapers and selects active providers based on configuration. |
| **2. Jitter Staggering** | Sleep between `0` and `cfg.jitter` ms | Disperses outbound connection spikes across time to prevent DDoS protection triggers. |
| **3. Concurrent Scraping** | Parallel async scraper execution | Scrapers parse HTML/JSON endpoints using customized `User-Agent`, `Referer`, and `Origin` headers. |
| **4. Two-Phase Verification** | `verifyStream()` then `verifyPlayable()` | Phase 1 validates HTTP status ($< 400$ via HEAD). Phase 2 parses HLS manifests and verifies segment availability. Dead streams are discarded. |
| **5. Proxy URL Rewriting** | Encodes target URL into `/api?url=...` | Adds proxy flags, sets required playback headers, and prepares segment de-obfuscation. |
| **6. Progressive Emission** | Pushes SSE `source` event | Delivers playable stream candidates to the client player immediately without waiting for slower providers. |

---

## Jitter Staggering & Rate-Limit Defense

If a client triggers 60 scrapers instantaneously, your client IP address could send hundreds of simultaneous HTTP requests in the same millisecond, triggering upstream Cloudflare or DDoS rate limits.

To mitigate this, Vyla introduces **per-source jitter**:
```javascript
const jitterDelay = Math.floor(Math.random() * (cfg.jitter || 400));
await new Promise(resolve => setTimeout(resolve, jitterDelay));
```
By staggering outbound requests across a 100ms–800ms window, upstream hosts perceive natural traffic patterns, dramatically reducing HTTP 429 (Too Many Requests) errors.

---

## Two-Phase Playback Verification

Many streaming extractors successfully return a URL, only for that URL to return an HTTP 403 Forbidden, an empty manifest, or a dead video chunk. To protect players from stalling, Vyla validates every candidate through two independent verification stages before emitting it:

### Phase 1: `verifyStream()`
- Dispatches a lightweight HTTP `HEAD` request to the upstream target URL.
- Enforces custom `User-Agent`, `Referer`, and `Origin` headers.
- Requires HTTP status code `< 400` within 4,000 milliseconds.

### Phase 2: `verifyPlayable()`
- Fetches the initial playlist bytes through the local proxy.
- Validates the presence of the `#EXTM3U` header tag.
- Checks for stream definitions:
  - If a Master Playlist: ensures valid `#EXT-X-STREAM-INF` entries exist.
  - If a Media Playlist: ensures valid `#EXTINF` duration tags and playable segment URIs exist.
- Attempts a test read on the first media segment or key URI.
- Only candidates that pass both phases are deemed **verified**.

---

## The Universal HLS Proxy & Byte-Mask Stripper

Modern streaming hosts often protect their video segments by adding CORS restrictions, token signatures, or binary header masking. Stream API handles this transparently:

### 1. M3U8 Playlist Rewriting
When an HLS stream is proxied, Stream API fetches the upstream playlist and rewrites every internal URI:
- **AES-128 Key URIs**: `#EXT-X-KEY:METHOD=AES-128,URI="/api?url=<key>&<param>=1"`
- **Video Chunks**: Segment URIs are rewritten to route back through the `/api` proxy endpoint.
- **CORS Headers**: Returned with `Access-Control-Allow-Origin: *` and `Access-Control-Allow-Headers: *`.

### 2. Segment Byte-Mask Stripping
Certain major CDNs mask MPEG-TS chunks by prepending a 120-byte fake image header (`image/png`, `image/jpeg`, TikTok CDN, or `letsgocdn` signatures) so firewalls treat them as images.

When Stream API proxies these segments, it inspects the leading bytes and automatically strips the 120-byte image wrapper:
```javascript
const needsStrip = searchParams.has('tt') || STRIP_REGEX.test(cleanUrl);
if (needsStrip && (chunk[0] === 0x89 || chunk[0] === 0xFF || chunk[0] === 0x00)) {
    return chunk.subarray(120); // Strips fake header, leaving clean MPEG-TS
}
```

---

## Inter-Process Caching

Verified stream results are cached in-memory with a **5-minute Time-To-Live (TTL)**:
- **Cache Key**: `source_key + tmdb_id + season + episode`
- In multi-core cluster deployments, cache entries are coordinated across workers via inter-process communication (IPC) messages (`cache:get`, `cache:hit`, `cache:set`).
- Automatic prune routines run every 30 seconds to evict expired items and enforce maximum cache limits (default: 1,500 entries).

================================================================================
FILE: products/home.md
================================================================================

# Vyla Home (Desktop)

<p class="page-description">The native desktop control center and player runtime for Windows, macOS, and Linux built on Tauri v2 and an embedded Node.js sidecar.</p>

<img class="vyla-banner" src="/src/assets/images/desktop/site_preview.webp" alt="Vyla Home desktop application preview displaying streaming interface" loading="lazy" decoding="async" fetchpriority="low" />

## Overview

**Vyla Home** is the flagship desktop application of the Vyla ecosystem. Engineered for performance and privacy, Vyla Home packages the entire Vyla streaming runtime into a lightweight native shell using **Tauri v2** and an embedded Node.js sidecar process.

Instead of running heavy web browsers with excessive RAM overhead, Vyla Home leverages system-native WebViews (WebView2 on Windows, WebKit on macOS/Linux), ensuring instant boot times, hardware-accelerated video decoding, and tiny background resource footprints.

---

## Downloads

Official binary releases are published directly to the [Vyla Home GitLab Releases](https://gitlab.com/vyla-entertainment/home/-/releases):

| Platform | Package Format | Architecture | Download Link |
| :--- | :--- | :--- | :--- |
| **Windows** | Setup Installer (`.exe`) / Portable | x86_64 (64-bit) | [Download for Windows (.exe)](https://gitlab.com/vyla-entertainment/home/-/releases) |
| **macOS** | Disk Image (`.dmg`) | Universal (Apple Silicon & Intel) | [Download for macOS (.dmg)](https://gitlab.com/vyla-entertainment/home/-/releases) |
| **Linux** | Source Build / Flatpak (in progress) | x86_64, aarch64 | [Build from Source](#linux-build-guide) |

:::callout-info
When launching Vyla Home for the first time, the application will automatically perform a self-check, initialize local caches, and establish secure RPC connections.
:::

---

## Architectural Implementation

Vyla Home operates via a dual-process architecture:

| Process Layer | Tech Stack | Responsibilities & Capabilities |
| :--- | :--- | :--- |
| **Tauri Main Process** | Rust | Manages native OS window lifecycle, system tray icons, native menus, and hosts the secure WebView renderer. |
| **Inter-Process Channel** | Stdio IPC | Bi-directional JSON-RPC stream communicating over standard input and standard output (`stdin` / `stdout`). |
| **Node.js Sidecar Process** | Node.js (`main.js`) | Orchestrates `ServiceManager` for local/remote fallback, verifies update cryptographic signatures via `UpdateClient`, manages Discord Rich Presence, and handles local cached data. |

### File Locations & Directory Structure
Vyla Home stores its configuration, cryptographic keys, cached catalogs, and logs in standard operating system directories:

| OS | Default Storage Path |
| :--- | :--- |
| **Windows** | `%APPDATA%\vyla-home\vyla-home-files\` |
| **macOS** | `~/Library/Application Support/vyla-home/vyla-home-files/` |
| **Linux** | `~/.local/share/vyla-home/vyla-home-files/` |

### Diagnostics & Logs
If you encounter runtime issues, inspect the sidecar debug log:
- **Windows**: `%APPDATA%\vyla-home\vyla-home-files\logs\node-debug.log`
- **macOS/Linux**: `<AppDataDir>/logs/node-debug.log`

---

## Windows Troubleshooting: WebView2 Runtime

On Windows systems, Vyla Home utilizes Microsoft's Evergreen WebView2 runtime. If your installation encounters a `WebView2 runtime initialization error`:

1. Ensure the Microsoft Edge WebView2 Evergreen Runtime is installed from [Microsoft's official site](https://developer.microsoft.com/en-us/microsoft-edge/webview2/).
2. For portable or standalone deployments, verify that `WebView2Loader.dll` exists in the `bin/` directory adjacent to the binary:
  
```bash
vyla-home\bin\WebView2Loader.dll
```

---

## Linux Build Guide

To build and run Vyla Home natively on Linux distributions (such as Fedora, Ubuntu, Debian, or Arch):

### 1. Install System Dependencies

:::code-group
<!-- tab: Fedora / RHEL -->
```bash
sudo dnf install -y \
  webkit2gtk4.1-devel curl wget openssl-devel \
  libappindicator-gtk3-devel librsvg2-devel \
  gcc gcc-c++ make automake autoconf nodejs npm
```

<!-- tab: Ubuntu / Debian -->
```bash
sudo apt-get update && sudo apt-get install -y \
  libwebkit2gtk-4.1-dev build-essential curl wget \
  libssl-dev libayatana-appindicator3-dev librsvg2-dev \
  nodejs npm
```

<!-- tab: Arch Linux -->
```bash
sudo pacman -Syu --needed \
  webkit2gtk-4.1 base-devel curl wget openssl \
  libappindicator-gtk3 librsvg nodejs npm
```
:::

### 2. Install Rust Toolchain
```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"
```

### 3. Clone and Build
```bash
# Clone the repository
git clone https://gitlab.com/vyla-entertainment/home.git vyla-home
cd vyla-home

# Install Node dependencies
npm install

# Package runtime payload
npm run build:payload

# Launch in developer mode
npm run dev

# Or compile production binary
npm run build
```

---

## Developer Workflows

The Vyla Home repository includes specialized scripts for continuous development and release management:

```bash
# Start the full application in development mode with hot reload
npm run dev

# Package the local application payload into update-payload.zip
npm run build:payload

# Test the UI shell with a simulated test harness
npm run dev -- -- --env VYLA_TEST_UI=1

# Compile and package a full production installer release
npm run release:full
```

### Resolving File Locks (OS Error 32)
If a hung process locks the binary during development on Windows:
```powershell
Stop-Process -Name "vyla-home", "node", "cargo" -Force -ErrorAction SilentlyContinue
```

================================================================================
FILE: products/go.md
================================================================================

# Vyla Go (Android Mobile)

<p class="page-description">The native Android mobile client for the Vyla ecosystem, combining hardware-accelerated shaders, automated runtime management, and mobile streaming.</p>

<img class="vyla-banner" src="/src/assets/images/android/site_preview.webp" alt="Vyla Go mobile streaming application interface" loading="lazy" decoding="async" fetchpriority="low" />

## Overview

**Vyla Go** brings the power of the Vyla media ecosystem directly to Android smartphones and tablets. Built using **Tauri v2 Mobile**, Vyla Go delivers a fluid, responsive touch experience backed by native hardware acceleration and custom WebGL shaders.

Designed for mobile reliability on varying cellular and Wi-Fi networks, Vyla Go automatically coordinates local resource extraction, service fallbacks, and remote update fetching without requiring constant manual APK re-installations.

---

## Downloads

Official APK packages are published on the [Vyla Go GitLab Releases](https://gitlab.com/vyla-entertainment/go/-/releases):

| Package | Target Architectures | Compatibility | Download Link |
| :--- | :--- | :--- | :--- |
| **Universal APK** | `arm64-v8a`, `armeabi-v7a`, `x86_64` | Android 7.0+ (API 24+) | [Download Universal APK](https://gitlab.com/vyla-entertainment/go/-/releases) |
| **ARM64 APK** | `aarch64` | Modern 64-bit Android Devices | [Download ARM64 APK](https://gitlab.com/vyla-entertainment/go/-/releases) |

---

## Key Features

- **Tauri v2 Mobile Architecture**: Native Rust-backed Android application layer with secure Chromium WebView rendering.
- **Hardware-Accelerated WebGL Shaders**: Real-time dynamic glassmorphism, responsive ambient backdrops, and fluid gesture navigation.
- **Automated Resource Management**: Downloads and unpacks core service updates directly from official release channels, keeping scraper definitions up to date.
- **Low-Latency Mobile Playback**: Supports HLS and direct stream resolution with adaptive mobile bitrate handling.

---

## Building from Source

### Prerequisites
Before compiling Vyla Go, ensure your development environment has:
- **Node.js**: v20 or newer
- **Rust & Cargo**: Latest stable toolchain
- **Android Studio**: Android SDK & NDK (v29+)
- **Cross-Compilation Targets**:
  
```bash
rustup target add aarch64-linux-android x86_64-linux-android
```

### Build Commands

```bash
# 1. Install project dependencies
npm install

# 2. Package the runtime update payload
npm run build:payload

# 3. Compile the release APKs
npm run build:apk
```

The compiled release packages are output to:
```
src-tauri/gen/android/app/build/outputs/apk/universal/release/app-universal-release.apk
```

---

## Developer & Debugging Guide (ADB)

The Vyla Go repository provides complete ADB integration for debugging, log collection, and direct device installation:

### Streaming Device Logs
Monitor the application logs in real time via ADB:
```powershell
# Stream live application logs tagged VylaGo
& "$env:LOCALAPPDATA\Android\Sdk\platform-tools\adb.exe" logcat -s VylaGo

# Clear the log buffer and stream fresh output
& "$env:LOCALAPPDATA\Android\Sdk\platform-tools\adb.exe" logcat -c
& "$env:LOCALAPPDATA\Android\Sdk\platform-tools\adb.exe" logcat -s VylaGo
```

### Crash Diagnostics
Inspect unhandled exceptions, native SIGSEGV errors, and runtime failures:
```powershell
& "$env:LOCALAPPDATA\Android\Sdk\platform-tools\adb.exe" logcat -d | Select-String "VylaGo|AndroidRuntime|FATAL"
```

### Direct Device Installation
Install your newly built APK directly to a connected USB or Wi-Fi debug device:
```powershell
& "$env:LOCALAPPDATA\Android\Sdk\platform-tools\adb.exe" install -r "src-tauri\gen\android\app\build\outputs\apk\universal\release\app-universal-release.apk"
```

### Resetting App State
To completely terminate and purge cached app state:
```powershell
& "$env:LOCALAPPDATA\Android\Sdk\platform-tools\adb.exe" shell am force-stop com.vyla.go
& "$env:LOCALAPPDATA\Android\Sdk\platform-tools\adb.exe" shell pm clear com.vyla.go
```

### Fixing Emulator DNS Timeouts
When running Android emulators that fail to reach remote release endpoints:
```powershell
& "$env:LOCALAPPDATA\Android\Sdk\platform-tools\adb.exe" shell settings put global private_dns_mode off
```

================================================================================
FILE: products/tv.md
================================================================================

# Vyla TV (Android TV)

<p class="page-description">The native 10-foot Leanback streaming experience for Android TV and Google TV, built with Jetpack Compose and ExoPlayer.</p>

<img class="vyla-banner" src="/src/assets/images/android-tv/site-preview.webp" alt="Vyla TV application Leanback interface on television display" loading="lazy" decoding="async" fetchpriority="low" />

## Overview

**Vyla TV** is the living-room client in the Vyla ecosystem. Built entirely as a native Android application using modern **Jetpack Compose for TV** and Google's high-performance **ExoPlayer (Media3)** engine, Vyla TV brings the decentralized media experience to large displays.

Every interface component in Vyla TV is designed specifically for remote control navigation, ensuring seamless D-pad focus management, rapid title browsing, and cinema-grade playback.

---

## Downloads

Official TV APK builds are published to the [Vyla TV GitLab Releases](https://gitlab.com/vyla-entertainment/TV/-/releases):

| Platform | Format | Recommended Target Devices | Download Link |
| :--- | :--- | :--- | :--- |
| **Android TV / Google TV** | `.apk` | Sony Bravia, Chromecast with Google TV, NVIDIA Shield TV, Xiaomi Mi Box | [Download Vyla TV APK](https://gitlab.com/vyla-entertainment/TV/-/releases) |
| **Amazon Fire TV** | `.apk` | Fire TV Stick 4K / Max, Fire TV Cube | [Download Vyla TV APK](https://gitlab.com/vyla-entertainment/TV/-/releases) |

---

## TV Experience & Features

- **D-Pad Directional Navigation**: Engineered from the ground up for directional remotes. No mouse pointers, virtual cursors, or awkward touch adaptations.
- **ExoPlayer Media3 Engine**: Hardware-accelerated video decoding with direct support for adaptive HLS (m3u8), MP4, and MKV streams.
- **Playback Control Matrix**:
  - Variable playback speeds (0.5x, 0.75x, 1.0x, 1.25x, 1.5x, 2.0x).
  - Multi-track subtitle selector with custom sync adjustment and font sizing.
  - Multi-stream source switcher to toggle between upstream providers without leaving the player.
- **Catalog & Library**:
  - TMDB catalog integration with detailed cast, plot synopses, and genre filters.
  - "Watch Later" watchlist and persistent "Favorites" library stored locally on device.
  - Instant resume tracking with automatic timestamp memory.

---

## Sideloading on Android TV / Fire TV

If your device does not have a direct browser installer:

1. Install **Downloader by AFTVnews** from the Google Play Store or Amazon Appstore.
2. In your TV's settings, navigate to **Settings > System > Developer Options** (or **Device & Software > Developer Options**) and enable **Install Unknown Apps** for Downloader.
3. Open Downloader and enter the direct APK URL from our releases:
   
```bash
https://gitlab.com/vyla-entertainment/TV/-/releases
```
4. Download the latest `.apk` and select **Install**.

---

## Building from Source

### Prerequisites
- Node.js 20+
- Java Development Kit (JDK 17 or JDK 21)
- Android SDK with Android TV API 26+

### Build Steps

```bash
# Clone the repository
git clone https://gitlab.com/vyla-entertainment/TV.git vyla-tv
cd vyla-tv

# Install JavaScript asset bundling tools
npm install

# Build JS resolver bundle and compile debug APK via Gradle
npm run dev
```

The resulting package will be generated at:
```
android/app/build/outputs/apk/debug/vyla.apk
```

### Developing in Android Studio
To inspect Kotlin source code or UI composables directly:
1. Launch Android Studio.
2. Choose **Open an Existing Project** and select the `android/` subfolder inside the TV repository.
3. Allow Gradle to sync and build targets.

================================================================================
FILE: products/player.md
================================================================================

# Building a Custom Player

<p class="page-description">Architectural principles, format handling, and engineering guidelines for building resilient video players backed by Vyla infrastructure.</p>

## Overview

In the Vyla ecosystem, you are never locked into an official frontend. Vyla provides the discovery, resolution, and proxy layers; your application owns the player experience. Whether you are building a custom web portal, desktop client, or mobile app, this guide covers the core engineering patterns required for a robust player.

---

## Integration Boundaries

Choose your integration point based on your architecture:

| Architecture | Integration Point | Data Flow | Best For |
| :--- | :--- | :--- | :--- |
| **Node.js Backend** | **Vyla SDK Directly** | `sdk.getStream()` in-process | Applications with full backend control, custom authentication, and server-side session tracking. |
| **Browser / Mobile** | **Stream API Gateway** | SSE `/movie` or `/tv` over HTTP | Web applications, smart TV frontends, or lightweight mobile clients requiring an HTTP/SSE source feed. |

---

## Playback Formats: HLS vs Direct Video

Resolved candidate streams come in two primary container types:

1. **HLS Streams (`type: "hls"`)**:
   - Master M3U8 playlists containing multiple bitrate/resolution variants.
   - Proxied through Stream API (`/api?url=...`), which automatically rewrites chunk URLs and AES-128 encryption key URIs.
   - Requires native HLS support (Safari on macOS/iOS) or a JavaScript HLS MSE library such as [HLS.js](https://github.com/video-dev/hls.js/) in modern browsers.
2. **Direct Media Files (`type: "mp4"`)**:
   - Progressive MP4 or MKV streams.
   - Proxied with HTTP Range header forwarding (`206 Partial Content`), allowing smooth scrubbing and seeking.
   - Directly assignable to the HTML5 `<video>` element `src` attribute.

---

## Resilient Player Architecture

Upstream streaming hosts are dynamic: network latencies fluctuate, upstream proxies fail, and geo-restrictions vary. A production-ready Vyla player must adhere to five design rules:

### 1. Start on the First Candidate
Never wait for all providers to finish. Stream API emits verified sources over Server-Sent Events (SSE). The moment the first `source` event arrives (typically within 3 to 8 seconds):
- Initialize your player immediately.
- Store any subsequent incoming `source` events in a priority fallback array.

### 2. Maintain a Fallback Priority Array
If the active stream stalls, encounters an unrecoverable network error, or buffer-underruns:
- Catch the error event (e.g. `Hls.Events.ERROR` with fatal flag).
- Pop the next candidate from your fallback queue.
- Re-attach the media source without disrupting the user's viewing session.

### 3. Decouple Subtitles from Video Playback
Subtitles are retrieved independently from the video stream. Never block initial video buffering waiting for subtitle tracks to download. Load the video stream immediately and inject subtitle tracks (`<track kind="subtitles">`) asynchronously once resolved.

### 4. Implement a Client-Side Timeout
Always set a client-side watchdog timer (typically 15 to 20 seconds). If no viable candidate emits a valid video stream before the timer expires, render an informative empty state allowing the user to retry or switch servers.

### 5. Clean Up on Title Switch
When a viewer selects a new movie or episode:
- Call `eventSource.close()` on the active SSE connection.
- Invoke `hls.destroy()` or `video.removeAttribute('src')`.
- Clear pending retry timers and abort in-flight fetch requests.

---

## Reference Implementation: Minimal Web Player

Below is a complete, copyable implementation using native HTML5 and HLS.js:

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Vyla Custom Player</title>
  <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
  <style>
    video { width: 100%; max-width: 960px; height: auto; background: #000; border-radius: 8px; }
    .status { font-family: sans-serif; margin-top: 8px; color: #666; }
  </style>
</head>
<body>
  <video id="vyla-video" controls playsinline></video>
  <div id="status" class="status">Connecting to Stream API...</div>

  <script>
    const API_BASE = "https://your-stream-api.example.com";
    const TMDB_ID = 155; // The Dark Knight

    const video = document.getElementById("vyla-video");
    const statusEl = document.getElementById("status");

    const fallbackSources = [];
    let isPlaying = false;
    let hlsInstance = null;

    // Connect to progressive SSE route
    const eventSource = new EventSource(`${API_BASE}/movie?id=${TMDB_ID}`);

    eventSource.onmessage = (event) => {
      const data = JSON.parse(event.data);

      if (data.type === "meta") {
        statusEl.textContent = `Found: ${data.meta.title} (${data.meta.year})`;
        if (data.subtitles) loadSubtitles(data.subtitles);
      } 
      else if (data.type === "source") {
        if (!isPlaying) {
          playCandidate(data);
        } else {
          fallbackSources.push(data);
        }
      } 
      else if (data.type === "done") {
        eventSource.close();
        if (!isPlaying && fallbackSources.length === 0) {
          statusEl.textContent = "No compatible streaming sources found.";
        }
      }
    };

    eventSource.onerror = () => {
      eventSource.close();
      if (!isPlaying) statusEl.textContent = "Error connecting to Stream API.";
    };

    function playCandidate(candidate) {
      isPlaying = true;
      statusEl.textContent = `Streaming from provider: ${candidate.source} (${candidate.quality})`;

      if (candidate.type === "hls") {
        if (Hls.isSupported()) {
          if (hlsInstance) hlsInstance.destroy();
          hlsInstance = new Hls({ maxBufferLength: 30 });
          hlsInstance.loadSource(candidate.url);
          hlsInstance.attachMedia(video);
          hlsInstance.on(Hls.Events.MANIFEST_PARSED, () => video.play());

          hlsInstance.on(Hls.Events.ERROR, (event, errorData) => {
            if (errorData.fatal) {
              console.warn("HLS fatal error encountered. Switching to fallback candidate...");
              hlsInstance.destroy();
              isPlaying = false;
              if (fallbackSources.length > 0) playCandidate(fallbackSources.shift());
            }
          });
        } else if (video.canPlayType("application/vnd.apple.mpegurl")) {
          video.src = candidate.url;
          video.play();
        }
      } else {
        video.src = candidate.url;
        video.play();
      }
    }

    function loadSubtitles(subtitles) {
      subtitles.forEach((sub) => {
        const track = document.createElement("track");
        track.kind = "subtitles";
        track.label = sub.label;
        track.srclang = sub.label.slice(0, 2).toLowerCase();
        track.src = sub.file;
        video.appendChild(track);
      });
    }
  </script>
</body>
</html>
```

---

## Next Steps

- Explore the complete [Client Integration Guide](/guides/integrations) for React, Vue, and ExoPlayer examples.
- Review error classification in the [Error Handling Guide](/guides/error-handling).
- Review the SSE event protocol in [Paths & Playback Events](/stream-api/reference/paths).

================================================================================
FILE: sdk/vyla-sdk/index.md
================================================================================

# Vyla SDK (`@vyla-entertainment/sdk`)

<p class="page-description">The official Node.js scraping and resolver library for movies, television series, subtitles, downloads, and manga.</p>

<img class="vyla-banner" src="/src/assets/images/devices.webp" alt="Vyla SDK developer tools and multi-platform support" loading="lazy" decoding="async" fetchpriority="low" />

## Overview

`@vyla-entertainment/sdk` is the core media resolver engine powering the entire Vyla ecosystem. Available as a pure ES Module for Node.js environments, the SDK aggregates over 60 streaming providers, extracts multi-language subtitle tracks, discovers direct download packages, and interfaces with manga archives.

Whether you are building a custom backend API, an automated scraper pipeline, a command-line tool, or an embeddable player backend, the SDK provides a clean, typed JavaScript and TypeScript interface.

---

## Installation

Install the package via npm, pnpm, or yarn:

```bash
npm install @vyla-entertainment/sdk
```

### System Requirements
- **Node.js**: v20.0.0 or higher (ESM native)
- **TMDB API Key (Optional but Recommended)**: Required for sources that query metadata by IMDb ID or episode titles. Obtain a free key from [The Movie Database](https://www.themoviedb.org/).

---

## SDK Capabilities

| Functional Engine | Primary Methods | Output Data & Features |
| :--- | :--- | :--- |
| **Stream Engine** | `getStream()`, `getSources()`, `probeSource()` | Direct MP4 and adaptive HLS (`.m3u8`) links, quality tags, and verified playback flags. |
| **Subtitle Parser** | `getSubtitles()` | Multi-language WebVTT (`.vtt`) and SubRip (`.srt`) track descriptors with language labels. |
| **Download Engine** | `getDownloads()` | Direct high-speed download links, file sizes in bytes, and container specifications (MKV/MP4). |
| **Manga Engine** | `searchManga()`, `getManga()`, `getMangaChapter()` | Titles, covers, chapter indexes, and image page URLs bypassing TLS fingerprint protection. |

### 1. Video Stream Resolution
Queries active providers for direct MP4 and adaptive HLS streaming links based on TMDB movie or TV identifiers.

### 2. Multi-Language Subtitles
Extracts clean `.vtt` and `.srt` subtitle tracks from multiple open subtitle providers, categorized by language label.

### 3. Media Downloads
Resolves high-speed direct media download packages (including MKV containers with file size metadata).

### 4. Manga Discovery & Reading
Features a dedicated manga scraping module leveraging `node-tls-client` with Chrome 131 TLS fingerprinting to search manga, view chapters, and retrieve high-resolution page assets.

---

## Quick Example

```javascript
import VylaSDK from '@vyla-entertainment/sdk';

// Initialize the SDK instance
const sdk = new VylaSDK({
  tmdbApiKey: process.env.TMDB_API_KEY
});

// 1. Inspect all active providers
const sources = sdk.getSources(true);
console.log(`Active providers: ${sources.length}`);

// 2. Resolve a movie stream (TMDB ID 155: The Dark Knight)
try {
  const stream = await sdk.getStream('vidlink', 155);
  console.log('Stream resolved:', stream.url);
  console.log('Format:', stream.type); // "hls" or "mp4"
} catch (err) {
  console.error('Resolution error:', err.message);
}

// 3. Retrieve available subtitle tracks
const subtitles = await sdk.getSubtitles(155);
console.log(`Found ${subtitles.length} subtitle tracks`);
```

---

## SDK Navigation

- **[SDK Quickstart](/sdk/vyla-sdk/quickstart)**: Practical, step-by-step tutorial for resolving movies, TV episodes, and handling errors.
- **[Complete API Reference](/sdk/vyla-sdk/reference)**: Exhaustive documentation of all classes, methods, parameters, and TypeScript types.
- **[Manga Module Guide](/sdk/vyla-sdk/manga)**: Guide for manga search, chapter page extraction, and aspect-ratio rendering.
- **[Contributing a Source](/sdk/vyla-sdk/contributing)**: How to author, test, and contribute a new provider scraper.

================================================================================
FILE: sdk/vyla-sdk/quickstart.md
================================================================================

# Vyla SDK Quickstart

<p class="page-description">Get up and running with the Vyla SDK in under five minutes. Learn how to resolve movies, television episodes, subtitles, and downloads.</p>

## Prerequisites

Ensure you have Node.js 20+ installed on your system. Create a new Node.js project:

```bash
mkdir vyla-demo && cd vyla-demo
npm init -y
npm pkg set type="module"
npm install @vyla-entertainment/sdk dotenv
```

Create a `.env` file containing your TMDB API key:

```ini
TMDB_API_KEY=your_tmdb_api_key_here
```

---

## 1. Initializing the SDK

Create an `index.js` file and initialize the `VylaSDK` class:

```javascript
import 'dotenv/config';
import VylaSDK from '@vyla-entertainment/sdk';

const sdk = new VylaSDK({
  tmdbApiKey: process.env.TMDB_API_KEY
});

console.log('Vyla SDK initialized successfully!');
```

---

## 2. Resolving a Movie Stream

To resolve a movie stream, supply the source key and the numeric TMDB movie ID:

```javascript
// Example: The Dark Knight (TMDB ID: 155)
const sourceKey = 'vidlink';
const tmdbId = 155;

try {
  const result = await sdk.getStream(sourceKey, tmdbId);
  console.log('Stream Candidate URL:', result.url);
  console.log('Container Type:', result.type);     // "hls" or "mp4"
  console.log('Video Quality:', result.quality);   // "1080p", "720p", etc.
  console.log('Upstream Server:', result.server);
} catch (error) {
  console.error(`Failed to resolve ${sourceKey}:`, error.message);
}
```

---

## 3. Resolving a Television Episode

For TV series, provide the TMDB show ID, season number, and episode number:

```javascript
// Example: Breaking Bad (TMDB ID: 1396) Season 1, Episode 1
const showId = 1396;
const season = 1;
const episode = 1;

try {
  const tvStream = await sdk.getStream('vixsrc', showId, season, episode);
  console.log('TV Episode Stream:', tvStream.url);
} catch (error) {
  console.error('TV stream resolution failed:', error.message);
}
```

---

## 4. Multi-Source Concurrent Resolution with Fallbacks

In production, you should query multiple active providers concurrently and select the fastest viable stream:

```javascript
async function resolveFastestStream(tmdbId, s = null, e = null) {
  // 1. Retrieve all enabled sources
  const activeSources = sdk.getSources(true);

  // 2. Query active providers concurrently with timeout protection
  const queryPromises = activeSources.map(async (cfg) => {
    try {
      const stream = await Promise.race([
        sdk.getStream(cfg.key, tmdbId, s, e),
        new Promise((_, reject) => 
          setTimeout(() => reject(new Error('Timeout')), cfg.timeout || 10000)
        )
      ]);
      return { source: cfg.key, label: cfg.label, stream };
    } catch {
      return null;
    }
  });

  const results = await Promise.all(queryPromises);
  const successful = results.filter(Boolean);

  if (successful.length === 0) {
    throw new Error('No viable streaming sources resolved.');
  }

  console.log(`Resolved ${successful.length} valid streams!`);
  return successful;
}

// Test the resolver
const sources = await resolveFastestStream(155);
console.log('Primary Source:', sources[0].label, sources[0].stream.url);
```

---

## 5. Fetching Subtitles and Downloads

Subtitles and direct download links can be fetched in parallel:

```javascript
const [subtitles, downloads] = await Promise.all([
  sdk.getSubtitles(155),
  sdk.getDownloads(155)
]);

console.log('--- Subtitle Tracks ---');
subtitles.slice(0, 5).forEach((sub) => {
  console.log(`[${sub.type.toUpperCase()}] ${sub.label}: ${sub.file}`);
});

console.log('--- Download Packages ---');
downloads.forEach((dl) => {
  console.log(`[${dl.quality}] Size: ${dl.size ? (dl.size / (1024**3)).toFixed(2) + ' GB' : 'Unknown'} -> ${dl.url}`);
});
```

---

## 6. Live Source Health Probing

To check which providers are operational in your network environment:

```javascript
const healthReport = await sdk.probeAllSources();

for (const [key, status] of Object.entries(healthReport)) {
  const icon = status.ok ? 'OK' : 'FAIL';
  console.log(`[${icon}] ${key}: ${status.ok ? status.ms + 'ms' : 'offline'}`);
}
```

---

## Next Steps

- Consult the [Complete API Reference](/sdk/vyla-sdk/reference) for exhaustive class and method parameters.
- Learn how to integrate manga reading with the [Manga SDK Guide](/sdk/vyla-sdk/manga).
- Deploy an HTTP/SSE bridge with the [Stream API Guide](/stream-api/overview).

================================================================================
FILE: sdk/vyla-sdk/reference.md
================================================================================

# Vyla SDK API Reference

<p class="page-description">Complete technical reference for the `@vyla-entertainment/sdk` package: classes, methods, parameters, interfaces, and TypeScript definitions.</p>

## Class: `VylaSDK`

The primary entry point of the package. Instantiated to manage scraper execution, health probing, subtitle retrieval, downloads, and manga discovery.

```typescript
import VylaSDK from '@vyla-entertainment/sdk';
```

---

### Constructor

```typescript
constructor(options?: VylaSDKOptions)
```

Creates a new instance of `VylaSDK`.

#### Parameters
| Parameter | Type | Required | Default | Description |
| :--- | :--- | :--- | :--- | :--- |
| `options.tmdbApiKey` | `string` | Optional | `null` | Your TMDB v3 API Key. Highly recommended; required by sources that query metadata by IMDb ID or episode name. |
| `options.penguManifest` | `any` | Optional | `null` | Custom manifest definition for the Pengu provider source. |

#### Example
```javascript
const sdk = new VylaSDK({
  tmdbApiKey: '9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d'
});
```

---

### `getSources(excludeDisabled?)`

```typescript
getSources(excludeDisabled?: boolean): SourceConfig[]
```

Returns the registered list of provider scraper configurations.

#### Parameters
| Parameter | Type | Required | Default | Description |
| :--- | :--- | :--- | :--- | :--- |
| `excludeDisabled` | `boolean` | Optional | `false` | When `true`, filters out providers marked with `disabled: true`. |

#### Returns
Array of [`SourceConfig`](#interface-sourceconfig) objects.

#### Example
```javascript
const activeSources = sdk.getSources(true);
console.log(`Available active providers: ${activeSources.map(s => s.key).join(', ')}`);
```

---

### `getStream(key, id, s?, e?, clientIP?)`

```typescript
async getStream(
    key: string,
    id: string | number,
    s?: number | null,
    e?: number | null,
    clientIP?: string | null
): Promise<StreamResult | { allUrls: StreamResult[] }>
```

Executes the scraper module for a specified provider and resolves streaming candidate URLs.

#### Parameters
| Parameter | Type | Required | Default | Description |
| :--- | :--- | :--- | :--- | :--- |
| `key` | `string` | Required | — | The source key identifier (e.g. `'vidlink'`, `'vixsrc'`). |
| `id` | `string \| number` | Required | — | Numeric TMDB ID or string IMDb ID (for movies and TV shows). |
| `s` | `number \| null` | Optional | `null` | Season number (required for TV episodes). |
| `e` | `number \| null` | Optional | `null` | Episode number (required for TV episodes). |
| `clientIP` | `string \| null` | Optional | `null` | Client IP address passed for upstream geo-token generation. |

#### Returns
A Promise resolving to a [`StreamResult`](#interface-streamresult) object, or `{ allUrls: StreamResult[] }` if the source supports multi-URL extraction.

#### Throws
- `Error('Source with key "..." not found')` if the key does not exist.
- `Error('Source module for key "..." not found')` if the source module is disabled or failed to import.
- Upstream network errors or scraper extraction errors if the title cannot be found.

#### Example
```javascript
// Movie resolution
const movieStream = await sdk.getStream('vidlink', 155);

// TV episode resolution (Breaking Bad S01E01)
const episodeStream = await sdk.getStream('vixsrc', 1396, 1, 1);
```

---

### `getSubtitles(id, s?, e?)`

```typescript
async getSubtitles(
    id: string | number,
    s?: number | null,
    e?: number | null
): Promise<SubtitleResult[]>
```

Discovers and parses all available subtitle tracks for a movie or TV episode.

#### Parameters
| Parameter | Type | Required | Default | Description |
| :--- | :--- | :--- | :--- | :--- |
| `id` | `string \| number` | Required | — | TMDB media identifier. |
| `s` | `number \| null` | Optional | `null` | Season number (TV shows). |
| `e` | `number \| null` | Optional | `null` | Episode number (TV shows). |

#### Returns
A Promise resolving to an array of [`SubtitleResult`](#interface-subtitleresult) objects.

---

### `getDownloads(id, s?, e?)`

```typescript
async getDownloads(
    id: string | number,
    s?: number | null,
    e?: number | null
): Promise<DownloadResult[]>
```

Resolves direct media download packages and torrent/debrid links.

#### Returns
A Promise resolving to an array of [`DownloadResult`](#interface-downloadresult) objects.

---

### `probeSource(key)`

```typescript
async probeSource(key: string): Promise<ProbeResult>
```

Sends a lightweight probe request against the designated source to measure responsiveness and availability.

#### Parameters
| Parameter | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| `key` | `string` | Required | The provider key to probe. |

#### Returns
A Promise resolving to a [`ProbeResult`](#interface-proberesult) object: `{ ok: boolean, ms: number | null }`.

---

### `probeAllSources()`

```typescript
async probeAllSources(): Promise<ProbeAllResult>
```

Concurrently probes all active (non-disabled) sources and compiles a live health map.

#### Returns
A Promise resolving to a [`ProbeAllResult`](#type-probeallresult) dictionary mapping source keys to their probe results.

---

### Manga Methods

#### `searchManga(query, page?, perPage?)`
```typescript
async searchManga(query: string, page?: number, perPage?: number): Promise<any>
```
Queries the manga catalog via `atsu.moe` using Chrome 131 TLS fingerprinting. Returns paginated title listings.

#### `getManga(id)`
```typescript
async getManga(id: string): Promise<any>
```
Retrieves full manga details including description, genres, author, status, and chapter list.

#### `getMangaChapter(mangaId, chapterId)`
```typescript
async getMangaChapter(mangaId: string, chapterId: string): Promise<any>
```
Resolves ordered image URLs, dimensions, and aspect ratios for all pages in a given chapter.

---

## TypeScript Interfaces

### `Interface: SourceConfig`

```typescript
export interface SourceConfig {
    key: string;
    label: string;
    sourceFile: string;
    proxyParam: string;
    timeout: number;
    jitter: number;
    retries: number;
    multiUrl: boolean;
    skipProxy?: boolean;
    skipVerify?: boolean;
    verifyHeaders?: boolean;
    disabled?: boolean;
    sourcesTimeout?: number;
    cdnHeaders?: {
        pattern: RegExp;
        headers: {
            Referer: string;
            Origin: string;
        };
    }[];
}
```

### `Interface: StreamResult`

```typescript
export interface StreamResult {
    url: string;
    headers: {
        "User-Agent": string;
        Referer: string;
        Origin: string;
        [key: string]: string;
    };
    server: string;
    quality: string;
    type: "mp4" | "hls";
    skipVerify?: boolean;
    skipProxy?: boolean;
}
```

### `Interface: SubtitleResult`

```typescript
export interface SubtitleResult {
    label: string;
    file: string;
    type: "vtt" | "srt";
    source: string;
}
```

### `Interface: DownloadResult`

```typescript
export interface DownloadResult {
    url: string;
    quality: string;
    size: number | null;
    type: "mkv";
    active: boolean;
}
```

### `Interface: ProbeResult` & `ProbeAllResult`

```typescript
export interface ProbeResult {
    ok: boolean;
    ms: number | null;
}

export type ProbeAllResult = Record<string, ProbeResult>;
```

================================================================================
FILE: sdk/vyla-sdk/manga.md
================================================================================

# Manga Resolution Module

<p class="page-description">How to integrate manga title discovery, chapter listings, and high-resolution page resolution using the Vyla SDK.</p>

## Overview

In addition to video streaming, `@vyla-entertainment/sdk` includes a native Manga resolution module. Powered by `atsu.moe` and leveraging `node-tls-client`, the module bypasses anti-bot TLS fingerprinting by mimicking real Google Chrome 131 cryptographic handshakes.

This allows developers to build responsive, ad-free manga reading interfaces directly into their applications.

---

## Technical Architecture

Upstream manga archives frequently block standard Node.js `fetch` or `axios` requests using JA3/JA4 TLS fingerprinting. To ensure reliable connectivity:

1. **TLS Emulation**: Uses `node-tls-client` configured with `ClientIdentifier.chrome_131`.
2. **Session Persistence**: Reuses keep-alive TLS sessions across search and chapter page requests.
3. **Structured Geometry**: Returns explicit image dimensions (`width`, `height`) and pre-calculated aspect ratios so mobile and desktop readers can prevent layout shifts during image loading.

---

## Manga Methods

### 1. Searching for Titles

Search the manga catalog by query string with pagination support:

```javascript
import VylaSDK from '@vyla-entertainment/sdk';

const sdk = new VylaSDK();

// Search for "Chainsaw Man", page 1, 10 items per page
const searchResult = await sdk.searchManga('Chainsaw Man', 1, 10);

console.log(`Total results: ${searchResult.total}`);
searchResult.items.forEach((manga) => {
  console.log(`[ID: ${manga.id}] ${manga.title} - ${manga.latestChapter}`);
});
```

#### Search Response Structure
```json
{
  "page": 1,
  "perPage": 10,
  "total": 42,
  "items": [
    {
      "id": "chainsaw-man",
      "title": "Chainsaw Man",
      "cover": "https://cdn.atsu.moe/covers/chainsaw-man.webp",
      "status": "Ongoing",
      "latestChapter": "Chapter 180"
    }
  ]
}
```

---

### 2. Fetching Manga Details & Chapters

Retrieve full metadata, descriptions, genres, and the complete chapter index:

```javascript
const mangaDetails = await sdk.getManga('chainsaw-man');

console.log('Title:', mangaDetails.title);
console.log('Synopsis:', mangaDetails.description);
console.log('Genres:', mangaDetails.genres.join(', '));
console.log('Available Chapters:', mangaDetails.chapters.length);

// Inspect the latest chapter
const latest = mangaDetails.chapters[0];
console.log(`Latest Chapter: ${latest.chapterNumber} (ID: ${latest.id})`);
```

---

### 3. Resolving Chapter Pages

To render the reader view, fetch the ordered page image assets for a specific chapter:

```javascript
const mangaId = 'chainsaw-man';
const chapterId = 'chapter-1';

const pages = await sdk.getMangaChapter(mangaId, chapterId);

console.log(`Chapter contains ${pages.length} pages.`);

pages.forEach((page, index) => {
  console.log(`Page ${index + 1}: ${page.url} [${page.width}x${page.height}]`);
});
```

#### Page Object Structure
```json
{
  "index": 1,
  "url": "https://cdn.atsu.moe/data/.../01.webp",
  "width": 1080,
  "height": 1600,
  "aspectRatio": 0.675
}
```

---

## Reader Layout Best Practices

When rendering manga pages in a frontend reader:

1. **Prevent Cumulative Layout Shift (CLS)**: Use the provided `aspectRatio` or `width`/`height` in CSS (`aspect-ratio: attr(width) / attr(height);`) to reserve vertical scroll space before each image finishes downloading.
2. **Preload Neighboring Pages**: Implement a 2-page lookahead preloader so viewers turning pages experience instantaneous transitions.
3. **Session Cleanup**: In long-running background tasks, invoke `cleanup()` from the module when closing reader sessions to terminate idle TLS sockets.

================================================================================
FILE: sdk/vyla-sdk/contributing.md
================================================================================

# Contributing a Source Provider

<p class="page-description">Complete technical guide for authoring, testing, and contributing a new video scraping resolver to the Vyla SDK.</p>

## Overview

The Vyla SDK maintains its high reliability through a distributed collection of independent provider scrapers located in `src/sources/`. We welcome contributions of new sources that expand coverage for movies, television, and international content.

---

## Scraper Architecture

Every provider module is a self-contained ES Module adhering to a single exported contract:

```typescript
export async function getStream(args: StreamArgs): Promise<StreamResult | { allUrls: StreamResult[] }>
```

### The `args` Object
When your scraper's `getStream()` is invoked, the SDK passes a normalized `args` context containing:

| Field | Type | Description |
| :--- | :--- | :--- |
| `id` | `string \| number` | The TMDB numeric media ID or string IMDb ID. |
| `s` | `number \| null` | Season number for television episodes (or `null` for movies). |
| `e` | `number \| null` | Episode number for television episodes (or `null` for movies). |
| `clientIP` | `string \| null` | The viewer's client IP address (if passed from an upstream proxy). |
| `fetch` | `Function` | Node.js fetch wrapper pre-configured with timeout controls. |
| `imdbId` | `string \| null` | Automatically resolved IMDb ID (if TMDB API key is configured). |
| `title` | `string \| null` | Verified media title string. |
| `year` | `number \| null` | Media release year. |

---

## Step-by-Step Implementation Guide

### Step 1: Create the Scraper Module
Create a new file in `src/sources/<source_name>.js`:

```javascript
// src/sources/mysource.js

const BASE_URL = 'https://provider-domain.example.com';

const DEFAULT_HEADERS = {
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
  'Referer': `${BASE_URL}/`,
  'Origin': BASE_URL,
};

/**
 * Resolves a streaming candidate for movies or TV episodes.
 */
export async function getStream({ id, s, e, imdbId }) {
  // 1. Determine query target
  const isTv = s != null && e != null;
  const endpoint = isTv
    ? `${BASE_URL}/api/tv/${id}/${s}/${e}`
    : `${BASE_URL}/api/movie/${id}`;

  // 2. Fetch upstream provider payload
  const response = await fetch(endpoint, {
    headers: DEFAULT_HEADERS
  });

  if (!response.ok) {
    throw new Error(`Upstream returned HTTP ${response.status}`);
  }

  const data = await response.json();
  if (!data.streamUrl) {
    throw new Error('No stream found in upstream response');
  }

  // 3. Return normalized StreamResult
  return {
    url: data.streamUrl,
    headers: {
      ...DEFAULT_HEADERS,
      'Referer': data.referer || DEFAULT_HEADERS.Referer
    },
    server: 'MySource-Primary',
    quality: data.quality || '1080p',
    type: data.streamUrl.includes('.m3u8') ? 'hls' : 'mp4'
  };
}
```

---

### Step 2: Register in `src/config.js`

Add your provider configuration to the `SOURCES` array in `src/config.js`:

```javascript
{
    key: 'mysource',
    label: 'My Source',
    sourceFile: 'mysource',
    proxyParam: 'ms',
    timeout: 12000,
    jitter: 400,
    retries: 1,
    multiUrl: false,
    skipProxy: false,
    skipVerify: false
}
```

#### Configuration Field Guidelines:
- `key`: Lowercase alphanumeric identifier without spaces (e.g. `vidlink`, `cinecat`).
- `label`: Clean display title shown in UI menus.
- `proxyParam`: Unique 2-to-4 character query flag used by the Stream API HLS proxy (must not collide with existing flags).
- `timeout`: Maximum execution budget before aborting (typically 8,000ms–15,000ms).
- `jitter`: Random delay ceiling (typically 300ms–500ms) to avoid server burst locks.

---

### Step 3: Local Testing

Run your scraper against known TMDB titles using the test runner:

```bash
# Test a known movie (The Dark Knight - TMDB 155)
node test/index.js mysource 155

# Test a known TV episode (Breaking Bad S01E01 - TMDB 1396)
node test/index.js mysource 1396 1 1
```

Verify that:
1. A valid URL is printed.
2. The `type` is correctly identified as `'hls'` or `'mp4'`.
3. Required upstream headers (`Referer`, `Origin`, `User-Agent`) are included.
4. Testing an invalid ID throws a clean error without crashing the process.

---

## Contribution Rules & Checklist

Before submitting a Pull Request to the GitLab repository:

- [ ] Code is formatted with clean ES Module syntax.
- [ ] No hardcoded personal API keys or credentials.
- [ ] Provider does not execute external untrusted `eval()` or un-sanitized script execution.
- [ ] Upstream stream candidate URLs must be verified for playback.
- [ ] Errors are thrown with informative messages (`throw new Error(...)`).

================================================================================
FILE: stream-api/overview/index.md
================================================================================

# Stream API Overview

<p class="page-description">A self-hosted Node.js HTTP and Server-Sent Events (SSE) streaming gateway for progressive source discovery, HLS proxying, and subtitle extraction.</p>

<img class="vyla-banner" src="/src/assets/images/devices.webp" alt="Vyla Stream API infrastructure across client devices" loading="lazy" decoding="async" fetchpriority="low" />

## Overview

**Stream API** is the dedicated backend gateway for the Vyla ecosystem. While the Vyla SDK executes directly in Node.js environments, web browsers, mobile applications, and smart TVs require a standard HTTP/SSE bridge to communicate with upstream providers, circumvent browser CORS restrictions, and decrypt video streams.

Stream API wraps `@vyla-entertainment/sdk` in a high-concurrency, self-hostable service designed for maximum throughput and zero playback stutter.

---

## Architectural Highlights

| Cluster Role | Process Type | Responsibilities & Functions |
| :--- | :--- | :--- |
| **Primary Process** | Node.js Cluster Master | Spawns and supervises worker processes across CPU cores, manages the shared 1,500-entry in-memory LRU cache (5-minute TTL), coordinates IPC messages (`cache:get` / `cache:set`), and executes cache cleanup every 30 seconds. |
| **Inter-Process Channel** | Node.js IPC | High-throughput bi-directional message pipe (`process.send` and `cluster.on('message')`) synchronizing cache entries across workers without Redis or external database overhead. |
| **Worker Processes** | Forked HTTP Workers (`0..N`) | Runs native HTTP request routers (`http.createServer`), pushes progressive Server-Sent Events (SSE), executes universal reverse proxying with live M3U8/key rewriting, and strips 120-byte image obfuscation masks. |

### 1. Multi-Core Cluster Architecture
Stream API leverages Node's native `cluster` module to fork independent worker processes across available CPU cores. If one worker experiences a heavy upstream network timeout, other workers continue handling client requests without interruption.

### 2. Progressive Streaming over Server-Sent Events (SSE)
Rather than blocking HTTP requests for 20 seconds while 60 providers resolve, Stream API utilizes Server-Sent Events:
- **Instant Metadata**: Title info and subtitle tracks arrive in the first event (`type: "meta"`).
- **Progressive Sources**: As each provider scraper finishes verification, a `type: "source"` event is pushed immediately.
- **Completion Signal**: When all sources complete, a `type: "done"` event closes the stream cleanly.

### 3. Shared In-Memory LRU Cache
All cluster workers communicate with a centralized in-memory cache managed by the primary process:
- **Cache TTL**: 5 minutes (300,000 ms).
- **Capacity**: 1,500 items max with LRU eviction.
- **Cache Hit Latency**: < 2 milliseconds for frequently requested titles.

### 4. Reverse Proxy & Chunk De-Obfuscator
- Transparently proxies HLS playlists (`/api?url=...`), rewriting AES encryption keys and `.ts` chunk URIs to inject permissive CORS headers.
- Strips 120-byte fake image headers prepended to video chunks by ByteDance/TikTok-based content delivery networks.
- Supports HTTP Range headers (`206 Partial Content`) for seeking large MP4 and MKV media containers.

---

## Route Overview

| Route | Protocol | Primary Purpose | Reference |
| :--- | :--- | :--- | :--- |
| **`/movie?id=:id`** | GET (SSE) | Progressive movie source resolution | [Paths Reference](/stream-api/reference/paths) |
| **`/tv?id=:id&season=:s&episode=:e`** | GET (SSE) | Progressive TV episode source resolution | [Paths Reference](/stream-api/reference/paths) |
| **`/subtitles/movie/:id`** | GET (REST) | Multi-language subtitle tracks for movies | [Media Data Reference](/stream-api/reference/media-data) |
| **`/subtitles/tv/:id/:s/:e`** | GET (REST) | Subtitle tracks for TV episodes | [Media Data Reference](/stream-api/reference/media-data) |
| **`/downloads/movie/:id`** | GET (REST) | Direct media download packages for movies | [Media Data Reference](/stream-api/reference/media-data) |
| **`/downloads/tv/:id/:s/:e`** | GET (REST) | Direct media download packages for TV | [Media Data Reference](/stream-api/reference/media-data) |
| **`/api?url=:url`** | GET (Proxy) | Universal HLS & video chunk proxy | [Paths Reference](/stream-api/reference/paths) |
| **`/health`** | GET (REST) | Cluster status, cache size, source health | [Operations Reference](/stream-api/reference/operations) |
| **`/test/:source`** | GET (REST) | Direct test harness for individual sources | [Operations Reference](/stream-api/reference/operations) |

---

## Stream API Documentation Index

- **[Paths & Playback Events](/stream-api/reference/paths)**: Complete SSE payload contracts, parameters, and proxy options.
- **[Subtitles & Media Downloads](/stream-api/reference/media-data)**: REST endpoints for subtitle extraction and direct media files.
- **[Operations, Health & Testing](/stream-api/reference/operations)**: Cluster health monitoring, probe IDs, and debug routes.
- **[API Keys & Authentication](/stream-api/authentication)**: Key management, SQLite database, and partner keys.
- **[Production Self-Hosting Guide](/stream-api/deployment/self-hosting)**: Docker containerization, PM2, systemd, and Nginx reverse proxy configurations.

================================================================================
FILE: stream-api/reference/paths.md
================================================================================

# Paths & Playback Events

<p class="page-description">Detailed API reference for Stream API streaming endpoints, Server-Sent Events contracts, and proxy query parameters.</p>

## Progressive Playback Endpoints

Stream API uses Server-Sent Events (SSE) to deliver real-time discovery events directly to player clients. This eliminates long HTTP timeouts and allows players to begin buffering the moment the first candidate resolves.

---

### 1. Movie Stream Endpoint: `GET /movie` (or `/api/movie`)

Establishes an SSE event stream for a movie.

```http
GET /movie?id=155 HTTP/1.1
Host: your-api.example.com
Accept: text/event-stream
```

#### Query Parameters
| Parameter | Type | Required | Description | Example |
| :--- | :--- | :--- | :--- | :--- |
| `id` | `integer` | Required | Numeric TMDB Movie ID | `155` (The Dark Knight) |

---

### 2. Television Stream Endpoint: `GET /tv` (or `/api/tv`)

Establishes an SSE event stream for a television series episode.

```http
GET /tv?id=1396&season=1&episode=1 HTTP/1.1
Host: your-api.example.com
Accept: text/event-stream
```

#### Query Parameters
| Parameter | Type | Required | Description | Example |
| :--- | :--- | :--- | :--- | :--- |
| `id` | `integer` | Required | Numeric TMDB TV Series ID | `1396` (Breaking Bad) |
| `season` | `integer` | Required | Season number | `1` |
| `episode` | `integer` | Required | Episode number | `1` |

---

## Server-Sent Events (SSE) Contract

Connections to `/movie` and `/tv` return `Content-Type: text/event-stream` and emit events sequentially:

### Event 1: `meta` (Emitted Immediately)
Delivers title metadata and parsed subtitle tracks while scrapers are still running.

```json
data: {
  "type": "meta",
  "meta": {
    "title": "The Dark Knight",
    "year": 2008,
    "tmdb_id": 155,
    "imdb_id": "tt0468569",
    "poster": "https://image.tmdb.org/t/p/w500/...",
    "backdrop": "https://image.tmdb.org/t/p/original/..."
  },
  "subtitles": [
    {
      "label": "English",
      "file": "https://your-api.example.com/api?url=...",
      "type": "vtt",
      "source": "opensubtitles"
    }
  ]
}
```

### Event 2..N: `source` (Emitted Progressively)
Emitted as each provider scraper successfully resolves and passes two-phase verification.

```json
data: {
  "type": "source",
  "source": "vidlink",
  "label": "VidLink Primary",
  "url": "https://your-api.example.com/api?url=https%3A%2F%2Fupstream.cdn%2Fmaster.m3u8&vl=1",
  "server": "vidlink-cf",
  "quality": "1080p",
  "type": "hls",
  "headers": {
    "User-Agent": "Mozilla/5.0 ...",
    "Referer": "https://vidlink.pro/"
  }
}
```

### Event Final: `done` (Stream Closes)
Emitted when all enabled scrapers have finished resolving or reached their maximum timeout. The server closes the SSE connection immediately after.

```json
data: {
  "type": "done",
  "total": 5
}
```

---

## The Universal Reverse Proxy: `GET /api`

The `/api` route handles media proxying, M3U8 rewriting, segment stripping, and TMDB queries.

### 1. Media Proxying: `/api?url=:encoded_url`

```http
GET /api?url=https%3A%2F%2Fcdn.example.com%2Fvideo.m3u8&proxyHeaders=%7B%22Referer%22%3A%22https%3A%2F%2Fsite.com%22%7D HTTP/1.1
```

#### Query Parameters
| Parameter | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| `url` (or `proxy`) | `string` | Required | URL-encoded destination target. |
| `proxyHeaders` | `string` | Optional | URL-encoded JSON dictionary of custom headers to forward upstream. |
| `<source_flag>` | `string` | Optional | Provider flag matching `proxyParam` (e.g. `&vl=1`, `&vx=1`) to apply source-specific referer rules. |
| `tt` | `string` | Optional | Forces the 120-byte image de-masking routine on MPEG-TS video chunks. |

#### Proxy Behaviors
- **M3U8 Playlists**: Rewrites all `.ts` chunk lines and AES `#EXT-X-KEY` URIs so that player requests route through the proxy with permissive CORS headers.
- **Obfuscated Chunks**: If chunks begin with PNG (`0x89`), JPEG (`0xFF`), or null (`0x00`) fake headers, Stream API automatically slices off the leading 120 bytes.
- **Range Seeking**: Forwards `Range: bytes=start-end` headers to upstream servers and returns HTTP `206 Partial Content`, enabling smooth scrubbing in MP4/MKV media.

---

### 2. Active Sources Listing: `/api?sources_meta=1`

Returns the list of active streaming sources currently loaded into the instance:

```json
{
  "sources": [
    { "key": "vidlink", "label": "VidLink", "timeout": 12000 },
    { "key": "vixsrc", "label": "VixSrc", "timeout": 10000 },
    { "key": "cinecat", "label": "CineCat", "timeout": 15000 }
  ]
}
```

---

## HTTP Status Codes & Error Responses

| Status Code | Description | Example Payload |
| :--- | :--- | :--- |
| **`200 OK`** | Request succeeded or SSE stream opened | `text/event-stream` or JSON payload |
| **`206 Partial Content`** | Byte-range media response for video scrubbing | Binary video stream chunk |
| **`400 Bad Request`** | Missing required parameters or invalid TMDB ID | `{"error": "missing id", "route": "/movie?id=:tmdb_id"}` |
| **`404 Not Found`** | Unknown route | `{"error": "not found"}` |
| **`502 Bad Gateway`** | Upstream provider connection failed or timed out | `{"error": "upstream connection timeout"}` |

================================================================================
FILE: stream-api/reference/media-data.md
================================================================================

# Subtitles & Media Downloads

<p class="page-description">REST API reference for retrieving subtitle tracks and direct media download packages for movies and television series.</p>

## Subtitle Endpoints

Stream API provides dedicated REST endpoints to fetch subtitle tracks independently from video streams. Subtitles are discovered and parsed into web-standard `.vtt` or `.srt` formats.

---

### 1. Movie Subtitles

```http
GET /subtitles/movie/:id HTTP/1.1
Host: your-api.example.com
```

#### Path Parameters
| Parameter | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| `id` | `integer` | Required | Numeric TMDB Movie ID (e.g. `155`) |

#### Example Request & Response
```bash
curl https://your-api.example.com/subtitles/movie/155
```

```json
{
  "subtitles": [
    {
      "label": "English",
      "file": "https://your-api.example.com/api?url=https%3A%2F%2Fsubtitles.org%2Fen.vtt",
      "type": "vtt",
      "source": "opensubtitles"
    },
    {
      "label": "Spanish",
      "file": "https://your-api.example.com/api?url=https%3A%2F%2Fsubtitles.org%2Fes.vtt",
      "type": "vtt",
      "source": "opensubtitles"
    },
    {
      "label": "French",
      "file": "https://your-api.example.com/api?url=https%3A%2F%2Fsubtitles.org%2Ffr.srt",
      "type": "srt",
      "source": "subdl"
    }
  ]
}
```

---

### 2. Television Episode Subtitles

```http
GET /subtitles/tv/:id/:season/:episode HTTP/1.1
Host: your-api.example.com
```

#### Path Parameters
| Parameter | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| `id` | `integer` | Required | Numeric TMDB TV Series ID (e.g. `1396`) |
| `season` | `integer` | Required | Season number (e.g. `1`) |
| `episode` | `integer` | Required | Episode number (e.g. `1`) |

#### Example Request
```bash
curl https://your-api.example.com/subtitles/tv/1396/1/1
```

---

## Download Endpoints

Stream API resolves high-speed direct media download packages and torrent/debrid links. Download lookups are separated from playback streams to allow offline caching or background download managers.

---

### 1. Movie Downloads

```http
GET /downloads/movie/:id HTTP/1.1
Host: your-api.example.com
```

#### Example Response
```json
{
  "downloads": [
    {
      "quality": "1080p",
      "size": 2450882194,
      "type": "mkv",
      "active": true,
      "url": "https://fast-cdn.example.com/download/the-dark-knight-1080p.mkv"
    },
    {
      "quality": "720p",
      "size": 1150428190,
      "type": "mkv",
      "active": true,
      "url": "https://fast-cdn.example.com/download/the-dark-knight-720p.mkv"
    }
  ]
}
```

---

### 2. Television Episode Downloads

```http
GET /downloads/tv/:id/:season/:episode HTTP/1.1
Host: your-api.example.com
```

#### Example Response
```json
{
  "downloads": [
    {
      "quality": "1080p",
      "size": 1420882194,
      "type": "mkv",
      "active": true,
      "url": "https://fast-cdn.example.com/download/breaking-bad-s01e01-1080p.mkv"
    }
  ]
}
```

---

## Best Practices for Clients

1. **Do Not Block Initial Playback**: Initiate subtitle and download queries asynchronously. The video player should start playback immediately on the first candidate stream, and subtitles should be attached dynamically as they arrive.
2. **CORS Handling**: Subtitle files proxied through `/api?url=...` are served with `Access-Control-Allow-Origin: *`, ensuring HTML5 `<track>` elements load cleanly in cross-origin browser contexts.
3. **Format Support**: While most modern players prefer `.vtt`, some tracks are returned in `.srt`. If your player strictly requires WebVTT, convert SRT timestamps (`00:01:20,500` -> `00:01:20.500`) client-side before loading.

================================================================================
FILE: stream-api/reference/operations.md
================================================================================

# Operations, Health & Diagnostics

<p class="page-description">Monitoring, cluster diagnostics, live health probing, and testing endpoints in Stream API.</p>

## The Health Check Endpoint: `GET /health`

Stream API provides an automated health probe endpoint that executes live responsiveness checks across all registered scraper modules.

```http
GET /health HTTP/1.1
Host: your-api.example.com
```

### Response Status Codes
- **`200 OK`**: All active provider sources passed their health probes.
- **`207 Multi-Status`**: One or more providers failed their probes (degraded state), but the API gateway remains functional.

### Example Response Payload
```json
{
  "note": "This is a health check endpoint. This is extremely unreliable, be sure to test sources directly.",
  "status": "ok",
  "timestamp": "2026-11-14T20:30:00.000Z",
  "tmdb": true,
  "cache": 142,
  "probe_id": 155,
  "sources": {
    "vidlink": { "ok": true, "ms": 420 },
    "vixsrc": { "ok": true, "ms": 610 },
    "cinecat": { "ok": true, "ms": 890 },
    "movy": { "ok": false, "ms": null }
  }
}
```

#### Response Fields
| Field | Type | Description |
| :--- | :--- | :--- |
| `status` | `string` | Overall system state (`"ok"` or `"degraded"`). |
| `timestamp` | `string` | ISO 8601 timestamp of probe completion. |
| `tmdb` | `boolean` | `true` if `TMDB_API_KEY` is configured and valid in the environment. |
| `cache` | `integer` | Current number of active cached titles in the primary LRU cache. |
| `probe_id` | `integer` | The standard TMDB ID used to probe source responsiveness. |
| `sources` | `object` | Dictionary of per-source availability (`ok`) and roundtrip latency in milliseconds (`ms`). |

---

## Direct Source Testing: `GET /test/:source`

To test an individual scraper directly without querying all 60 providers:

```http
GET /test/vidlink?id=155 HTTP/1.1
```

For television episodes, pass season and episode query parameters:
```http
GET /test/vixsrc?id=1396&s=1&e=1 HTTP/1.1
```

### Response
Returns the raw resolved candidate object directly from the provider scraper:

```json
{
  "source": "vidlink",
  "url": "https://upstream.example.com/playlist.m3u8",
  "quality": "1080p",
  "type": "hls",
  "server": "vidlink-cf"
}
```

---

## Deep Debug Route: `GET /debug/:source`

When `ENABLE_DEBUG_ROUTE=true` is set in your environment variables, Stream API exposes a comprehensive diagnostic route:

```http
GET /debug/vidlink?id=155 HTTP/1.1
```

### Diagnostic Output Includes:
1. **Raw Scraper Payload**: Unmodified JSON or HTML received from the upstream host.
2. **Extraction Timings**: Milliseconds spent parsing DOM, solving tokens, and resolving URLs.
3. **Phase 1 Verification**: Status code, response headers, and latency of the `HEAD` request.
4. **Phase 2 Verification**: First 500 bytes of the master M3U8 playlist and test chunk fetch status.
5. **Rewritten URLs**: Preview of how chunk URIs will be rewritten by the proxy.

:::callout-warning
**Security Note**: Keep `ENABLE_DEBUG_ROUTE=false` in public production environments to avoid leaking internal scraper tokens or upstream endpoints.
:::

---

## Cluster & Cache Architecture

### Primary Supervisor & Worker Pool Architecture
- **Central In-Memory Cache**: Holds up to 1,500 verified title entries in a shared LRU table with a 5-minute TTL.
- **Periodic Pruner**: Runs every 30 seconds to clean expired keys and enforce memory ceilings.
- **Worker Lifecycle Supervisor**: Spawns and supervises $N$ worker processes matching CPU core count, automatically restarting terminated workers.
- **IPC Message Dispatcher**: Routes `cache:get` and `cache:set` messages between worker threads and the primary process.

1. **IPC Cache Synchronization**: When a worker resolves a title, it sends a `cache:set` message to the primary process. When another worker receives a request for the same title, it sends a `cache:get` message and receives an instant `cache:hit` without re-scraping upstream hosts.
2. **Cache Pruning**: The primary process evicts stale items older than 300,000ms (5 minutes). If total cache size exceeds 1,500 items, the oldest entries are evicted immediately.
3. **Worker Auto-Restart**: If a worker process exits unexpectedly or exceeds memory limits, the primary cluster supervisor automatically spawns a replacement worker.

================================================================================
FILE: stream-api/authentication/index.md
================================================================================

# API Keys & Authentication

<p class="page-description">Managing API keys, rate limits, SQLite database synchronization, and authorization headers in Stream API.</p>

## Overview

Stream API includes a built-in cryptographic key management and rate-limiting system backed by SQLite. When enabled, client applications must supply an authenticated key to establish Server-Sent Events connections or request proxied media streams.

---

## Key Structure & Prefixes

API keys are 32-character hexadecimal strings generated with a specific prefix indicating the client tier:

| Key Prefix | Key Type | Intended Use Case | Default Rate Limit |
| :--- | :--- | :--- | :--- |
| **`pk_`** | **Partner Key** | Verified high-volume partner frontends and applications | 1,000 req / minute |
| **`sk_`** | **Standard Key** | Private self-hosters and internal client instances | 500 req / minute |
| **`pub_`** | **Public Key** | Anonymous public trial access or open community frontends | 10 req / minute |

---

## Generating API Keys via CLI

The Stream API repository includes a CLI tool (`add-key.mjs`) to generate and insert keys into the active SQLite database:

```bash
# Syntax: node add-key.mjs <type> <rate_limit_per_min> <client_name>

# 1. Create a Standard Key for a personal desktop client:
node add-key.mjs standard 500 my-desktop-client

# 2. Create a Partner Key for a high-traffic community player:
node add-key.mjs partner 1000 partner-frontend

# 3. Create a restricted Public Key:
node add-key.mjs public 10 public-guest
```

### CLI Output Example
```
Generated Key: sk_8f14b2d39a7e4c5b10e9f8a7b6c5d4e3
Type: standard
Limit: 500 req/min
Client: my-desktop-client
Status: Active
```
The key is printed once upon creation. Copy and deliver it to your client application securely.

---

## Managing Keys via JSON Database Export

For automated deployments or bulk key management, you can export the database to a JSON file:

### 1. Export Database
```bash
node export-db.mjs
```
This dumps the active SQLite database tables into `db.json`:
```json
{
  "keys": [
    {
      "key": "sk_8f14b2d39a7e4c5b10e9f8a7b6c5d4e3",
      "type": "standard",
      "limit": 500,
      "client": "my-desktop-client",
      "active": 1,
      "created_at": "2026-11-14T12:00:00Z"
    }
  ]
}
```

### 2. Modify and Re-Import
Edit `db.json` to add, revoke, or modify limits, then commit the changes back to SQLite:
```bash
node update-db.mjs
```

---

## Client Authorization Headers

Clients can authenticate requests by passing the key in one of the following locations:

### 1. Authorization Header (Recommended)
```http
GET /movie?id=155 HTTP/1.1
Host: your-api.example.com
Authorization: Bearer sk_8f14b2d39a7e4c5b10e9f8a7b6c5d4e3
```

### 2. Custom API Key Header
```http
X-API-Key: sk_8f14b2d39a7e4c5b10e9f8a7b6c5d4e3
```

### 3. Query Parameter (for EventSource & HTML5 Video)
Because native browser `EventSource` and `<video>` tags do not support custom request headers, you can pass the key as a query parameter:
```http
GET /movie?id=155&key=sk_8f14b2d39a7e4c5b10e9f8a7b6c5d4e3 HTTP/1.1
```

---

## Rate Limit Headers

When requests are evaluated, Stream API returns standard rate-limiting headers:

```http
HTTP/1.1 200 OK
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 498
X-RateLimit-Reset: 1731614460
```

If a client exceeds their tier quota, Stream API responds with HTTP 429:
```json
{
  "error": "Rate limit exceeded. Please retry in 32 seconds.",
  "retry_after": 32
}
```

================================================================================
FILE: stream-api/deployment/self-hosting.md
================================================================================

# Self-Hosting Stream API

<p class="page-description">Complete production self-hosting guide for Stream API: Docker, Node.js systemd, PM2, and Nginx reverse proxy configuration with SSE streaming support.</p>

## Overview

Stream API is designed to be completely self-hostable on any Linux virtual private server (VPS), home server, or Docker container environment. Running your own instance gives you private access, eliminates shared IP rate limits, and allows you to tune worker concurrency to your hardware.

---

## Environment Variables

Configure your environment variables via a `.env` file in the project root:

| Variable | Required | Default | Description |
| :--- | :--- | :--- | :--- |
| `PORT` | Optional | `7860` | HTTP port on which the server binds. |
| `TMDB_API_KEY` | **Recommended** | `""` | The Movie Database v3 API key. Required for scrapers that resolve metadata via IMDb ID or episode titles. |
| `WORKER_COUNT` | Optional | `os.cpus().length` | Number of worker processes to fork in cluster mode. |
| `ENABLE_DEBUG_ROUTE` | Optional | `false` | Enables deep diagnostic traces at `/debug/:source`. Keep `false` in production. |
| `GA_MEASUREMENT_ID` | Optional | `""` | Google Analytics 4 Measurement ID for private usage telemetry. |
| `GA_API_SECRET` | Optional | `""` | Google Analytics 4 Measurement Protocol API Secret. |
| `FALLBACK_BASE` | Optional | `""` | Secondary Stream API instance URL used for failover redirects. |
| `IS_HF` | Optional | `false` | Enables HuggingFace Spaces compatibility constraints. |

---

## Deployment Option 1: Docker (Recommended)

### 1. Dockerfile
Create a `Dockerfile` in the project directory:

```dockerfile
FROM node:20-alpine

WORKDIR /app

# Install native dependencies required for TLS and encryption
RUN apk add --no-cache python3 make g++

COPY package*.json ./
RUN npm ci --omit=dev

COPY . .

ENV PORT=7860
EXPOSE 7860

CMD ["node", "server.js"]
```

### 2. Docker Compose
Create a `docker-compose.yml` file:

```yaml
version: '3.8'

services:
  stream-api:
    build: .
    container_name: vyla-stream-api
    restart: unless-stopped
    ports:
      - "127.0.0.1:7860:7860"
    environment:
      - PORT=7860
      - TMDB_API_KEY=your_tmdb_api_key_here
      - WORKER_COUNT=4
      - ENABLE_DEBUG_ROUTE=false
    volumes:
      - ./data:/app/data
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
```

Start the container in detached mode:
```bash
docker compose up -d
```

---

## Deployment Option 2: Direct Node.js & Systemd

### 1. Installation
```bash
# Clone the repository
git clone https://gitlab.com/vyla-entertainment/stream-api.git /opt/stream-api
cd /opt/stream-api

# Install dependencies
npm ci --omit=dev
```

### 2. Create Systemd Service
Create `/etc/systemd/system/stream-api.service`:

```ini
[Unit]
Description=Vyla Stream API Service
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/stream-api
ExecStart=/usr/bin/node /opt/stream-api/server.js
Restart=always
RestartSec=5
Environment=NODE_ENV=production
Environment=PORT=7860
Environment=TMDB_API_KEY=your_tmdb_api_key_here
Environment=WORKER_COUNT=4

# Security Hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full

[Install]
WantedBy=multi-user.target
```

Enable and start the service:
```bash
sudo systemctl daemon-reload
sudo systemctl enable --now stream-api
sudo systemctl status stream-api
```

---

## Reverse Proxy: Nginx Configuration

Because Stream API utilizes **Server-Sent Events (SSE)** and large **HLS video streams**, your reverse proxy must disable proxy buffering. Standard buffering will delay SSE events until the buffer fills, breaking progressive playback.

Create an Nginx configuration at `/etc/nginx/sites-available/stream-api.conf`:

```nginx
server {
    server_name stream-api.yourdomain.com;

    # Maximum upload size for DB syncs
    client_max_body_size 20M;

    location / {
        proxy_pass http://127.0.0.1:7860;
        proxy_http_version 1.1;

        # Mandatory for Server-Sent Events (SSE)
        proxy_set_header Connection '';
        proxy_buffering off;
        proxy_cache off;
        chunked_transfer_encoding off;

        # Keep-Alive & Timeouts for long media streams
        proxy_read_timeout 90s;
        proxy_send_timeout 90s;

        # Forward Client Identifiers for Geo-Token Verification
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    listen 80;
}
```

Enable the configuration and obtain a free SSL certificate via Certbot:
```bash
sudo ln -s /etc/nginx/sites-available/stream-api.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

# Install Let's Encrypt SSL
sudo certbot --nginx -d stream-api.yourdomain.com
```

---

## Verifying Your Deployment

Once deployed, verify the installation by testing the `/health` endpoint:

```bash
curl -i https://stream-api.yourdomain.com/health
```

You should receive an HTTP 200 (or 207) with JSON detailing the cluster status, cache count, and source probe results.

================================================================================
FILE: guides/integrations.md
================================================================================

# Client Integration Guide

<p class="page-description">Frontend and native player implementation patterns for integrating Vyla Stream API with HLS.js, React, Vue, Android ExoPlayer, and iOS AVPlayer.</p>

## Overview

Stream API exposes standard HTTP and Server-Sent Events (SSE) interfaces, allowing it to integrate with any modern video player library. This guide provides copyable, production-ready integration patterns across multiple platforms and frameworks.

---

## Pattern 1: React Player Hook

Below is a complete custom React hook (`useVylaStream`) managing SSE event consumption, fallback candidate queuing, and playback state:

```tsx
import { useState, useEffect, useRef } from 'react';

interface StreamSource {
  source: string;
  label: string;
  url: string;
  quality: string;
  type: 'hls' | 'mp4';
}

interface StreamMeta {
  title: string;
  year: number;
  poster: string;
}

export function useVylaStream(apiBase: string, tmdbId: number, season?: number, episode?: number) {
  const [meta, setMeta] = useState<StreamMeta | null>(null);
  const [activeSource, setActiveSource] = useState<StreamSource | null>(null);
  const [subtitles, setSubtitles] = useState<any[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const fallbackQueue = useRef<StreamSource[]>([]);
  const eventSourceRef = useRef<EventSource | null>(null);

  useEffect(() => {
    setIsLoading(true);
    setError(null);
    fallbackQueue.current = [];

    const endpoint = season != null && episode != null
      ? `${apiBase}/tv?id=${tmdbId}&season=${season}&episode=${episode}`
      : `${apiBase}/movie?id=${tmdbId}`;

    const es = new EventSource(endpoint);
    eventSourceRef.current = es;

    es.onmessage = (event) => {
      const data = JSON.parse(event.data);

      if (data.type === 'meta') {
        setMeta(data.meta);
        if (data.subtitles) setSubtitles(data.subtitles);
      } 
      else if (data.type === 'source') {
        if (!activeSource) {
          setActiveSource(data);
          setIsLoading(false);
        } else {
          fallbackQueue.current.push(data);
        }
      } 
      else if (data.type === 'done') {
        es.close();
        if (!activeSource && fallbackQueue.current.length === 0) {
          setError('No available streaming sources found.');
          setIsLoading(false);
        }
      }
    };

    es.onerror = () => {
      es.close();
      if (!activeSource) {
        setError('Failed to connect to Stream API.');
        setIsLoading(false);
      }
    };

    return () => {
      es.close();
    };
  }, [apiBase, tmdbId, season, episode]);

  const triggerNextFallback = () => {
    if (fallbackQueue.current.length > 0) {
      const next = fallbackQueue.current.shift()!;
      console.warn(`Switching to fallback candidate: ${next.label}`);
      setActiveSource(next);
    } else {
      setError('All provider stream candidates exhausted.');
    }
  };

  return { meta, activeSource, subtitles, isLoading, error, triggerNextFallback };
}
```

---

## Pattern 2: Vue 3 Composable Component

```vue
<template>
  <div class="player-wrapper">
    <video ref="videoRef" controls playsinline></video>
    <div v-if="isLoading" class="loading-overlay">Discovering streams...</div>
    <div v-if="error" class="error-banner">{{ error }}</div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch } from 'vue';
import Hls from 'hls.js';

const props = defineProps<{
  apiBase: string;
  tmdbId: number;
}>();

const videoRef = ref<HTMLVideoElement | null>(null);
const isLoading = ref(true);
const error = ref<string | null>(null);
let hls: Hls | null = null;
let es: EventSource | null = null;

function loadStream(url: string) {
  if (!videoRef.value) return;

  if (Hls.isSupported()) {
    if (hls) hls.destroy();
    hls = new Hls({ maxBufferLength: 30 });
    hls.loadSource(url);
    hls.attachMedia(videoRef.value);
    hls.on(Hls.Events.MANIFEST_PARSED, () => videoRef.value?.play());
  } else if (videoRef.value.canPlayType('application/vnd.apple.mpegurl')) {
    videoRef.value.src = url;
    videoRef.value.play();
  }
}

onMounted(() => {
  es = new EventSource(`${props.apiBase}/movie?id=${props.tmdbId}`);
  let firstSourceReceived = false;

  es.onmessage = (e) => {
    const data = JSON.parse(e.data);
    if (data.type === 'source' && !firstSourceReceived) {
      firstSourceReceived = true;
      isLoading.value = false;
      loadStream(data.url);
    } else if (data.type === 'done') {
      es?.close();
    }
  };
});

onUnmounted(() => {
  es?.close();
  hls?.destroy();
});
</script>
```

---

## Pattern 3: Android Native (Kotlin & ExoPlayer)

In Android applications, connect to the Stream API proxy using Google's `MediaItem`:

```kotlin
import androidx.media3.common.MediaItem
import androidx.media3.common.MimeTypes
import androidx.media3.exoplayer.ExoPlayer

fun playStream(player: ExoPlayer, proxiedHlsUrl: String) {
    val mediaItem = MediaItem.Builder()
        .setUri(proxiedHlsUrl)
        .setMimeType(MimeTypes.APPLICATION_M3U8)
        .build()

    player.setMediaItem(mediaItem)
    player.prepare()
    player.playWhenReady = true
}
```

---

## Pattern 4: iOS / macOS Native (Swift & AVPlayer)

Because iOS AVPlayer natively handles HLS streams and respects cookies/redirects, assigning the proxied URL is straightforward:

```swift
import AVKit

func playVylaStream(proxiedUrlString: String) {
    guard let url = URL(string: proxiedUrlString) else { return }
    let player = AVPlayer(url: url)
    let playerViewController = AVPlayerViewController()
    playerViewController.player = player
    
    // Present player and begin playback
    present(playerViewController, animated: true) {
        player.play()
    }
}
```

================================================================================
FILE: guides/error-handling.md
================================================================================

# Error Handling & Resilience Guide

<p class="page-description">Strategies, error classification, and recovery patterns for handling network stalls, upstream rate limits, and streaming failures.</p>

## Overview

Streaming from distributed upstream web providers is inherently dynamic. Upstream CDN nodes rotate domains, regional ISPs implement traffic shaping, and token signatures expire. 

Building a resilient client requires planning for failure at every step. This guide explains how Vyla handles errors internally and how client players should respond.

---

## Error Classification Matrix

| Error Type | Common Cause | Stream API / SDK Behavior | Recommended Player Action |
| :--- | :--- | :--- | :--- |
| **HTTP 400 Bad Request** | Missing or malformed TMDB ID, invalid season/episode | Returns immediate JSON error payload without querying providers. | Validate input parameters client-side before sending requests. |
| **HTTP 429 Too Many Requests** | Upstream host rate-limiting client IP | SDK provider applies backoff delay and retries up to `retries` limit. | If proxy returns 429, respect the `retry_after` header and back off. |
| **HTTP 502 Bad Gateway** | Upstream provider host is unreachable or timed out | Provider is discarded; other scrapers continue executing. | Fall back to the next available stream candidate in your queue. |
| **SSE Disconnect** | Network hiccup or client tab backgrounded | Connection drops; `EventSource.onerror` fires. | If video is already playing, do not interrupt. Otherwise, reconnect after 2 seconds. |
| **HLS Fatal Media Error** | Segment buffer stall, corrupt chunk, or missing decryption key | Player triggers `Hls.Events.ERROR` with `fatal: true`. | Call `hls.destroy()` and load the next candidate from your fallback queue. |

---

## Client Fallback Queue Strategy

Always treat streaming candidate resolution as a prioritized queue rather than a single static link:

### Queue Priority Assignment

| Candidate Stream | Player State | Fallback Precedence |
| :--- | :--- | :--- |
| **Candidate 1** (`vidlink`) | **Active Playback** | Mounted into HLS.js or ExoPlayer on arrival. |
| **Candidate 2** (`vixsrc`) | **Standby Backup** | Enqueued as Priority #1 fallback stream. |
| **Candidate 3** (`cinecat`) | **Standby Backup** | Enqueued as Priority #2 fallback stream. |

### Recovery Sequence on Stream Stall
1. **Error Interception**: Player detects a fatal network or decode event (`data.fatal === true`).
2. **Timestamp Preservation**: Record current playback offset (e.g. `currentTime = 142.5s`).
3. **Buffer Teardown**: Call `hls.destroy()` or `player.release()` to release media pipelines and decoders.
4. **Queue Advancement**: Dequeue the next available verified candidate from the standby queue.
5. **Seamless Seek**: Mount the fallback source and seek immediately to the preserved timestamp upon `loadedmetadata`.

### Implementing Fallback Recovery in JavaScript

```javascript
function attachHlsPlayer(videoElement, candidate, fallbackQueue) {
  const hls = new Hls({
    maxBufferLength: 30,
    maxMaxBufferLength: 60,
    enableWorker: true
  });

  hls.loadSource(candidate.url);
  hls.attachMedia(videoElement);

  hls.on(Hls.Events.ERROR, (event, data) => {
    if (!data.fatal) return;

    console.warn(`Encountered fatal error on ${candidate.source}:`, data.type);

    switch (data.type) {
      case Hls.ErrorTypes.NETWORK_ERROR:
        console.log("Attempting network recovery...");
        hls.startLoad();
        break;
      case Hls.ErrorTypes.MEDIA_ERROR:
        console.log("Attempting media recovery...");
        hls.recoverMediaError();
        break;
      default:
        // Unrecoverable error: switch to next fallback candidate
        hls.destroy();
        if (fallbackQueue.length > 0) {
          const nextCandidate = fallbackQueue.shift();
          const lastTime = videoElement.currentTime;
          console.warn(`Switching to fallback candidate: ${nextCandidate.label}`);

          attachHlsPlayer(videoElement, nextCandidate, fallbackQueue);
          videoElement.addEventListener('loadedmetadata', () => {
            videoElement.currentTime = lastTime;
            videoElement.play();
          }, { once: true });
        } else {
          showErrorOverlay("All available streaming providers have failed.");
        }
        break;
    }
  });

  return hls;
}
```

---

## Client-Side Timeout Budgets

Never leave users hanging on an indefinite spinner. Implement a two-tiered timeout budget:

1. **Initial Candidate Timeout (8–10 seconds)**: If no `type: "source"` event has arrived within 8 seconds, update the UI to indicate extended searching.
2. **Hard Timeout (20 seconds)**: If the stream has not completed or emitted a viable candidate within 20 seconds:
   - Call `eventSource.close()`.
   - Render a helpful empty-state UI with a "Retry" button or an option to change the server URL.

---

## Decoupled Subtitle Fallback

Subtitles originate from independent subtitle repositories (e.g. OpenSubtitles, SubDL). If a subtitle track fails to load:
- The video playback must continue uninterrupted.
- Log a warning in the console.
- Offer the viewer an in-player menu to toggle alternative subtitle providers or upload a local `.srt`/`.vtt` file.

================================================================================
FILE: resources/faq.md
================================================================================

# Frequently Asked Questions (FAQ)

<p class="page-description">Answers to common questions regarding the Vyla ecosystem, self-hosting, platform compatibility, and legal policies.</p>

## General Questions

### What is Vyla?
Vyla is a community-built, decentralized media platform and developer ecosystem. It provides client applications (Desktop, Android, Android TV), a multi-provider scraping resolver SDK (`@vyla-entertainment/sdk`), and a self-hostable HTTP/SSE streaming gateway (Stream API).

### Does Vyla host or stream any media?
**No.** Vyla does not host, upload, cache, or distribute copyrighted video files or media streams. The software functions purely as a client-side indexing and scraping engine that queries publicly accessible third-party providers on demand.

### Is Vyla free and open source?
Yes. All components of the Vyla ecosystem are open source, licensed under standard permissive open-source licenses, and free to inspect, fork, and self-host.

---

## Technical & Developer Questions

### Why do I need a TMDB API Key?
The Movie Database (TMDB) provides authoritative metadata, cover artwork, cast details, and standardized numeric identifiers for movies and TV episodes. Several provider scrapers require converting TMDB IDs to IMDb IDs or episode names. You can obtain a free API key at [themoviedb.org](https://www.themoviedb.org/).

### Why do some sources work on my home PC but fail on a datacenter VPS?
Many public upstream video hosts employ Cloudflare or proprietary anti-bot protections that block known datacenter IP subnets (e.g. AWS, DigitalOcean, Hetzner, OVH) while allowing residential IP connections. When self-hosting Stream API on a VPS, some scrapers may encounter IP-based challenges that do not appear on residential connections.

### What is the difference between Vyla SDK and Stream API?
- **Vyla SDK (`@vyla-entertainment/sdk`)**: A Node.js library you install directly in a backend application using `npm install`. It runs scrapers directly in your process.
- **Stream API**: A standalone, self-hostable HTTP/SSE microservice that wraps the SDK, providing a web API for mobile apps, smart TVs, and browser frontends that cannot execute Node.js modules natively.

### What is the 120-byte segment de-masking routine?
Certain streaming providers mask video chunks by prepending a 120-byte fake image header (such as a PNG or JPEG file signature) to disguise traffic. Stream API inspects video chunks and automatically slices off the fake header, restoring valid MPEG-TS video for standard video players.

---

## Application & Platform Questions

### Which desktop operating systems are supported by Vyla Home?
Vyla Home officially supports 64-bit Windows (Windows 10/11), macOS (Universal binary supporting Apple Silicon and Intel), and Linux (via source compilation and Flatpak packages).

### Can I run Vyla TV on Amazon Fire TV devices?
Yes. Vyla TV is built for Android TV (API 26+) and is fully compatible with Amazon Fire TV devices (Fire TV Stick 4K, Fire TV Cube, etc.). You can sideload the APK using tools like Downloader.

### What should I do if Vyla Home fails with a WebView2 error on Windows?
Ensure the Microsoft Edge WebView2 Evergreen Runtime is installed. If running a portable version, verify that `WebView2Loader.dll` is present in the `bin/` directory adjacent to the application executable.

---

## Policies & Community

### How do rights holders request removal of a source?
Rights holders can submit source removal requests directly to our team. We promptly review and disable scrapers for requested domains. See our [DMCA Policy](/misc/project/dmca) for contact instructions.

### How can I contribute to Vyla?
We welcome code contributions, documentation improvements, and bug reports on [GitLab](https://gitlab.com/vyla-entertainment). Check out the [Contributing Guide](/sdk/vyla-sdk/contributing) to learn how to author and submit new provider scrapers.

================================================================================
FILE: resources/troubleshooting.md
================================================================================

# Troubleshooting & Diagnostics

<p class="page-description">Step-by-step diagnostic workflows and resolutions for common issues across Vyla Home, Vyla Go, Vyla TV, Stream API, and the SDK.</p>

## Desktop: Vyla Home

### 1. Windows: "WebView2 runtime initialization error"
- **Cause**: The Microsoft Edge WebView2 runtime is missing or corrupted on the host machine.
- **Resolution**:
  1. Download and run the Evergreen Bootstrapper installer from [Microsoft's WebView2 page](https://developer.microsoft.com/en-us/microsoft-edge/webview2/).
  2. If using portable builds, verify that `WebView2Loader.dll` exists in `bin\WebView2Loader.dll`.

### 2. Windows: "OS Error 32: File in use by another process"
- **Cause**: A previous Tauri, Node.js, or Cargo process is still running in the background and holding a file lock.
- **Resolution**: Terminate any dangling processes in PowerShell:
  
```powershell
  Stop-Process -Name "vyla-home", "node", "cargo" -Force -ErrorAction SilentlyContinue
```

### 3. Linux: Build Fails with Missing WebKit or AppIndicator
- **Cause**: Linux requires native GTK3 and WebKit development headers.
- **Resolution**: Install required system packages:
  - **Fedora**: `sudo dnf install webkit2gtk4.1-devel libappindicator-gtk3-devel librsvg2-devel`
  - **Ubuntu/Debian**: `sudo apt install libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev`

### 4. Inspecting Node Sidecar Logs
If Vyla Home launches but media fails to resolve:
- **Windows**: Open `%APPDATA%\vyla-home\vyla-home-files\logs\node-debug.log`
- **macOS**: Open `~/Library/Application Support/vyla-home/vyla-home-files/logs/node-debug.log`

---

## Mobile: Vyla Go

### 1. Emulator DNS Timeouts when Connecting to GitLab
- **Cause**: Android emulators occasionally fail to resolve remote domains when private DNS is active.
- **Resolution**: Disable private DNS mode via ADB:
  
```powershell
  & "$env:LOCALAPPDATA\Android\Sdk\platform-tools\adb.exe" shell settings put global private_dns_mode off
```

### 2. Dumping Crash Logs from Device
To capture a full logcat dump of crash traces:
```powershell
& "$env:LOCALAPPDATA\Android\Sdk\platform-tools\adb.exe" logcat -d | Select-String "VylaGo|AndroidRuntime|FATAL"
```

### 3. Resetting Cached App Data
```powershell
& "$env:LOCALAPPDATA\Android\Sdk\platform-tools\adb.exe" shell am force-stop com.vyla.go
& "$env:LOCALAPPDATA\Android\Sdk\platform-tools\adb.exe" shell pm clear com.vyla.go
```

---

## Living Room: Vyla TV

### 1. Build Fails during `assembleDebug`
- **Cause**: Incompatible Java Development Kit (JDK) or missing Android TV SDK platform.
- **Resolution**:
  1. Ensure JDK 17 or JDK 21 is active: `java -version`.
  2. Ensure Android TV API level 26 or higher is installed via Android Studio SDK Manager.

### 2. Video Stalls or Fails to Play on Fire TV
- **Cause**: Hardware codec mismatch or network buffer underrun.
- **Resolution**:
  1. Inside the player, press the Down button on your D-pad to open the stream switcher.
  2. Select an alternative provider (e.g. switch from an adaptive HLS stream to a direct 1080p stream).

---

## Backend: Stream API

### 1. SSE Events Delayed or Arriving All at Once
- **Cause**: The reverse proxy (Nginx, Cloudflare, Caddy) is buffering chunked responses.
- **Resolution**:
  1. In Nginx, ensure `proxy_buffering off;` and `proxy_cache off;` are configured in your `location` block.
  2. In Cloudflare, ensure response buffering is disabled for your streaming subdomain.

### 2. `EADDRINUSE: address already in use :::7860`
- **Cause**: A previous Stream API instance is already bound to port 7860.
- **Resolution**:
  
```bash
  # Find PID on Linux
  lsof -i :7860
  # Kill hung process
  kill -9 <PID>
```

### 3. TMDB API Warnings in Console
- **Warning**: `Warning: TMDB_API_KEY not set, imdb-required sources will be unavailable`
- **Resolution**: Add `TMDB_API_KEY=your_key` to your `.env` file and restart the service.

================================================================================
FILE: resources/glossary.md
================================================================================

# Ecosystem Glossary

<p class="page-description">Authoritative definitions for technical terms, protocols, and architectural concepts across the Vyla ecosystem.</p>

## A

### AES-128 Encryption
A symmetric key cipher frequently used in HLS streaming. The playlist references an encryption key endpoint (`#EXT-X-KEY:METHOD=AES-128,URI="..."`). Stream API proxies and rewrites these key URIs to ensure playback permissions and headers match the viewer's session.

---

## C

### Cluster Primary & Worker
Node.js architecture utilized by Stream API. The **Primary** master process allocates CPU affinity, coordinates IPC messaging, and supervises workers. **Workers** handle inbound HTTP client requests, parse streams, and query upstream hosts concurrently.

---

## E

### ExoPlayer (Media3)
Google's high-performance, customizable media player library for Android. Used by Vyla TV to render adaptive 4K/HDR HLS streams with hardware acceleration.

---

## F

### Fallback Priority Queue
A client-side architecture where candidate video streams emitted by Stream API are queued in memory. If the currently playing stream crashes or drops offline, the player immediately mounts the next candidate in the queue without interrupting the viewer.

---

## H

### HLS (HTTP Live Streaming)
An adaptive bitrate streaming communications protocol developed by Apple. Video is divided into a sequence of small HTTP-based file chunks (.ts or .m4s) indexed by a master `.m3u8` playlist.

### HLS.js
A JavaScript library that implements an HLS client using HTML5 video and Media Source Extensions (MSE). Used by custom web players to play Vyla HLS streams in browsers lacking native HLS support.

---

## J

### Jitter Staggering
A randomized delay (0 to 800ms) injected before scraper network requests fire. Prevents dozens of concurrent scrapers from triggering upstream Cloudflare or DDoS rate limits at the same millisecond.

---

## M

### M3U8 Playlist
A UTF-8 encoded text file representing an HLS playlist. Stream API intercepts and rewrites master and media M3U8 playlists so that chunk and encryption key URLs route through the proxy with valid CORS headers.

---

## P

### Progressive Streaming
A delivery pattern where metadata and media candidates are emitted to client players in real time over Server-Sent Events (SSE) as each scraper finishes, rather than waiting for all scrapers to complete.

### Provider / Scraper
A self-contained JavaScript module in `@vyla-entertainment/sdk` (`src/sources/`) that queries an upstream video host, extracts stream URLs, and formats headers.

---

## S

### Server-Sent Events (SSE)
A standardized HTML5 server-to-client streaming technology over a persistent HTTP connection (`Content-Type: text/event-stream`). Used by Stream API `/movie` and `/tv` routes to emit `meta`, `source`, and `done` events.

### Sidecar Process
An architectural pattern used in Vyla Home where a secondary runtime process (Node.js) is bundled adjacent to the primary native application shell (Tauri Rust binary) to manage local services.

---

## T

### Tauri v2
A framework for building tiny, ultra-fast native applications for all major desktop and mobile platforms using web frontends and Rust backends. Vyla Home and Vyla Go are built on Tauri v2.

### TMDB (The Movie Database)
A community-built movie and television database. Vyla standardizes all movie and TV series queries on numeric TMDB IDs.

### TS Segment De-Masking (120-Byte Stripping)
A de-obfuscation routine implemented in Stream API. Certain CDNs disguise video chunks by prepending a 120-byte fake image header (PNG, JPEG, TikTok CDN). Stream API removes these 120 bytes, restoring valid MPEG-TS video for media players.

================================================================================
FILE: ARCHITECTURE.md
================================================================================

# Vyla Ecosystem Architecture

> High-level architecture, module boundaries, communication protocols, and design principles of the Vyla Ecosystem.

## System Topology

| Ecosystem Layer | Core Technologies | Primary Responsibilities |
| :--- | :--- | :--- |
| **Client Interfaces** | Vyla Home (Tauri v2), Vyla Go (Mobile), Vyla TV (ExoPlayer), Web Players | Render UI, manage local user state, initiate playback via SSE, handle failover queues. |
| **Stream API Gateway** | Node.js Cluster, SSE, HTTP Proxy | Multi-core IPC caching (1,500 entries, 5-min TTL), HLS/AES key rewriting, 120-byte fake image mask stripping. |
| **Vyla SDK Resolver** | `@vyla-entertainment/sdk` (ESM) | 60+ provider scrapers, randomized jitter scheduling, two-phase stream validation, manga scraping with Chrome 131 TLS fingerprinting. |
| **Upstream Hosts** | Third-party CDNs & Video Hosts | Remote video segment delivery, HLS manifest endpoints, subtitle hosts. |

## Projects Overview

| Directory / Package | Language / Framework | Purpose |
| :--- | :--- | :--- |
| `Documentation` | HTML5, Vanilla JS, CSS3 | Official developer documentation platform hosted at [vyla.cc](https://vyla.cc). |
| `Stream API` | Node.js (Cluster, HTTP, SSE) | Self-hosted streaming microservice gateway with caching and reverse proxying. |
| `SDK` | Node.js (ESM), TLS Client | Core multi-provider scraping library (`@vyla-entertainment/sdk`). |
| `Home` | Tauri v2, Rust, Node.js Sidecar | Native desktop application for Windows, macOS, and Linux. |
| `TV` | Kotlin, Jetpack Compose, ExoPlayer | Native 10-foot Leanback streaming application for Android TV and Fire TV. |
| `Go` | Tauri v2 Mobile, WebGL Shaders | Native mobile client for Android devices. |

## Core Architectural Invariants

1. **Decoupled Resolution**: Client interfaces never scrape providers directly; they interact through `@vyla-entertainment/sdk` or the Stream API gateway.
2. **Progressive Playback**: Streaming links are emitted incrementally over Server-Sent Events (SSE). Players start playback on the first candidate (3-8s) and queue subsequent sources as fallbacks.
3. **Transparent Proxying**: All upstream HLS playlists are rewritten to route segments and AES encryption keys through the local gateway, bypassing browser CORS restrictions and stripping 120-byte image obfuscation masks.
4. **Resilience by Default**: Provider queries are scheduled with randomized jitter and timeout budgets to prevent burst rate limits.

================================================================================
FILE: CONTRIBUTING.md
================================================================================

# Contributing to the Vyla Ecosystem

Thank you for your interest in contributing to Vyla! We welcome contributions across all ecosystem repositories: frontend applications, developer tooling, documentation, and scraper modules.

## How to Contribute

### 1. Contributing Source Scrapers (`SDK`)
The most common contribution is adding or updating a provider scraper in `@vyla-entertainment/sdk`:
- Follow the [Contributing a Source Guide](https://vyla.cc/sdk/vyla-sdk/contributing).
- Author modules inside `src/sources/<source_name>.js`.
- Ensure your module exports `async function getStream(args)` returning a valid `StreamResult`.
- Register the new source in `src/config.js`.
- Test against known movie (TMDB 155) and TV (TMDB 1396) identifiers.

### 2. Contributing to Applications
- **Vyla Home**: Native desktop client built on Tauri v2. Review [Home Documentation](https://vyla.cc/products/home).
- **Vyla Go**: Native Android mobile client built on Tauri v2 Mobile. Review [Go Documentation](https://vyla.cc/products/go).
- **Vyla TV**: Android TV Leanback client built with Jetpack Compose & ExoPlayer. Review [TV Documentation](https://vyla.cc/products/tv).

### 3. Contributing to Documentation
- Edit or add markdown files in the `Documentation` repository.
- Ensure semantic Markdown formatting, accurate code snippets, and WCAG accessibility standards.
- Check that all internal links resolve cleanly.

## Code Standards & Guidelines

- **ES Modules**: Write modern, clean ES Module syntax (`import`/`export`).
- **No Secrets**: Never commit private API keys, tokens, or personal server endpoints.
- **Error Handling**: Throw informative, descriptive errors rather than silently swallowing exceptions.
- **Verification**: Ensure all stream candidates pass two-phase verification (`verifyStream` and `verifyPlayable`).

================================================================================
FILE: SECURITY.md
================================================================================

# Security Policy

## Supported Versions

Security updates and bug fixes are applied to the latest releases of the Vyla ecosystem projects:

| Project | Supported Versions |
| :--- | :--- |
| **Vyla Home** | Latest 1.1.x release |
| **Vyla Go** | Latest 1.0.x release |
| **Vyla TV** | Latest 1.0.x release |
| **Stream API** | Latest 2.0.x release |
| **Vyla SDK** | Latest 1.28.x release |

## Reporting a Vulnerability

We take the security of our users and infrastructure seriously. If you discover a vulnerability, memory safety issue, or data leak within any Vyla project:

1. **Do not create a public issue** on GitLab or GitHub.
2. Contact the core maintainers privately via Discord or by emailing our security team.
3. Provide detailed steps to reproduce the issue, including environment details and proof-of-concept scripts where applicable.

We will review, patch, and publish a coordinated advisory and release promptly.

================================================================================
FILE: GLOSSARY.md
================================================================================

# Vyla Ecosystem Glossary

Authoritative reference glossary of terms, abbreviations, and architectural patterns used across the Vyla ecosystem.

- **AES-128 Key Rewriting**: The process in Stream API where HLS encryption key URIs (`#EXT-X-KEY`) are rewritten to route through the local proxy with permissive CORS headers.
- **Cluster Primary**: The master Node.js process in Stream API that manages inter-process IPC, shared LRU caching, and worker lifecycles.
- **Cluster Worker**: A child process in Stream API handling incoming HTTP requests and executing scraper resolution.
- **ExoPlayer (Media3)**: Google's media playback library for Android, powering Vyla TV's native Leanback interface.
- **Fallback Queue**: A client-side array holding secondary video candidates emitted by Stream API to provide instant recovery if the primary stream fails.
- **HLS (HTTP Live Streaming)**: Adaptive streaming protocol using M3U8 playlists and MPEG-TS / fragmented MP4 chunks.
- **HLS.js**: JavaScript library enabling HLS playback in standard HTML5 video elements via Media Source Extensions (MSE).
- **Jitter Staggering**: A randomized delay (0–800ms) injected into scraper requests to prevent concurrent burst requests against upstream CDNs.
- **Manga Module**: A module in `@vyla-entertainment/sdk` powered by `atsu.moe` and `node-tls-client` that bypasses TLS anti-bot protections via Chrome 131 fingerprinting.
- **Server-Sent Events (SSE)**: Standardized persistent HTTP streaming protocol (`text/event-stream`) used by `/movie` and `/tv` to emit metadata and sources progressively.
- **Sidecar Process**: A companion Node.js background process bundled inside Vyla Home (Tauri v2) to supervise local services and file updates.
- **TMDB ID**: The numeric identifier assigned by The Movie Database (themoviedb.org) used across all Vyla movie and television endpoints.
- **TS Segment De-Masking**: The routine in Stream API that strips the first 120 bytes off obfuscated video chunks disguised as fake PNG or JPEG files.

