Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/zshall/program-guide/llms.txt

Use this file to discover all available pages before exploring further.

Television Simulator ‘99 is intentionally lean: there is no framework, no bundler, and no generated code. Every file you see in the repository is a file that ships directly to the browser. Understanding where things live makes it straightforward to customise the simulator, add new channels, or change the visual style without having to trace an unfamiliar build pipeline.

Directory Tree

program-guide/
├── channels/
│   └── 012/          # Prevue Channel (Channel 12)
│       ├── layout.html
│       └── script.js
├── css/
│   ├── fonts/        # PrevueGrid.ttf, PrevueList.ttf, VCR_OSD.ttf
│   └── site.css      # compiled from SCSS
├── data/
│   └── guide.xml     # channel listings, ads, notices
├── img/
│   ├── backdrop.png
│   ├── tv.png
│   └── tvsim-ogimg.png
├── js/
│   ├── core/
│   │   └── tv.js     # TV class — application bootstrap
│   └── helpers/
│       ├── channel.js      # Channel base class
│       ├── helpers.js      # Helpers utility class
│       └── youtube-ctrl.js # YouTubeApi static class
├── lib/
│   ├── bettermarquee.js
│   ├── jquery-3.2.1.min.js
│   └── moment.js
├── scss/
│   ├── channels/
│   │   └── 012.scss  # Channel 12 layout styles
│   ├── core/
│   │   ├── scanlines.scss
│   │   └── tv.scss
│   └── site.scss     # entry point, imports all partials
├── favicon.ico
└── index.html        # app entry point
No bundler, transpiler, or package manager is involved at runtime. The files listed above are served directly to the browser as-is. The only pre-processing step is compiling scss/site.scss into css/site.css — and a pre-compiled site.css is already committed to the repository, so even that step is optional unless you are modifying styles.

index.html — Application Entry Point

index.html is the only HTML document in the project. It defines the outer TV shell — the .tv container, the img.tv-mask bezel graphic, the .screen area, and the on-screen display divs (#tvm-top-right for the channel number, #tvm-bottom-left for the MUTING indicator). At the bottom of <body> it loads every script in dependency order, then instantiates the TV class and calls startUp():
<!-- Load JS libraries -->
<script src="lib/jquery-3.2.1.min.js"></script>
<script src="lib/moment.js"></script>
<script src="lib/bettermarquee.js"></script>
<script src="js/helpers/helpers.js"></script>
<script src="js/helpers/youtube-ctrl.js"></script>
<script src="js/helpers/channel.js"></script>

<!-- Load application JS -->
<script src="channels/012/script.js"></script>
<script src="js/core/tv.js"></script>

<script>
    var tv = new TV();
    tv.startUp();
</script>
The ordering is strict: libraries first, then helpers (which the channel and TV classes depend on), then channel classes (which extend Channel), then the TV class itself (which references channel classes by name).

channels/ — Per-Channel Code and Markup

Each channel lives in its own numbered subdirectory (channels/012/, channels/013/, etc.). The directory name is zero-padded to three digits and must match the number attribute used in guide.xml. Every channel directory contains exactly two files:
FilePurpose
layout.htmlThe HTML fragment loaded into .current-channel when the channel is switched to. It contains the DOM structure the channel’s JavaScript operates on — the YouTube player target div, the guide table, the marquee element, and so on.
script.jsA JavaScript class that extends Channel and implements the show() and teardown() lifecycle methods for this channel.
Channel 12 (channels/012/) is the only built-in channel. Its layout.html defines a split-screen layout with a #ytplayer div on the right, a .video-left ad panel on the left, and a <marquee>-wrapped guide table below. Its script.js defines Channel12, which reads guideData (the parsed guide.xml document), builds the listing rows dynamically, cycles through ads, and manages a real-time clock interval.

css/ — Compiled Styles and Fonts

css/site.css is the compiled output of scss/site.scss. It is the only stylesheet linked by index.html. The css/fonts/ subdirectory contains three typefaces that are referenced by @font-face declarations in site.scss:
  • PrevueGrid.ttf — the grid font used for channel numbers, call signs, and listing text in the guide; declared as the PrevueGrid font-family in scss/site.scss
  • PrevueList.ttf — a companion Prevue font bundled in the repository (not currently referenced by any @font-face declaration)
  • VCR_OSD.ttf — the VCR on-screen display font used for the real-time clock and channel number overlay; declared as the VCR font-family in scss/site.scss
These fonts were recreated from authentic Prevue Channel hardware by members of the Prevue Guide preservation community.

data/guide.xml — Channel Listings Data

data/guide.xml is the single source of truth for everything the guide grid displays. The TV.startUp() method fetches it via $.ajax after the YouTube API is ready. The parsed XML document is stored as window.guideData and passed to every channel class constructor. The file follows this structure:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<guide>
  <videos>
    <video id="oemoqEuJdFE" />
  </videos>
  <ads>
    <ad duration="30">
      <p>HBO<br />12 months $10.95 / mo.</p>
    </ad>
  </ads>
  <channel number="12" name="PRV" default="default" watchable="watchable">
    <listing timeslot="1" type="1">Prevue Channel</listing>
  </channel>
  <channel number="3" name="KCBS">
    <notice>Public offices closed Monday, May 3, 1999.</notice>
    <listing timeslot="19" type="1">News</listing>
  </channel>
</guide>
The default and watchable attributes on the <channel> element tell the TV class which channel to load automatically on startup. timeslot values are integers representing 30-minute blocks counted from midnight (so 19 = 9:30 AM, 33 = 7:30 PM, etc.). The type attribute maps to Prevue Channel programme-type colour codes.

img/ — Visual Assets

FilePurpose
tv.pngThe CRT television bezel overlay, rendered on top of the screen area using img.tv-mask. The .screen div sits behind it, sized to align with the transparent screen area of the PNG.
backdrop.pngA background texture image rendered behind the TV frame.
tvsim-ogimg.pngThe Open Graph social preview image referenced in index.html’s og:image meta tag.

js/ — Application JavaScript

js/helpers/helpers.jsHelpers Utility Class

A static utility class with three methods used throughout the codebase:
  • Helpers.isMobile() — returns an object with per-platform detection methods (Android, iOS, etc.) plus .any(). Used by TV.startUp() to skip scanlines and resize handling on mobile.
  • Helpers.padLeft(nr, n, str) — zero-pads a number to n digits. Used to construct channel directory paths (012) and the OSD channel number display (12" 12").
  • Helpers.loadScript(scriptUrl) — dynamically injects a <script> tag and returns a Promise, used by YouTubeApi.loadYouTubeAPI().

js/helpers/youtube-ctrl.jsYouTubeApi Static Class

A thin static wrapper around the YouTube IFrame API player object. All video operations go through this class:
MethodDescription
YouTubeApi.loadYouTubeAPI()Injects the YouTube IFrame API script. When the API is ready it fires onYouTubeIframeAPIReady, which dispatches the custom youtubeReady DOM event that triggers guide XML loading.
YouTubeApi.restartVideo(player)Stops and replays the current video from the beginning.
YouTubeApi.stopVideo(player)Calls player.stopVideo().
YouTubeApi.toggleMuteVideo(player)Toggles mute state and returns true if now muted.
YouTubeApi.muteVideo(player)Mutes the player.
YouTubeApi.unmuteVideo(player)Unmutes the player.

js/helpers/channel.jsChannel Base Class

Every channel class extends Channel. The base class constructor accepts a jQuery container reference and the parsed guideData XML document, and initialises empty timeouts and intervals registries. The teardown() method iterates both registries to clear all pending timers and stops any active YouTube player before emptying the container DOM — ensuring clean channel switching with no memory or timer leaks.

js/core/tv.jsTV Class

The top-level application class, instantiated once in index.html. Its constructor accepts optional maxWidth, maxHeight, warmupTime, and firstStart parameters (defaulting to 1200, 1000, 3000ms, and true), and registers all channel classes in a this.classes map. Key methods:
MethodDescription
tv.startUp()Attaches resize and button handlers, loads the YouTube API, fetches guide.xml, and calls showChannel() for the default channel once the XML is ready.
tv.showChannel(number, callback)Tears down the current channel, loads the new channel’s layout.html into .current-channel, instantiates the channel class, and fades the screen in. Displays the channel number in the OSD for four seconds.
tv.toggleMute()Delegates to YouTubeApi.toggleMuteVideo() and updates the #tvm-bottom-left MUTING indicator.
tv.handleResize()Computes a scale() transform to fit the 1200 × 1000 px TV frame within the current viewport dimensions.

lib/ — Third-Party Libraries

All dependencies are vendored as single files — no CDN links, no package manager manifest.
FileVersionPurpose
jquery-3.2.1.min.js3.2.1DOM manipulation, AJAX, and event handling throughout the codebase
moment.jsDate/time formatting for the real-time clock and time-column headers in the guide
bettermarquee.jsJavaScript replacement for the native <marquee> element, providing smoother, controllable vertical scrolling for the guide grid

scss/ — SCSS Source Files

The SCSS is organised into three layers and compiled to css/site.css by running node-sass scss/site.scss css/site.css (configured in .vscode/tasks.json).
FileRole
scss/site.scssEntry point. Declares @font-face rules, defines colour variables ($yellow, $dark-blue, gradients, etc.), and @imports the core and channel partials. Also scopes the Channel 12 styles under .tv .screen #ch-12.
scss/core/tv.scssStyles for the outer .tv frame, the .screen area, the .about credits overlay, the .tv-mask bezel, and the OSD message divs.
scss/core/scanlines.scssThe .scanlines pseudo-element overlay that simulates CRT scan lines. Applied to .screen on non-mobile devices by TV.startUp().
scss/channels/012.scssLayout styles for the Channel 12 Prevue Channel screen — the split-screen video/ad panel, the guide table typography (PrevueGrid font, column widths, row colours), and the marquee container dimensions.

Build docs developers (and LLMs) love