1document.addEventListener("DOMContentLoaded", () => { 2 document.querySelectorAll(".px-timeline .swiper").forEach((el) => { 3 const swiperData = JSON.parse(el.dataset.swiper); 4 5 const swiper = new Swiper(el, { 6 direction: "horizontal", 7 loop: swiperData['type'] == 'loop' ? true : false, 8 autoplay: swiperData['autoplay'] ? true : false, 9 slidesPerGroup: swiperData['perMove'], 10 slidesPerView: 1, 11 breakpoints: { 12 320: { 13 slidesPerView: 1, 14 spaceBetween: 15, 15 }, 16 450: { 17 slidesPerView: 1, 18 spaceBetween: 15, 19 }, 20 768: { 21 slidesPerView: swiperData['perPage'] > 2 ? 2 : swiperData['perPage'], 22 spaceBetween: 30, 23 }, 24 1200: { 25 slidesPerView: document.body.classList.contains('single-meldestelle') 26 ? (swiperData['perPage'] > 4 ? 4 : swiperData['perPage']) 27 : (swiperData['perPage'] > 3 ? 3 : swiperData['perPage']), 28 // spaceBetween: document.body.classList.contains('single-meldestelle') ? 20 : 30, 29 }, 30 1500: { 31 slidesPerView: swiperData['perPage'], 32 spaceBetween: document.body.classList.contains('single-meldestelle') ? 20 : 50, 33 } 34 }, 35 spaceBetween: 15, 36 zoom: true, 37 pagination: { 38 el: el.querySelector(".swiper-pagination"), 39 clickable: true, 40 }, 41 navigation: { 42 nextEl: el.querySelector(".btn-next"), 43 prevEl: el.querySelector(".btn-prev"), 44 }, 45 scrollbar: { 46 el: el.querySelector(".swiper-scrollbar"), 47 draggable: true, 48 }, 49 on: { 50 init: function() { 51 // Numbering if no icon 52 const timelineContainer = el.closest('.px-timeline'); 53 const timelineItems = timelineContainer.querySelectorAll('.timeline-single'); 54 timelineItems.forEach((item, index) => { 55 const numberSpan = item.querySelector('.icon-number .number'); 56 if (numberSpan) { 57 numberSpan.textContent = index + 1; 58 } 59 }); 60 61 // Show/hide navigation controls based on slide count 62 const navigationControls = timelineContainer.querySelector('.navigation-controls'); 63 const totalSlides = timelineItems.length; 64 const currentSlidesPerView = this.params.slidesPerView; 65 66 if (navigationControls) { 67 if (totalSlides > currentSlidesPerView) { 68 navigationControls.style.display = 'flex'; 69 } else { 70 navigationControls.style.display = 'none'; 71 } 72 } 73 74 // Year navigation generation if enabled 75 const yearNavigation = timelineContainer.querySelector('.year-navigation'); 76 const yearNavigationInner = timelineContainer.querySelector('.year-navigation-inner'); 77 if (yearNavigation && yearNavigationInner) { 78 // Remove previous buttons to avoid duplicates 79 yearNavigationInner.innerHTML = ''; 80 81 const years = []; 82 83 // Collect all years and create fallback numbers for slides without a year 84 timelineItems.forEach((item, index) => { 85 const yearElement = item.querySelector('.year'); 86 let displayText = ''; 87 88 if (yearElement && yearElement.textContent.trim()) { 89 displayText = yearElement.textContent.trim(); 90 } else { 91 // Fallback: use slide index + 1 92 displayText = (index + 1).toString(); 93 } 94 95 // Collect only unique values 96 if (!years.find(y => y.text === displayText)) { 97 years.push({ 98 text: displayText, 99 slideIndex: index 100 }); 101 } 102 }); 103 104 // Create buttons for each year 105 const swiperInstance = this; 106 years.forEach((yearData, index) => { 107 const button = document.createElement('button'); 108 button.className = 'year-button';
109 button.textContent = yearData.text; 110 button.addEventListener('click', () => { 111 // Set active class 112 yearNavigationInner.querySelectorAll('.year-button').forEach(btn => btn.classList.remove('active')); 113 button.classList.add('active'); 114 115 // Navigate to corresponding slide 116 swiperInstance.slideTo(yearData.slideIndex); 117 }); 118 119 if (index === 0) button.classList.add('active'); 120 yearNavigationInner.appendChild(button); 121 }); 122 } 123 124 // Calculation of the start position for the line (centered over the first slide) 125 const progressLine = timelineContainer.querySelector('.px-timeline-inner'); 126 const swiperWrapper = el.querySelector('.swiper-wrapper'); 127 128 if (progressLine && swiperWrapper) { 129 const containerWidth = el.offsetWidth; 130 const slidesPerView = this.params.slidesPerView; 131 const slideWidth = containerWidth / slidesPerView; 132 const startOffset = slideWidth / 2; // Center of the first slide 133 134 // Set CSS variables for the line 135 progressLine.style.setProperty('--line-start', startOffset + 'px'); 136 progressLine.style.setProperty('--line-end', (containerWidth - startOffset) + 'px'); 137 } 138 } 139 } 140 }); 141 }); 142});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.