Docs/Skills and code/src/
src/video-explorer.js
const videoCache = new WeakMap();
const VIDEO_PRESETS = Object.freeze({
breakout: { label: "Within-channel breakout", minViews: 1000, minMedianMultiple: 3, sort: "median_multiple" },
audience_penetration: { label: "Views exceed subscriber base", minViewsPerSubscriber: 1, sort: "views_per_subscriber" },
fast_start: { label: "Fast start · first 30 days", maxAgeDays: 30, minViewsPerDay: 100, sort: "views_per_day" },
recent_traction: { label: "Recent uploads · high lifetime views/day", maxAgeDays: 180, minViewsPerDay: 50, sort: "views_per_day" },
observed_momentum: { label: "Observed momentum · snapshot growth", minSnapshotGrowthPerDay: 10, sort: "snapshot_growth" },
evergreen: { label: "Evergreen library winners", minAgeDays: 365, minViews: 1000, minViewsPerDay: 10, sort: "views_per_day" },
long_tail_outliers: { label: "Old videos still outperforming", minAgeDays: 365, minViews: 1000, minMedianMultiple: 2, sort: "median_multiple" },
sleeper_hits: { label: "Sleeper hits · modest channel", maxSubscribers: 100000, minViews: 10000, minViewsPerSubscriber: 0.5, sort: "views_per_subscriber" },
question_titles: { label: "Question-led packaging", titlePattern: "question", sort: "views_per_day" },
number_titles: { label: "Number-led packaging", titlePattern: "number", sort: "views_per_day" },
curiosity_titles: { label: "Curiosity / explainer packaging", titlePattern: "curiosity", sort: "views_per_day" },
high_absolute: { label: "Highest absolute views", minViews: 10000, sort: "views" },
broad: { label: "Broad exploration", sort: "views" }
});
const QUEUE_KEYS = ["learn_from", "breaking_out", "durable_exemplars", "unexplored_niches", "reference_inspiration"];
const QUEUE_LABELS = { learn_from:"Learn from", breaking_out:"Breaking out", durable_exemplars:"Durable exemplars", unexplored_niches:"Unexplored niches", reference_inspiration:"Reference inspiration" };
const exists = (db, name) => !!db.prepare("SELECT 1 FROM sqlite_master WHERE type IN ('table','view') AND name=?").get(name);
const cols = (db, name) => exists(db,name) ? new Set(db.prepare(`PRAGMA table_info("${name.replaceAll('"','""')}")`).all().map(r=>r.name)) : new Set();
const qid = name => `"${String(name).replaceAll('"','""')}"`;
const expr = (set, alias, names, fallback="NULL") => {
const xs = names.filter(n=>set.has(n)).map(n=>`${alias}.${qid(n)}`);
return xs.length ? (xs.length===1 ? xs[0] : `COALESCE(${xs.join(',')})`) : fallback;
};
const num = (v,min=0,max=1e15) => { if(v==null || v==="") return null; const n=Number(v); return Number.isFinite(n)?Math.max(min,Math.min(max,n)):null; };
const safeText = v => String(v??"");
function titleFlag(title, pattern) {
const s = safeText(title);
if(pattern==="question") return /\?/.test(s) || /^(why|how|what|when|where|who|can|does|is|are|should)\b/i.test(s);
if(pattern==="number") return /\b\d{1,4}\b/.test(s);
if(pattern==="curiosity") return /\b(why|how|what|secret|truth|explained|mistake|reason|actually|really|inside|forgotten|hidden|surprising)\b/i.test(s);
return true;
}
function parseFilters(query) {
const sortValues = new Set(["views","views_per_day","median_multiple","views_per_subscriber","newest","oldest","title","channel","snapshot_growth"]);
return {
preset: VIDEO_PRESETS[query.preset] ? query.preset : "",
q: safeText(query.q).trim().slice(0,160), channel: safeText(query.channel).trim().slice(0,160),
minViews:num(query.minViews), maxViews:num(query.maxViews), minAgeDays:num(query.minAgeDays,0,1e7), maxAgeDays:num(query.maxAgeDays,0,1e7),
minViewsPerDay:num(query.minViewsPerDay), minMedianMultiple:num(query.minMedianMultiple,0,1e6),
minViewsPerSubscriber:num(query.minViewsPerSubscriber), maxSubscribers:num(query.maxSubscribers), minSnapshotGrowthPerDay:num(query.minSnapshotGrowthPerDay),
titlePattern:["question","number","curiosity"].includes(query.titlePattern)?query.titlePattern:"",
sort:sortValues.has(query.sort)?query.sort:"views"
};
}
function getVideoRowsUncached(db) {
const vc=cols(db,"videos"), cc=cols(db,"channels"), mc=cols(db,"channel_metadata"), sc=cols(db,"video_metric_snapshots");
if(!vc.has("video_id")) return {rows:[], schema:{vc,cc,mc,sc}, error:"The videos table or videos.video_id column is missing."};
const channelJoin = vc.has("channel_url") && cc.has("channel_url");
const metaJoin = channelJoin && mc.has("channel_url");
const joins=[];
if(channelJoin) joins.push("LEFT JOIN channels c ON c.channel_url=v.channel_url");
if(metaJoin) joins.push("LEFT JOIN channel_metadata m ON m.channel_url=v.channel_url");
const channelName = vc.has("channel_name") ? "v.channel_name" : (channelJoin && cc.has("name")?"c.name":"NULL");
const subs = metaJoin ? expr(mc,"m",["subscriber_count","subscribers"]) : "NULL";
const subsEffective = channelJoin ? `COALESCE(${subs},${expr(cc,"c",["subscriber_count","subscribers"])})` : subs;
const fields = [
`${expr(vc,"v",["video_id"])} AS video_id`, `${expr(vc,"v",["title"])} AS title`, `${expr(vc,"v",["url","video_url"])} AS url`,
`${expr(vc,"v",["channel_url"])} AS channel_url`, `${channelName} AS channel_name`, `${expr(vc,"v",["thumbnail_url","thumbnail","thumbnail_link"])} AS thumbnail_url`,
`${expr(vc,"v",["duration"])} AS duration`, `${expr(vc,"v",["view_count","views"])} AS base_views`, `${expr(vc,"v",["published_at","published_date"])} AS published_at`,
`${expr(vc,"v",["discovered_at","created_at"])} AS discovered_at`, `${subsEffective} AS channel_subscribers`,
`${expr(vc,"v",["description"])} AS description`
];
if(sc.has("video_id") && sc.has("view_count")) {
const timeCol=sc.has("observed_at")?"observed_at":(sc.has("captured_at")?"captured_at":null);
if(timeCol) {
// Rank the snapshot table once and join its per-video summary. The previous
// correlated-subquery approach ran several snapshot lookups per video.
joins.push(`LEFT JOIN (
SELECT video_id,
MAX(CASE WHEN rn_asc=1 THEN view_count END) AS earliest_snapshot_views,
MAX(CASE WHEN rn_desc=1 THEN view_count END) AS latest_snapshot_views,
COUNT(*) AS snapshot_count,
MAX(CASE WHEN rn_asc=1 THEN snapshot_time END) AS earliest_snapshot_at,
MAX(CASE WHEN rn_desc=1 THEN snapshot_time END) AS latest_snapshot_at
FROM (
SELECT video_id, view_count, ${qid(timeCol)} AS snapshot_time,
ROW_NUMBER() OVER (PARTITION BY video_id ORDER BY ${qid(timeCol)} ASC) AS rn_asc,
ROW_NUMBER() OVER (PARTITION BY video_id ORDER BY ${qid(timeCol)} DESC) AS rn_desc
FROM video_metric_snapshots
) ranked_snapshots GROUP BY video_id
) snapshot_summary ON snapshot_summary.video_id=v.video_id`);
fields.push("snapshot_summary.latest_snapshot_views AS latest_snapshot_views","snapshot_summary.earliest_snapshot_views AS earliest_snapshot_views","snapshot_summary.snapshot_count AS snapshot_count","snapshot_summary.latest_snapshot_at AS latest_snapshot_at","snapshot_summary.earliest_snapshot_at AS earliest_snapshot_at");
} else fields.push("NULL AS latest_snapshot_views","NULL AS earliest_snapshot_views","NULL AS snapshot_count","NULL AS latest_snapshot_at","NULL AS earliest_snapshot_at");
} else fields.push("NULL AS latest_snapshot_views","NULL AS earliest_snapshot_views","NULL AS snapshot_count","NULL AS latest_snapshot_at","NULL AS earliest_snapshot_at");
let rows=[];
try { rows=db.prepare(`SELECT ${fields.join(",")} FROM videos v ${joins.join(" ")} ORDER BY ${vc.has("view_count")?"v.view_count DESC":"v.video_id"}`).all(); }
catch(error) { return {rows:[],schema:{vc,cc,mc,sc},error:error.message}; }
return {rows,schema:{vc,cc,mc,sc},error:null};
}
function getVideoRows(db, forceRefresh = false) {
if (forceRefresh) videoCache.delete(db);
const cached = videoCache.get(db);
if (cached) return cached;
const loaded = getVideoRowsUncached(db);
if (loaded.error) return loaded;
const derived = deriveRows(loaded.rows);
const quality = qualitySummary(derived, loaded.schema);
const result = { ...loaded, derived, quality, cachedAt: Date.now() };
videoCache.set(db, result);
return result;
}
function median(values) { const a=values.filter(v=>Number.isFinite(v)&&v>=0).sort((x,y)=>x-y); if(!a.length)return null; const m=Math.floor(a.length/2); return a.length%2?a[m]:(a[m-1]+a[m])/2; }
function deriveRows(raw) {
const now=Date.now();
const rows=raw.map(r=>{
const views=num(r.latest_snapshot_views) ?? num(r.base_views);
const subs=num(r.channel_subscribers);
const published=r.published_at ? Date.parse(r.published_at) : NaN;
const ageDays=Number.isFinite(published)&&published<=now ? (now-published)/86400000 : null;
const viewsPerDay=views!=null&&ageDays!=null&&ageDays>=1 ? views/ageDays : null;
const first=num(r.earliest_snapshot_views), latest=num(r.latest_snapshot_views), snapshotCount=num(r.snapshot_count);
const growth=first!=null&&latest!=null&&snapshotCount>=2 ? latest-first : null;
const span=r.earliest_snapshot_at&&r.latest_snapshot_at ? (Date.parse(r.latest_snapshot_at)-Date.parse(r.earliest_snapshot_at))/86400000 : null;
const observedGrowthPerDay=growth!=null&&span>0?growth/span:null;
return {...r,views,channel_subscribers:subs,age_days:ageDays,views_per_day:viewsPerDay,views_per_subscriber:subs>0&&views!=null?views/subs:null,
snapshot_growth:growth,snapshot_span_days:span,snapshot_growth_per_day:observedGrowthPerDay,
title_pattern_question:titleFlag(r.title,"question"),title_pattern_number:titleFlag(r.title,"number"),title_pattern_curiosity:titleFlag(r.title,"curiosity")};
});
const byChannel=new Map();
for(const r of rows) if(r.channel_url && r.views!=null){ if(!byChannel.has(r.channel_url))byChannel.set(r.channel_url,[]); byChannel.get(r.channel_url).push(r.views); }
for(const r of rows){ const med=r.channel_url?median(byChannel.get(r.channel_url)||[]):null; r.channel_median_views=med; r.median_multiple=med>0&&r.views!=null?r.views/med:null; }
return rows;
}
function matches(r,f) {
if(f.q && ![r.title,r.channel_name,r.description,r.video_id].some(x=>safeText(x).toLowerCase().includes(f.q.toLowerCase())))return false;
if(f.channel && !safeText(r.channel_name).toLowerCase().includes(f.channel.toLowerCase()) && !safeText(r.channel_url).toLowerCase().includes(f.channel.toLowerCase()))return false;
if(f.minViews!=null && !(r.views!=null&&r.views>=f.minViews))return false;
if(f.maxViews!=null && !(r.views!=null&&r.views<=f.maxViews))return false;
if(f.minAgeDays!=null && !(r.age_days!=null&&r.age_days>=f.minAgeDays))return false;
if(f.maxAgeDays!=null && !(r.age_days!=null&&r.age_days<=f.maxAgeDays))return false;
if(f.minViewsPerDay!=null && !(r.views_per_day!=null&&r.views_per_day>=f.minViewsPerDay))return false;
if(f.minMedianMultiple!=null && !(r.median_multiple!=null&&r.median_multiple>=f.minMedianMultiple))return false;
if(f.minViewsPerSubscriber!=null && !(r.views_per_subscriber!=null&&r.views_per_subscriber>=f.minViewsPerSubscriber))return false;
if(f.maxSubscribers!=null && !(r.channel_subscribers!=null&&r.channel_subscribers<=f.maxSubscribers))return false;
if(f.minSnapshotGrowthPerDay!=null && !(r.snapshot_growth_per_day!=null&&r.snapshot_growth_per_day>=f.minSnapshotGrowthPerDay))return false;
if(f.titlePattern && !titleFlag(r.title,f.titlePattern))return false;
return true;
}
function sortRows(rows, sort) {
const key={views:"views",views_per_day:"views_per_day",median_multiple:"median_multiple",views_per_subscriber:"views_per_subscriber",snapshot_growth:"snapshot_growth_per_day",newest:"published_at",oldest:"published_at",title:"title",channel:"channel_name"}[sort]||"views";
return rows.sort((a,b)=>{
const av=a[key],bv=b[key]; if(sort==="oldest") return (Date.parse(av)||Infinity)-(Date.parse(bv)||Infinity);
if(sort==="newest") return (Date.parse(bv)||0)-(Date.parse(av)||0);
if(typeof av==="string"||typeof bv==="string") return safeText(av).localeCompare(safeText(bv));
return (bv??-Infinity)-(av??-Infinity);
});
}
function qualitySummary(rows,schema) {
const total=rows.length;
const missing=field=>rows.filter(r=>r[field]==null||r[field]==="").length;
return {total,views:missing("views"),date:missing("published_at"),thumb:missing("thumbnail_url"),channel:missing("channel_url"),subs:missing("channel_subscribers"),median:rows.filter(r=>r.median_multiple==null).length,
snapshots: schema.sc.size ? rows.filter(r=>!(Number(r.snapshot_count)>=2)).length : total, hasSnapshots:schema.sc.size>0, title:missing("title")};
}
function e(v){return String(v??"").replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'");}
function fmt(v){if(v==null||v==="")return "—";const n=Number(v);return Number.isFinite(n)?new Intl.NumberFormat("en",{notation:"compact",maximumFractionDigits:1}).format(n):String(v);}
function fixed(v,d=1){return v==null||!Number.isFinite(Number(v))?"—":Number(v).toFixed(d);}
function durationLabel(v){return v==null||v===""?"Duration unknown":String(v);}
function styles(){return `<style>
.vx-wrap{max-width:1500px;margin:0 auto}.vx-head{display:flex;justify-content:space-between;align-items:end;gap:16px;flex-wrap:wrap}.vx-head h1{font-size:30px;letter-spacing:-.7px;margin:0 0 6px}.vx-muted{color:#697386;font-size:12px;line-height:1.5}.vx-panel{background:#fff;border:1px solid #e3e6eb;border-radius:15px;padding:16px;margin:15px 0;box-shadow:0 4px 16px #14213d08}.vx-presets{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px}.vx-preset{border:1px solid #dfe4eb;background:#f7f8fa;border-radius:999px;padding:8px 11px;font-size:12px;cursor:pointer;color:#172033}.vx-preset:hover{background:#eaf1ff;border-color:#a8c1f7}.vx-form{display:grid;grid-template-columns:repeat(4,minmax(130px,1fr));gap:11px}.vx-field{display:flex;flex-direction:column;gap:5px;font-size:12px;color:#4b5563}.vx-field input,.vx-field select{min-width:0;padding:9px 10px;border:1px solid #d7dce3;border-radius:8px;font:inherit;font-size:13px;background:white}.vx-actions{display:flex;gap:9px;align-items:center;flex-wrap:wrap;margin-top:13px}.vx-actions button,.vx-btn{border:0;border-radius:8px;padding:10px 13px;background:#172033;color:white;text-decoration:none;font-size:13px;font-weight:700;cursor:pointer}.vx-actions .vx-clear{background:#edf0f4;color:#172033}.vx-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px;margin-top:14px}.vx-card{border:1px solid #e1e5ea;border-radius:13px;overflow:hidden;background:#fff;box-shadow:0 4px 14px #11108;min-width:0}.vx-thumb{width:100%;aspect-ratio:16/9;object-fit:cover;display:block;background:#e9edf2}.vx-no-thumb{width:100%;aspect-ratio:16/9;display:grid;place-items:center;background:linear-gradient(135deg,#eef2f6,#dfe6ef);color:#8a94a3;font-size:30px}.vx-body{padding:12px}.vx-title{font-size:14px;line-height:1.4;font-weight:750;color:#121826;text-decoration:none;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}.vx-title:hover{text-decoration:underline}.vx-channel{font-size:12px;color:#315da8;margin-top:7px;text-decoration:none;display:inline-block}.vx-metrics{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px;margin-top:10px}.vx-metric{background:#f6f8fa;border-radius:7px;padding:7px;min-width:0}.vx-metric b{font-size:13px;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#172033}.vx-metric span{font-size:9px;letter-spacing:.3px;text-transform:uppercase;color:#778091;display:block;margin-top:3px}.vx-tags{display:flex;gap:5px;flex-wrap:wrap;margin-top:9px}.vx-tag{font-size:10px;padding:4px 6px;border-radius:5px;background:#eef2f6;color:#4b5563}.vx-tag.good{background:#e4f6eb;color:#17683a}.vx-tag.warn{background:#fff2d4;color:#7c5900}.vx-quality{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;margin-top:10px}.vx-qitem{background:#f6f8fa;border-radius:8px;padding:9px}.vx-qitem b{display:block;font-size:17px}.vx-qitem span{display:block;color:#687386;font-size:11px;margin-top:2px}.vx-warning{background:#fff8e8;border:1px solid #f0dba6;border-radius:10px;padding:12px;color:#694f14;font-size:12px;line-height:1.55}.vx-empty{border:1px dashed #cfd5dd;border-radius:12px;text-align:center;padding:32px;color:#697386}.vx-results{display:flex;justify-content:space-between;gap:10px;align-items:center;flex-wrap:wrap}.vx-small{font-size:11px;color:#788293;margin-top:9px}@media(max-width:1000px){.vx-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.vx-form{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(max-width:680px){.vx-grid{grid-template-columns:1fr}.vx-form{grid-template-columns:repeat(2,minmax(0,1fr))}.vx-quality{grid-template-columns:repeat(2,minmax(0,1fr))}.vx-head h1{font-size:24px}}@media(max-width:420px){.vx-form{grid-template-columns:1fr}}
</style>`;}
function presetReadiness(q,preset){
const requirements={
breakout:[[q.views,"view counts"],[q.channel,"channel links for within-channel medians"]],
audience_penetration:[[q.views,"view counts"],[q.subs,"channel subscriber counts"]],
fast_start:[[q.views,"view counts"],[q.date,"publication dates"]],
recent_traction:[[q.views,"view counts"],[q.date,"publication dates"]],
observed_momentum:[[q.snapshots,"videos without at least two metric snapshots"]],
evergreen:[[q.views,"view counts"],[q.date,"publication dates"]],
long_tail_outliers:[[q.views,"view counts"],[q.date,"publication dates"],[q.median,"within-channel median comparisons"]],
sleeper_hits:[[q.views,"view counts"],[q.subs,"channel subscriber counts"]],
question_titles:[[q.title,"video titles"]], number_titles:[[q.title,"video titles"]], curiosity_titles:[[q.title,"video titles"]],
high_absolute:[[q.views,"view counts"]], broad:[]
};
const needed=requirements[preset]||[]; if(!preset||!needed.length)return `<div class="vx-muted" style="margin-top:8px">Select a preset to see its specific data dependencies. Missing fields are counted separately below.</div>`;
const missing=needed.filter(x=>x[0]>0); return `<div class="vx-warning" style="margin-top:10px"><b>Preset readiness — ${e(VIDEO_PRESETS[preset]?.label||preset)}:</b> ${missing.length?missing.map(x=>`${fmt(x[0])} videos lack ${e(x[1])}`).join("; ")+". These rows may be excluded from this preset or have unavailable derived metrics.":"No missing values detected for the core inputs of this preset in the saved corpus."} Use the remediation notes below to improve coverage.</div>`;
}
function qualityHtml(q,preset){return `${presetReadiness(q,preset)}<section class="vx-panel"><div><strong>Data coverage & limitations</strong><div class="vx-muted">Coverage is measured across ${fmt(q.total)} saved videos before filters. Derived metrics are unavailable when their inputs are missing.</div></div><div class="vx-quality"><div class="vx-qitem"><b>${fmt(q.views)}</b><span>Missing view counts</span></div><div class="vx-qitem"><b>${fmt(q.date)}</b><span>Missing publish dates</span></div><div class="vx-qitem"><b>${fmt(q.thumb)}</b><span>Missing thumbnails</span></div><div class="vx-qitem"><b>${fmt(q.subs)}</b><span>Missing channel subscribers</span></div><div class="vx-qitem"><b>${fmt(q.channel)}</b><span>Missing channel association</span></div><div class="vx-qitem"><b>${fmt(q.median)}</b><span>No within-channel median comparison</span></div><div class="vx-qitem"><b>${fmt(q.snapshots)}</b><span>${q.hasSnapshots?"Fewer than 2 metric snapshots":"Snapshot history unavailable"}</span></div></div><div class="vx-warning" style="margin-top:10px"><b>How to improve coverage:</b> missing video titles/views/dates/thumbnails usually require video metadata backfill; missing channel subscriber counts require channel metadata enrichment. A observed-momentum preset needs at least two dated snapshots per video. If snapshots are absent or sparse, use views/day only as an age-normalized proxy, not evidence of recent acceleration. Review <code>npm run enrichment:report</code> and the stage logs before deciding what to backfill.</div></section>`;}
function renderFilters(f){
const field=(name,label,value,ph="Optional")=>`<label class="vx-field">${e(label)}<input name="${name}" type="number" min="0" step="any" value="${value==null?"":e(value)}" placeholder="${e(ph)}"></label>`;
return `<form class="vx-panel" id="vx-filters" action="/explore/videos" method="GET"><div class="vx-form"><label class="vx-field">Preset<select name="preset" id="vx-preset"><option value="">Custom filters</option>${Object.entries(VIDEO_PRESETS).map(([k,p])=>`<option value="${k}" ${f.preset===k?"selected":""}>${e(p.label)}</option>`).join("")}</select></label><label class="vx-field">Search title, channel, description<input name="q" value="${e(f.q)}" placeholder="e.g. black holes, experiments"></label><label class="vx-field">Channel name / URL contains<input name="channel" value="${e(f.channel)}" placeholder="Optional"></label>${field("minViews","Minimum views",f.minViews,"10000")}${field("maxViews","Maximum views",f.maxViews)}${field("minAgeDays","Minimum age (days)",f.minAgeDays)}${field("maxAgeDays","Maximum age (days)",f.maxAgeDays,"30")}${field("minViewsPerDay","Minimum lifetime views/day",f.minViewsPerDay,"50")}${field("minMedianMultiple","Minimum views / channel median",f.minMedianMultiple,"3")}${field("minViewsPerSubscriber","Minimum video views / subscribers",f.minViewsPerSubscriber,"1")}${field("maxSubscribers","Maximum channel subscribers",f.maxSubscribers,"100000")}${field("minSnapshotGrowthPerDay","Minimum observed snapshot growth/day",f.minSnapshotGrowthPerDay,"Requires 2+ snapshots")}<label class="vx-field">Title pattern<select name="titlePattern"><option value="">Any title</option><option value="question" ${f.titlePattern==="question"?"selected":""}>Question-led</option><option value="number" ${f.titlePattern==="number"?"selected":""}>Number-led</option><option value="curiosity" ${f.titlePattern==="curiosity"?"selected":""}>Curiosity / explainer words</option></select></label><label class="vx-field">Sort by<select name="sort">${[["views","Highest views"],["views_per_day","Views per day (age-normalized)"],["median_multiple","Within-channel median multiple"],["views_per_subscriber","Views / subscribers"],["snapshot_growth","Observed snapshot growth/day"],["newest","Newest published"],["oldest","Oldest published"],["title","Title A–Z"],["channel","Channel A–Z"]].map(([v,l])=>`<option value="${v}" ${f.sort===v?"selected":""}>${e(l)}</option>`).join("")}</select></label></div><div class="vx-actions"><button type="submit">Apply filters</button><a class="vx-btn vx-clear" href="/explore/videos">Clear all</a><span class="vx-muted">Preset values can be edited; blank filters are ignored. Filters combine with AND.</span></div><div class="vx-small">“Views / channel median” compares a video with the median of the saved videos for its channel, not necessarily every video the channel has ever published. Title-pattern filters are heuristic labels, not proof that a packaging technique caused performance.</div></form>`;
}
function renderCard(r){
const thumb=r.thumbnail_url?`<img class="vx-thumb" src="${e(r.thumbnail_url)}" alt="${e(r.title||"Video thumbnail")}" loading="lazy" referrerpolicy="no-referrer">`:`<div class="vx-no-thumb">▶<span class="vx-muted"> Thumbnail missing</span></div>`;
const title=r.url?`<a class="vx-title" href="${e(r.url)}" target="_blank" rel="noopener noreferrer">${e(r.title||r.video_id)}</a>`:`<div class="vx-title">${e(r.title||r.video_id)}</div>`;
const ch=r.channel_url?`<a class="vx-channel" href="/explore/channel?url=${encodeURIComponent(r.channel_url)}">${e(r.channel_name||"Open channel")}</a>`:`<span class="vx-channel">${e(r.channel_name||"Channel unknown")}</span>`;
const tags=[]; if(r.median_multiple!=null&&r.median_multiple>=2)tags.push(`<span class="vx-tag good">${fixed(r.median_multiple)}× channel median</span>`); if(r.views_per_day!=null&&r.views_per_day>=100)tags.push(`<span class="vx-tag">${fmt(r.views_per_day)} views/day</span>`); if(r.snapshot_growth_per_day!=null)tags.push(`<span class="vx-tag">${fmt(r.snapshot_growth_per_day)} snapshot growth/day</span>`); if(r.title_pattern_question)tags.push(`<span class="vx-tag">Question title</span>`); if(r.title_pattern_number)tags.push(`<span class="vx-tag">Number title</span>`); if(r.title_pattern_curiosity)tags.push(`<span class="vx-tag">Curiosity / explainer terms</span>`);
return `<article class="vx-card">${r.url?`<a href="${e(r.url)}" target="_blank" rel="noopener noreferrer">${thumb}</a>`:thumb}<div class="vx-body">${title}${ch}<div class="vx-metrics"><div class="vx-metric"><b>${fmt(r.views)}</b><span>Views</span></div><div class="vx-metric"><b>${fmt(r.views_per_day)}</b><span>Lifetime views/day</span></div><div class="vx-metric"><b>${fixed(r.median_multiple)}×</b><span>Channel median</span></div><div class="vx-metric"><b>${fmt(r.channel_subscribers)}</b><span>Channel subs</span></div><div class="vx-metric"><b>${fixed(r.views_per_subscriber,2)}</b><span>Views / subs</span></div><div class="vx-metric"><b>${r.age_days==null?"—":fmt(r.age_days)+" d"}</b><span>Video age</span></div></div><div class="vx-tags">${tags.join("")||`<span class="vx-tag">No standout signal from current fields</span>`}</div><div class="vx-muted" style="margin-top:9px">${e(r.published_at||"Publish date unknown")} · ${e(durationLabel(r.duration))} · ${r.snapshot_count==null?"Snapshot history unavailable":`${fmt(r.snapshot_count)} snapshots`}</div></div></article>`;
}
function htmlPage(title,content,baseHead,nav){return `<!doctype html><html lang="en">${baseHead(title).replace("</head>",`${styles()}</head>`)}<body><div class="vx-wrap">${nav("video-explorer")} ${content}</div></body></html>`;}
function registerVideoExplorer(app,dbSource,{baseHead,nav}){
app.get("/explore/videos",(req,res)=>{
try {
const db=typeof dbSource === "function" ? dbSource() : dbSource;
const loaded=getVideoRows(db, req.query.refresh === "1"); if(loaded.error) return res.status(500).type("text").send(`Video Explorer could not read the database: ${loaded.error}`);
const all=loaded.derived; const f=parseFilters(req.query); const matched=sortRows(all.filter(r=>matches(r,f)),f.sort).slice(0,300); const quality=loaded.quality;
const content=`<header class="vx-head"><div><h1>Video Explorer</h1><div class="vx-muted">Find within-channel outliers, age-normalized performers, evergreen videos, and title-pattern examples.</div></div><div class="vx-muted">${fmt(matched.length)} shown · ${fmt(all.length)} saved videos scanned · cached after first load · <a href="/explore/videos?refresh=1">Refresh cached data</a></div></header><section class="vx-panel"><strong>Smart presets</strong><div class="vx-presets">${Object.entries(VIDEO_PRESETS).map(([k,p])=>`<button class="vx-preset" type="button" data-vpreset="${k}">${e(p.label)}</button>`).join("")}</div></section>${renderFilters(f)}${qualityHtml(quality,f.preset)}<div class="vx-results"><strong>Matching videos</strong><span class="vx-muted">Sorted by ${e(f.sort.replaceAll("_"," "))}; maximum 300 shown.</span></div><main class="vx-grid">${matched.length?matched.map(renderCard).join(""):`<div class="vx-empty">No videos match these filters. Try a broader preset or relax the thresholds.</div>`}</main><script>const ps=${JSON.stringify(VIDEO_PRESETS)};const form=document.getElementById('vx-filters');function usePreset(k,submit){const p=ps[k];if(!p)return;for(const el of form.elements){if(!el.name||el.name==='preset')continue;if(Object.prototype.hasOwnProperty.call(p,el.name))el.value=p[el.name];else if(['minViews','maxViews','minAgeDays','maxAgeDays','minViewsPerDay','minMedianMultiple','minViewsPerSubscriber','maxSubscribers','minSnapshotGrowthPerDay','titlePattern'].includes(el.name))el.value='';}form.elements.preset.value=k;if(submit)form.requestSubmit();}document.querySelectorAll('[data-vpreset]').forEach(b=>b.addEventListener('click',()=>usePreset(b.dataset.vpreset,true)));document.getElementById('vx-preset').addEventListener('change',ev=>{if(ev.target.value)usePreset(ev.target.value,false);});</script>`;
res.type("html").send(htmlPage("Video Explorer — YouTube Ecosystem Intelligence",content,baseHead,nav));
} catch(error){console.error("[viewer] Video Explorer failed:",error);res.status(500).type("text").send(`Video Explorer failed. Inspect the viewer terminal. Error: ${error.message}`);}
});
console.log("[viewer] Video Explorer registered at /explore/videos (schema-adaptive mode)");
}
export { registerVideoExplorer, VIDEO_PRESETS };
Shown as it is in the repository at build time (2026-11-03); the home directory appears as <home>. If this page and the file differ, the file is right. Back to the catalogue.