(function () { function esc(s) { const d = document.createElement('div'); d.textContent = s || ''; return d.innerHTML; } function pageMatches(page, filters) { const q = (filters.search || '').trim().toLowerCase(); const terms = filters.terms || []; const siteId = filters.siteId ? String(filters.siteId) : ''; const minWords = parseInt(filters.minWords, 10) || 0; const minHype = parseInt(filters.minHype, 10) || 0; if (siteId && String(page.site_id) !== siteId) return false; if ((page.word_count || 0) < minWords) return false; if ((page.hype_score || 0) < minHype) return false; if (filters.changedOnly && !page.recently_changed) return false; const hay = [ page.site_name, page.title, page.url, page.excerpt, page.content_read, page.meta_description, (page.headings || []).join(' '), (page.signals || []).join(' '), (page.links_sample || []).map(function (l) { return (l.label || '') + ' ' + (l.href || ''); }).join(' '), ] .join(' ') .toLowerCase(); if (q && hay.indexOf(q) < 0) return false; for (let i = 0; i < terms.length; i++) { if (hay.indexOf(String(terms[i]).toLowerCase()) < 0) return false; } return true; } function sortPages(pages, col, dir) { const mul = dir === 'asc' ? 1 : -1; const copy = pages.slice(); copy.sort(function (a, b) { let va; let vb; switch (col) { case 'site_name': va = (a.site_name || '').toLowerCase(); vb = (b.site_name || '').toLowerCase(); return va < vb ? -mul : va > vb ? mul : 0; case 'title': va = (a.title || a.url || '').toLowerCase(); vb = (b.title || b.url || '').toLowerCase(); return va < vb ? -mul : va > vb ? mul : 0; case 'word_count': return ((a.word_count || 0) - (b.word_count || 0)) * mul; case 'links_count': return ((a.links_count || 0) - (b.links_count || 0)) * mul; case 'crawled_at': va = a.crawled_at || ''; vb = b.crawled_at || ''; return va < vb ? -mul : va > vb ? mul : 0; case 'hype_score': default: return ((a.hype_score || 0) - (b.hype_score || 0)) * mul; } }); return copy; } function filterPages(pages, filters) { if (!pages || !pages.length) return []; return pages.filter(function (p) { return pageMatches(p, filters); }); } function highlightHtml(text, queries) { const raw = text || ''; if (!raw) return 'Geen tekst'; let html = esc(raw); const list = []; if (queries && queries.length) { queries.forEach(function (q) { if (q && String(q).trim()) list.push(String(q).trim()); }); } list.sort(function (a, b) { return b.length - a.length; }); list.forEach(function (term) { if (term.length < 2) return; const re = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + ')', 'gi'); html = html.replace(re, '$1'); }); return html; } function exportCsv(pages) { const rows = [['site', 'title', 'url', 'words', 'hype', 'changed', 'crawled_at', 'excerpt']]; pages.forEach(function (p) { rows.push([ p.site_name || '', (p.title || '').replace(/"/g, '""'), p.url || '', String(p.word_count || 0), String(p.hype_score || 0), p.recently_changed ? 'yes' : 'no', p.crawled_at || '', (p.excerpt || '').replace(/"/g, '""').slice(0, 500), ]); }); return rows .map(function (r) { return r.map(function (c) { return '"' + c + '"'; }).join(','); }) .join('\n'); } function downloadCsv(pages, filename) { const csv = exportCsv(pages); const blob = new Blob(['\ufeff' + csv], { type: 'text/csv;charset=utf-8' }); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = filename || 'parse-analyse.csv'; a.click(); URL.revokeObjectURL(a.href); } window.ParseIntel = { filterPages: filterPages, sortPages: sortPages, highlightHtml: highlightHtml, exportCsv: exportCsv, downloadCsv: downloadCsv, }; })();