(function () { 'use strict'; if (window.__fedafoneNavigationInstalled) return; window.__fedafoneNavigationInstalled = true; var YANDEX_COUNTER_ID = 93846267; var GOOGLE_TAG_ID = 'AW-16641554754'; var CHATRA_ID = 'qRv27LAnRq4wisFrb'; var activeController = null; var barTimers = []; var activeLanguage = languageFromUrl(location.href); var previousTrackedUrl = location.href; var loadedExternalScripts = new Set( Array.from(document.scripts) .map(function (s) { return s.src ? absoluteUrl(s.src) : ''; }) .filter(Boolean) ); var persistentScriptPatterns = [ /fedafone-navigation\.js/i, /jquery(?:-|\.|\/)/i, /bootstrap(?:\.bundle)?(?:\.min)?\.js/i, /smooth-scroll/i, /swiper-bundle/i, /vanilla-tilt/i, /parallax(?:\.min)?\.js/i, /\/theme(?:\.min)?\.js/i, /telegram\.org\/js\/telegram-web-app/i, /google\.com\/recaptcha\/api\.js/i, /gstatic\.com\/recaptcha/i, /mc\.yandex\.ru\/metrika/i, /call\.chatra\.io\/chatra\.js/i, /googletagmanager\.com\/gtag\/js/i ]; function absoluteUrl(value) { try { return new URL(value, location.href).href; } catch (_) { return value || ''; } } function languageFromUrl(url) { try { var part = new URL(url, location.href).pathname.split('/').filter(Boolean)[0] || ''; return /^(ru|en|pt|es|fr|de)$/i.test(part) ? part.toLowerCase() : ''; } catch (_) { return ''; } } function bar() { var el = document.getElementById('fedafone-navigation-bar'); if (!el) { el = document.createElement('div'); el.id = 'fedafone-navigation-bar'; el.className = 'bar-long'; el.setAttribute('aria-hidden', 'true'); el.style.cssText = 'height:5px;background-color:rgb(217,70,239);position:fixed;top:0;left:0;z-index:99999;width:0;opacity:1;transition:width .28s ease,opacity .2s ease;box-shadow:0 0 10px rgba(217,70,239,.35);pointer-events:none;'; document.documentElement.appendChild(el); } return el; } function clearBarTimers() { barTimers.forEach(clearTimeout); barTimers = []; } function startBar() { clearBarTimers(); var el = bar(); el.style.transition = 'none'; el.style.opacity = '1'; el.style.width = '0%'; requestAnimationFrame(function () { el.style.transition = 'width .28s ease,opacity .2s ease'; el.style.width = '18%'; }); barTimers.push(setTimeout(function () { el.style.width = '48%'; }, 180)); barTimers.push(setTimeout(function () { el.style.width = '72%'; }, 500)); barTimers.push(setTimeout(function () { el.style.width = '85.7031%'; }, 900)); } function finishBar() { clearBarTimers(); var el = bar(); el.style.width = '100%'; barTimers.push(setTimeout(function () { el.style.opacity = '0'; }, 160)); barTimers.push(setTimeout(function () { if (el.parentNode) el.remove(); }, 420)); } function sameFedafoneHost(a, b) { var hosts = ['fedafone.com', 'www.fedafone.com']; return hosts.indexOf(a) !== -1 && hosts.indexOf(b) !== -1; } function normaliseNavigationUrl(url) { var u = new URL(url, location.href); if (sameFedafoneHost(u.hostname, location.hostname)) { u.protocol = location.protocol; u.host = location.host; } return u; } function urlFromElement(a) { var raw = (a && a.getAttribute && (a.getAttribute('href') || a.getAttribute('data-href')) || '').trim(); if (raw) return raw; var onclick = (a && a.getAttribute && a.getAttribute('onclick') || '').trim(); if (!onclick) return ''; var m = onclick.match(/(?:window\.)?open\(\s*['\"]([^'\"]+)['\"]\s*,\s*['\"]_self['\"]\s*\)/i); if (m) return m[1]; m = onclick.match(/(?:window\.)?(?:location(?:\.href)?|document\.location)\s*=\s*['\"]([^'\"]+)['\"]/i); return m ? m[1] : ''; } function shouldHandle(a, event) { if (!a || event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return false; if (a.hasAttribute('download') || a.hasAttribute('data-no-pjax') || a.hasAttribute('data-full-reload')) return false; var target = (a.getAttribute('target') || '').toLowerCase(); if (target && target !== '_self') return false; if (a.hasAttribute('data-bs-toggle') || a.hasAttribute('data-scroll')) return false; var raw = urlFromElement(a); if (!raw || raw[0] === '#' || /^(mailto:|tel:|sms:|javascript:)/i.test(raw)) return false; var u; try { u = normaliseNavigationUrl(raw); } catch (_) { return false; } if (u.origin !== location.origin) return false; if (/^\/(?:api|ajax)\//i.test(u.pathname)) return false; if (/\.(?:pdf|zip|rar|7z|png|jpe?g|gif|webp|avif|svg|xml|json|csv|ics|mp4|mp3)(?:$|\?)/i.test(u.pathname + u.search)) return false; if (u.pathname === location.pathname && u.search === location.search && u.hash) return false; // Google tag must never remain active on the RU site. If the user comes from // another language where Google is already loaded, perform one real reload. if (languageFromUrl(u.href) === 'ru' && activeLanguage && activeLanguage !== 'ru') return false; return true; } function removeSyncedHeadNodes() { document.head.querySelectorAll('[data-fedafone-pjax-head="1"]').forEach(function (node) { node.remove(); }); } function syncHead(nextDoc) { document.title = nextDoc.title || document.title; var selectors = [ 'meta[name="description"]', 'meta[name="keywords"]', 'meta[name="robots"]', 'meta[property^="og:"]', 'meta[name^="twitter:"]', 'link[rel="canonical"]', 'link[rel="alternate"][hreflang]' ]; selectors.forEach(function (sel) { document.head.querySelectorAll(sel).forEach(function (n) { n.remove(); }); }); selectors.forEach(function (sel) { nextDoc.head.querySelectorAll(sel).forEach(function (n) { document.head.appendChild(n.cloneNode(true)); }); }); removeSyncedHeadNodes(); nextDoc.head.querySelectorAll('link[rel="stylesheet"]').forEach(function (link) { var href = absoluteUrl(link.getAttribute('href') || ''); if (!href) return; var alreadyLoaded = Array.from(document.head.querySelectorAll('link[rel="stylesheet"]')).some(function (existing) { return absoluteUrl(existing.getAttribute('href') || '') === href; }); if (!alreadyLoaded) { var clone = link.cloneNode(true); clone.setAttribute('data-fedafone-pjax-head', '1'); document.head.appendChild(clone); } }); nextDoc.head.querySelectorAll('style').forEach(function (style) { var clone = style.cloneNode(true); clone.setAttribute('data-fedafone-pjax-head', '1'); document.head.appendChild(clone); }); if (nextDoc.documentElement.lang) document.documentElement.lang = nextDoc.documentElement.lang; } function copyBodyAttributes(nextBody) { Array.from(document.body.attributes).forEach(function (a) { document.body.removeAttribute(a.name); }); Array.from(nextBody.attributes).forEach(function (a) { document.body.setAttribute(a.name, a.value); }); } function persistentPatternFor(src) { for (var i = 0; i < persistentScriptPatterns.length; i++) { if (persistentScriptPatterns[i].test(src)) return persistentScriptPatterns[i]; } return null; } function persistentFamilyAlreadyLoaded(src) { var pattern = persistentPatternFor(src); if (!pattern) return false; return Array.from(loadedExternalScripts).some(function (existing) { return pattern.test(existing); }); } function createExecutableScript(sourceScript) { var s = document.createElement('script'); Array.from(sourceScript.attributes || []).forEach(function (a) { if (a.name !== 'src') s.setAttribute(a.name, a.value); }); return s; } function loadExternalScript(sourceScript, forceHead) { return new Promise(function (resolve) { var src = absoluteUrl(sourceScript.src || sourceScript.getAttribute('src') || ''); if (!src) { resolve(); return; } if (loadedExternalScripts.has(src) || persistentFamilyAlreadyLoaded(src)) { if (sourceScript.ownerDocument === document && sourceScript.parentNode) sourceScript.remove(); resolve(); return; } var s = createExecutableScript(sourceScript); s.src = src; s.onload = function () { loadedExternalScripts.add(src); resolve(); }; s.onerror = function () { resolve(); }; if (forceHead || sourceScript.ownerDocument !== document || !sourceScript.parentNode) { document.head.appendChild(s); } else { sourceScript.replaceWith(s); } }); } function shouldSkipInlineScript(code) { return /mc\.yandex\.ru\/metrika|\bChatraID\b|call\.chatra\.io\/chatra\.js|googletagmanager\.com\/gtag|AW-16641554754|function\s+gtag\s*\(/i.test(code); } function executeInlineScript(oldScript) { return new Promise(function (resolve) { var code = oldScript.textContent || ''; if (!code.trim() || shouldSkipInlineScript(code)) { if (oldScript.parentNode) oldScript.remove(); resolve(); return; } var s = createExecutableScript(oldScript); s.text = code; oldScript.replaceWith(s); resolve(); }); } function runHeadExternalScripts(nextDoc) { var scripts = Array.from(nextDoc.head.querySelectorAll('script[src]')); var chain = Promise.resolve(); scripts.forEach(function (script) { chain = chain.then(function () { return loadExternalScript(script, true); }); }); return chain; } function runPageScripts(root) { var scripts = Array.from(root.querySelectorAll('script')); var chain = Promise.resolve(); scripts.forEach(function (oldScript) { chain = chain.then(function () { return oldScript.src ? loadExternalScript(oldScript, false) : executeInlineScript(oldScript); }); }); return chain; } function replaceBodyPreservingGlobals(nextBody) { // Never detach Chatra from the live DOM. Removing/re-appending its iframe can // reload the widget and make Chatra restore the dashboard/default palette. // Instead, delete every other old body node and import the next page around it. var chatra = document.getElementById('chatra'); var persistentRoot = chatra; // Normally #chatra is a direct body child. Keep this robust if Chatra changes // its wrapper structure later: preserve the whole top-level subtree containing it. while (persistentRoot && persistentRoot.parentNode && persistentRoot.parentNode !== document.body) { persistentRoot = persistentRoot.parentNode; } if (persistentRoot && persistentRoot.parentNode !== document.body) persistentRoot = null; Array.from(document.body.childNodes).forEach(function (node) { if (persistentRoot && node === persistentRoot) return; node.remove(); }); Array.from(nextBody.childNodes).forEach(function (node) { // A fetched page may contain a stale/static Chatra root in unusual setups. // The live widget is authoritative and must stay unique. if (node.nodeType === 1 && (node.id === 'chatra' || node.querySelector && node.querySelector('#chatra'))) return; document.body.insertBefore(document.importNode(node, true), persistentRoot || null); }); } function parseSwiperOptions(el) { var raw = el.getAttribute('data-swiper-options'); if (!raw) return {}; try { return JSON.parse(raw); } catch (_) { try { return JSON.parse(raw.replace(/\n/g, ' ')); } catch (_) { return {}; } } } function reinitSwipers() { if (typeof window.Swiper !== 'function') return; document.querySelectorAll('.swiper[data-swiper-options]').forEach(function (el) { if (el.swiper || el.classList.contains('swiper-initialized')) return; try { var options = parseSwiperOptions(el); var instance = new window.Swiper(el, options); if (options && options.tabs && instance && typeof instance.on === 'function') { instance.on('activeIndexChange', function (swiper) { var current = swiper.slides && swiper.slides[swiper.activeIndex]; var previous = swiper.slides && swiper.slides[swiper.previousIndex]; if (!current || !current.dataset.swiperTab) return; var currentTab = document.querySelector(current.dataset.swiperTab); var previousTab = previous && previous.dataset.swiperTab ? document.querySelector(previous.dataset.swiperTab) : null; if (previousTab) previousTab.classList.remove('active'); if (currentTab) currentTab.classList.add('active'); }); } } catch (err) { if (window.console && console.warn) console.warn('[fedafone navigation] Swiper init failed', err); } }); } function reinitVanillaTilt() { if (!window.VanillaTilt || typeof window.VanillaTilt.init !== 'function') return; document.querySelectorAll('[data-tilt]').forEach(function (el) { if (el.vanillaTilt) return; try { window.VanillaTilt.init(el); } catch (_) {} }); } function reinitParallax() { if (typeof window.Parallax !== 'function') return; document.querySelectorAll('.parallax').forEach(function (el) { if (el.__fedafoneParallax) return; try { el.__fedafoneParallax = new window.Parallax(el); } catch (_) {} }); } function reinitBootstrap() { if (!window.bootstrap) return; if (window.bootstrap.Tooltip) { document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(function (el) { try { window.bootstrap.Tooltip.getOrCreateInstance(el); } catch (_) {} }); } if (window.bootstrap.Popover) { document.querySelectorAll('[data-bs-toggle="popover"]').forEach(function (el) { try { window.bootstrap.Popover.getOrCreateInstance(el); } catch (_) {} }); } if (window.bootstrap.ScrollSpy) { document.querySelectorAll('[data-bs-spy="scroll"]').forEach(function (el) { try { window.bootstrap.ScrollSpy.getOrCreateInstance(el); } catch (_) {} }); } } function reinitSmoothScroll() { if (typeof window.SmoothScroll !== 'function') return; try { if (window.__fedafoneSmoothScroll && typeof window.__fedafoneSmoothScroll.destroy === 'function') { window.__fedafoneSmoothScroll.destroy(); } window.__fedafoneSmoothScroll = new window.SmoothScroll('a[data-scroll]', { speed: 800, speedAsDuration: true, offset: 20 }); } catch (_) {} } function renderRecaptcha() { if (!window.grecaptcha || typeof window.grecaptcha.render !== 'function') return; document.querySelectorAll('.g-recaptcha').forEach(function (el) { if (el.querySelector('iframe') || el.getAttribute('data-fedafone-rendered') === '1') return; try { window.grecaptcha.render(el, { sitekey: el.getAttribute('data-sitekey') }); el.setAttribute('data-fedafone-rendered', '1'); } catch (_) {} }); } function ensureChatra() { // ChatraSetup is read only when the widget boots. During PJAX navigation the // widget remains alive, so updating ChatraSetup alone does not repaint it. // Keep the site's custom palette in one place and also apply it via Chatra's // runtime API on every seamless page transition. var chatraColors = { buttonText: '#ffffff', buttonBg: '#6166f1' }; window.ChatraSetup = window.ChatraSetup || {}; window.ChatraSetup.colors = Object.assign({}, window.ChatraSetup.colors || {}, chatraColors); window.ChatraID = CHATRA_ID; if (typeof window.Chatra !== 'function') { window.Chatra = function () { (window.Chatra.q = window.Chatra.q || []).push(arguments); }; } var chatraScript = Array.from(document.scripts).find(function (s) { return /call\.chatra\.io\/chatra\.js/i.test(s.src || ''); }); if (!chatraScript) { var s = document.createElement('script'); s.async = true; s.src = 'https://call.chatra.io/chatra.js'; s.setAttribute('data-fedafone-global', 'chatra'); document.head.appendChild(s); loadedExternalScripts.add(absoluteUrl(s.src)); } function applyChatraRuntimeTheme() { try { window.Chatra('setColors', chatraColors); window.Chatra('show'); } catch (_) {} } // Apply immediately and once more after Chatra's own async rendering cycle. // The delayed calls are harmless if the widget is already fully ready. applyChatraRuntimeTheme(); setTimeout(applyChatraRuntimeTheme, 120); setTimeout(applyChatraRuntimeTheme, 600); try { window.Chatra('pageView'); } catch (_) {} } function yandexLoaderExists() { return Array.from(document.scripts).some(function (s) { return /mc\.yandex\.ru\/metrika\/tag\.js/i.test(s.src || ''); }); } function ensureYandexMetrika() { var alreadyPresent = typeof window.ym === 'function' && yandexLoaderExists(); if (typeof window.ym !== 'function') { window.ym = function () { (window.ym.a = window.ym.a || []).push(arguments); }; window.ym.l = +new Date(); } if (!yandexLoaderExists()) { var s = document.createElement('script'); s.async = true; s.src = 'https://mc.yandex.ru/metrika/tag.js'; s.setAttribute('data-fedafone-global', 'yandex'); document.head.appendChild(s); loadedExternalScripts.add(absoluteUrl(s.src)); } if (!window.__fedafoneYandexInitialized) { if (!alreadyPresent) { try { window.ym(YANDEX_COUNTER_ID, 'init', { clickmap: true, trackLinks: true, accurateTrackBounce: true, webvisor: true }); } catch (_) {} } window.__fedafoneYandexInitialized = true; } } function googleLoaderExists() { return Array.from(document.scripts).some(function (s) { return /googletagmanager\.com\/gtag\/js/i.test(s.src || '') && (s.src || '').indexOf(GOOGLE_TAG_ID) !== -1; }); } function ensureGoogleTag() { if (languageFromUrl(location.href) === 'ru') return { enabled: false, newlyInitialized: false }; var alreadyPresent = typeof window.gtag === 'function' && googleLoaderExists(); window.dataLayer = window.dataLayer || []; if (typeof window.gtag !== 'function') { window.gtag = function () { window.dataLayer.push(arguments); }; } if (!googleLoaderExists()) { var s = document.createElement('script'); s.async = true; s.src = 'https://www.googletagmanager.com/gtag/js?id=' + encodeURIComponent(GOOGLE_TAG_ID); s.setAttribute('data-fedafone-global', 'google'); document.head.appendChild(s); loadedExternalScripts.add(absoluteUrl(s.src)); } var newlyInitialized = false; if (!window.__fedafoneGoogleInitialized) { if (!alreadyPresent) { try { window.gtag('js', new Date()); window.gtag('config', GOOGLE_TAG_ID); newlyInitialized = true; } catch (_) {} } window.__fedafoneGoogleInitialized = true; } return { enabled: true, newlyInitialized: newlyInitialized }; } function ensureLegacyAnalyticsBridge() { window.analytics = window.analytics || {}; if (typeof window.analytics.goal !== 'function') { window.analytics.goal = function (goalName) { try { if (typeof window.ym === 'function' && goalName) { window.ym(YANDEX_COUNTER_ID, 'reachGoal', String(goalName)); } } catch (_) {} }; } } function ensureGlobalServices() { ensureChatra(); ensureYandexMetrika(); var googleState = ensureGoogleTag(); ensureLegacyAnalyticsBridge(); return googleState; } function trackVirtualPageView(fromUrl, googleState) { try { if (typeof window.ym === 'function') { window.ym(YANDEX_COUNTER_ID, 'hit', location.href, { title: document.title, referer: fromUrl || '' }); } } catch (_) {} if (languageFromUrl(location.href) !== 'ru' && googleState && googleState.enabled && !googleState.newlyInitialized) { try { if (typeof window.gtag === 'function') { window.gtag('event', 'page_view', { send_to: GOOGLE_TAG_ID, page_location: location.href, page_path: location.pathname + location.search, page_title: document.title }); } } catch (_) {} } } function rehydratePage() { reinitSwipers(); reinitVanillaTilt(); reinitParallax(); reinitBootstrap(); reinitSmoothScroll(); renderRecaptcha(); document.querySelectorAll('.page-loading').forEach(function (el) { el.classList.remove('active'); setTimeout(function () { if (el.parentNode) el.remove(); }, 250); }); document.dispatchEvent(new CustomEvent('fedafone:navigation', { detail: { url: location.href } })); } async function navigate(url, push) { var target; try { target = normaliseNavigationUrl(url); } catch (_) { location.href = url; return; } var targetLanguage = languageFromUrl(target.href); if (targetLanguage === 'ru' && activeLanguage && activeLanguage !== 'ru') { location.assign(target.href); return; } if (activeController) activeController.abort(); activeController = new AbortController(); startBar(); var fromUrl = previousTrackedUrl || location.href; try { var response = await fetch(target.href, { method: 'GET', credentials: 'same-origin', redirect: 'follow', headers: { 'Accept': 'text/html,application/xhtml+xml', 'X-Fedafone-Navigation': '1', 'X-Requested-With': 'fetch' }, signal: activeController.signal }); if (!response.ok || !/text\/html|application\/xhtml\+xml/i.test(response.headers.get('content-type') || '')) { throw new Error('navigation response'); } var html = await response.text(); var nextDoc = new DOMParser().parseFromString(html, 'text/html'); if (!nextDoc.body || !nextDoc.querySelector('main')) throw new Error('invalid document'); syncHead(nextDoc); copyBodyAttributes(nextDoc.body); replaceBodyPreservingGlobals(nextDoc.body); var finalUrl = response.url || target.href; try { finalUrl = normaliseNavigationUrl(finalUrl).href; } catch (_) {} if (push) history.pushState({ fedafoneNavigation: true }, '', finalUrl); activeLanguage = languageFromUrl(finalUrl); window.scrollTo(0, 0); await runHeadExternalScripts(nextDoc); await runPageScripts(document.body); var googleState = ensureGlobalServices(); rehydratePage(); trackVirtualPageView(fromUrl, googleState); previousTrackedUrl = finalUrl; finishBar(); } catch (err) { if (err && err.name === 'AbortError') return; finishBar(); location.assign(target.href); } } document.addEventListener('click', function (event) { var a = event.target.closest && event.target.closest('a, [data-href]'); if (!shouldHandle(a, event)) return; var raw = urlFromElement(a); var target = normaliseNavigationUrl(raw); event.preventDefault(); if (/\b(?:location(?:\.href)?\s*=|window\.location|document\.location|window\.open\s*\()/i.test(a.getAttribute('onclick') || '')) { event.stopImmediatePropagation(); } navigate(target.href, true); }, true); window.addEventListener('popstate', function () { navigate(location.href, false); }); window.addEventListener('pageshow', function () { finishBar(); ensureGlobalServices(); }); // Covers login/register/account pages that did not previously contain Chatra or counters. ensureGlobalServices(); })();