> ## Documentation Index
> Fetch the complete documentation index at: https://globaliptv.misidev.com/llms.txt
> Use this file to discover all available pages before exploring further.

# App constants

> Reference for all constants defined in AppConstants() in source/AppConstants.brs.

`source/AppConstants.brs` exposes a single function `AppConstants()` that returns an associative array of every tunable value in the application. Centralizing configuration here avoids magic numbers scattered across the codebase and makes it easy to audit and update values before a release.

```brightscript source/AppConstants.brs theme={null}
function AppConstants() as Object
    return {
        ' ... all constants ...
    }
end function
```

Call `AppConstants()` anywhere in BrightScript to get a fresh copy of the table. There is no global singleton — the AA is constructed on each call.

## Server & endpoints

| Constant            | Value                                                       | Description                                                                                                                                             |
| ------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `SERVER_LIST`       | `["http://172.17.11.2:3333", "https://admin.globaltv.lat"]` | Ordered list of backend servers. Index 0 is the LAN server; index 1 is the production server. The app tries servers in order and falls back on failure. |
| `PATH_HEALTH`       | `/health`                                                   | Health-check endpoint. Polled to determine if a server is reachable before attempting auth.                                                             |
| `PATH_HANDSHAKE`    | `/api/v1/app/devices/handshake`                             | Device handshake endpoint called at startup to register the device.                                                                                     |
| `PATH_AUTH_TPL`     | `/auth/{user}/{pass}`                                       | URL template for authentication. `{user}` and `{pass}` are substituted at runtime.                                                                      |
| `PATH_PLAYLIST_TPL` | `/auth/{user}/{pass}/playlist/m3u8/hls`                     | URL template for fetching the HLS channel playlist after successful auth.                                                                               |
| `PATH_ADS`          | `/api/v1/app/ads/active`                                    | Endpoint for fetching the current active ad snapshot from the main backend.                                                                             |
| `PATH_METRICS`      | `/api/v1/app/metrics/track`                                 | Endpoint for posting playback and engagement metrics.                                                                                                   |

<Note>
  `SERVER_LIST[0]` (`172.17.11.2:3333`) is a LAN address intended for local development. In production environments the app selects the best available server from the list based on health-check results.
</Note>

## Ads backend

| Constant                        | Value                             | Description                                                                                   |
| ------------------------------- | --------------------------------- | --------------------------------------------------------------------------------------------- |
| `ADS_API_BASE_URL`              | `https://ads.globaltv.lat/api/v1` | Base URL for the dedicated ads backend. All `ADS_PATH_*` constants are relative to this base. |
| `ADS_PATH_HANDSHAKE`            | `/app/devices/handshake`          | Ads backend handshake path.                                                                   |
| `ADS_PATH_HANDSHAKE_FALLBACK`   | `""`                              | Fallback path for the ads handshake. Empty string disables the fallback.                      |
| `ADS_PATH_ACTIVE`               | `/app/ads/active`                 | Path for fetching the active ad snapshot from the ads backend.                                |
| `ADS_PATH_ACTIVE_FALLBACK`      | `""`                              | Fallback path for the active ad snapshot. Empty string disables the fallback.                 |
| `ADS_PATH_IMPRESSIONS`          | `/app/impressions/events/batch`   | Path for posting impression events in batch.                                                  |
| `ADS_PATH_IMPRESSIONS_FALLBACK` | `""`                              | Fallback path for impression batch posting. Empty string disables the fallback.               |
| `ADS_USE_DEDICATED`             | `true`                            | When `true`, the app uses `ADS_API_BASE_URL` for all ad requests instead of the main backend. |
| `ADS_HANDSHAKE_ENABLED`         | `true`                            | When `true`, the app performs the ads handshake before fetching ad snapshots.                 |

## Timeouts & retries

| Constant                   | Value      | Description                                                                                                         |
| -------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------- |
| `TIMEOUT_HEALTH`           | `2500` ms  | Maximum wait time for a health-check response. Kept low so server selection is fast.                                |
| `TIMEOUT_AUTH`             | `15000` ms | Maximum wait time for an authentication response. Higher to accommodate slow connections.                           |
| `TIMEOUT_HTTP`             | `12000` ms | Default timeout for general HTTP requests (playlist fetch, metrics, etc.).                                          |
| `RETRY_MAX`                | `3`        | Maximum number of retry attempts for a failed HTTP request before giving up.                                        |
| `SERVER_LAN_FORCE_RETRIES` | `3`        | Number of forced retries specifically for the LAN server (`SERVER_LIST[0]`) before falling back to the next server. |

## Polling intervals

| Constant                | Value               | Description                                                                                      |
| ----------------------- | ------------------- | ------------------------------------------------------------------------------------------------ |
| `ADS_POLL_MS`           | `10000` ms          | Interval between ad snapshot polls in `AdsPollingTask`.                                          |
| `NET_RETRY_MS`          | `30000` ms          | Interval between connectivity retries in `ConnectivityTask` after a network failure is detected. |
| `FREEZE_CHECK_MS`       | `10000` ms          | Interval at which the player checks for a frozen or stalled video stream.                        |
| `SESSION_AUTH_CHECK_MS` | `420000` ms (7 min) | Interval between periodic re-authentication checks to detect expired or revoked sessions.        |

## Registry keys

The Roku registry is persistent key-value storage that survives channel reinstalls. All GlobalTV registry entries are stored under the `GlobalTV` section.

| Constant                  | Value                | Description                                                            |
| ------------------------- | -------------------- | ---------------------------------------------------------------------- |
| `REG_SECTION`             | `"GlobalTV"`         | Registry section name under which all keys are stored.                 |
| `REG_KEY_USER`            | `"username"`         | Stores the authenticated username.                                     |
| `REG_KEY_PASS`            | `"password"`         | Stores the authenticated password.                                     |
| `REG_KEY_SERVER`          | `"lastServer"`       | Stores the URL of the last successfully used server.                   |
| `REG_KEY_CHANNEL`         | `"lastChannelIndex"` | Stores the index of the last watched channel for auto-resume.          |
| `REG_KEY_SAFE_MARGIN`     | `"uiSafeMarginPct"`  | Stores the user-configured safe area margin percentage (0–10).         |
| `REG_KEY_SERVER_PROFILES` | `"serverProfiles"`   | Stores serialized server profile data for the server management panel. |

## Auth reason codes

These codes are returned by `GTV_AuthClassifyFailure()` to describe why an authentication attempt failed. They are used to drive the error messaging shown to the user.

| Constant                       | Value | Description                                                                           |
| ------------------------------ | ----- | ------------------------------------------------------------------------------------- |
| `AUTH_REASON_NONE`             | `0`   | Auth succeeded or failure reason is unknown.                                          |
| `AUTH_REASON_NETWORK_DOWN`     | `460` | HTTP response code `-1` — no network connectivity.                                    |
| `AUTH_REASON_CREDENTIALS`      | `401` | Bad username or password (HTTP 401, 403, 404, or credential signal in response body). |
| `AUTH_REASON_INACTIVE`         | `470` | Account exists but subscriber is inactive or disabled.                                |
| `AUTH_REASON_PASSWORD_CHANGED` | `471` | Session was revoked because the password was changed or reset.                        |

## Colors

All color values use Roku's `0xRRGGBBAA` hex format (8 digits including alpha). Fully opaque colors end in `FF`.

| Constant         | Value        | Description                                                                                                       |
| ---------------- | ------------ | ----------------------------------------------------------------------------------------------------------------- |
| `COLOR_PRIMARY`  | `0x2D57C1FF` | Brand blue. Used for focused elements, buttons, and section headers. Matches `docs.json` primary color `#2D57C1`. |
| `COLOR_BG`       | `0x0F1020FF` | Main background color. Deep navy, used for screen backgrounds.                                                    |
| `COLOR_BG_CARD`  | `0x1A1A2EFF` | Card and panel background. Also used as `splash_color=#1a1a2e` in the manifest.                                   |
| `COLOR_TEXT`     | `0xFFFFFFFF` | Primary text color. Full white.                                                                                   |
| `COLOR_TEXT_DIM` | `0x9E9E9EFF` | Dimmed text color. Used for secondary labels and hints.                                                           |
| `COLOR_ERROR`    | `0xE53935FF` | Error state color. Red.                                                                                           |
| `COLOR_SUCCESS`  | `0x43A047FF` | Success state color. Green.                                                                                       |
| `COLOR_WARNING`  | `0xFB8C00FF` | Warning state color. Amber.                                                                                       |
| `COLOR_OVERLAY`  | `0x000000CC` | Semi-transparent black overlay (80% opacity). Used behind modals and player overlays.                             |

## Typography

Font size values are integers representing points in the Roku design coordinate space (1920×1080).

| Constant      | Value (pt) | Description                                                        |
| ------------- | ---------- | ------------------------------------------------------------------ |
| `FONT_H1`     | `48`       | Primary heading size. Used for screen titles.                      |
| `FONT_H2`     | `36`       | Secondary heading size. Used for section headings and card titles. |
| `FONT_BODY`   | `24`       | Body text size. Used for descriptions, labels, and list items.     |
| `FONT_SMALL`  | `18`       | Small text size. Used for hints, timestamps, and metadata.         |
| `FONT_NUMBER` | `72`       | Large number display. Used for channel number overlays.            |

## UI & layout

<AccordionGroup>
  <Accordion title="Timing">
    | Constant         | Value     | Description                                                                                                         |
    | ---------------- | --------- | ------------------------------------------------------------------------------------------------------------------- |
    | `SPLASH_MS`      | `1500` ms | Duration the in-app splash screen is displayed. Matches `splash_min_time` in the manifest.                          |
    | `BANNER_MS`      | `3000` ms | Duration a notification banner stays visible before auto-dismissing.                                                |
    | `BANNER_FADE_MS` | `300` ms  | Duration of the banner fade-out animation.                                                                          |
    | `CHANNEL_BUF_MS` | `1200` ms | Buffer delay before switching to a new channel, preventing rapid flipping from triggering unnecessary stream loads. |
  </Accordion>

  <Accordion title="Safe area">
    | Constant                 | Value | Description                                                                                               |
    | ------------------------ | ----- | --------------------------------------------------------------------------------------------------------- |
    | `UI_SAFE_MARGIN_PCT`     | `0`   | Default safe area margin as a percentage of the screen dimension. `0` means no margin applied by default. |
    | `UI_SAFE_MARGIN_MIN_PCT` | `0`   | Minimum allowed safe area margin. Enforced by `GTV_GetSafeMarginPct()`.                                   |
    | `UI_SAFE_MARGIN_MAX_PCT` | `10`  | Maximum allowed safe area margin. User-configurable up to 10% via the Settings screen.                    |

    The user-configured value is persisted to the registry under `REG_KEY_SAFE_MARGIN` and read back by `GTV_GetSafeMarginPct()` at runtime, which clamps it to `[UI_SAFE_MARGIN_MIN_PCT, UI_SAFE_MARGIN_MAX_PCT]`.
  </Accordion>

  <Accordion title="Channel grid">
    | Constant                       | Value          | Description                                                                                                                           |
    | ------------------------------ | -------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
    | `CHANNEL_TILE_MODE`            | `"badge_only"` | Controls how channel tiles are rendered in the main grid. `badge_only` shows only the channel number badge without artwork.           |
    | `PARSER_STRICT_CHANNEL_NUMBER` | `true`         | When `true`, the playlist parser rejects channels with non-numeric or missing channel numbers rather than assigning a fallback value. |
  </Accordion>

  <Accordion title="Diagnostic flags">
    | Constant               | Value   | Description                                                                           |
    | ---------------------- | ------- | ------------------------------------------------------------------------------------- |
    | `LAYOUT_DIAG`          | `false` | Enables verbose layout diagnostics printed to the telnet log via `GTV_LayoutPrint()`. |
    | `MAINSCREEN_GRID_DIAG` | `false` | Enables grid layout diagnostic output in `MainScreen`.                                |
    | `ADS_FLOW_DIAG`        | `false` | Enables ad flow diagnostic output in the ads subsystem.                               |

    Set any of these to `true` locally to trace layout or ads behavior. All three default to `false` and should remain `false` in production builds.
  </Accordion>
</AccordionGroup>
