Video füllt jetzt die komplette Hero-Section (88vh) statt nur den 700px-breiten Slide-Container. Ein-/Ausblenden per CSS-Transition (0.8s) gekoppelt an den aktiven Slide (nur bei Slide 0 sichtbar). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
547 Zeilen
22 KiB
JavaScript
547 Zeilen
22 KiB
JavaScript
/* AegisSight Monitor - Product Page v2 */
|
|
(function () {
|
|
'use strict';
|
|
|
|
/* ==================== NAVBAR ==================== */
|
|
var navbar = document.getElementById('navbar');
|
|
window.addEventListener('scroll', function () {
|
|
navbar.classList.toggle('scrolled', window.scrollY > 10);
|
|
});
|
|
|
|
/* ==================== MOBILE MENU ==================== */
|
|
var toggle = document.querySelector('.mobile-menu-toggle');
|
|
var menu = document.getElementById('mobile-menu');
|
|
var overlay = document.getElementById('mobile-overlay');
|
|
|
|
function closeMenu() {
|
|
toggle.classList.remove('active');
|
|
menu.classList.remove('open');
|
|
overlay.classList.remove('open');
|
|
toggle.setAttribute('aria-expanded', 'false');
|
|
}
|
|
|
|
toggle.addEventListener('click', function () {
|
|
var isOpen = menu.classList.contains('open');
|
|
if (isOpen) { closeMenu(); } else {
|
|
toggle.classList.add('active');
|
|
menu.classList.add('open');
|
|
overlay.classList.add('open');
|
|
toggle.setAttribute('aria-expanded', 'true');
|
|
}
|
|
});
|
|
|
|
overlay.addEventListener('click', closeMenu);
|
|
menu.querySelectorAll('a').forEach(function (l) { l.addEventListener('click', closeMenu); });
|
|
|
|
/* ==================== SMOOTH SCROLL ==================== */
|
|
document.querySelectorAll('a[href^="#"]').forEach(function (link) {
|
|
link.addEventListener('click', function (e) {
|
|
var t = document.querySelector(this.getAttribute('href'));
|
|
if (t) { e.preventDefault(); t.scrollIntoView({ behavior: 'smooth' }); }
|
|
});
|
|
});
|
|
|
|
/* ==================== HERO SLIDER ==================== */
|
|
var heroSlides = document.querySelectorAll('.hero-slide');
|
|
var heroDots = document.querySelectorAll('.hero-dot');
|
|
var heroCurrentSlide = 0;
|
|
var heroTimer = null;
|
|
var HERO_INTERVAL = 8000;
|
|
var heroIsTransitioning = false;
|
|
|
|
function heroGoTo(index) {
|
|
if (heroIsTransitioning || index === heroCurrentSlide || !heroSlides.length) return;
|
|
heroIsTransitioning = true;
|
|
|
|
var oldIndex = heroCurrentSlide;
|
|
heroSlides[oldIndex].classList.add('exiting');
|
|
heroSlides[oldIndex].classList.remove('active');
|
|
if (heroDots[oldIndex]) heroDots[oldIndex].classList.remove('active');
|
|
|
|
setTimeout(function () {
|
|
heroSlides[oldIndex].classList.remove('exiting');
|
|
heroCurrentSlide = index;
|
|
heroSlides[heroCurrentSlide].classList.add('active');
|
|
if (heroDots[heroCurrentSlide]) heroDots[heroCurrentSlide].classList.add('active');
|
|
heroIsTransitioning = false;
|
|
// Fullscreen video only on slide 0
|
|
var vid = document.getElementById('hero-fullscreen-video');
|
|
if (vid) vid.classList.toggle('visible', heroCurrentSlide === 0);
|
|
}, 400);
|
|
}
|
|
|
|
function heroNext() {
|
|
heroGoTo((heroCurrentSlide + 1) % heroSlides.length);
|
|
}
|
|
|
|
function heroPrev() {
|
|
heroGoTo((heroCurrentSlide - 1 + heroSlides.length) % heroSlides.length);
|
|
}
|
|
|
|
function heroStartAutoplay() {
|
|
heroStopAutoplay();
|
|
heroTimer = setInterval(heroNext, HERO_INTERVAL);
|
|
}
|
|
|
|
function heroStopAutoplay() {
|
|
if (heroTimer) { clearInterval(heroTimer); heroTimer = null; }
|
|
}
|
|
|
|
heroDots.forEach(function (dot, i) {
|
|
dot.addEventListener('click', function () {
|
|
heroGoTo(i);
|
|
heroStartAutoplay();
|
|
});
|
|
});
|
|
|
|
var heroPrevBtn = document.querySelector('.hero-arrow-prev');
|
|
var heroNextBtn = document.querySelector('.hero-arrow-next');
|
|
if (heroPrevBtn) heroPrevBtn.addEventListener('click', function () { heroPrev(); heroStartAutoplay(); });
|
|
if (heroNextBtn) heroNextBtn.addEventListener('click', function () { heroNext(); heroStartAutoplay(); });
|
|
|
|
var heroSlider = document.querySelector('.hero-slider');
|
|
if (heroSlider) {
|
|
heroSlider.addEventListener('mouseenter', heroStopAutoplay);
|
|
heroSlider.addEventListener('mouseleave', heroStartAutoplay);
|
|
|
|
var heroTouchStartX = 0;
|
|
heroSlider.addEventListener('touchstart', function (e) {
|
|
heroTouchStartX = e.changedTouches[0].screenX;
|
|
heroStopAutoplay();
|
|
}, { passive: true });
|
|
heroSlider.addEventListener('touchend', function (e) {
|
|
var diff = e.changedTouches[0].screenX - heroTouchStartX;
|
|
if (Math.abs(diff) > 50) {
|
|
if (diff < 0) heroNext(); else heroPrev();
|
|
}
|
|
heroStartAutoplay();
|
|
}, { passive: true });
|
|
}
|
|
|
|
document.addEventListener('visibilitychange', function () {
|
|
if (document.hidden) { heroStopAutoplay(); }
|
|
else { heroStartAutoplay(); }
|
|
});
|
|
|
|
if (heroSlides.length > 1) heroStartAutoplay();
|
|
|
|
/* ==================== MAP STATE ==================== */
|
|
var mapInstance = null;
|
|
var markerLayer = null;
|
|
var legendControl = null;
|
|
var lageData = {};
|
|
var dataLoaded = false;
|
|
|
|
var lageTitles = {
|
|
'iran-konflikt': 'Gro\u00dflage - Irankonflikt',
|
|
'cyberangriffe': 'Cyberangriffe auf deutsche Infrastruktur',
|
|
'deepfakes': 'Rechtliche Lage von Deepfakes in Deutschland'
|
|
};
|
|
|
|
/* ==================== 3D CAROUSEL ==================== */
|
|
var cards = document.querySelectorAll('.carousel-card');
|
|
var dots = document.querySelectorAll('.carousel-dot');
|
|
var activeIndex = 0;
|
|
|
|
window.positionCards = function positionCards(idx) {
|
|
activeIndex = idx;
|
|
cards.forEach(function (card, i) {
|
|
card.classList.remove('active', 'left', 'right', 'hidden');
|
|
if (i === idx) card.classList.add('active');
|
|
else if (i === (idx - 1 + cards.length) % cards.length) card.classList.add('left');
|
|
else if (i === (idx + 1) % cards.length) card.classList.add('right');
|
|
else card.classList.add('hidden');
|
|
});
|
|
dots.forEach(function (dot, i) {
|
|
dot.classList.toggle('active', i === idx);
|
|
});
|
|
// Update map based on active Lage (only after data loaded)
|
|
if (!dataLoaded) return;
|
|
var lage = cards[idx].getAttribute('data-lage');
|
|
var mapSection = document.getElementById('map-section');
|
|
if (lage && lageData[lage]) {
|
|
mapSection.classList.remove('map-hidden');
|
|
showMarkers(lageData[lage].locations, lageData[lage].category_labels);
|
|
// Stats-Bar aktualisieren
|
|
var titleEl = document.querySelector('.live-stats-title');
|
|
if (titleEl) titleEl.textContent = lageTitles[lage] || lage;
|
|
countUp(document.getElementById('stat-articles'), lageData[lage].article_count);
|
|
countUp(document.getElementById('stat-sources'), lageData[lage].source_count);
|
|
countUp(document.getElementById('stat-factchecks'), lageData[lage].factcheck_count);
|
|
} else {
|
|
if (mapSection) mapSection.classList.add('map-hidden');
|
|
clearMarkers();
|
|
}
|
|
}
|
|
|
|
cards.forEach(function (card, i) {
|
|
card.addEventListener('click', function () {
|
|
if (!card.classList.contains('active')) positionCards(i);
|
|
});
|
|
});
|
|
|
|
dots.forEach(function (dot, i) {
|
|
dot.addEventListener('click', function () { positionCards(i); });
|
|
});
|
|
|
|
positionCards(0);
|
|
|
|
// Arrow navigation
|
|
var prevBtn = document.querySelector('.carousel-prev');
|
|
var nextBtn = document.querySelector('.carousel-next');
|
|
if (prevBtn) prevBtn.addEventListener('click', function () {
|
|
positionCards((activeIndex - 1 + cards.length) % cards.length);
|
|
});
|
|
if (nextBtn) nextBtn.addEventListener('click', function () {
|
|
positionCards((activeIndex + 1) % cards.length);
|
|
});
|
|
|
|
/* ==================== SIMPLE MARKDOWN ==================== */
|
|
function mdToHtml(md) {
|
|
if (!md) return '';
|
|
var lines = md.split('\n');
|
|
var html = '';
|
|
var inList = false;
|
|
for (var i = 0; i < lines.length; i++) {
|
|
var line = lines[i].trim();
|
|
if (!line) {
|
|
if (inList) { html += '</ul>'; inList = false; }
|
|
continue;
|
|
}
|
|
line = line.replace(/\[(\d+[a-z]?)\]/g, '');
|
|
line = line.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>');
|
|
if (/^## /.test(line)) {
|
|
if (inList) { html += '</ul>'; inList = false; }
|
|
html += '<h2>' + line.replace(/^## /, '') + '</h2>';
|
|
} else if (/^### /.test(line)) {
|
|
if (inList) { html += '</ul>'; inList = false; }
|
|
html += '<h3>' + line.replace(/^### /, '') + '</h3>';
|
|
} else if (/^- /.test(line)) {
|
|
if (!inList) { html += '<ul>'; inList = true; }
|
|
html += '<li>' + line.replace(/^- /, '') + '</li>';
|
|
} else {
|
|
if (inList) { html += '</ul>'; inList = false; }
|
|
html += '<p>' + line + '</p>';
|
|
}
|
|
}
|
|
if (inList) html += '</ul>';
|
|
return html;
|
|
}
|
|
|
|
/* ==================== COUNT-UP ANIMATION ==================== */
|
|
function countUp(el, target) {
|
|
if (!el) return;
|
|
if (!target) { el.textContent = '0'; return; }
|
|
var duration = 1200;
|
|
var startTime = null;
|
|
function step(ts) {
|
|
if (!startTime) startTime = ts;
|
|
var progress = Math.min((ts - startTime) / duration, 1);
|
|
var ease = 1 - Math.pow(1 - progress, 3);
|
|
el.textContent = Math.floor(ease * target).toLocaleString('de-DE');
|
|
if (progress < 1) requestAnimationFrame(step);
|
|
}
|
|
requestAnimationFrame(step);
|
|
}
|
|
|
|
/* ==================== LIVE DATA ==================== */
|
|
function timeAgo(dateStr) {
|
|
var diffMin = Math.floor((Date.now() - new Date(dateStr).getTime()) / 60000);
|
|
if (diffMin < 1) return 'Gerade eben aktualisiert';
|
|
if (diffMin < 60) return 'Aktualisiert vor ' + diffMin + ' Min.';
|
|
var diffH = Math.floor(diffMin / 60);
|
|
if (diffH < 24) return 'Aktualisiert vor ' + diffH + ' Std.';
|
|
var diffD = Math.floor(diffH / 24);
|
|
return 'Aktualisiert vor ' + diffD + (diffD === 1 ? ' Tag' : ' Tagen');
|
|
}
|
|
|
|
function loadLiveData() {
|
|
fetch('/lagen/iran-konflikt/data/summary.json?t=' + Date.now())
|
|
.then(function (r) { if (!r.ok) throw new Error(r.status); return r.json(); })
|
|
.then(function (data) {
|
|
var inc = data.incident || {};
|
|
// summary.json has flat structure
|
|
|
|
var ea = document.getElementById('stat-articles');
|
|
var es = document.getElementById('stat-sources');
|
|
var ef = document.getElementById('stat-factchecks');
|
|
countUp(ea, inc.article_count);
|
|
countUp(es, inc.source_count);
|
|
countUp(ef, inc.factcheck_count);
|
|
|
|
// Excerpt: pre-extracted in summary.json
|
|
var excerptEl = document.getElementById('excerpt-text');
|
|
if (excerptEl && data.zusammenfassung) {
|
|
excerptEl.innerHTML = mdToHtml(data.zusammenfassung);
|
|
}
|
|
|
|
// Store data and init map
|
|
lageData['iran-konflikt'] = {
|
|
locations: data.locations || [],
|
|
category_labels: data.category_labels || {},
|
|
article_count: inc.article_count || 0,
|
|
source_count: inc.source_count || 0,
|
|
factcheck_count: inc.factcheck_count || 0
|
|
};
|
|
dataLoaded = true;
|
|
createMap();
|
|
var mapSection = document.getElementById('map-section');
|
|
if (mapSection) mapSection.classList.remove('map-hidden');
|
|
showMarkers(data.locations || [], data.category_labels || {});
|
|
})
|
|
.catch(function () {
|
|
});
|
|
}
|
|
|
|
/* ==================== LEAFLET MAP ==================== */
|
|
function clearMarkers() {
|
|
if (markerLayer) { mapInstance.removeLayer(markerLayer); markerLayer = null; }
|
|
if (legendControl && mapInstance) { mapInstance.removeControl(legendControl); legendControl = null; }
|
|
}
|
|
|
|
function createMap() {
|
|
if (mapInstance) return;
|
|
var mapEl = document.getElementById('map-container');
|
|
if (!mapEl || typeof L === 'undefined') return;
|
|
|
|
mapInstance = L.map(mapEl, {
|
|
center: [33.0, 48.0], zoom: 5, zoomControl: true, scrollWheelZoom: true,
|
|
minZoom: 2, maxBounds: [[-85, -180], [85, 180]], maxBoundsViscosity: 1.0
|
|
});
|
|
|
|
L.tileLayer('https://tile.openstreetmap.de/{z}/{x}/{y}.png', {
|
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
|
maxZoom: 19, noWrap: true
|
|
}).addTo(mapInstance);
|
|
|
|
setTimeout(function () { mapInstance.invalidateSize(); }, 500);
|
|
}
|
|
|
|
function pulseIcon(color) {
|
|
return L.divIcon({
|
|
className: '',
|
|
html: '<div class="pulse-marker-wrapper">'
|
|
+ '<div class="pulse-marker-ring" style="border-color:' + color + '"></div>'
|
|
+ '<div class="pulse-marker-ring" style="border-color:' + color + '"></div>'
|
|
+ '<div class="pulse-marker-dot" style="background:' + color + ';box-shadow:0 0 10px ' + color + '"></div>'
|
|
+ '</div>',
|
|
iconSize: [20, 20], iconAnchor: [10, 10], popupAnchor: [0, -12]
|
|
});
|
|
}
|
|
|
|
function buildPopup(loc) {
|
|
var html = '<strong style="color:#E8ECF4;">' + (loc.name || '') + '</strong>';
|
|
if (loc.country_code) html += ' <span style="color:#8896AB;font-size:0.8rem;">(' + loc.country_code + ')</span>';
|
|
html += '<br><span style="font-size:0.85rem;color:#8896AB;">' + (loc.article_count || 0) + ' Artikel</span>';
|
|
if (loc.top_articles && loc.top_articles.length > 0) {
|
|
html += '<div style="margin-top:6px;border-top:1px solid #1E2D45;padding-top:6px;">';
|
|
loc.top_articles.forEach(function (a) {
|
|
var hl = (a.headline || '').replace(/\*\*/g, '');
|
|
if (hl.length > 60) hl = hl.substring(0, 60) + '\u2026';
|
|
if (a.url) {
|
|
html += '<a href="' + a.url + '" target="_blank" rel="noopener" style="color:#C8A851;font-size:0.8rem;display:block;margin-top:3px;text-decoration:none;">' + hl + '</a>';
|
|
} else {
|
|
html += '<span style="color:#8896AB;font-size:0.8rem;display:block;margin-top:3px;">' + hl + '</span>';
|
|
}
|
|
html += '<span style="color:#556B7A;font-size:0.7rem;">' + (a.source || '') + '</span>';
|
|
});
|
|
html += '</div>';
|
|
}
|
|
return html;
|
|
}
|
|
|
|
function showMarkers(locations, apiLabels) {
|
|
if (!mapInstance) createMap();
|
|
clearMarkers();
|
|
|
|
var categoryColors = {
|
|
primary: '#ef4444',
|
|
secondary: '#f59e0b',
|
|
tertiary: '#3b82f6',
|
|
mentioned: '#7b7b7b'
|
|
};
|
|
|
|
var defaultLabels = {
|
|
primary: 'Hauptgeschehen',
|
|
secondary: 'Reaktionen',
|
|
tertiary: 'Beteiligte',
|
|
mentioned: 'Erw\u00e4hnt'
|
|
};
|
|
|
|
var categoryLabels = {};
|
|
['primary', 'secondary', 'tertiary', 'mentioned'].forEach(function (k) {
|
|
categoryLabels[k] = (apiLabels && apiLabels[k]) || defaultLabels[k];
|
|
});
|
|
|
|
var clusterGroup = L.markerClusterGroup({
|
|
maxClusterRadius: 50,
|
|
spiderfyOnMaxZoom: true,
|
|
showCoverageOnHover: false,
|
|
zoomToBoundsOnClick: true,
|
|
disableClusteringAtZoom: 10
|
|
});
|
|
|
|
var usedCategories = {};
|
|
var bounds = [];
|
|
|
|
locations.forEach(function (loc) {
|
|
if (!loc.lat || !loc.lon) return;
|
|
var cat = loc.category || 'mentioned';
|
|
var color = categoryColors[cat] || '#7b7b7b';
|
|
usedCategories[cat] = true;
|
|
|
|
var marker;
|
|
if (cat === 'primary' || cat === 'secondary') {
|
|
marker = L.marker([loc.lat, loc.lon], { icon: pulseIcon(color) });
|
|
} else {
|
|
marker = L.circleMarker([loc.lat, loc.lon], {
|
|
radius: 5, fillColor: color, fillOpacity: 0.7,
|
|
color: color, weight: 1, opacity: 0.9
|
|
});
|
|
}
|
|
marker.bindPopup(buildPopup(loc), { maxWidth: 300 });
|
|
clusterGroup.addLayer(marker);
|
|
bounds.push([loc.lat, loc.lon]);
|
|
});
|
|
|
|
markerLayer = clusterGroup;
|
|
mapInstance.addLayer(markerLayer);
|
|
|
|
var legend = L.control({ position: 'bottomright' });
|
|
legend.onAdd = function () {
|
|
var div = L.DomUtil.create('div');
|
|
div.style.cssText = 'background:#151D2E;padding:10px 14px;border-radius:4px;border:1px solid #1E2D45;box-shadow:0 2px 8px rgba(0,0,0,0.3);font-size:0.8rem;line-height:1.8;color:#E8ECF4;';
|
|
var html = '<strong style="color:#C8A851;">Legende</strong><br>';
|
|
['primary', 'secondary', 'tertiary', 'mentioned'].forEach(function (cat) {
|
|
if (usedCategories[cat]) {
|
|
html += '<span style="color:' + categoryColors[cat] + ';">●</span> ' + categoryLabels[cat] + '<br>';
|
|
}
|
|
});
|
|
div.innerHTML = html;
|
|
return div;
|
|
};
|
|
legendControl = legend;
|
|
legendControl.addTo(mapInstance);
|
|
|
|
if (bounds.length > 0) {
|
|
mapInstance.fitBounds(bounds, { padding: [30, 30], maxZoom: 7 });
|
|
}
|
|
|
|
setTimeout(function () { mapInstance.invalidateSize(); }, 300);
|
|
}
|
|
|
|
/* ==================== CONTACT MODAL ==================== */
|
|
window.openContactModal = function () {
|
|
document.getElementById('contact-modal').style.display = 'flex';
|
|
document.body.style.overflow = 'hidden';
|
|
};
|
|
|
|
window.closeContactModal = function () {
|
|
document.getElementById('contact-modal').style.display = 'none';
|
|
document.body.style.overflow = '';
|
|
};
|
|
|
|
// Close on overlay click
|
|
var modalOverlay = document.getElementById('contact-modal');
|
|
if (modalOverlay) {
|
|
modalOverlay.addEventListener('click', function (e) {
|
|
if (e.target === modalOverlay) closeContactModal();
|
|
});
|
|
}
|
|
|
|
// Close on Escape
|
|
document.addEventListener('keydown', function (e) {
|
|
if (e.key === 'Escape' && modalOverlay && modalOverlay.style.display === 'flex') {
|
|
closeContactModal();
|
|
}
|
|
});
|
|
|
|
// Form submit -> server-side SMTP
|
|
window.submitContact = function (e) {
|
|
e.preventDefault();
|
|
var btn = e.target.querySelector('button[type="submit"]');
|
|
if (btn) { btn.disabled = true; btn.textContent = 'Wird gesendet...'; }
|
|
|
|
fetch('/api/contact', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
name: document.getElementById('cf-name').value,
|
|
organisation: document.getElementById('cf-org').value,
|
|
email: document.getElementById('cf-email').value,
|
|
message: document.getElementById('cf-message').value
|
|
})
|
|
})
|
|
.then(function (r) { return r.json().then(function (d) { return { ok: r.ok, data: d }; }); })
|
|
.then(function (res) {
|
|
if (res.ok) {
|
|
document.getElementById('contact-form').style.display = 'none';
|
|
document.getElementById('form-success').style.display = 'block';
|
|
} else {
|
|
alert(res.data.error || 'Fehler beim Senden');
|
|
if (btn) { btn.disabled = false; btn.textContent = 'Nachricht senden'; }
|
|
}
|
|
})
|
|
.catch(function () {
|
|
alert('Verbindungsfehler. Bitte versuchen Sie es erneut.');
|
|
if (btn) { btn.disabled = false; btn.textContent = 'Nachricht senden'; }
|
|
});
|
|
return false;
|
|
};
|
|
|
|
/* ==================== LOAD DEEPFAKES DATA ==================== */
|
|
function loadDeepfakesData() {
|
|
fetch('/lagen/deepfakes/data/summary.json?t=' + Date.now())
|
|
.then(function (r) { if (!r.ok) throw new Error(r.status); return r.json(); })
|
|
.then(function (data) {
|
|
var excerptEl = document.getElementById('excerpt-text-deepfakes');
|
|
if (excerptEl && data.zusammenfassung) {
|
|
var lines = data.zusammenfassung.split("\n");
|
|
var filtered = lines.filter(function(l) { var t = l.trim(); return !t || t.indexOf("## ") === 0 || t.indexOf("- ") === 0; });
|
|
excerptEl.innerHTML = mdToHtml(filtered.join("\n"));
|
|
}
|
|
|
|
// Store data for map
|
|
lageData['deepfakes'] = {
|
|
locations: data.locations || [],
|
|
category_labels: data.category_labels || {},
|
|
article_count: (data.incident || {}).article_count || 0,
|
|
source_count: (data.incident || {}).source_count || 0,
|
|
factcheck_count: (data.incident || {}).factcheck_count || 0
|
|
};
|
|
})
|
|
.catch(function () {
|
|
var el = document.getElementById('excerpt-text-deepfakes');
|
|
if (el) el.textContent = 'Daten konnten nicht geladen werden.';
|
|
});
|
|
}
|
|
|
|
/* ==================== LOAD CYBERANGRIFFE DATA ==================== */
|
|
function loadCyberangriffeData() {
|
|
fetch('/lagen/cyberangriffe/data/summary.json?t=' + Date.now())
|
|
.then(function (r) { if (!r.ok) throw new Error(r.status); return r.json(); })
|
|
.then(function (data) {
|
|
var excerptEl = document.getElementById('excerpt-text-cyberangriffe');
|
|
if (excerptEl && data.zusammenfassung) {
|
|
excerptEl.innerHTML = mdToHtml(data.zusammenfassung);
|
|
}
|
|
lageData['cyberangriffe'] = {
|
|
locations: data.locations || [],
|
|
category_labels: data.category_labels || {},
|
|
article_count: (data.incident || {}).article_count || 0,
|
|
source_count: (data.incident || {}).source_count || 0,
|
|
factcheck_count: (data.incident || {}).factcheck_count || 0
|
|
};
|
|
})
|
|
.catch(function () {
|
|
var el = document.getElementById('excerpt-text-cyberangriffe');
|
|
if (el) el.textContent = 'Daten konnten nicht geladen werden.';
|
|
});
|
|
}
|
|
|
|
/* ==================== INIT ==================== */
|
|
loadLiveData();
|
|
loadDeepfakesData();
|
|
loadCyberangriffeData();
|
|
})();
|