Pick a source, ask it anything, and watch it answer — or dodge — in its own voice. Quick, shareable, no homework required.
Now analyzing
1. Choose your content
Tap a Quick load below, or pick a country, an outlet, or a single show — then hit Load.
EP = episodes · W = words
📅 Date range:→
Your content library isn't showing yet. If you opened this by double-clicking the file, close it and open it through your local server instead (that's what makes the show list appear). You can also add files manually below.
Or upload a file manually —
Click to choose file(s) or drag them here. Everything is processed on your own computer — nothing is uploaded anywhere.
Only stored in your browser; sent only to Anthropic when you ask a question. Enter it once here.
Shows you've loaded
Grouped automatically from titles (e.g. a weekly show, press conferences, one-off statements). Uncheck any group to exclude it from the stats, chart, and period comparison below.
2. Compare two periods
Compare two date ranges side by side — how the themes, tone, and targets shifted.
0 episodes in range
0 episodes in range
The narrative uses the API key set in panel 1 (Admin).
Reading through your content...
Advanced: load a precomputed comparison.json (from 2_analyze_discourse.py) —
Load comparison.json from 2_analyze_discourse.py
A starting point for exploring — worth checking the source episodes for anything you plan to cite.
3. Topics, names & timeline
Rank the most frequent words, phrases and people/names across everything loaded above, and chart any of them by month or quarter. Click × on a row to remove it (the next-ranked entry moves up). Click rows to add them to the trend chart.
Analytics run automatically when you load data — use Recompute after changing the show filter.
Or load a precomputed topics_timeline.json (from 3_extract_topics.py) —
Load topics_timeline.json from 3_extract_topics.py
Excluded terms · Unify names — click to show/hide the editors
Excluded words & names
Press × on any row in the lists below to exclude it everywhere (the next-ranked term moves up). Excluded terms collect here — click one to bring it back. Saved in this browser.
Unify alternative names → one main name
One group per line: Main name = alternative1, alternative2, ... (accents ignored). Unified entries show a 👤 in the lists. Applied everywhere — lists, chart, periods, cast. Saved in this browser.
Normalized metrics make different-sized selections comparable.
recurring phrases & slogans
Top names (people, organizations, places)
Mentions over time for selected terms — click rows above to add/remove them here (up to 6).
Optional: labeled_topics.json from 4_label_topics.py — labeled thematic topics and representative recurring moments.
Load labeled_topics.json from 4_label_topics.py
Optional: analysis.json from 2_analyze_discourse.py --bucket month/quarter — theme summaries per month/quarter.
Load analysis.json from 2_analyze_discourse.py --bucket month/quarter
4. Periods breakdown
Split everything loaded into date periods and compare side by side: episodes, word count, positive/negative language per 10k words, warm vs hostile framing, and each period's top names and phrases. Renders automatically after data loads; switch the granularity or type custom break dates (e.g. an election date) to re-slice.
Coverage tone: who gets warm vs hostile framing
A cast of recurring figures and forces, measured directly from the loaded transcripts: how often each is named (per 10k words), the tone of the language around each mention (share of hostile words like fascista, criminal, traidor vs warm words like victoria, dignidad, amor within ±120 characters), and how each figure shifts between the first and second half of the date range. Figures are grouped as warmly framed / hostilely framed / mixed, re-derived on every run for whatever content is loaded. Important: this measures the tone of the words surrounding each name — a proxy for how warmly or harshly a figure is discussed — not whether the outlet supports them and not our own judgment. A figure can land in "hostilely framed" simply because they're often discussed alongside conflict words (attacks, war, threats), even when the coverage is sympathetic. Read it as coverage temperature, not endorsement. Tone covers Spanish + English.
Add to cast:
Edit the cast — the full list, including the labels we assigned (override any of them here)
To add a figure, just give the name and its trigger words — e.g. Padrino López = padrino lopez, vladimir padrino. The content assigns the framing itself (warmly framed / hostilely framed / mixed) from the measured tone around its mentions, and the line is rewritten with the assigned group so you can override it if needed. You can also pin a group explicitly using its keyword: ally | Cuba = cuba, fidel castro (accepted keywords: hero = warmly framed, villain = hostilely framed, ally, threat). Triggers match accent-insensitively. Saved in this browser.
Compare sentiment across time frames — pick up to 3 periods to see how each figure's position and hostility shift
Each figure's framing (warmly framed / hostilely framed / mixed), % hostile and rate are re-derived within each period you define, so you can watch the framing move over time. Set at least two periods to compare; leave them empty to fall back to first-half vs second-half.
from (month)to (month)Period 1Period 2Period 3
Debate: two voices, you moderate
Two figures argue a topic you set — each replies only in their own recorded words. You are the moderator: pick the pair, set the topic, optionally give them a real event to react to, then add follow-ups to steer it.
🏆 Debate leaderboard· all players
…
1 · Who debates?
vs
Each debater argues from their own recorded words — no need to load anything. To widen the context, you can load more sources on Select content first.
2 · What should they debate?
3 · A real event for them to react to (optional)
Interview: a host sits down with a guest
Pick a broadcaster to host and anyone as the guest. The host asks the questions in their own on-air style; the guest answers only in their own recorded words. Set the theme, then steer it with follow-ups.
1 · Who's on air?
interviews
Tip: pick your host from News anchors & hosts — they run the interview in their own on-air voice. Nothing to load; each voice comes from their own recorded words.
2 · What's the interview about?
Upload a clip
Paste what someone said, a transcript, or an article. You can see which cast member you sound most like (just for fun), or help us identify it and file it for review. Your upload is kept separate — it never trains the system or enters the archive unless we review and approve it.
1 · Choose what to do
2 · Paste or dictate, then run
Library: channels, playlists & title groups
A full catalog of everything you've collected, filed under channel → playlist → title group, with the key part of each title and its main topics. It refreshes automatically after each update.
7. Live program log — what aired & how often
The live signal segmented into identified programs by tools/segment_live.py: each airing's show, air date/time, and — because VTV re-airs content — a play count so you can see what the audience heard more than once. Replays aren't stored twice; they're logged here. Re-run the tool (or let the nightly job do it) to refresh data/vtv_live_airlog.json.
Predict: how would they cover it, and what do they avoid?
Type a topic — even today's news — and see how they'd spin it, plus what they refuse to touch.
Accuracy
Ask the archive: meet IAN & SPIN
Two voices, one topic. IAN gives you the straight answer. SPIN is the spokesperson — ask it something awkward and it'll dodge, twist your question, and pivot, exactly like a politician on camera.
Text a public figure like they're on the other end of the line — answers built only from their own recorded words.
Hi, I'm IAN — your Intelligent Automatic Narrator. I've sat through thousands of hours of TV so you don't have to. Choose your content above and ask me anything about it.