{"id":1942,"date":"2026-03-05T12:18:01","date_gmt":"2026-03-05T11:18:01","guid":{"rendered":"https:\/\/www.rchfullstack.com\/?page_id=1942"},"modified":"2026-03-05T12:21:07","modified_gmt":"2026-03-05T11:21:07","slug":"factagent","status":"publish","type":"page","link":"https:\/\/www.rchfullstack.com\/index.php\/factagent\/","title":{"rendered":"FactAgent"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"1942\" class=\"elementor elementor-1942\">\n\t\t\t\t<div class=\"elementor-element elementor-element-9ab5975 e-flex e-con-boxed e-con e-parent\" data-id=\"9ab5975\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-10c79b7 elementor-widget elementor-widget-spacer\" data-id=\"10c79b7\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-501f662 e-flex e-con-boxed e-con e-parent\" data-id=\"501f662\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-dd76fb1 elementor-widget elementor-widget-html\" data-id=\"dd76fb1\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"sv\">\r\n<head>\r\n<meta charset=\"UTF-8\">\r\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n<title>FactAgent \u2013 AI Faktakontroll<\/title>\r\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=IBM+Plex+Mono:wght@300;400;500;600&display=swap\" rel=\"stylesheet\">\r\n<style>\r\n  :root {\r\n    --blue:       #0E5287;\r\n    --blue-dark:  #0a3d63;\r\n    --blue-deeper:#072d4a;\r\n    --green:      #889407;\r\n    --green-light:#a0ad08;\r\n    --white:      #ffffff;\r\n    --white-dim:  #ffffff;\r\n    --white-muted:#ffffff;\r\n    --white-faint:rgba(255,255,255,0.25);\r\n    --white-ghost:rgba(255,255,255,0.1);\r\n  }\r\n  * { box-sizing: border-box; margin: 0; padding: 0; }\r\n  body {\r\n    background: var(--blue);\r\n    color: var(--white);\r\n    font-family: 'IBM Plex Mono', monospace;\r\n    min-height: 100vh;\r\n    overflow-x: hidden;\r\n  }\r\n  @keyframes scan { 0% { left: -100% } 100% { left: 100% } }\r\n  @keyframes pulse { 0%,100% { opacity: 0.3 } 50% { opacity: 1 } }\r\n  @keyframes slideIn { from { opacity:0; transform:translateY(8px) } to { opacity:1; transform:translateY(0) } }\r\n  @keyframes rotate { from { transform:rotate(0deg) } to { transform:rotate(360deg) } }\r\n\r\n  ::-webkit-scrollbar { width: 4px; }\r\n  ::-webkit-scrollbar-track { background: var(--blue-dark); }\r\n  ::-webkit-scrollbar-thumb { background: var(--white-faint); border-radius: 2px; }\r\n\r\n  #header {\r\n    border-bottom: 1px solid var(--white-faint);\r\n    padding: 14px 24px;\r\n    display: flex; align-items: center; justify-content: space-between;\r\n    background: var(--blue-dark);\r\n    flex-wrap: wrap; gap: 10px;\r\n  }\r\n  .logo-wrap { display:flex; align-items:center; gap:12px; }\r\n  .logo-icon {\r\n    width:32px; height:32px; border-radius:4px;\r\n    background: var(--blue-deeper);\r\n    border: 1px solid var(--white-faint);\r\n    display:flex; align-items:center; justify-content:center;\r\n    font-size:14px; color:var(--green-light);\r\n  }\r\n  .logo-title { font-size:14px; font-weight:600; letter-spacing:0.15em; color:#ffffff; }\r\n  .logo-title span { color:var(--green-light); }\r\n  .logo-sub { font-size:10px; color:#ffffff; letter-spacing:0.1em; margin-top:2px; }\r\n\r\n  #layout { display:flex; height:calc(100vh - 65px); }\r\n\r\n  #sidebar {\r\n    width:200px; border-right:1px solid var(--white-faint);\r\n    padding:16px 12px; overflow-y:auto; background:var(--blue-dark); flex-shrink:0;\r\n  }\r\n  .sidebar-title { font-size:10px; color:#ffffff; letter-spacing:0.1em; margin-bottom:12px; }\r\n  .history-empty { font-size:11px; color:#ffffff; line-height:1.6; }\r\n  .history-item {\r\n    padding:8px 10px; border-radius:4px; border:1px solid var(--white-faint);\r\n    margin-bottom:8px; cursor:pointer; background:var(--white-ghost);\r\n    font-size:11px; color:#ffffff; line-height:1.5;\r\n    transition:border-color 0.2s, background 0.2s;\r\n  }\r\n  .history-item:hover { border-color:var(--green); background:rgba(136,148,7,0.15); }\r\n  .history-query { color:#ffffff; margin-bottom:4px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }\r\n  .history-meta { display:flex; justify-content:space-between; }\r\n  .history-time { color:#ffffff; }\r\n\r\n  #main { flex:1; display:flex; flex-direction:column; overflow:hidden; }\r\n\r\n  #input-area { padding:20px 24px; border-bottom:1px solid var(--white-faint); background:var(--blue-dark); }\r\n  .input-label { font-size:11px; color:#ffffff; letter-spacing:0.1em; margin-bottom:8px; }\r\n  textarea {\r\n    width:100%; background:var(--blue-deeper); border:1px solid var(--white-faint); border-radius:6px;\r\n    padding:14px 16px; color:#ffffff; font-size:13px; font-family:'IBM Plex Mono',monospace;\r\n    line-height:1.6; resize:none; transition:border-color 0.2s;\r\n  }\r\n  textarea::placeholder { color:rgba(255,255,255,0.5); }\r\n  textarea:focus { outline:none; border-color:var(--green-light); }\r\n  .input-footer { display:flex; justify-content:space-between; align-items:center; margin-top:10px; }\r\n  .input-hint { font-size:10px; color:#ffffff; }\r\n  #analyze-btn {\r\n    padding:9px 22px; background:var(--green); border:none;\r\n    border-radius:4px; color:#ffffff; font-size:12px;\r\n    font-family:'IBM Plex Mono',monospace; letter-spacing:0.1em; font-weight:600;\r\n    cursor:pointer; transition:all 0.2s; display:flex; align-items:center; gap:8px;\r\n  }\r\n  #analyze-btn:disabled { background:rgba(255,255,255,0.2); color:rgba(255,255,255,0.5); cursor:not-allowed; }\r\n  #analyze-btn:not(:disabled):hover { background:var(--green-light); }\r\n  .spinner {\r\n    width:10px; height:10px; border:1.5px solid #ffffff;\r\n    border-top-color:transparent; border-radius:50%;\r\n    animation:rotate 0.8s linear infinite;\r\n  }\r\n\r\n  #phase-bar { padding:12px 24px; background:var(--blue-deeper); border-bottom:1px solid var(--white-faint); display:none; }\r\n  .phase-header { display:flex; justify-content:space-between; margin-bottom:6px; }\r\n  .phase-label { font-size:11px; color:#ffffff; letter-spacing:0.08em; }\r\n  .phase-pct { font-size:11px; color:#ffffff; }\r\n  .scan-track { position:relative; height:2px; background:var(--white-faint); border-radius:1px; overflow:hidden; }\r\n  .scan-bar {\r\n    position:absolute; top:0; left:-100%; width:100%; height:100%;\r\n    background:linear-gradient(90deg,transparent,var(--green-light),transparent);\r\n    animation:scan 1.5s linear infinite;\r\n  }\r\n\r\n  #results { flex:1; overflow-y:auto; padding:20px 24px; }\r\n\r\n  .empty-state { text-align:center; margin-top:60px; }\r\n  .empty-icon { font-size:48px; margin-bottom:16px; opacity:0.5; }\r\n  .empty-title { font-size:13px; letter-spacing:0.15em; color:#ffffff; }\r\n  .empty-sub { font-size:11px; margin-top:8px; color:#ffffff; }\r\n\r\n  \r\n  \r\n  \r\n  \r\n\r\n  .score-card {\r\n    display:flex; justify-content:space-between; align-items:center;\r\n    margin-bottom:20px; padding:16px 20px;\r\n    background:var(--blue-deeper); border:1px solid var(--white-faint); border-radius:6px;\r\n    animation:slideIn 0.4s ease forwards;\r\n  }\r\n  .score-label { font-size:10px; color:#ffffff; letter-spacing:0.1em; margin-bottom:6px; }\r\n  .score-number { font-size:36px; font-weight:600; line-height:1; }\r\n  .score-unit { font-size:16px; }\r\n  .score-right { flex:1; margin-left:24px; }\r\n  .score-bar-track { height:6px; background:var(--white-faint); border-radius:3px; overflow:hidden; margin-bottom:10px; }\r\n  .score-bar-fill { height:100%; border-radius:3px; transition:width 1s ease; }\r\n  .score-summary { font-size:12px; color:#ffffff; line-height:1.6; }\r\n\r\n  .redflags {\r\n    margin-bottom:16px; padding:12px 16px;\r\n    background:rgba(224,92,92,0.12); border:1px solid rgba(224,92,92,0.4); border-radius:6px;\r\n    animation:slideIn 0.4s ease forwards;\r\n  }\r\n  .redflag-title { font-size:10px; color:#ff8080; letter-spacing:0.1em; margin-bottom:8px; }\r\n  .redflag-item { font-size:12px; color:#ffffff; margin-bottom:4px; padding-left:10px; border-left:2px solid rgba(224,92,92,0.6); }\r\n\r\n  .claims-title { font-size:10px; color:#ffffff; letter-spacing:0.1em; margin-bottom:12px; }\r\n  .claim-card {\r\n    background:var(--blue-deeper); border:1px solid var(--white-faint);\r\n    border-radius:6px; padding:16px 20px; margin-bottom:12px;\r\n    animation:slideIn 0.4s ease forwards; opacity:0;\r\n  }\r\n  .claim-header { display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:10px; }\r\n  .claim-num { font-size:13px; color:#ffffff; letter-spacing:0.05em; text-transform:uppercase; }\r\n  .verdict-badge { padding:3px 10px; border-radius:3px; font-size:11px; font-weight:600; letter-spacing:0.08em; display:flex; align-items:center; gap:5px; }\r\n  .claim-text { color:#ffffff; font-size:14px; line-height:1.6; margin:0 0 14px; }\r\n  .sources-title { font-size:11px; color:#ffffff; margin-bottom:8px; letter-spacing:0.05em; }\r\n  .sources-row { display:flex; flex-wrap:wrap; gap:6px; }\r\n  .source-badge { display:flex; align-items:center; gap:6px; padding:4px 10px; border-radius:4px; font-size:11px; }\r\n  .source-dot { width:5px; height:5px; border-radius:50%; }\r\n  .claim-analysis { margin-top:14px; padding:10px 14px; background:var(--white-ghost); border-radius:4px; font-size:13px; color:#ffffff; line-height:1.6; }\r\n  .conflicts-title { font-size:11px; color:#e8cc00; margin-bottom:8px; letter-spacing:0.05em; margin-top:12px; }\r\n  .conflict-item { font-size:12px; color:#ffffff; padding:6px 10px; background:rgba(200,168,0,0.1); border-radius:3px; margin-bottom:4px; }\r\n\r\n  .recommendation {\r\n    padding:14px 18px; background:var(--blue-deeper);\r\n    border:1px solid var(--white-faint); border-left:3px solid var(--green);\r\n    border-radius:6px; font-size:12px; color:#ffffff; line-height:1.7;\r\n    animation:slideIn 0.4s ease forwards;\r\n  }\r\n  .rec-label { font-size:10px; color:var(--green-light); letter-spacing:0.1em; margin-bottom:6px; }\r\n  .error-msg { padding:20px; color:#ff8080; font-size:13px; }\r\n\r\n  @media(max-width:640px) {\r\n    #sidebar { display:none; }\r\n  }\r\n<\/style>\r\n<\/head>\r\n<body>\r\n\r\n<div id=\"header\">\r\n  <div class=\"logo-wrap\">\r\n    <div class=\"logo-icon\">\u25ce<\/div>\r\n    <div>\r\n      <div class=\"logo-title\">FACT<span>AGENT<\/span><\/div>\r\n      <div class=\"logo-sub\">K\u00c4LLKONTROLL \u00b7 FAKTA \u00b7 TROV\u00c4RDIGHET<\/div>\r\n    <\/div>\r\n  <\/div>\r\n<\/div>\r\n\r\n<div id=\"layout\">\r\n  <div id=\"sidebar\">\r\n    <div class=\"sidebar-title\">HISTORIK<\/div>\r\n    <div id=\"history-list\">\r\n      <div class=\"history-empty\">Inga analyser \u00e4nnu.<\/div>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div id=\"main\">\r\n    <div id=\"input-area\">\r\n      <div class=\"input-label\">KLISTRA IN TEXT, RUBRIK ELLER P\u00c5ST\u00c5ENDE F\u00d6R ANALYS<\/div>\r\n      <textarea id=\"query-input\" rows=\"4\"\r\n        placeholder=\"Ex: 'Sverige har den h\u00f6gsta skatten i EU' eller klistra in en nyhetartikel...\"><\/textarea>\r\n      <div class=\"input-footer\">\r\n        <div class=\"input-hint\" id=\"char-count\">Ctrl+Enter f\u00f6r att analysera \u00b7 0 tecken<\/div>\r\n        <button id=\"analyze-btn\" disabled>\u25b6 ANALYSERA<\/button>\r\n      <\/div>\r\n    <\/div>\r\n\r\n    <div id=\"phase-bar\">\r\n      <div class=\"phase-header\">\r\n        <div class=\"phase-label\" id=\"phase-label\">S\u00f6ker...<\/div>\r\n        <div class=\"phase-pct\" id=\"phase-pct\">0%<\/div>\r\n      <\/div>\r\n      <div class=\"scan-track\"><div class=\"scan-bar\"><\/div><\/div>\r\n    <\/div>\r\n\r\n    <div id=\"results\">\r\n      <div class=\"empty-state\">\r\n        <div class=\"empty-icon\">\u25ce<\/div>\r\n        <div class=\"empty-title\">REDO F\u00d6R ANALYS<\/div>\r\n        <div class=\"empty-sub\">Agenten s\u00f6ker, matchar och flaggar \u2013 du ber\u00e4ttar historien.<\/div>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n<\/div>\r\n\r\n<script>\r\n\r\n\r\nconst VERDICT = {\r\n  VERIFIED:    { label:\"Verifierad\",           color:\"#00d4aa\", bg:\"rgba(0,212,170,0.15)\",  icon:\"\u2713\" },\r\n  CONFLICTING: { label:\"Motstridiga uppgifter\", color:\"#f5c842\", bg:\"rgba(245,200,66,0.15)\", icon:\"\u26a1\" },\r\n  UNVERIFIED:  { label:\"Ej verifierbar\",        color:\"#ff8080\", bg:\"rgba(255,128,128,0.15)\",icon:\"?\" },\r\n};\r\n\r\nconst PHASES = [\r\n  { label:\"S\u00f6ker i trov\u00e4rdiga k\u00e4llor...\",    pct:25 },\r\n  { label:\"Matchar och j\u00e4mf\u00f6r k\u00e4lldata...\",  pct:50 },\r\n  { label:\"Identifierar motstridigheter...\", pct:75 },\r\n  { label:\"Sammanst\u00e4ller faktaunderlag...\",  pct:90 },\r\n  { label:\"Agenten analyserar...\",           pct:99 },\r\n];\r\n\r\nlet isAnalyzing = false;\r\nlet analysisHistory = [];\r\n\r\nconst queryInput  = document.getElementById('query-input');\r\nconst charCount   = document.getElementById('char-count');\r\nconst analyzeBtn  = document.getElementById('analyze-btn');\r\nconst phaseBar    = document.getElementById('phase-bar');\r\nconst phaseLabel  = document.getElementById('phase-label');\r\nconst phasePct    = document.getElementById('phase-pct');\r\nconst results     = document.getElementById('results');\r\nconst historyList = document.getElementById('history-list');\r\n\r\nqueryInput.addEventListener('input', () => {\r\n  const len = queryInput.value.length;\r\n  charCount.textContent = `Ctrl+Enter f\u00f6r att analysera \u00b7 ${len} tecken`;\r\n  analyzeBtn.disabled = len === 0 || isAnalyzing;\r\n});\r\n\r\nqueryInput.addEventListener('keydown', e => {\r\n  if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) analyze();\r\n});\r\n\r\nanalyzeBtn.addEventListener('click', analyze);\r\n\r\nfunction scoreColor(s) {\r\n  return s >= 70 ? '#00d4aa' : s >= 40 ? '#f5c842' : '#ff8080';\r\n}\r\n\r\nfunction sleep(ms) { return new Promise(r => setTimeout(r, ms)); }\r\n\r\n\/\/ \u2500\u2500\u2500 KLISTRA IN DINA API-NYCKLAR H\u00c4R \u2500\u2500\u2500\r\nconst NEWSAPI_KEY  = 'DIN_NEWSAPI_NYCKEL_H\u00c4R';\r\nconst GEMINI_KEY   = 'DIN_GEMINI_API_NYCKEL_H\u00c4R';\r\n\/\/ \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nasync function fetchNews(query) {\r\n  const keywords = query.replace(\/['\"]\/g, '').split(' ').slice(0, 4).join(' ');\r\n  try {\r\n    const url = `https:\/\/newsapi.org\/v2\/everything?q=${encodeURIComponent(keywords)}&language=sv&sortBy=publishedAt&pageSize=5&apiKey=${NEWSAPI_KEY}`;\r\n    const resp = await fetch(url);\r\n    const data = await resp.json();\r\n    if (data.status !== 'ok' || !data.articles?.length) {\r\n      const url2 = `https:\/\/newsapi.org\/v2\/everything?q=${encodeURIComponent(keywords)}&language=en&sortBy=publishedAt&pageSize=5&apiKey=${NEWSAPI_KEY}`;\r\n      const resp2 = await fetch(url2);\r\n      const data2 = await resp2.json();\r\n      return data2.articles || [];\r\n    }\r\n    return data.articles || [];\r\n  } catch(e) { return []; }\r\n}\r\n\r\nfunction formatArticles(articles) {\r\n  if (!articles.length) return 'Inga relevanta nyhetsartiklar hittades.';\r\n  return articles.map((a, i) =>\r\n    `[${i+1}] ${a.source?.name || 'Ok\u00e4nd'} (${a.publishedAt?.substring(0,10) || ''})\\nRubrik: ${a.title}\\nIngress: ${a.description || '-'}`\r\n  ).join('\\n\\n');\r\n}\r\n\r\nasync function analyze() {\r\n  const q = queryInput.value.trim();\r\n  if (!q || isAnalyzing) return;\r\n  isAnalyzing = true;\r\n  analyzeBtn.disabled = true;\r\n  analyzeBtn.innerHTML = '<div class=\"spinner\"><\/div> ANALYSERAR';\r\n  results.innerHTML = '';\r\n  phaseBar.style.display = 'block';\r\n\r\n  const delays = [1500, 1500, 1000, 500, 0];\r\n  for (let i = 0; i < PHASES.length; i++) {\r\n    phaseLabel.textContent = PHASES[i].label;\r\n    phasePct.textContent = PHASES[i].pct + '%';\r\n    if (delays[i]) await sleep(delays[i]);\r\n  }\r\n\r\n  try {\r\n    phaseLabel.textContent = 'H\u00e4mtar nyhetsdata...';\r\n    const articles = await fetchNews(q);\r\n    const newsContext = formatArticles(articles);\r\n\r\n    phaseLabel.textContent = 'Agenten analyserar mot k\u00e4lldata...';\r\n    phasePct.textContent = '99%';\r\n\r\n    const systemPrompt = `Du \u00e4r FactAgent \u2013 AI-faktakontrollagent f\u00f6r journalister. Analysera p\u00e5st\u00e5enden mot verkliga nyhetsartiklar.\r\n\r\nBasera analysen p\u00e5 de bifogade artiklarna. Om artiklarna bekr\u00e4ftar \u2013 VERIFIED. Om de mots\u00e4ger \u2013 CONFLICTING. Om inga \u00e4r relevanta \u2013 UNVERIFIED.\r\n\r\nSvara ALLTID i detta exakta JSON-format (inget annat, inga backticks):\r\n{\r\n  \"summary\": \"bed\u00f6mning baserad p\u00e5 artiklarna (2-3 meningar)\",\r\n  \"credibilityScore\": 75,\r\n  \"claims\": [\r\n    {\r\n      \"claim\": \"p\u00e5st\u00e5endet\",\r\n      \"verdict\": \"VERIFIED\",\r\n      \"analysis\": \"analys baserad p\u00e5 artiklarna\",\r\n      \"sources\": [{\"source\": {\"id\": \"x\", \"name\": \"K\u00e4llnamn\"}, \"status\": \"confirmed\"}],\r\n      \"conflicts\": []\r\n    }\r\n  ],\r\n  \"redFlags\": [],\r\n  \"recommendation\": \"konkret rekommendation till journalisten\"\r\n}`;\r\n\r\n    const geminiUrl = `https:\/\/generativelanguage.googleapis.com\/v1beta\/models\/gemini-2.0-flash:generateContent?key=${GEMINI_KEY}`;\r\n    const resp = await fetch(geminiUrl, {\r\n      method: 'POST',\r\n      headers: { 'Content-Type': 'application\/json' },\r\n      body: JSON.stringify({\r\n        contents: [{\r\n          parts: [{\r\n            text: systemPrompt + '\\n\\nP\u00e5st\u00e5ende: \"' + q + '\"\\n\\nNyhetsartiklar:\\n' + newsContext\r\n          }]\r\n        }],\r\n        generationConfig: { temperature: 0.2, maxOutputTokens: 1500 }\r\n      })\r\n    });\r\n\r\n    const data = await resp.json();\r\n    if (data.error) throw new Error(data.error.message || 'Gemini API-fel');\r\n    if (!data.candidates?.length) throw new Error('Inget svar fr\u00e5n Gemini. Kontrollera API-nyckeln.');\r\n    const text = data.candidates[0]?.content?.parts?.[0]?.text || '';\r\n    const clean = text.replace(\/```json\\n?\/g,'').replace(\/```\\n?\/g,'').trim();\r\n    let parsed;\r\n    try { parsed = JSON.parse(clean); }\r\n    catch { parsed = { summary: text.substring(0,300), credibilityScore:50, claims:[], redFlags:[], recommendation:'Kontrollera k\u00e4llorna manuellt.' }; }\r\n\r\n    parsed._articles = articles;\r\n    renderResult(parsed);\r\n    addHistory(q, parsed);\r\n\r\n  } catch(err) {\r\n    results.innerHTML = `<div class=\"error-msg\">Fel vid analys: ${err.message}<\/div>`;\r\n  }\r\n\r\n  isAnalyzing = false;\r\n  phaseBar.style.display = 'none';\r\n  analyzeBtn.innerHTML = '\u25b6 ANALYSERA';\r\n  analyzeBtn.disabled = queryInput.value.trim() === '';\r\n}\r\n\r\n\r\n\r\nfunction renderResult(r) {\r\n  const sc = scoreColor(r.credibilityScore);\r\n  let html = `\r\n    <div class=\"score-card\">\r\n      <div>\r\n        <div class=\"score-label\">TROV\u00c4RDIGHETSSCORE<\/div>\r\n        <div class=\"score-number\" style=\"color:${sc}\">${r.credibilityScore}<span class=\"score-unit\">%<\/span><\/div>\r\n      <\/div>\r\n      <div class=\"score-right\">\r\n        <div class=\"score-bar-track\">\r\n          <div class=\"score-bar-fill\" style=\"width:${r.credibilityScore}%;background:linear-gradient(90deg,${sc}99,${sc})\"><\/div>\r\n        <\/div>\r\n        <div class=\"score-summary\">${r.summary || ''}<\/div>\r\n      <\/div>\r\n    <\/div>`;\r\n\r\n  if (r.redFlags && r.redFlags.length > 0) {\r\n    html += `<div class=\"redflags\"><div class=\"redflag-title\">\u26a0 VARNINGSSIGNALER<\/div>`;\r\n    r.redFlags.forEach(f => { html += `<div class=\"redflag-item\">${f}<\/div>`; });\r\n    html += `<\/div>`;\r\n  }\r\n\r\n  if (r.claims && r.claims.length > 0) {\r\n    html += `<div class=\"claims-title\">P\u00c5ST\u00c5ENDEANALYS \u00b7 ${r.claims.length} IDENTIFIERADE<\/div>`;\r\n    r.claims.forEach((c, i) => { html += renderClaim(c, i); });\r\n  }\r\n\r\n  if (r.recommendation) {\r\n    html += `<div class=\"recommendation\">\r\n      <div class=\"rec-label\">\u2192 REKOMMENDATION<\/div>\r\n      ${r.recommendation}\r\n    <\/div>`;\r\n  }\r\n\r\n  \/\/ Visa k\u00e4llartiklar om de finns\r\n  if (r._articles && r._articles.length > 0) {\r\n    html += `<div style=\"margin-top:20px;\">\r\n      <div style=\"font-size:10px;color:#ffffff;letter-spacing:0.1em;margin-bottom:10px;opacity:0.6;\">K\u00c4LLARTIKLAR FR\u00c5N NEWSAPI<\/div>`;\r\n    r._articles.forEach(a => {\r\n      html += `<div style=\"padding:10px 14px;background:rgba(255,255,255,0.05);border:1px solid rgba(255,255,255,0.12);border-radius:4px;margin-bottom:6px;\">\r\n        <div style=\"font-size:11px;color:#a0ad08;margin-bottom:3px;\">${a.source?.name || ''} \u00b7 ${a.publishedAt?.substring(0,10) || ''}<\/div>\r\n        <div style=\"font-size:12px;color:#ffffff;\">${a.title}<\/div>\r\n        ${a.url ? `<a href=\"${a.url}\" target=\"_blank\" style=\"font-size:10px;color:rgba(255,255,255,0.5);text-decoration:none;\">L\u00e4s artikel \u2192<\/a>` : ''}\r\n      <\/div>`;\r\n    });\r\n    html += `<\/div>`;\r\n  }\r\n\r\n  results.innerHTML = html;\r\n}\r\n\r\nfunction renderClaim(c, i) {\r\n  const v = VERDICT[c.verdict] || VERDICT.UNVERIFIED;\r\n  const sourceColors = { confirmed:'#00d4aa', conflicting:'#f5c842', absent:'rgba(255,255,255,0.3)', checking:'#a0ad08' };\r\n\r\n  let sourcesHTML = '';\r\n  if (c.sources && c.sources.length) {\r\n    sourcesHTML = `<div class=\"sources-title\">K\u00c4LLSTATUS<\/div><div class=\"sources-row\">`;\r\n    c.sources.forEach(s => {\r\n      const col = sourceColors[s.status] || 'rgba(255,255,255,0.3)';\r\n      sourcesHTML += `<div class=\"source-badge\" style=\"border:1px solid ${col};background:rgba(255,255,255,0.05);color:#ffffff\">\r\n        <div class=\"source-dot\" style=\"background:${col}\"><\/div>${s.source.name}\r\n      <\/div>`;\r\n    });\r\n    sourcesHTML += `<\/div>`;\r\n  }\r\n\r\n  let conflictsHTML = '';\r\n  if (c.conflicts && c.conflicts.length) {\r\n    conflictsHTML = `<div class=\"conflicts-title\">\u26a1 KONFLIKTPUNKTER<\/div>`;\r\n    c.conflicts.forEach(cf => { conflictsHTML += `<div class=\"conflict-item\">${cf}<\/div>`; });\r\n  }\r\n\r\n  return `<div class=\"claim-card\" style=\"border-left:3px solid ${v.color};animation-delay:${i*0.1}s\">\r\n    <div class=\"claim-header\">\r\n      <div class=\"claim-num\">P\u00e5st\u00e5ende #${i+1}<\/div>\r\n      <div class=\"verdict-badge\" style=\"background:${v.bg};color:${v.color}\">\r\n        <span>${v.icon}<\/span>${v.label}\r\n      <\/div>\r\n    <\/div>\r\n    <p class=\"claim-text\">\"${c.claim}\"<\/p>\r\n    ${sourcesHTML}\r\n    ${c.analysis ? `<div class=\"claim-analysis\">${c.analysis}<\/div>` : ''}\r\n    ${conflictsHTML}\r\n  <\/div>`;\r\n}\r\n\r\nfunction addHistory(q, r) {\r\n  analysisHistory.unshift({ query: q, result: r, time: new Date() });\r\n  if (analysisHistory.length > 5) analysisHistory.pop();\r\n  renderHistory();\r\n}\r\n\r\nfunction renderHistory() {\r\n  if (analysisHistory.length === 0) {\r\n    historyList.innerHTML = '<div class=\"history-empty\">Inga analyser \u00e4nnu.<\/div>';\r\n    return;\r\n  }\r\n  historyList.innerHTML = analysisHistory.map((h, i) => {\r\n    const sc = scoreColor(h.result.credibilityScore);\r\n    const t = h.time.toLocaleTimeString('sv', { hour:'2-digit', minute:'2-digit' });\r\n    return `<div class=\"history-item\" onclick=\"loadHistory(${i})\">\r\n      <div class=\"history-query\">${h.query.substring(0,38)}...<\/div>\r\n      <div class=\"history-meta\">\r\n        <span style=\"color:${sc}\">${h.result.credibilityScore}%<\/span>\r\n        <span class=\"history-time\">${t}<\/span>\r\n      <\/div>\r\n    <\/div>`;\r\n  }).join('');\r\n}\r\n\r\nfunction loadHistory(i) {\r\n  const h = analysisHistory[i];\r\n  queryInput.value = h.query;\r\n  charCount.textContent = `Ctrl+Enter f\u00f6r att analysera \u00b7 ${h.query.length} tecken`;\r\n  analyzeBtn.disabled = false;\r\n  renderResult(h.result);\r\n}\r\n<\/script>\r\n<\/body>\r\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>FactAgent \u2013 AI Faktakontroll \u25ce FACTAGENT K\u00c4LLKONTROLL \u00b7 FAKTA \u00b7 TROV\u00c4RDIGHET HISTORIK Inga analyser \u00e4nnu. KLISTRA IN TEXT, RUBRIK ELLER P\u00c5ST\u00c5ENDE F\u00d6R ANALYS Ctrl+Enter f\u00f6r att analysera \u00b7 0 tecken \u25b6 ANALYSERA S\u00f6ker&#8230; 0% \u25ce REDO F\u00d6R ANALYS Agenten s\u00f6ker, matchar och flaggar \u2013 du ber\u00e4ttar historien.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"site-sidebar-layout":"no-sidebar","site-content-layout":"page-builder","ast-site-content-layout":"full-width-container","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"folder":[],"class_list":["post-1942","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.rchfullstack.com\/index.php\/wp-json\/wp\/v2\/pages\/1942","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rchfullstack.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.rchfullstack.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.rchfullstack.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rchfullstack.com\/index.php\/wp-json\/wp\/v2\/comments?post=1942"}],"version-history":[{"count":7,"href":"https:\/\/www.rchfullstack.com\/index.php\/wp-json\/wp\/v2\/pages\/1942\/revisions"}],"predecessor-version":[{"id":1949,"href":"https:\/\/www.rchfullstack.com\/index.php\/wp-json\/wp\/v2\/pages\/1942\/revisions\/1949"}],"wp:attachment":[{"href":"https:\/\/www.rchfullstack.com\/index.php\/wp-json\/wp\/v2\/media?parent=1942"}],"wp:term":[{"taxonomy":"folder","embeddable":true,"href":"https:\/\/www.rchfullstack.com\/index.php\/wp-json\/wp\/v2\/folder?post=1942"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}