1/** 2 * lang-switcher.js â animierter SVG-Sprachumschalter im "+"-Button (.sm-buttons). 3 * 4 * 1) Intro (einmal pro Session, nach dem Preloader): zeigt die zwei ANDEREN 5 * Sprach-Flaggen (per aktueller Sprache geordnet) und blendet dann smooth in 6 * das "+" über. Reines GSAP-Crossfade (opacity/scale) â kein MorphSVG nötig. 7 * DE: ð¯ðµ â ð¬ð§ â + | JA: ð¬ð§ â ð©ðª â + | EN: ð¯ðµ â ð©ðª â + 8 * 2) Toggle: Klick/Tap auf das "+" öffnet/schlieÃt die DE/JP/EN-Links. Bleibt 9 * offen bis Tap auÃerhalb oder Auswahl. 10 * 11 * BUGFIX ggü. alter Lösung: Die Seite feuert via jQuery bei mouseenter/-leave 12 * JEDES <a> ein SYNTHETISCHES `$('.cursor').click()`. Der alte Outside-Click- 13 * Close interpretierte das als AuÃenklick â Menü schloss beim Mausbewegen. 14 * Fix: Ãffnen nur bei `e.isTrusted`; SchlieÃen über `pointerdown` (nicht click, 15 * da .click() kein pointerdown/mousedown auslöst) + isTrusted-Guard. 16 */ 17(function () { 18 'use strict'; 19 20 var FLAGS = ['kl-ls-japan', 'kl-ls-germany', 'kl-ls-uk']; 21 var ORDER = { 22 de: ['kl-ls-japan', 'kl-ls-uk'], // JP â EN(UK) â + 23 ja: ['kl-ls-uk', 'kl-ls-germany'], // EN(UK) â DE â + 24 en: ['kl-ls-japan', 'kl-ls-germany'], // JP â DE â + 25 }; 26 var lang = (document.documentElement.getAttribute('lang') || 'de').toLowerCase().slice(0, 2); 27 var reduced = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches; 28 29 function byId(id) { return document.getElementById(id); } 30 31 function lockToPlus() { 32 FLAGS.forEach(function (id) { var g = byId(id); if (g) g.style.opacity = '0'; }); 33 var plus = byId('kl-ls-plus'); 34 if (!plus) return; 35 if (typeof gsap !== 'undefined') gsap.set(plus, { opacity: 1, scale: 1, rotation: 0, clearProps: 'transform' }); 36 else plus.style.opacity = '1'; 37 } 38 39 // ââ Intro ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 40 var introStarted = false; 41 function playIntro() { 42 if (introStarted) return; introStarted = true; 43 var seen; 44 try { seen = sessionStorage.getItem('kl_lang_intro_seen'); } catch (_) {} 45 if (seen || reduced || typeof gsap === 'undefined' || !byId('kl-ls-plus')) { lockToPlus(); return; } 46 47 var order = ORDER[lang] || ORDER.de; 48 var plus = byId('kl-ls-plus'); 49 gsap.set(plus, { opacity: 0 }); 50 FLAGS.forEach(function (id) { var g = byId(id); if (g) gsap.set(g, { opacity: 0 }); }); 51 52 var tl = gsap.timeline({ 53 onComplete: function () { 54 try { sessionStorage.setItem('kl_lang_intro_seen', '1'); } catch (_) {} 55 lockToPlus(); 56 }, 57 }); 58 var t = 0.15; 59 order.forEach(function (id, i) { 60 var g = byId(id); 61 if (!g) return; 62 var last = (i === order.length - 1); 63 tl.fromTo(g, { opacity: 0, scale: 0.7, transformOrigin: '50% 50%' }, 64 { opacity: 1, scale: 1, duration: 0.42, ease: 'power2.out' }, t); 65 if (!last) { 66 tl.to(g, { opacity: 0, scale: 1.18, duration: 0.36, ease: 'power2.in' }, t + 0.66); 67 t += 0.86; 68 } else { 69 // Letzte Flagge wird horizontal zusammengequetscht (scaleXâ0) â aus dem 70 // entstehenden vertikalen Streifen "springt" das "+" auf. Kein Einblenden, 71 // sondern eine Quetsch-Verwandlung Flagge â Plus. 72 var sq = t + 0.78; 73 tl.to(g, { scaleX: 0.05, scaleY: 0.9, opacity: 0, duration: 0.9, ease: 'power2.inOut', transformOrigin: '50% 50%' }, sq); 74 tl.fromTo(plus, { opacity: 0, scaleX: 0.05, scaleY: 0.85, transformOrigin: '50% 50%' }, 75 { opacity: 1, scaleX: 1, scaleY: 1, duration: 0.62, ease: 'back.out(1.6)' }, sq + 0.52); 76 } 77 }); 78 } 79 80 // Start nach dem Preloader (der deckt sonst die Animation ab). Auf Rückbesuchen 81 // ist der Preloader übersprungen (KL_FAST_PATH) â sofort. Fallback-Timeout, falls 82 // das Event nie kommt. 83 if (window.KL_FAST_PATH) playIntro(); 84 window.addEventListener('kl:preloader-done', playIntro); 85 setTimeout(playIntro, 6500); 86 87 // ââ Toggle (öffnen) ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 88 document.addEventListener('click', function (e) { 89 if (e.isTrusted === false) return; // synthetisches .cursor.click() ignorieren 90 var plus = e.target && e.target.closest ? e.target.closest('.sm-button-plus') : null; 91 if (!plus) return; 92 e.preventDefault(); 93 e.stopPropagation(); // verwaiste IX2-Interaktion blocken 94 var box = document.querySelector('.sm-buttons'); 95 if (box) box.classList.toggle('kl-sm-open'); 96 }, true); 97 98 // ââ SchlieÃen (AuÃen-Pointerdown, immun gegen synthetische Klicks) ââââââââââ 99 function closeOnOutside(e) { 100 if (e.isTrusted === false) return; 101 var open = document.querySelector('.sm-buttons.kl-sm-open'); 102 if (!open) return; 103 if (!(e.target && e.target.closest && e.target.closest('.sm-buttons'))) open.classList.remove('kl-sm-open'); 104 } 105 if ('PointerEvent' in window) { 106 document.addEventListener('pointerdown', closeOnOutside, true); 107 } else { 108 document.addEventListener('mousedown', closeOnOutside, true); 109 document.addEventListener('touchstart', closeOnOutside, true); 110 } 111})();
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.