function renderPill(type, value, extra = '') { return `${escapeHTML(value)}`; } function renderCard(p, matches = []) { const coverStyle = p.cover ? `style="background-image:url(${p.cover}); background-size:cover;"` : ''; let excerpt = p.excerpt; if (matches.length) { const terms = new Set(matches.flatMap(m => m.indices.map(i => excerpt.slice(i[0], i[1] + 1)))); terms.forEach(t => { excerpt = excerpt.replace(new RegExp(escapeRegExp(t), 'gi'), `${t}`); }); } const programPills = (p.programs || []).map(pr => renderPill('program', state.programTitles[pr] || pr)).join(''); return `

${escapeHTML(p.title)}

${renderPill('section', state.sectionTitles[p.section] || p.section)} ${programPills}

${formatDate(p.date)}

${excerpt}

`; } function renderPager(currentPage, totalPages, baseParts, currentParams) { if (totalPages <= 1) return ''; let buttons = ''; if (currentPage > 1) buttons += ``; buttons += `Page ${currentPage} of ${totalPages}`; if (currentPage < totalPages) buttons += ``; return `
${buttons}
`; } function renderControls(sort, baseParts, currentParams) { return `
`; } function renderFilters(availableTags, activeTags, baseParts, currentParams) { const tagPills = availableTags.sort().map(t => `${escapeHTML(t)}`).join(''); return `

Filter by Tag

${tagPills}
`; } function escapeRegExp(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); }