{Now I have a clear picture. Let me plan the execution:
Global vars at top level of the IIFE (need to be declared globally):
Lines 3-6: const params, videoId, listParam, indexParam - URL params
Lines 246-248: hqActive, hqSyncRemovers, lastStreamSrc
Lines 251-262: iframe tracking vars
Lines 384: volState (an IIFE itself)
Lines 389-399: currentStreamData, currentVideoMeta, currentVideoId, _relatedVideos, streamOnlyMode, streamBestAudioUrl, streamAudioFormats, streamVideoFormats, lastNormalStreamSrc, cachedInvInstance, playerErrorHandler
Lines 1922-1924: transcriptTracks, currentLang, activeTranscriptLine
I also need to track down where streamExcludeList, reloadAllInProgress, reloadAllBtn, _homeVideoQueue, _homeVideoQueueIdx, and PLAYLIST_CACHE_TTL are declared. From what I've seen so far, reloadAllInProgress and reloadAllBtn show up around lines 2376-2377, and streamExcludeList is referenced in the doStreamAlt function.
Rather than chasing down every variable declaration individually, I'm thinking a cleaner approach would be to consolidate all the shared global state into a single file, split the functions into logical modules, and keep the main page-watch.js focused on initialization and URL parameter handling. Let me search for where all these top-level declarations actually live.
Looking at what I've already found, I can see that streamExcludeList, reloadAllInProgress, reloadAllBtn, _homeVideoQueue, and _homeVideoQueueIdx aren't top-level declarations at all—they're scoped inside functions like initWatch. So I don't need to worry about moving those to a globals file. Now I'm identifying which variables actually need to be accessible across multiple files, starting with hqActive and hqSyncRemovers from the original lines. Now I'm mapping out the file boundaries for the split, organizing the functions across five separate modules based on their responsibilities—iframe handling, HQ mode, the mode bar, player setup, video info and comments, transcript functionality, and playlist controls. I'm seeing that initWatch must be a large async function somewhere in that 260-line range, and I need to figure out where exactly it sits among all the playlist and streaming functions. So watch-controls.js should span from line 2105 through initCustomControls, which starts around line 2497, capturing all the cache functions, the main watch logic, instance handling, and stream controls. Lines 264-1919 break down into five modules: iframe handling, HQ mode setup, the mode bar, the video player, and video info with comments.
The remaining code splits into transcript handling, data caching and initialization, custom controls with formatting and stream alternatives, and finally the main entry point that reconstructs globals and runs on page load. The script loading order in the HTML file chains these modules together, with page-watch.js loaded last as the entry point.
I'm realizing the function declarations happen when scripts parse, but the actual calls occur at runtime during DOMContentLoaded. Since all scripts load synchronously before that event fires, functions defined in later files like page-watch.js will be available when earlier modules call them. the order doesn't matter for function calls.
So the load order can be:
watch-iframe.js (defines parseTimeSec, _sendIframeCmd, etc.)
wat
ch-hq.js (defines teardownHQ, etc.)
watch-modebar.js (defines initModeBar, etc.)
watch-player.js (defines setupPlayer, etc.)
watch-info.js (defines renderVideoInfo, etc.)
watch-transcript.js (defines tsToSeconds, etc.)
watch-data.js (defines initWatch, etc.)
watch-controls.js (defines initCustomControls, etc.)
page-watch.js (defines globals, utility functions + DOMContentLoaded - calls initHeaderSearch + initWatch)
This works because all var globals are hoisted and available at parse time, every function from all files exists by the time DOMContentLoaded fires, and the callback in page-watch.js orchestrates everything by calling initWatch, which then invokes all the other setup functions. I'm realizing that volState uses an IIFE pattern that executes immediately when the file loads, so if I move it to page-watch.js as a var declaration with that same IIFE, it'll initialize properly before any other code tries to reference it. The DOMContentLoaded callback will fire after all scripts load regardless of where page-watch.js sits in the load order, so the execution timing works out either way. What matters is that I need to move page-watch.js to load first so its globals are defined before the other watch-*.js files try to use them, then add the new split files after it in base.html. Now I'm ready to execute the transformation—I'll use Python to handle the CSS modifications and bash sed commands to extract the JavaScript sections into separate files, then manually adjust page-watch.js to remove the IIFE wrapper and add the necessary guards. Continuing to map out the file boundaries, I see watch-hq.js ends with the closing brace of initHQMode, then watch-modebar.js starts with initModeBar and runs through switchVideoTrack, followed by watch-player.js with setupPlayer through initDownloadBtn, watch-info.js with renderVideoInfo through initComments, and finally watch-transcript.js starting with the transcript section header but containing some variable declarations I need to handle carefully. I'm realizing I need to clarify how JavaScript scope works in the browser—specifically whether const and let declarations at the top level of a script tag actually create global variables accessible from other scripts, or if they're scoped differently than var. So my approach of extracting sections without converting let to var should work because let declarations at the script level are accessible across scripts in a browser environment—they're not properties of window, but they're still in the global scope that other scripts can reference. I'm realizing this is a subtle distinction in how the browser handles script scope versus the object environment record. The key insight is that when I extract functions like teardownHQ to separate files, they'll reference variables like hqSyncRemovers that currently live inside the IIFE. I need to declare these shared state variables at the top level of page-watch.js so they're accessible to all the extracted functions across different files.
My plan is to restructure page-watch.js by removing the IIFE wrapper entirely, keeping the guard logic at the top (though I'll need to handle the early return differently), declaring all the shared state variables globally, including the utility functions, and setting up the initialization code. Then I'll extract the iframe-related functions and HQ-related functions into their own files, which will naturally access these top-level variables through the shared global scope. Setting up the watch page globals...
I'm parsing the URL parameters to extract the video ID, list, and index, then setting up a DOMContentLoaded listener that initializes the header search and either shows an error if no video ID exists or calls initWatch. I'm noticing the original code had an IIFE guard checking for the 'page-watch' class, which I need to preserve to avoid running this on other pages. Restructuring the initialization code... I need to check whether listParam and indexParam are passed as arguments to initWatch or accessed as globals from within that function. Since only videoId is explicitly passed in the call, these parameters likely need to remain at the top level as let declarations so they're accessible throughout the script.
Now I'm ready to execute the refactoring plan: I'll use Python to transform the CSS, extract the JavaScript sections with sed into new files, write the updated page-watch.js with the global parameter declarations, and modify base.html accordingly. For the extraction, I need to skip the transcript variable declarations since those belong in the new file, and make sure not to include the IIFE closing at the end. Let me verify what's at the end of the file to confirm where the IIFE closes.
}