Mudanças entre as edições de "Widget:C.Skills"

De Wiki Gla
Ir para navegação Ir para pesquisar
m
m (rft otimizado)
Linha 1: Linha 1:
<!-- MAIN SKILLS SYSTEM -->
<!-- WEAPON TOGGLE SYSTEM - Estado global + popup i18n -->
<script>
<script>
     (function () {
     (() => {
        const $ = (s, root = document) => root.querySelector(s);
         let modalListenersBound = false;
        const $$ = (s, root = document) => Array.from(root.querySelectorAll(s));
 
        const ensureRemoved = sel => {
         // Variável global para o ícone do weapon toggle
            Array.from(document.querySelectorAll(sel)).forEach(n => n.remove());
         let globalWeaponToggleIcon = null;
         };
 
        const onceFlag = (el, key) => {
         // Função helper para construir URL de arquivo (mesmo sistema usado em Character.Skills.html)
            if (!el) return false;
            if (el.dataset[key]) return false;
            el.dataset[key] = '1';
            return true;
         };
         const addOnce = (el, ev, fn) => {
            if (!el) return;
            const attr = `data-wired-${ev}`;
            if (el.hasAttribute(attr)) return;
            el.addEventListener(ev, fn);
            el.setAttribute(attr, '1');
         };
        const FLAG_ICON_FILES = {
            aggro: 'Enemyaggro-icon.png', bridge: 'Bridgemaker-icon.png', wall: 'Destroywall-icon.png', quickcast: 'Quickcast-icon.png', wallpass: 'Passthroughwall-icon.png'
        };
        const subBarTemplateCache = window.__skillSubBarTemplateCache || (window.__skillSubBarTemplateCache = new Map());
        const imagePreloadCache = window.__skillImagePreloadCache || (window.__skillImagePreloadCache = new Map());
        const videoPreloadCache = window.__skillVideoPreloadCache || (window.__skillVideoPreloadCache = new Set());
        const flagRowCache = window.__skillFlagRowCache || (window.__skillFlagRowCache = new Map());
        const flagIconURLCache = window.__skillFlagIconURLCache || (window.__skillFlagIconURLCache = new Map());
         function filePathURL(fileName) {
         function filePathURL(fileName) {
             // Evita requisições para Nada.png que não existe
             // Evita requisições para Nada.png que não existe
Linha 33: Linha 13:
                 return '';
                 return '';
             }
             }
             const f = encodeURIComponent(fileName.replace(/^Arquivo:|^File:/, ''));
             // Remove prefixos e decodifica se já estiver codificado (evita double encoding)
            let cleanName = fileName.replace(/^Arquivo:|^File:/, '');
            try {
                // Tenta decodificar primeiro (caso já venha codificado como %27)
                cleanName = decodeURIComponent(cleanName);
            } catch (e) {
                // Se falhar, usa o nome original
            }
            // Agora codifica corretamente
            const f = encodeURIComponent(cleanName);
             const base = (window.mw && mw.util && typeof mw.util.wikiScript === 'function') ? mw.util.wikiScript() : (window.mw && window.mw.config ? (mw.config.get('wgScript') || '/index.php') : '/index.php');
             const base = (window.mw && mw.util && typeof mw.util.wikiScript === 'function') ? mw.util.wikiScript() : (window.mw && window.mw.config ? (mw.config.get('wgScript') || '/index.php') : '/index.php');
             // Garante HTTPS para evitar Mixed Content
             // Garante HTTPS para evitar Mixed Content
Linha 41: Linha 30:
             }
             }
             return url;
             return url;
        } function slugify(s) {
            if (!s) return '';
            return String(s).toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '').replace(/[^\w\s-]/g, '').replace(/[\s:/\-]+/g, '-').replace(/^-+|-+$/g, '').replace(/-+/g, '-');
        } window.__skillSlugify = slugify;
        function getLangKey() {
            const skillsRoot = document.getElementById('skills');
            const raw = (document.documentElement.lang || skillsRoot?.dataset.i18nDefault || 'pt').toLowerCase();
            return raw === 'pt-br' ? 'pt' : (raw.split('-')[0] || 'pt');
        } function chooseDescFrom(obj) {
            const lang = getLangKey();
            // Aceita tanto desc_i18n quanto desc para compatibilidade
            const pack = obj.desc_i18n || obj.desc || {
                pt: obj.descPt, en: obj.descEn, es: obj.descEs, pl: obj.descPl
            };
            return (pack && (pack[lang] || pack.pt || pack.en || pack.es || pack.pl)) || '';
        } function renderSubAttributesFromObj(s, L) {
            const chip = (label, val) => (val ? `<div class="attr-row"><span class="attr-label">${label}</span><span class="attr-value">${val}</span></div>` : '');
            const pve = (s.powerpve || '').toString().trim();
            const pvp = (s.powerpvp || '').toString().trim();
            const en = (s.energy || '').toString().trim();
            const cd = (s.cooldown || '').toString().trim();
            const rows = [cd ? chip(L.cooldown, cd) : '', en ? chip((en.startsWith('-') ? L.energy_cost : L.energy_gain), en.startsWith('-') ? en.replace(/^-/, '') : en.replace(/^\+?/, '')) : '', pve ? chip(L.power, pve) : '', pvp ? chip(L.power_pvp, pvp) : '',].filter(Boolean);
            return rows.length ? `<div class="attr-list">${rows.join('')}</div>` : '';
        } function getFlagIconURL(key) {
            if (!FLAG_ICON_FILES[key]) return '';
            if (!flagIconURLCache.has(key)) {
                flagIconURLCache.set(key, filePathURL(FLAG_ICON_FILES[key]));
            } return flagIconURLCache.get(key);
        } function renderFlagsRow(flags) {
            const arr = (flags || []).filter(Boolean);
            if (!arr.length) return '';
            const cacheKey = arr.join('|');
            if (flagRowCache.has(cacheKey)) {
                return flagRowCache.get(cacheKey);
            } const items = arr.map(k => {
                const url = getFlagIconURL(k);
                return url ? `<img class="skill-flag" data-flag="${k}" alt="" src="${url}">` : '';
            }).join('');
            const html = items ? `<div class="skill-flags" role="group" aria-label="Características">${items}</div>` : '';
            if (html) flagRowCache.set(cacheKey, html);
            return html;
        } function applyFlagTooltips(container) {
            const skillsRoot = document.getElementById('skills');
            if (!skillsRoot) return;
            let pack = {
            };
            try {
                pack = JSON.parse(skillsRoot.dataset.i18nFlags || '{}');
            } catch (e) {
            } const lang = getLangKey();
            const dict = pack[lang] || pack.pt || {
            };
            const flags = container.querySelectorAll('.skill-flags .skill-flag[data-flag]');
            const tooltip = window.__globalSkillTooltip;
            if (!tooltip) return;
            flags.forEach(el => {
                const key = el.getAttribute('data-flag');
                const tip = (dict && dict[key]) || '';
                if (!tip) return;
                if (el.dataset.flagTipWired) return;
                el.dataset.flagTipWired = '1';
                el.setAttribute('aria-label', tip);
                if (el.hasAttribute('title')) el.removeAttribute('title');
                el.addEventListener('mouseenter', () => {
                    const tipEl = document.querySelector('.skill-tooltip');
                    if (tipEl) tipEl.classList.add('flag-tooltip');
                    tooltip.show(el, tip);
                });
                el.addEventListener('mousemove', () => {
                    if (performance.now() >= tooltip.lockUntil.value) {
                        tooltip.measureAndPos(el);
                    }
                });
                el.addEventListener('click', () => {
                    tooltip.lockUntil.value = performance.now() + 240;
                    tooltip.measureAndPos(el);
                });
                el.addEventListener('mouseleave', () => {
                    const tipEl = document.querySelector('.skill-tooltip');
                    if (tipEl) tipEl.classList.remove('flag-tooltip');
                    tooltip.hide();
                });
            });
         }
         }


         // ====== Skill/Subskill inheritance helpers ======
         // Função para resolver o ícone do weapon toggle do character-box
         const mainSkillsMeta = {
         function resolveCharacterWeaponIcon() {
            byIndex: new Map(),
             const root = document.querySelector('.character-box');
             byName: new Map(),
             if (!root) return;
            ready: false
             const raw = root.dataset.weaponicon;
        };
             if (!raw || raw.trim() === '' || raw === 'Nada.png') {
 
                globalWeaponToggleIcon = null;
        function normalizeFileURL(raw, fallback = '') {
                 return;
             if (!raw) return fallback;
             }
             const val = String(raw).trim();
            globalWeaponToggleIcon = filePathURL(raw.trim());
             if (!val) return fallback;
            // console.log('[WeaponToggle] Resolved weaponicon:', raw, '->', globalWeaponToggleIcon);
            if (/^(https?:)?\/\//i.test(val) || val.startsWith('data:') || val.includes('Especial:FilePath/')) {
                 return val;
             } return filePathURL(val);
         }
         }


         function extractFileNameFromURL(url) {
         // Textos i18n para o popup
             if (!url) return '';
        const i18nTexts = {
             const match = String(url).match(/(?:FilePath\/)([^&?]+)/i);
             pt: {
             return match ? decodeURIComponent(match[1]) : '';
                title: 'Visualização com Arma Especial',
         }
                body1: 'Este modo ativa a visualização do personagem equipado com sua <strong>arma especial</strong>.',
                body2: 'Algumas habilidades são diferentes enquanto estão com a arma equipada, essas habilidades ficam <strong>destacadas com borda vermelha</strong>.',
                dontShow: 'Não mostrar novamente',
                ok: 'Entendi',
                weaponLink: 'Ver página da arma:'
             },
            en: {
                title: 'Special Weapon View',
                body1: 'This mode activates the view of the character equipped with their <strong>special weapon</strong>.',
                body2: 'Some abilities are different while equipped with the weapon, these abilities are <strong>highlighted with a red border</strong>.',
                dontShow: "Don't show again",
                ok: 'Got it',
                weaponLink: 'View weapon page:'
            },
            es: {
                title: 'Visualización con Arma Especial',
                body1: 'Este modo activa la visualización del personaje equipado con su <strong>arma especial</strong>.',
                body2: 'Algunas habilidades son diferentes mientras están con el arma equipada, estas habilidades quedan <strong>destacadas con borde rojo</strong>.',
                dontShow: 'No mostrar de nuevo',
                ok: 'Entendido',
                weaponLink: 'Ver página del arma:'
            },
             pl: {
                title: 'Widok z Bronią Specjalną',
                body1: 'Ten tryb aktywuje widok postaci wyposażonej w <strong>broń specjalną</strong>.',
                body2: 'Niektóre umiejętności różnią się podczas posiadania broni, te umiejętności są <strong>podświetlone czerwoną obwódką</strong>.',
                dontShow: 'Nie pokazuj ponownie',
                ok: 'Rozumiem',
                weaponLink: 'Zobacz stronę broni:'
            }
         };


         function parseAttrString(raw) {
         const getCurrentLang = () => {
             const parts = (raw || '').split(',').map(v => v.trim());
             const html = document.documentElement.lang || 'pt-br';
             const safe = idx => {
            const norm = html.toLowerCase().split('-')[0];
                const val = parts[idx] || '';
             return i18nTexts[norm] ? norm : 'pt';
                return (val && val !== '-') ? val : '';
        };
            };
            return {
                powerpve: safe(0),
                powerpvp: safe(1),
                energy: safe(2),
                cooldown: safe(3)
            };
        }


         function hasText(value) {
         const bindModalEvents = () => {
            return typeof value === 'string' ? value.trim() !== '' : value !== undefined && value !== null;
             if (modalListenersBound) return;
        }
             modalListenersBound = true;
 
             document.addEventListener('click', (ev) => {
        function pickFilled(current, fallback) {
                 if (ev.target.closest('.weapon-modal-close') || ev.target.closest('.weapon-modal-btn')) {
             if (current === 0 || current === '0') return current;
                    const checkbox = document.getElementById('weapon-dont-show');
             if (!hasText(current)) return fallback;
                    if (checkbox && checkbox.checked) {
             return current;
                        try { localStorage.setItem('glaWeaponPopupDismissed', '1'); } catch (x) { }
        }
                     }
 
                    hidePopup();
        function buildMainSkillsMeta(nodes) {
                     return;
            if (mainSkillsMeta.ready) {
                return mainSkillsMeta;
            }
            (nodes || []).forEach(icon => {
                 const index = (icon.dataset.index || '').trim();
                if (!index) return;
                const name = (icon.dataset.nome || icon.dataset.name || '').trim();
                const attrs = parseAttrString(icon.dataset.atr || '');
                let iconFile = (icon.dataset.iconFile || '').trim();
                if (!iconFile) {
                    const imgSrc = icon.querySelector('img')?.src || '';
                    const iconMatch = imgSrc.match(/(?:FilePath|images)\/([^\/?]+)$/);
                     iconFile = iconMatch ? decodeURIComponent(iconMatch[1]) : '';
                }
                let videoFile = (icon.dataset.videoFile || '').trim();
                if (!videoFile) {
                     videoFile = extractFileNameFromURL(icon.dataset.video || '');
                 }
                 }
                 const meta = {
                 if (ev.target.classList.contains('weapon-modal-overlay')) {
                    index,
                     hidePopup();
                    name,
                    icon: iconFile || 'Nada.png',
                    level: icon.dataset.level || '',
                    video: videoFile || '',
                    powerpve: attrs.powerpve || '',
                    powerpvp: attrs.powerpvp || '',
                    energy: attrs.energy || '',
                    cooldown: attrs.cooldown || '',
                    desc: icon.dataset.desc || '',
                    descPt: icon.dataset.descPt || '',
                    descEn: icon.dataset.descEn || '',
                    descEs: icon.dataset.descEs || '',
                    descPl: icon.dataset.descPl || ''
                };
                mainSkillsMeta.byIndex.set(index, meta);
                mainSkillsMeta.byIndex.set(parseInt(index, 10), meta);
                if (name) {
                     mainSkillsMeta.byName.set(name, meta);
                 }
                 }
             });
             });
            mainSkillsMeta.ready = true;
         };
            return mainSkillsMeta;
         }


         function inheritSubskillFromMain(sub, meta) {
         const applyWeaponState = (enabled) => {
             if (!sub || !meta) return sub;
             if (typeof window.__setGlobalWeaponEnabled === 'function') {
            // Suporta refS (novo) e refM (legado)
                window.__setGlobalWeaponEnabled(enabled);
            const refS = ((sub.refS || sub.S || sub.s || '') + '').trim();
             }
            const refIndex = ((sub.refM || sub.M || sub.m || '') + '').trim();
            let name = (sub.name || sub.n || '').trim();
             let main = null;


            try {
                localStorage.setItem('glaWeaponEnabled', enabled ? '1' : '0');
            } catch (x) { }


             // Primeiro tenta por refS
             // Dispara evento para atualizar subskills
             if (refS) {
             window.dispatchEvent(new CustomEvent('gla:weaponToggled', { detail: { enabled } }));
                main = meta.byIndex.get(refS) || meta.byIndex.get(parseInt(refS, 10));
            }
            // Depois por refM
            if (!main && refIndex) {
                main = meta.byIndex.get(refIndex) || meta.byIndex.get(parseInt(refIndex, 10));
            }
            // Por último pelo nome
            if (!main && name) {
                main = meta.byName.get(name);
            }
            if (!main) {
                return sub;
            }


             const hydrated = { ...sub };
             // SISTEMA UNIFICADO: Aplica toggle em skills E subskills
            if (!name && main.name) {
            // Skills principais e subskills usam data-weapon (padronizado)
                name = main.name;
            document.querySelectorAll('.skill-icon[data-weapon], .subicon[data-weapon]').forEach(el => {
            }
                if (enabled) {
            hydrated.name = name || hydrated.name || main.name || '';
                    el.classList.add('has-weapon-available');
            hydrated.icon = pickFilled(hydrated.icon, main.icon || 'Nada.png');
                } else {
            hydrated.level = pickFilled(hydrated.level, main.level || '');
                    el.classList.remove('has-weapon-available');
                    el.classList.remove('weapon-equipped');
                    el.style.removeProperty('--weapon-badge-url');
                    const ind = el.querySelector('.weapon-indicator');
                    if (ind) ind.remove();
                }
            });


             // Vídeo NUNCA é herdado da skill principal
             // Atualiza descrição da skill/subskill selecionada (se houver) para refletir estado da arma
             // Se a chave 'video' existe = foi especificado pelo editor (mesmo que vazio)
            // Aguarda um pouco mais para garantir que o estado global foi sincronizado
            // Se não existe = não foi especificado = não herda, fica vazio
             setTimeout(() => {
            const hasOwnVideo = Object.prototype.hasOwnProperty.call(sub, 'video');
                // Atualiza skill principal se houver - força reativação completa incluindo vídeo
            hydrated.video = hasOwnVideo ? (sub.video || '') : '';
                const sel = document.querySelector('.skill-icon.active:not(.weapon-bar-toggle)');
                if (sel) {
                    // Força uma reativação completa da skill para garantir que vídeo seja atualizado
                    if (typeof window.__subskills !== 'undefined' && window.__subskills.hideAll) {
                        const videoBox = document.querySelector('.video-container') || document.querySelector('.skills-video-box');
                        if (videoBox) window.__subskills.hideAll(videoBox);
                    }
                    // Reativa a skill para atualizar vídeo, descrição e atributos
                    if (typeof window.__lastActiveSkillIcon !== 'undefined' && window.__lastActiveSkillIcon === sel) {
                        sel.dispatchEvent(new Event('click', { bubbles: true }));
                    } else {
                        sel.dispatchEvent(new Event('click', { bubbles: true }));
                    }
                }
                // Atualiza subskill ativa se houver - força reativação completa incluindo vídeo
                const activeSub = document.querySelector('.subicon.active');
                if (activeSub) {
                    activeSub.dispatchEvent(new Event('click', { bubbles: true }));
                }
            }, 100);
        };


            hydrated.powerpve = pickFilled(hydrated.powerpve, main.powerpve || '');
        const updateModalTexts = (modal) => {
            hydrated.powerpvp = pickFilled(hydrated.powerpvp, main.powerpvp || '');
             const lang = getCurrentLang();
             hydrated.energy = pickFilled(hydrated.energy, main.energy || '');
             const t = i18nTexts[lang];
             hydrated.cooldown = pickFilled(hydrated.cooldown, main.cooldown || '');


             if (!hasText(hydrated.descPt) && hasText(main.descPt)) hydrated.descPt = main.descPt;
             const title = modal.querySelector('.weapon-modal-header h3');
            if (!hasText(hydrated.descEn) && hasText(main.descEn)) hydrated.descEn = main.descEn;
             if (title) title.textContent = t.title;
            if (!hasText(hydrated.descEs) && hasText(main.descEs)) hydrated.descEs = main.descEs;
            if (!hasText(hydrated.descPl) && hasText(main.descPl)) hydrated.descPl = main.descPl;
             if (!hasText(hydrated.desc) && hasText(main.desc)) hydrated.desc = main.desc;


             if (!hydrated.desc_i18n && (hydrated.descPt || hydrated.descEn || hydrated.descEs || hydrated.descPl)) {
             const body = modal.querySelector('.weapon-modal-body');
                 hydrated.desc_i18n = {
            if (body) {
                    pt: hydrated.descPt || '',
                 const p1 = body.querySelector('p:first-child');
                    en: hydrated.descEn || '',
                const p2 = body.querySelector('p:nth-child(2)');
                    es: hydrated.descEs || '',
                if (p1) p1.innerHTML = t.body1;
                    pl: hydrated.descPl || ''
                 if (p2) p2.innerHTML = t.body2;
                 };
             }
             }


             return hydrated;
             const checkbox = modal.querySelector('.weapon-modal-checkbox span');
        }
            if (checkbox) checkbox.textContent = t.dontShow;


        function inheritSubskillTree(subs, meta) {
             const btn = modal.querySelector('.weapon-modal-btn');
             if (!Array.isArray(subs)) return [];
             if (btn) btn.textContent = t.ok;
             return subs.map(sub => {
                const hydrated = inheritSubskillFromMain(sub, meta);
                if (Array.isArray(hydrated.subs)) {
                    hydrated.subs = inheritSubskillTree(hydrated.subs, meta);
                }
                return hydrated;
            });
        }


        function collectAssetsFromSubs(subs, iconsSet, videosSet, flagsSet) {
             // Atualiza link da arma se existir
             if (!Array.isArray(subs)) return;
             try {
             subs.forEach(sub => {
                 const firstWithWeapon = document.querySelector('.skill-icon[data-weapon]');
                 const iconURL = normalizeFileURL(sub.icon || 'Nada.png', '');
                 if (firstWithWeapon) {
                 if (iconURL && iconURL !== '') iconsSet.add(iconURL);
                    const raw = firstWithWeapon.getAttribute('data-weapon');
                // Vídeo normal
                    const obj = JSON.parse(raw || '{}');
                if (sub.video && sub.video.trim() !== '' && sub.video !== 'Nada.png' && !sub.video.toLowerCase().includes('nada.png')) {
                     const nm = (obj && obj.name) ? String(obj.name).trim() : '';
                     const videoURL = normalizeFileURL(sub.video);
                     if (nm) {
                    if (videoURL) videosSet.add(videoURL);
                         const linkHost = (window.mw && mw.util && typeof mw.util.getUrl === 'function') ? mw.util.getUrl(nm) : ('/index.php?title=' + encodeURIComponent(nm));
                }
                        const holder = modal.querySelector('.weapon-info-link');
                // Vídeo de weapon
                        if (holder) {
                if (sub.weapon && typeof sub.weapon === 'object' && sub.weapon.video && sub.weapon.video.trim() !== '' && sub.weapon.video !== 'Nada.png' && !sub.weapon.video.toLowerCase().includes('nada.png')) {
                            holder.style.display = 'block';
                    const weaponVideoURL = normalizeFileURL(sub.weapon.video);
                            holder.innerHTML = `<a href="${linkHost}">${t.weaponLink} ${nm}</a>`;
                     if (weaponVideoURL) videosSet.add(weaponVideoURL);
                }
                if (Array.isArray(sub.flags)) {
                    sub.flags.forEach(flagKey => {
                         const url = getFlagIconURL(flagKey);
                        if (url) flagsSet.add(url);
                    });
                } if (Array.isArray(sub.subs)) {
                    collectAssetsFromSubs(sub.subs, iconsSet, videosSet, flagsSet);
                }
            });
        } function buildAssetManifest() {
            if (window.__skillAssetManifest && window.__skillAssetManifest.ready) {
                return window.__skillAssetManifest;
            } const iconsSet = new Set();
            const videosSet = new Set();
            const flagsSet = new Set();
            iconItems.forEach(el => {
                const img = el.querySelector('img');
                if (img && img.src) {
                    iconsSet.add(img.src);
                } else if (el.dataset.iconFile) {
                    const iconURL = normalizeFileURL(el.dataset.iconFile);
                    if (iconURL) iconsSet.add(iconURL);
                }
                // Vídeo normal da skill
                const videoRaw = (el.dataset.videoFile || el.dataset.video || '').trim();
                if (videoRaw && videoRaw !== 'Nada.png' && !videoRaw.toLowerCase().includes('nada.png')) {
                    const videoURL = normalizeFileURL(videoRaw);
                    if (videoURL) videosSet.add(videoURL);
                }
                // Vídeo de weapon da skill
                if (el.dataset.weapon) {
                    try {
                        const weaponData = JSON.parse(el.dataset.weapon);
                        if (weaponData && weaponData.video && weaponData.video.trim() !== '' && weaponData.video !== 'Nada.png' && !weaponData.video.toLowerCase().includes('nada.png')) {
                            const weaponVideoURL = normalizeFileURL(weaponData.video);
                            if (weaponVideoURL) videosSet.add(weaponVideoURL);
                         }
                         }
                    } catch (e) {
                     }
                     }
                 }
                 }
                if (el.dataset.flags) {
            } catch (_) { }
                    try {
        };
                        const parsedFlags = JSON.parse(el.dataset.flags);
 
                        (parsedFlags || []).forEach(flagKey => {
        const ensureModal = () => {
                            const url = getFlagIconURL(flagKey);
             let modal = document.getElementById('weapon-info-modal');
                            if (url) flagsSet.add(url);
             if (modal) {
                        });
                 updateModalTexts(modal);
                    } catch (e) {
                return modal;
                    }
                } if (el.dataset.subs) {
                    try {
                        const subs = JSON.parse(el.dataset.subs);
                        collectAssetsFromSubs(subs, iconsSet, videosSet, flagsSet);
                    } catch (e) {
                    }
                }
            });
            Object.keys(FLAG_ICON_FILES).forEach(flagKey => {
                const url = getFlagIconURL(flagKey);
                if (url) flagsSet.add(url);
            });
             const manifest = {
                icons: iconsSet, videos: videosSet, flags: flagsSet, ready: true
            };
            window.__skillAssetManifest = manifest;
            return manifest;
        } const subskillVideosCache = new Map();
        window.__subskillVideosCache = subskillVideosCache;
        let assetManifest = null;
        const skillsTab = $('#skills');
        const skinsTab = $('#skins');
        ensureRemoved('.top-rail');
        ensureRemoved('.content-card');
        ensureRemoved('.video-placeholder');
        Array.from(document.querySelectorAll('.card-skins-title, .card-skins .card-skins-title, .cardskins-title, .rail-title')).forEach(t => {
             if ((t.textContent || '').trim().toLowerCase().includes('skins')) {
                 t.remove();
             }
             }
        });
 
        if (skillsTab) {
            // Insere dentro da character-box para isolar completamente
             const iconBar = skillsTab.querySelector('.icon-bar');
             const container = document.querySelector('.character-box') || document.querySelector('#mw-content-text') || document.body;
             if (iconBar) {
 
                const rail = document.createElement('div');
             modal = document.createElement('div');
                rail.className = 'top-rail skills';
            modal.id = 'weapon-info-modal';
                // Criar wrapper de scroll para permitir glow sem clipping
            modal.className = 'weapon-modal';
                 if (!iconBar.parentElement || !iconBar.parentElement.classList.contains('icon-scroll-x')) {
            modal.innerHTML = `
                     const scrollWrapper = document.createElement('div');
            <div class="weapon-modal-overlay"></div>
                    scrollWrapper.className = 'icon-scroll-x';
            <div class="weapon-modal-content">
                     scrollWrapper.appendChild(iconBar);
                 <div class="weapon-modal-header">
                     rail.appendChild(scrollWrapper);
                    <h3></h3>
                } else {
                     <button class="weapon-modal-close" type="button" aria-label="Fechar">&times;</button>
                     rail.appendChild(iconBar.parentElement);
                </div>
                 }
                <div class="weapon-modal-body">
                 skillsTab.prepend(rail);
                     <p></p>
            } const details = skillsTab.querySelector('.skills-details');
                     <p></p>
            const videoContainer = skillsTab.querySelector('.video-container');
                     <p class="weapon-info-link"></p>
            const card = document.createElement('div');
                 </div>
             card.className = 'content-card skills-grid';
                 <div class="weapon-modal-footer">
             if (details) card.appendChild(details);
                    <label class="weapon-modal-checkbox">
             if (videoContainer) card.appendChild(videoContainer);
                        <input type="checkbox" id="weapon-dont-show">
             skillsTab.appendChild(card);
                        <span></span>
         } const iconsBar = $('#skills') ? $('.icon-bar', $('#skills')) : null;
                    </label>
         const skillsTopRail = iconsBar ? iconsBar.closest('.top-rail.skills') : null;
                    <button class="weapon-modal-btn" type="button"></button>
        const iconItems = iconsBar ? Array.from(iconsBar.querySelectorAll('.skill-icon')) : [];
                </div>
        buildMainSkillsMeta(iconItems);
             </div>
        // Verifica se há weapon em skills principais OU em subskills
        `;
        function checkHasAnyWeapon() {
             container.appendChild(modal);
            // Verifica skills principais
             updateModalTexts(modal);
            const hasMainWeapon = iconItems.some(el => {
            bindModalEvents();
                 const weapon = el.dataset.weapon;
             return modal;
                 return weapon && weapon.trim() !== '' && weapon !== '{}';
         };
            });
 
            if (hasMainWeapon) {
         const showPopup = () => {
                return true;
            const modal = ensureModal();
            if (modal) {
                updateModalTexts(modal);
                // Força reflow antes de adicionar classe para garantir transição
                 void modal.offsetHeight;
                 modal.classList.add('show');
             }
             }
            // Verifica subskills
        };
            for (const el of iconItems) {
 
                const subsRaw = el.getAttribute('data-subs');
        const hidePopup = () => {
                if (!subsRaw) continue;
             const m = document.getElementById('weapon-info-modal');
                try {
             if (m) m.classList.remove('show');
                    const subs = JSON.parse(subsRaw);
        };
                    if (Array.isArray(subs) && subs.some(s => s && s.weapon && typeof s.weapon === 'object' && Object.keys(s.weapon).length > 0)) {
 
                        return true;
         window.__applyWeaponState = applyWeaponState;
                    }
         window.__glaWeaponShowPopup = showPopup;
                } catch (e) { }
         window.__glaWeaponHidePopup = hidePopup;
            }
             return false;
        }
        const hasWeaponSkillAvailable = checkHasAnyWeapon();
        let weaponToggleBtn = null;
        if (!assetManifest) {
            assetManifest = buildAssetManifest();
            // Pré-carrega apenas ícones e flags críticos
            if (assetManifest.icons && assetManifest.icons.size) {
                assetManifest.icons.forEach(url => {
                    if (!url || imagePreloadCache.has(url)) return;
                    const img = new Image();
                    img.decoding = 'async';
                    img.loading = 'eager';
                    img.referrerPolicy = 'same-origin';
                    img.src = url;
                    imagePreloadCache.set(url, img);
                });
            }
             if (assetManifest.flags && assetManifest.flags.size) {
                assetManifest.flags.forEach(url => {
                    if (!url || imagePreloadCache.has(url)) return;
                    const img = new Image();
                    img.decoding = 'async';
                    img.loading = 'eager';
                    img.referrerPolicy = 'same-origin';
                    img.src = url;
                    imagePreloadCache.set(url, img);
                });
            }
         } const descBox = $('#skills') ? $('.desc-box', $('#skills')) : null;
        const videoBox = $('#skills') ? $('.video-container', $('#skills')) : null;
        const videosCache = new Map();
        const nestedVideoElByIcon = new WeakMap();
        const barStack = [];
         window.__barStack = barStack;
        let initialBarSnapshot = null;
        let totalVideos = 0, loadedVideos = 0, autoplay = false;
         window.__lastActiveSkillIcon = null;
        let userHasInteracted = false;
        let globalWeaponEnabled = false;
         try {
         try {
             if (localStorage.getItem('glaWeaponEnabled') === '1') {
             window.dispatchEvent(new CustomEvent('weapon:ready', { detail: { applyWeaponState, showPopup, hidePopup } }));
                globalWeaponEnabled = true;
            }
         } catch (err) {
         } catch (err) {
         }
         }
        const weaponStateListeners = new Set();
 
         let showWeaponPopupFn = null;
         // Escuta mudanças de idioma
         let popupShouldOpen = false;
         window.addEventListener('gla:langChanged', () => {
        function attachWeaponPopupFn(fn) {
             const modal = document.getElementById('weapon-info-modal');
             if (typeof fn !== 'function') return;
             if (modal) updateModalTexts(modal);
            showWeaponPopupFn = fn;
        });
             if (popupShouldOpen) {
 
                popupShouldOpen = false;
         // Função para obter o nome da arma
                try {
         function getWeaponName() {
                    showWeaponPopupFn();
            let weaponName = 'Arma Especial';
                } catch (err) {
                }
            }
         }
        attachWeaponPopupFn(window.__glaWeaponShowPopup);
         function requestWeaponPopupDisplay() {
             try {
             try {
                 if (localStorage.getItem('glaWeaponPopupDismissed') === '1') return;
                 const firstWithWeapon = document.querySelector('.skill-icon[data-weapon]');
            } catch (err) {
                 if (firstWithWeapon) {
            }
                    const raw = firstWithWeapon.getAttribute('data-weapon');
            if (typeof showWeaponPopupFn === 'function') {
                    const obj = JSON.parse(raw || '{}');
                showWeaponPopupFn();
                     if (obj && obj.name) {
                return;
                         weaponName = String(obj.name).trim();
            }
            popupShouldOpen = true;
        }
        function onWeaponStateChange(fn) {
            if (typeof fn !== 'function') return;
            weaponStateListeners.add(fn);
        }
        function syncWeaponButtonState(enabled) {
            if (!weaponToggleBtn || !weaponToggleBtn.isConnected) return;
            // Usa .weapon-active em vez de .active para não conflitar com skills
            weaponToggleBtn.classList.toggle('weapon-active', !!enabled);
            weaponToggleBtn.classList.remove('active'); // Garante que .active nunca seja aplicado
            weaponToggleBtn.setAttribute('aria-pressed', enabled ? 'true' : 'false');
            weaponToggleBtn.setAttribute('aria-label', enabled ? 'Desativar Arma Especial' : 'Ativar Arma Especial');
        }
        function syncWeaponRailState(enabled) {
            if (skillsTopRail) {
                skillsTopRail.classList.toggle('weapon-mode-on', !!enabled);
            }
        }
        function notifyWeaponStateListeners(enabled) {
            weaponStateListeners.forEach(listener => {
                try {
                    listener(enabled);
                } catch (err) {
                 }
            });
        }
        let pendingWeaponState = null;
        window.addEventListener('weapon:ready', (ev) => {
            if (ev && ev.detail && ev.detail.showPopup) {
                attachWeaponPopupFn(ev.detail.showPopup);
            }
            if (pendingWeaponState === null) return;
            if (typeof window.__applyWeaponState === 'function') {
                const target = pendingWeaponState;
                pendingWeaponState = null;
                window.__applyWeaponState(target);
            }
        });
        window.__setGlobalWeaponEnabled = (enabled) => {
            globalWeaponEnabled = enabled;
            notifyWeaponStateListeners(enabled);
        };
        function requestWeaponState(targetState) {
            if (typeof window.__applyWeaponState === 'function') {
                pendingWeaponState = null;
                window.__applyWeaponState(targetState);
                return;
            }
            pendingWeaponState = targetState;
        }
        onWeaponStateChange(syncWeaponButtonState);
        function reapplyWeaponClassesToBar() {
            // SISTEMA UNIFICADO: Aplica em skills E subskills (sempre, não só quando weapon está ativo)
            // Busca em skills principais (dentro de iconsBar)
            iconsBar.querySelectorAll('.skill-icon[data-weapon]').forEach(el => {
                const weapon = el.dataset.weapon;
                if (weapon && weapon.trim() !== '' && weapon !== '{}') {
                    if (!el.classList.contains('has-weapon-available')) {
                        el.classList.add('has-weapon-available');
                    }
                     if (!el.querySelector('.weapon-indicator')) {
                         const ind = document.createElement('div');
                        ind.className = 'weapon-indicator';
                        el.appendChild(ind);
                     }
                     }
                 }
                 }
             });
             } catch (e) { }
            // Busca em subskills (dentro de subskills-rail)
             return weaponName;
            document.querySelectorAll('.subskills-rail .subicon[data-weapon]').forEach(el => {
                const weapon = el.dataset.weapon;
                if (weapon && weapon.trim() !== '' && weapon !== '{}') {
                    if (!el.classList.contains('has-weapon-available')) {
                        el.classList.add('has-weapon-available');
                    }
                }
             });
        }
        // Aplica classes de weapon imediatamente ao carregar
        reapplyWeaponClassesToBar();
        // REMOVIDO: setupWeaponBarToggle - O toggle de weapon agora é criado apenas pelo C.WeaponToggle.html no header
        // Não cria mais botão na barra de skills - apenas aplica classes visuais
        onWeaponStateChange(syncWeaponRailState);
        // Reaplica classes quando o estado do weapon muda (para garantir que funcione mesmo quando toggle é ativado fora da barra)
        onWeaponStateChange(() => {
            // Usa setTimeout para garantir que o DOM foi atualizado
            setTimeout(() => {
                reapplyWeaponClassesToBar();
            }, 50);
        });
        syncWeaponRailState(globalWeaponEnabled);
        (function injectWeaponStyles() {
            if (document.getElementById('weapon-toggle-styles')) return;
            const style = document.createElement('style');
            style.id = 'weapon-toggle-styles';
            style.textContent = `
        /* ========== ESTILOS DE WEAPON - NOVO SISTEMA ========== */
       
        /* Animação simples para borda */
        @keyframes weapon-border-flow {
            0% { background-position: 0% 0%; }
            100% { background-position: 200% 0%; }
         }
         }


         /* Animação sutil para brilho */
         // Função para criar o novo toggle abaixo do char-translator
         @keyframes weapon-glow-breathe {
         function createWeaponToggle() {
             0%, 100% { opacity: 0.7; }
             // Remove toggle antigo se existir
             50% { opacity: 1; }
            const oldToggle = document.querySelector('.weapon-bar-toggle');
        }
             if (oldToggle) oldToggle.remove();


        /* ===== ÍCONE COM ARMA - Só mostra efeitos quando weapon-mode-on está ativo ===== */
            const existingContainer = document.querySelector('.weapon-toggle-container');
        /* Quando NÃO está em weapon-mode-on, os ícones com arma devem ser normais (mesma borda padrão) */
             if (existingContainer) return existingContainer;
        .character-box .top-rail.skills:not(.weapon-mode-on) .icon-bar .skill-icon.has-weapon-available:not(.weapon-bar-toggle)::after {
            /* Reseta para borda padrão quando toggle está desativado - com transição suave */
            background: none !important;
            box-shadow: inset 0 0 0 var(--icon-ring-w) var(--icon-idle) !important;
            animation: none !important;
            -webkit-mask: none !important;
            mask: none !important;
            padding: 0 !important;
            transition: box-shadow 0.2s ease, background 0.2s ease, padding 0.2s ease !important;
        }
        .character-box .top-rail.skills:not(.weapon-mode-on) .icon-bar .skill-icon.has-weapon-available:not(.weapon-bar-toggle)::before {
            /* Remove efeitos de glow quando toggle está desativado - com transição suave */
            opacity: 0 !important;
            transition: opacity 0.2s ease !important;
        }
        /* Quando ativo mas toggle desativado, usa borda padrão de ativo */
        .character-box .top-rail.skills:not(.weapon-mode-on) .icon-bar .skill-icon.has-weapon-available:not(.weapon-bar-toggle).active::after {
            background: none !important;
             box-shadow: inset 0 0 0 var(--icon-ring-w) var(--icon-active) !important;
            animation: none !important;
            -webkit-mask: none !important;
            mask: none !important;
            padding: 0 !important;
            transition: box-shadow 0.2s ease, background 0.2s ease, padding 0.2s ease !important;
        }


        /* ===== MODO WEAPON ON - INATIVO ===== */
            const characterHeader = document.querySelector('.character-header');
        .character-box .top-rail.skills.weapon-mode-on .icon-bar .skill-icon.has-weapon-available:not(.weapon-bar-toggle):not(.active)::after {
             if (!characterHeader) return null;
            pointer-events: none !important;
            box-shadow: none !important;
             background: linear-gradient(90deg,
                #FF3333 0%,
                #FF0000 50%,
                #FF3333 100%) !important;
            background-size: 200% 100% !important;
            animation: weapon-border-flow 3s linear infinite !important;
            -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0) !important;
            mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0) !important;
            -webkit-mask-composite: xor !important;
            mask-composite: exclude !important;
            padding: 2px !important;
        }


        .character-box .top-rail.skills.weapon-mode-on .icon-bar .skill-icon.has-weapon-available:not(.weapon-bar-toggle):not(.active)::before {
             // Resolve o ícone
             pointer-events: none !important;
             resolveCharacterWeaponIcon();
             inset: 0 !important;
             const weaponName = getWeaponName();
            border-radius: inherit !important;
            z-index: 1 !important;
            animation: weapon-glow-breathe 2s ease-in-out infinite !important;
             box-shadow:
                0 0 8px 0 rgba(255, 0, 0, 0.4),
                0 0 12px 0 rgba(255, 51, 51, 0.3),
                0 0 16px 0 rgba(255, 0, 0, 0.2) !important;
            opacity: 1 !important;
        }


        /* ===== MODO WEAPON ON - ATIVO ===== */
            // Cria o container do toggle
        .character-box .top-rail.skills.weapon-mode-on .icon-bar .skill-icon.has-weapon-available:not(.weapon-bar-toggle).active {
            const container = document.createElement('div');
             transform: scale(1.10) !important;
            container.className = 'weapon-toggle-container';
             z-index: 5 !important;
            container.setAttribute('role', 'button');
        }
             container.setAttribute('aria-pressed', 'false');
             container.setAttribute('aria-label', weaponName);


        .character-box .top-rail.skills.weapon-mode-on .icon-bar .skill-icon.has-weapon-available:not(.weapon-bar-toggle).active::after {
            // Cria o sprite (círculo com imagem)
             pointer-events: none !important;
             const sprite = document.createElement('div');
            box-shadow: none !important;
             sprite.className = 'weapon-toggle-sprite';
            background: linear-gradient(90deg,
                #FFEB3B 0%,
                #FFD700 50%,
                #FFEB3B 100%) !important;
             background-size: 200% 100% !important;
            animation: weapon-border-flow 2s linear infinite !important;
            -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0) !important;
            mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0) !important;
            -webkit-mask-composite: xor !important;
            mask-composite: exclude !important;
            padding: 2px !important;
        }


        .character-box .top-rail.skills.weapon-mode-on .icon-bar .skill-icon.has-weapon-available:not(.weapon-bar-toggle).active::before {
            if (globalWeaponToggleIcon) {
            pointer-events: none !important;
                const img = document.createElement('img');
            inset: 0 !important;
                img.src = globalWeaponToggleIcon;
            border-radius: inherit !important;
                img.alt = weaponName;
            z-index: 1 !important;
                img.className = 'weapon-toggle-icon';
            animation: weapon-glow-breathe 1.5s ease-in-out infinite !important;
                 img.decoding = 'async';
            box-shadow:
                 img.loading = 'eager'; // Ícone do toggle é crítico - carrega imediatamente
                 0 0 10px 0 rgba(255, 215, 0, 0.5),
                 img.onerror = function () {
                 0 0 16px 0 rgba(255, 235, 59, 0.4),
                    // console.error('[WeaponToggle] Erro ao carregar imagem:', globalWeaponToggleIcon);
                 0 0 22px 0 rgba(255, 215, 0, 0.3) !important;
                };
            opacity: 1 !important;
                img.onload = function () {
        }
                    // console.log('[WeaponToggle] Imagem carregada com sucesso:', globalWeaponToggleIcon);
            `;
                 };
            document.head.appendChild(style);
                 sprite.appendChild(img);
        })();
        function applyWeaponBadge(el, weaponData, equipped) {
            // Encontrar ou criar o badge
            let badge = el.querySelector('.weapon-badge');
            if (!badge) {
                badge = document.createElement('div');
                 badge.className = 'weapon-badge';
                 el.appendChild(badge);
             }
             }


             if (equipped && weaponData) {
             // Cria a barra com texto
                el.classList.add('weapon-equipped');
            const bar = document.createElement('div');
                 const weaponIconUrl = filePathURL(weaponData.icon || 'Nada.png');
            bar.className = 'weapon-toggle-bar';
                 if (weaponIconUrl) {
            const nameSpan = document.createElement('span');
                     el.style.setProperty('--weapon-badge-url', `url('${weaponIconUrl}')`);
            nameSpan.className = 'weapon-toggle-name';
            nameSpan.setAttribute('data-lang', getCurrentLang());
            bar.appendChild(nameSpan);
 
            container.appendChild(sprite);
            container.appendChild(bar);
 
            // Adiciona evento de clique
            container.addEventListener('click', () => {
                 let currentState = false;
                try {
                    currentState = localStorage.getItem('glaWeaponEnabled') === '1';
                } catch (e) { }
                const nextState = !currentState;
                 if (nextState) {
                     // Verifica se o popup foi dispensado antes de mostrar
                    let shouldShowPopup = true;
                    try {
                        if (localStorage.getItem('glaWeaponPopupDismissed') === '1') {
                            shouldShowPopup = false;
                        }
                    } catch (e) { }
                    if (shouldShowPopup && typeof window.__glaWeaponShowPopup === 'function') {
                        window.__glaWeaponShowPopup();
                    }
                 }
                 }
                if (typeof window.__applyWeaponState === 'function') {
                    window.__applyWeaponState(nextState);
                }
            });
            // Insere no container de controles (character-header-controls)
            const controlsContainer = document.querySelector('.character-header-controls');
            if (controlsContainer) {
                controlsContainer.appendChild(container);
             } else {
             } else {
                 el.classList.remove('weapon-equipped');
                 // Fallback: insere no character-header se o container não existir
                 el.style.removeProperty('--weapon-badge-url');
                 characterHeader.appendChild(container);
             }
             }
         } function getWeaponKey(el) {
 
             return (el.dataset.index || '') + ':' + (el.dataset.nome || el.dataset.name || '');
            // Atualiza estado visual inicial
        } function isWeaponModeOn() {
            updateToggleVisualState();
 
            return container;
         }
 
        // Função para atualizar o estado visual do toggle
        function updateToggleVisualState() {
             const container = document.querySelector('.weapon-toggle-container');
            if (!container) return;
 
            let isEnabled = false;
             try {
             try {
                 return localStorage.getItem('glaWeaponEnabled') === '1';
                 isEnabled = localStorage.getItem('glaWeaponEnabled') === '1';
             } catch (e) {
             } catch (e) { }
                 return false;
 
            if (isEnabled) {
                container.classList.add('weapon-active');
                 container.setAttribute('aria-pressed', 'true');
            } else {
                container.classList.remove('weapon-active');
                container.setAttribute('aria-pressed', 'false');
             }
             }
        } function getWeaponDataForIcon(iconEl) {
 
             if (!iconEl || !iconEl.dataset.weapon) return null;
             // Atualiza idioma do texto
             try {
             const nameSpan = container.querySelector('.weapon-toggle-name');
                return JSON.parse(iconEl.dataset.weapon);
             if (nameSpan) {
             } catch (e) {
                 nameSpan.setAttribute('data-lang', getCurrentLang());
                 return null;
             }
             }
         } function getEffectiveSkillVideoFromIcon(iconEl) {
         }
            const weaponOn = globalWeaponEnabled;
            const weaponData = getWeaponDataForIcon(iconEl);
            const baseVideoFile = (iconEl.dataset.videoFile || '').trim();
            const baseVideoURL = (iconEl.dataset.video || '').trim();


            // console.log('[Skills DEBUG]', {
        // Observa quando o container de controles é criado para posicionar o toggle
             //    skillName: iconEl.dataset.nome || iconEl.dataset.name,
        function observeCharacterHeader() {
             //    weaponOn,
            const controlsContainer = document.querySelector('.character-header-controls');
            //     hasWeaponData: !!weaponData,
             const characterHeader = document.querySelector('.character-header');
            //    weaponData: weaponData,
             if (controlsContainer) {
            //    baseVideoFile,
                // Container existe - cria o toggle imediatamente
            //    baseVideoURL
                createWeaponToggle();
            // });
             } else if (characterHeader) {
 
                 // Header existe mas container não - cria o container e depois o toggle
             if (weaponOn && weaponData) {
                const newContainer = document.createElement('div');
                 // console.log('[Skills] checking weapon video', {
                 newContainer.className = 'character-header-controls';
                //    skillName: iconEl.dataset.nome || iconEl.dataset.name,
                 characterHeader.appendChild(newContainer);
                //    hasVideo: !!(weaponData.video),
                 // Aguarda um frame para garantir que o container foi adicionado
                 //    videoValue: weaponData.video,
                 requestAnimationFrame(() => {
                 //    videoTrimmed: weaponData.video ? weaponData.video.trim() : ''
                     createWeaponToggle();
                 // });
                });
                 if (weaponData.video && weaponData.video.trim() !== '') {
            } else {
                     // console.log('[Skills] video escolhido (weapon)', iconEl.dataset.nome || iconEl.dataset.name, weaponData.video);
                // Nada existe ainda - tenta novamente após um delay
                    return weaponData.video.trim();
                setTimeout(observeCharacterHeader, 100);
                }
             }
             }
            const result = baseVideoFile || baseVideoURL || '';
         }
            // console.log('[Skills] video escolhido (base)', iconEl.dataset.nome || iconEl.dataset.name, result);
            return result;
         } function createVideoElement(videoURL, extraAttrs = {
        }) {
            const v = document.createElement('video');
            v.className = 'skill-video';
            v.setAttribute('controls', '');
            v.setAttribute('preload', 'metadata');
            v.setAttribute('playsinline', '');
            v.style.display = 'none';
            v.style.width = '100%';
            v.style.height = 'auto';
            v.style.aspectRatio = '16/9';
            v.style.objectFit = 'cover';
            Object.keys(extraAttrs).forEach(k => {
                v.dataset[k] = extraAttrs[k];
            });
            // Detectar formato do vídeo pela extensão
            const ext = (videoURL.split('.').pop() || '').toLowerCase().split('?')[0];
            const mimeTypes = {
                'mp4': 'video/mp4',
                'm4v': 'video/mp4',
                'webm': 'video/webm',
                'ogv': 'video/ogg',
                'ogg': 'video/ogg',
                'mov': 'video/quicktime'
            };
            const mimeType = mimeTypes[ext] || 'video/mp4';


            const src = document.createElement('source');
        // Observa mudanças no DOM para detectar quando o container de controles é criado
            src.src = videoURL;
         function observeDOMForHeader() {
            src.type = mimeType;
             const observer = new MutationObserver((mutations) => {
            v.appendChild(src);
                 mutations.forEach((mutation) => {
 
                     mutation.addedNodes.forEach((node) => {
            // Fallback para Safari/iOS mais antigos
                         if (node.nodeType === 1) {
            v.setAttribute('webkit-playsinline', '');
                            if (node.classList && (node.classList.contains('character-header-controls') || node.classList.contains('character-header'))) {
            v.setAttribute('x-webkit-airplay', 'allow');
                                 setTimeout(() => createWeaponToggle(), 10);
 
                             } else if (node.querySelector && (node.querySelector('.character-header-controls') || node.querySelector('.character-header'))) {
            return v;
                                 setTimeout(() => createWeaponToggle(), 10);
         } function precreateSubskillVideos() {
             if (!videoBox) return;
            // console.log('[Skills] precreateSubskillVideos: iniciando pré-criação de TODOS os vídeos de subskills');
            let createdCount = 0;
            iconItems.forEach(parentIcon => {
                 const subsRaw = parentIcon.dataset.subs || parentIcon.getAttribute('data-subs');
                if (!subsRaw) return;
                try {
                     const subs = JSON.parse(subsRaw);
                    if (!Array.isArray(subs)) return;
                    const parentIdx = parentIcon.dataset.index || '';
                    subs.forEach(s => {
                         const subName = (s.name || s.n || '').trim();
                        // Vídeo normal da subskill
                        if (s.video && s.video.trim() !== '' && s.video !== 'Nada.png' && !s.video.toLowerCase().includes('nada.png')) {
                            const key = `sub:${parentIdx}:${subName}`;
                            if (subskillVideosCache.has(key)) return;
                            const videoURL = normalizeFileURL(s.video);
                            if (videoURL && videoURL.trim() !== '') {
                                 const v = createVideoElement(videoURL, {
                                    sub: '1', parentIndex: parentIdx, subName: subName, cacheKey: key
                                });
                                v.setAttribute('preload', 'metadata');
                                v.muted = true; // Permite autoload em mais navegadores
                                videoBox.appendChild(v);
                                subskillVideosCache.set(key, v);
                                createdCount++;
                                // Não força carregamento - será carregado quando necessário
                                // v.load();
                             }
                        }
                        // Vídeo de weapon da subskill
                        if (s.weapon && typeof s.weapon === 'object' && s.weapon.video && s.weapon.video.trim() !== '' && s.weapon.video !== 'Nada.png' && !s.weapon.video.toLowerCase().includes('nada.png')) {
                            const weaponKey = `sub:${parentIdx}:${subName}:weapon`;
                            if (subskillVideosCache.has(weaponKey)) return;
                            const weaponVideoURL = normalizeFileURL(s.weapon.video);
                            if (weaponVideoURL && weaponVideoURL.trim() !== '') {
                                 const v = createVideoElement(weaponVideoURL, {
                                    sub: '1', parentIndex: parentIdx, subName: subName, weapon: '1', cacheKey: weaponKey
                                });
                                v.setAttribute('preload', 'metadata');
                                v.muted = true; // Permite autoload em mais navegadores
                                videoBox.appendChild(v);
                                subskillVideosCache.set(weaponKey, v);
                                createdCount++;
                                // Não força carregamento - será carregado quando necessário
                                // v.load();
                             }
                             }
                         }
                         }
                     });
                     });
                 } catch (e) {
                 });
                }
             });
             });
             // console.log('[Skills] precreateSubskillVideos: criados', createdCount, 'vídeos. Cache size:', subskillVideosCache.size);
 
             observer.observe(document.body, { childList: true, subtree: true });
         }
         }


         // Função para forçar carregamento de todos os vídeos
         const boot = () => {
        function forceLoadAllVideos() {
             // Resolve o ícone do character antes de tudo
            if (!videoBox) return;
             resolveCharacterWeaponIcon();
            const allVideos = videoBox.querySelectorAll('video[data-sub="1"]');
             // console.log('[Skills] forceLoadAllVideos: forçando load de', allVideos.length, 'vídeos');
             allVideos.forEach(v => {
                if (v.readyState < 2) {
                    v.load();
                }
            });
        }


        // Pré-cria vídeos de subskills IMEDIATAMENTE no carregamento
            // Verificar se existe alguma skill ou subskill com arma
        precreateSubskillVideos();
             function checkHasAnyWeapon() {
        // Força carregamento novamente após curto delay para garantir
                 // PRIORIDADE 1: Verifica se há weaponicon global no character-box
        setTimeout(() => {
                 const characterBox = document.querySelector('.character-box');
             precreateSubskillVideos();
                 if (characterBox && characterBox.dataset.weaponicon) {
            forceLoadAllVideos();
                     const weaponIcon = characterBox.dataset.weaponicon.trim();
        }, 100);
                     if (weaponIcon && weaponIcon !== '' && weaponIcon !== 'Nada.png') {
        // E mais uma vez após um delay maior para garantir que tudo esteja pronto
                         return true;
        setTimeout(forceLoadAllVideos, 500);
        if (iconItems.length && videoBox) {
            iconItems.forEach(el => {
                const idx = el.dataset.index || '';
                 // Vídeo normal
                 const src = (el.dataset.videoFile || el.dataset.video || '').trim();
                 if (src && src !== 'Nada.png' && !src.toLowerCase().includes('nada.png') && !videosCache.has(idx)) {
                    totalVideos++;
                     const videoURL = normalizeFileURL(src);
                     if (videoURL) {
                        const v = createVideoElement(videoURL, {
                            index: idx
                        });
                        v.setAttribute('preload', 'metadata');
                        v.style.maxWidth = '100%';
                        v.addEventListener('canplaythrough', () => {
                            loadedVideos++;
                            if (!userHasInteracted && loadedVideos === 1) {
                                try {
                                    v.pause();
                                    v.currentTime = 0;
                                } catch (e) {
                                }
                            } if (loadedVideos === totalVideos) autoplay = true;
                        }, {
                            once: true
                        });
                        v.addEventListener('error', () => {
                            loadedVideos++;
                            if (loadedVideos === totalVideos) autoplay = true;
                         }, {
                            once: true
                        });
                        videoBox.appendChild(v);
                        videosCache.set(idx, v);
                        // Força carregamento
                        v.load();
                     }
                     }
                 }
                 }
                 // Vídeo de weapon
 
                 if (el.dataset.weapon) {
                 // PRIORIDADE 2: Verifica skills principais
                     try {
                const mainSkills = document.querySelectorAll('.skill-icon[data-weapon]');
                        const weaponData = JSON.parse(el.dataset.weapon);
                 for (const el of mainSkills) {
                        if (weaponData && weaponData.video && weaponData.video.trim() !== '' && weaponData.video !== 'Nada.png' && !weaponData.video.toLowerCase().includes('nada.png')) {
                     const weapon = el.dataset.weapon;
                             const weaponKey = `weapon:${idx}:${(el.dataset.nome || el.dataset.name || '').trim()}`;
                    if (weapon && weapon.trim() !== '' && weapon !== '{}') {
                             if (!videosCache.has(weaponKey)) {
                        try {
                                totalVideos++;
                             const weaponObj = JSON.parse(weapon);
                                const weaponVideoURL = normalizeFileURL(weaponData.video);
                             if (weaponObj && typeof weaponObj === 'object' && Object.keys(weaponObj).length > 0) {
                                if (weaponVideoURL) {
                                return true;
                                    const v = createVideoElement(weaponVideoURL, {
                                        index: idx, weapon: '1'
                                    });
                                    v.setAttribute('preload', 'metadata');
                                    v.style.maxWidth = '100%';
                                    v.addEventListener('canplaythrough', () => {
                                        loadedVideos++;
                                        if (loadedVideos === totalVideos) autoplay = true;
                                    }, {
                                        once: true
                                    });
                                    v.addEventListener('error', () => {
                                        loadedVideos++;
                                        if (loadedVideos === totalVideos) autoplay = true;
                                    }, {
                                        once: true
                                    });
                                    videoBox.appendChild(v);
                                    videosCache.set(weaponKey, v);
                                    // Força carregamento
                                    v.load();
                                }
                             }
                             }
                        } catch (e) {
                            // Se não for JSON válido mas não está vazio, considera válido
                            return true;
                         }
                         }
                    } catch (e) {
                     }
                     }
                 }
                 }
            });
 
        } function wireTooltipsForNewIcons() {
                // PRIORIDADE 3: Verifica weaponicon em skills principais
            const tip = document.querySelector('.skill-tooltip');
                const skillsWithWeaponIcon = document.querySelectorAll('.skill-icon[data-weaponicon]');
            if (!tip) return;
                 for (const el of skillsWithWeaponIcon) {
            let lockUntil2 = 0;
                     const weaponIcon = el.dataset.weaponicon;
            Array.from(document.querySelectorAll('.icon-bar .skill-icon')).forEach(icon => {
                     if (weaponIcon && weaponIcon.trim() !== '' && weaponIcon !== 'Nada.png') {
                if (icon.dataset.weaponToggle === '1' || icon.classList.contains('weapon-bar-toggle')) return;
                        return true;
                 if (icon.dataset.tipwired) return;
                     }
                icon.dataset.tipwired = '1';
                const label = icon.dataset.nome || icon.dataset.name || icon.title || '';
                if (label && !icon.hasAttribute('aria-label')) icon.setAttribute('aria-label', label);
                if (icon.hasAttribute('title')) icon.removeAttribute('title');
                const img = icon.querySelector('img');
                if (img) {
                     const imgAlt = img.getAttribute('alt') || '';
                    const imgTitle = img.getAttribute('title') || '';
                     if (!label && (imgAlt || imgTitle)) icon.setAttribute('aria-label', imgAlt || imgTitle);
                    img.setAttribute('alt', '');
                    if (img.hasAttribute('title')) img.removeAttribute('title');
                } const measureAndPos = (el) => {
                    if (!el || tip.getAttribute('aria-hidden') === 'true') return;
                    tip.style.left = '0px';
                    tip.style.top = '0px';
                    const rect = el.getBoundingClientRect();
                    const tr = tip.getBoundingClientRect();
                    let left = Math.round(rect.left + (rect.width - tr.width) / 2);
                    left = Math.max(8, Math.min(left, window.innerWidth - tr.width - 8));
                    const coarse = (window.matchMedia && matchMedia('(pointer: coarse)').matches) || (window.innerWidth <= 600);
                    let top = coarse ? Math.round(rect.bottom + 10) : Math.round(rect.top - tr.height - 8);
                    if (top < 8) top = Math.round(rect.bottom + 10);
                    tip.style.left = left + 'px';
                    tip.style.top = top + 'px';
                };
                const show = (el, text) => {
                    tip.textContent = text || '';
                    tip.setAttribute('aria-hidden', 'false');
                    measureAndPos(el);
                    tip.style.opacity = '1';
                };
                const hide = () => {
                    tip.setAttribute('aria-hidden', 'true');
                    tip.style.opacity = '0';
                    tip.style.left = '-9999px';
                    tip.style.top = '-9999px';
                };
                icon.addEventListener('mouseenter', () => show(icon, (icon.dataset.nome || icon.dataset.name || '')));
                icon.addEventListener('mousemove', () => {
                    if (performance.now() >= lockUntil2) measureAndPos(icon);
                });
                icon.addEventListener('click', () => {
                    lockUntil2 = performance.now() + 240;
                    measureAndPos(icon);
                });
                icon.addEventListener('mouseleave', hide);
            });
        } function showVideoForIcon(el) {
            userHasInteracted = true;
            if (!videoBox) return;
            const effectiveVideo = getEffectiveSkillVideoFromIcon(el);
            if (!effectiveVideo || effectiveVideo.trim() === '') {
                videoBox.style.display = 'none';
                return;
            }
            const videoURL = normalizeFileURL(effectiveVideo);
            if (!videoURL || videoURL.trim() === '') {
                videoBox.style.display = 'none';
                return;
            }
            Array.from(videoBox.querySelectorAll('video.skill-video')).forEach(v => {
                try {
                     v.pause();
                } catch (e) {
                 }
                 }
                v.style.display = 'none';
            });
            if (window.__subskills) window.__subskills.hideAll?.(videoBox);
            const hasIdx = !!el.dataset.index;
            const weaponOn = globalWeaponEnabled;
            const weaponData = getWeaponDataForIcon(el);
            const isWeaponVideo = weaponOn && weaponData && weaponData.video && weaponData.video.trim() !== '';


            // console.log('[Skills] showVideoForIcon chamado', {
                // PRIORIDADE 4: Verifica subskills
            //    skillName: el.dataset.nome || el.dataset.name,
                 const skillIcons = document.querySelectorAll('.skill-icon[data-subs]');
            //    weaponOn,
                 for (const el of skillIcons) {
            //    isWeaponVideo,
            //    effectiveVideo: getEffectiveSkillVideoFromIcon(el)
            // });
            const videoKey = isWeaponVideo ? `weapon:${getWeaponKey(el)}` : (el.dataset.index || '');
            if (hasIdx && !isWeaponVideo && videosCache.has(el.dataset.index)) {
                 const v = videosCache.get(el.dataset.index);
                videoBox.style.display = 'block';
                v.style.display = 'block';
                 try {
                    v.currentTime = 0;
                } catch (e) {
                }
                const suppress = document.body.dataset.suppressSkillPlay === '1';
                if (!suppress) {
                    v.play().catch(() => {
                    });
                } else {
                     try {
                     try {
                         v.pause();
                         const subs = JSON.parse(el.getAttribute('data-subs') || '[]');
                     } catch (e) {
                        if (Array.isArray(subs) && subs.some(s => s && s.weapon && typeof s.weapon === 'object' && Object.keys(s.weapon).length > 0)) {
                    }
                            return true;
                        }
                     } catch (e) { }
                 }
                 }
                 return;
                 return false;
             }
             }
             let v = null;
             const hasAnyWeapon = checkHasAnyWeapon();
            if (isWeaponVideo) {
 
                v = videoBox.querySelector(`video[data-weapon-key="${videoKey}"]`);
             if (!hasAnyWeapon) {
            } else {
                 // Limpar estado visual para chars sem arma (previne cache entre páginas)
                v = nestedVideoElByIcon.get(el);
                 const topRail = document.querySelector('.top-rail.skills');
            }
                 if (topRail) {
             if (!v) {
                     topRail.classList.remove('weapon-mode-on');
                v = createVideoElement(videoURL, isWeaponVideo ? {
                    weaponKey: videoKey
                } : {});
                if (isWeaponVideo) {
                    videoBox.appendChild(v);
                } else {
                    videoBox.appendChild(v);
                    nestedVideoElByIcon.set(el, v);
                }
            } else {
                 // Verifica se o source já tem a URL correta (compara apenas o pathname/filename)
                 const src = v.querySelector('source');
                 if (src) {
                     const currentURL = src.src || '';
                    const currentFilename = currentURL.split('/').pop().split('?')[0];
                    const targetFilename = videoURL.split('/').pop().split('?')[0];
                    // Só recarrega se o arquivo for realmente diferente
                    if (currentFilename !== targetFilename) {
                        src.src = videoURL;
                        v.load();
                    }
                 }
                 }
            }
                document.querySelectorAll('.skill-icon.has-weapon-available').forEach(el => {
            videoBox.style.display = 'block';
                    el.classList.remove('has-weapon-available');
            v.style.display = 'block';
                    el.classList.remove('weapon-equipped');
            try {
                    el.style.removeProperty('--weapon-badge-url');
                v.currentTime = 0;
                    const ind = el.querySelector('.weapon-indicator');
            } catch (e) {
                    if (ind) ind.remove();
            }
            const suppress = document.body.dataset.suppressSkillPlay === '1';
            if (!suppress) {
                v.play().catch(() => {
                 });
                 });
            } else {
                 // Remover toggle se existir
                 try {
                 const toggleContainer = document.querySelector('.weapon-toggle-container');
                    v.pause();
                 if (toggleContainer) toggleContainer.remove();
                } catch (e) {
                 // Atualizar estado global para desligado
                 }
                 if (typeof window.__setGlobalWeaponEnabled === 'function') {
            }
                     window.__setGlobalWeaponEnabled(false);
        } function activateSkill(el, options = {
        }) {
            const {
                openSubs = true
            } = options;
            const tip = document.querySelector('.skill-tooltip');
            if (tip) {
                tip.setAttribute('aria-hidden', 'true');
                 tip.style.opacity = '0';
                tip.style.left = '-9999px';
                tip.style.top = '-9999px';
            } const skillsRoot = document.getElementById('skills');
            const i18nMap = skillsRoot ? JSON.parse(skillsRoot.dataset.i18nAttrs || '{}') : {
            };
            const L = i18nMap[getLangKey()] || i18nMap.pt || {
                cooldown: 'Recarga', energy_gain: 'Ganho de energia', energy_cost: 'Custo de energia', power: 'Poder', power_pvp: 'Poder PvP', level: 'Nível'
            };
            const name = el.dataset.nome || el.dataset.name || '';
            const level = (el.dataset.level || '').trim();
            let weaponData = null;
            if (el.dataset.weapon) {
                try {
                    weaponData = JSON.parse(el.dataset.weapon);
                } catch (e) {
                    weaponData = null;
                }
            } const hasWeapon = !!weaponData;
            const weaponEquipped = hasWeapon && globalWeaponEnabled;
            const lang = getLangKey();
            const baseDescPack = {
                 pt: el.dataset.descPt || '', en: el.dataset.descEn || '', es: el.dataset.descEs || '', pl: el.dataset.descPl || ''
            };
            const baseDesc = baseDescPack[lang] || baseDescPack.pt || baseDescPack.en || baseDescPack.es || baseDescPack.pl || el.dataset.desc || '';
            // Aceita tanto desc_i18n quanto desc para compatibilidade
            let weaponDescPack = {};
            if (weaponData) {
                 if (weaponData.desc_i18n) {
                    weaponDescPack = weaponData.desc_i18n;
                } else if (weaponData.desc) {
                    weaponDescPack = weaponData.desc;
                } else {
                    weaponDescPack = {
                        pt: weaponData.descPt || '', en: weaponData.descEn || '', es: weaponData.descEs || '', pl: weaponData.descPl || ''
                    };
                }
            }
            const weaponDesc = weaponDescPack[lang] || weaponDescPack.pt || weaponDescPack.en || weaponDescPack.es || weaponDescPack.pl || '';
            const chosenDesc = (weaponEquipped && weaponDesc) ? weaponDesc : baseDesc;
            const descHtml = chosenDesc.replace(/'''(.*?)'''/g, '<b>$1</b>');
            let attrsHTML = '';
            if (weaponEquipped && weaponData) {
                // Usa valores do weapon, mas só se existirem (não herda da skill base)
                const wPve = (weaponData.powerpve !== undefined && weaponData.powerpve !== null && weaponData.powerpve !== '') ? weaponData.powerpve.toString().trim() : '';
                const wPvp = (weaponData.powerpvp !== undefined && weaponData.powerpvp !== null && weaponData.powerpvp !== '') ? weaponData.powerpvp.toString().trim() : '';
                const wEnergy = (weaponData.energy !== undefined && weaponData.energy !== null && weaponData.energy !== '') ? weaponData.energy.toString().trim() : '';
                const wCd = (weaponData.cooldown !== undefined && weaponData.cooldown !== null && weaponData.cooldown !== '') ? weaponData.cooldown.toString().trim() : '';
                const weaponAttrs = [wPve, wPvp, wEnergy, wCd].join(',');
                // console.log('[Skills] weaponAttrs string:', weaponAttrs, { wPve, wPvp, wEnergy, wCd, weaponData });
                attrsHTML = renderAttributes(weaponAttrs);
            } else {
                attrsHTML = el.dataset.atr ? renderAttributes(el.dataset.atr) : (el.dataset.subattrs ? renderSubAttributesFromObj(JSON.parse(el.dataset.subattrs), L) : '');
            } let flagsHTML = '';
            if (el.dataset.flags) {
                try {
                     const flags = JSON.parse(el.dataset.flags);
                    flagsHTML = renderFlagsRow(flags);
                } catch (e) {
                 }
                 }
            } if (descBox) {
                descBox.innerHTML = `<div class="skill-title"><h3>${name}</h3></div>${level ? `<div class="skill-level-line"><span class="attr-label">${L.level} ${level}</span></div>` : ''}${attrsHTML}<div class="desc">${descHtml}</div>`;
            } if (hasWeapon) {
                applyWeaponBadge(el, weaponData, weaponEquipped);
            } if (videoBox) {
                const oldFlags = videoBox.querySelector('.skill-flags');
                if (oldFlags) oldFlags.remove();
                if (flagsHTML) {
                    videoBox.insertAdjacentHTML('beforeend', flagsHTML);
                    applyFlagTooltips(videoBox);
                }
            } const currIcons = Array.from(iconsBar.querySelectorAll('.skill-icon'));
            currIcons.forEach(i => i.classList.remove('active'));
            el.classList.add('active');
            if (!autoplay && loadedVideos > 0) autoplay = true;
            window.__lastActiveSkillIcon = el;
            // Lógica de vídeo: usa função centralizada que já considera weapon
            showVideoForIcon(el);
            const subsRaw = el.dataset.subs || el.getAttribute('data-subs');
            const isBack = el.dataset.back === 'true' || el.getAttribute('data-back') === 'true' || el.dataset.back === 'yes' || el.getAttribute('data-back') === 'yes' || el.dataset.back === '1' || el.getAttribute('data-back') === '1';
            if (isBack && barStack.length) {
                const prev = barStack.pop();
                renderBarFromItems(prev.items);
                const btn = document.querySelector('.skills-back-wrapper');
                if (btn) btn.style.display = barStack.length ? 'block' : 'none';
                 return;
                 return;
            } if (openSubs && subsRaw && subsRaw.trim() !== '') {
                if (barStack.length && barStack[barStack.length - 1].parentIcon === el) return;
                try {
                    const subs = JSON.parse(subsRaw);
                    pushSubBarFrom(subs, el);
                } catch {
                }
             }
             }
        } function wireClicksForCurrentBar() {
            const currIcons = Array.from(iconsBar.querySelectorAll('.skill-icon'));
            currIcons.forEach(el => {
                if (el.dataset.weaponToggle === '1' || el.classList.contains('weapon-bar-toggle')) return;
                if (el.dataset.wired) return;
                el.dataset.wired = '1';
                const label = el.dataset.nome || el.dataset.name || '';
                el.setAttribute('aria-label', label);
                if (el.hasAttribute('title')) el.removeAttribute('title');
                const img = el.querySelector('img');
                if (img) {
                    img.setAttribute('alt', '');
                    if (img.hasAttribute('title')) img.removeAttribute('title');
                } el.addEventListener('click', () => {
                    activateSkill(el, {
                        openSubs: true
                    });
                });
            });
            wireTooltipsForNewIcons();
        } function animateIconsBarEntrance() {
            Array.from(iconsBar.children).forEach((c, i) => {
                c.style.opacity = '0';
                c.style.transform = 'translateY(6px)';
                requestAnimationFrame(() => {
                    setTimeout(() => {
                        c.style.transition = 'opacity .18s ease, transform .18s ease';
                        c.style.opacity = '1';
                        c.style.transform = 'translateY(0)';
                    }, i * 24);
                });
            });
        } function snapshotCurrentBarItemsFromDOM() {
            return Array.from(iconsBar.querySelectorAll('.skill-icon')).filter(el => el.dataset.weaponToggle !== '1').map(el => {
                const img = el.querySelector('img');
                const iconURL = img ? img.src : '';
                const subsRaw = el.dataset.subs || el.getAttribute('data-subs') || '';
                let subs = null;
                try {
                    subs = subsRaw ? JSON.parse(subsRaw) : null;
                } catch {
                    subs = null;
                } const subattrsRaw = el.dataset.subattrs || '';
                let flags = null;
                if (el.dataset.flags) {
                    try {
                        flags = JSON.parse(el.dataset.flags);
                    } catch (e) {
                    }
                } let weapon = null;
                if (el.dataset.weapon) {
                    try {
                        weapon = JSON.parse(el.dataset.weapon);
                    } catch (e) {
                    }
                } return {
                    name: el.dataset.nome || el.dataset.name || '', index: el.dataset.index || '', level: el.dataset.level || '', desc: el.dataset.desc || '', descPt: el.dataset.descPt || '', descEn: el.dataset.descEn || '', descEs: el.dataset.descEs || '', descPl: el.dataset.descPl || '', attrs: el.dataset.atr || el.dataset.attrs || '', video: el.dataset.video || '', iconURL, subs, subattrsStr: subattrsRaw, flags: flags, weapon: weapon
                };
            });
        } function ensureBackButton() {
            const rail = iconsBar.closest('.top-rail.skills');
            if (!rail) return null;
            let wrap = rail.parentElement;
            if (!wrap || !wrap.classList || !wrap.classList.contains('skills-rail-wrap')) {
                const parentNode = rail.parentNode;
                const newWrap = document.createElement('div');
                newWrap.className = 'skills-rail-wrap';
                parentNode.insertBefore(newWrap, rail);
                newWrap.appendChild(rail);
                wrap = newWrap;
            } let backWrap = wrap.querySelector('.skills-back-wrapper');
            if (!backWrap) {
                backWrap = document.createElement('div');
                backWrap.className = 'skills-back-wrapper';
                const btnInner = document.createElement('button');
                btnInner.className = 'skills-back';
                btnInner.type = 'button';
                btnInner.setAttribute('aria-label', 'Voltar');
                btnInner.innerHTML = '<svg class="back-chevron" width="100%" height="100%" viewBox="0 0 36 32" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" preserveAspectRatio="xMidYMid meet"><path d="M10 2L4 16L10 30" stroke="currentColor" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/><path d="M20 2L14 16L20 30" stroke="currentColor" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/><path d="M30 2L24 16L30 30" stroke="currentColor" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/></svg>';
                backWrap.appendChild(btnInner);
                wrap.insertBefore(backWrap, rail);
                btnInner.addEventListener('click', () => {
                    if (!barStack.length) return;
                    const prev = barStack.pop();
                    renderBarFromItems(prev.items);
                    backWrap.style.display = barStack.length ? 'block' : 'none';
                    wrap.classList.toggle('has-sub-bar', barStack.length > 0);
                    if (!barStack.length) btnInner.classList.remove('peek');
                });
            } backWrap.style.display = barStack.length ? 'block' : 'none';
            wrap.classList.toggle('has-sub-bar', barStack.length > 0);
            const btnInner = backWrap.querySelector('.skills-back');


             // Calcula a posição do botão baseado na posição real do top-rail
             ensureModal();
            function updateBackButtonPosition() {
                if (!rail || !backWrap) return;
                const railRect = rail.getBoundingClientRect();
                const wrapRect = wrap.getBoundingClientRect();
                // Calcula a posição relativa do rail dentro do wrap
                const railLeft = railRect.left - wrapRect.left;
                // Posiciona o wrapper na borda esquerda do rail
                // O botão interno usa translateX(-97%) para ficar atrás da barra
                backWrap.style.left = railLeft + 'px';
            }


             // Atualiza a posição quando necessário
             // Cria o novo toggle - tenta múltiplas vezes para garantir
            if (backWrap.style.display !== 'none') {
            observeCharacterHeader();
                // Usa requestAnimationFrame para garantir que o DOM foi atualizado
            observeDOMForHeader();
                requestAnimationFrame(() => {
                    updateBackButtonPosition();
                });


                // Recalcula em resize e scroll
            // Tenta criar novamente após um delay maior para garantir que o translator já criou o container
                if (!backWrap.dataset.positionWired) {
            setTimeout(() => {
                    backWrap.dataset.positionWired = '1';
                const existing = document.querySelector('.weapon-toggle-container');
                    const updateOnResize = () => {
                if (!existing) {
                        if (backWrap.style.display !== 'none') {
                     observeCharacterHeader();
                            updateBackButtonPosition();
                        }
                    };
                    window.addEventListener('resize', updateOnResize);
                    const observer = new ResizeObserver(() => {
                        if (backWrap.style.display !== 'none') {
                            updateBackButtonPosition();
                        }
                     });
                    if (rail) observer.observe(rail);
                    observer.observe(wrap);
                 }
                 }
             }
             }, 500);


            return btnInner;
             // Última tentativa após 1 segundo
        } function renderBarFromItems(items) {
             setTimeout(() => {
            const tip = document.querySelector('.skill-tooltip');
                 const existing = document.querySelector('.weapon-toggle-container');
            if (tip) {
                 if (!existing) {
                tip.setAttribute('aria-hidden', 'true');
                     observeCharacterHeader();
                tip.style.opacity = '0';
                tip.style.left = '-9999px';
                tip.style.top = '-9999px';
            } iconsBar.innerHTML = '';
            items.forEach((it, idx) => {
                const node = document.createElement('div');
                node.className = 'skill-icon';
                node.dataset.nome = it.name || '';
                if (it.index) node.dataset.index = it.index;
                if (it.level) node.dataset.level = it.level;
                if (it.desc) node.dataset.desc = it.desc;
                if (it.descPt) node.dataset.descPt = it.descPt;
                if (it.descEn) node.dataset.descEn = it.descEn;
                if (it.descEs) node.dataset.descEs = it.descEs;
                if (it.descPl) node.dataset.descPl = it.descPl;
                if (it.attrs) node.dataset.atr = it.attrs;
                if (it.video) node.dataset.video = it.video;
                if (it.subs) node.dataset.subs = JSON.stringify(it.subs);
                if (it.subattrsStr) node.dataset.subattrs = it.subattrsStr;
                if (it.flags) node.dataset.flags = JSON.stringify(it.flags);
                if (it.weapon) node.dataset.weapon = JSON.stringify(it.weapon);
                if (!it.index) node.dataset.nested = '1';
                const img = document.createElement('img');
                img.alt = '';
                img.src = it.iconURL || (it.icon ? filePathURL(it.icon) : '');
                img.decoding = 'async';
                img.loading = 'lazy';
                img.width = 50;
                img.height = 50;
                node.appendChild(img);
                iconsBar.appendChild(node);
            });
            animateIconsBarEntrance();
            wireClicksForCurrentBar();
             // Remove qualquer toggle antigo que possa aparecer
            const oldToggle = iconsBar.querySelector('.weapon-bar-toggle');
            if (oldToggle) oldToggle.remove();
            // Reaplica classes de weapon após renderizar barra
             reapplyWeaponClassesToBar();
            const b = ensureBackButton();
            if (b) b.classList.add('peek');
            // Atualiza a posição do botão back após a barra ser renderizada
            requestAnimationFrame(() => {
                 const backWrap = document.querySelector('.skills-back-wrapper');
                 if (backWrap && backWrap.style.display !== 'none') {
                     const rail = iconsBar.closest('.top-rail.skills');
                    const wrap = rail ? rail.parentElement : null;
                    if (rail && wrap && wrap.classList.contains('skills-rail-wrap')) {
                        const railRect = rail.getBoundingClientRect();
                        const wrapRect = wrap.getBoundingClientRect();
                        const railLeft = railRect.left - wrapRect.left;
                        // Posiciona na borda esquerda do rail (botão fica atrás com translateX)
                        backWrap.style.left = railLeft + 'px';
                    }
                 }
                 }
             });
             }, 1000);
        } function pushSubBarFrom(subs, parentIconEl) {
 
            const tip = document.querySelector('.skill-tooltip');
             // Remove qualquer toggle antigo que apareça nas barras de skills/subskills
            if (tip) {
             function removeOldToggles() {
                tip.setAttribute('aria-hidden', 'true');
                 document.querySelectorAll('.weapon-bar-toggle').forEach(toggle => {
                tip.style.opacity = '0';
                     toggle.remove();
                tip.style.left = '-9999px';
                tip.style.top = '-9999px';
            } const parentNameSnapshot = parentIconEl ? (parentIconEl.dataset.nome || parentIconEl.dataset.name || '') : '';
            const parentIndexSnapshot = parentIconEl ? (parentIconEl.dataset.index || '') : '';
            barStack.push({
                items: snapshotCurrentBarItemsFromDOM(), parentIcon: parentIconEl, parentName: parentNameSnapshot, parentIndex: parentIndexSnapshot
            });
            ensureBackButton();
            const langKey = getLangKey();
            let cacheKey = null;
            if (parentIconEl) {
                cacheKey = parentIconEl.dataset.subCacheKey || null;
                if (!cacheKey) {
                    if (parentIconEl.dataset.index) {
                        cacheKey = `idx:${parentIconEl.dataset.index}`;
                    } else {
                        const slug = slugify(parentIconEl.dataset.nome || parentIconEl.dataset.name || '');
                        if (slug) cacheKey = `slug:${slug}`;
                    } if (cacheKey) parentIconEl.dataset.subCacheKey = cacheKey;
                }
             } if (cacheKey) {
                const cached = subBarTemplateCache.get(cacheKey);
                if (cached && cached.lang === langKey) {
                    iconsBar.innerHTML = '';
                    const clone = cached.template.cloneNode(true);
                    iconsBar.appendChild(clone);
                    animateIconsBarEntrance();
                    wireClicksForCurrentBar();
                    // Remove qualquer toggle antigo que possa aparecer
                    const oldToggle2 = iconsBar.querySelector('.weapon-bar-toggle');
                    if (oldToggle2) oldToggle2.remove();
                    // Reaplica classes de weapon após renderizar do cache
                    reapplyWeaponClassesToBar();
                    const cachedBtn = ensureBackButton();
                    if (cachedBtn) cachedBtn.classList.add('peek');
                    return;
                }
            } const skillsRoot = document.getElementById('skills');
            const i18nMap = skillsRoot ? JSON.parse(skillsRoot.dataset.i18nAttrs || '{}') : {
            };
            const L = i18nMap[getLangKey()] || i18nMap.pt || {
                cooldown: 'Recarga', energy_gain: 'Ganho de energia', energy_cost: 'Custo de energia', power: 'Poder', power_pvp: 'Poder PvP', level: 'Nível'
            };
            const hydratedSubs = inheritSubskillTree(subs, mainSkillsMeta);
            const items = (hydratedSubs || []).filter(s => {
                // Filtra só se não tem nada útil
                const hasName = (s.name || s.n || '').trim() !== '';
                const hasIcon = (s.icon || '').trim() !== '' && s.icon !== 'Nada.png';
                const hasRef = (s.refS || s.refM || '').toString().trim() !== '';
                return hasName || hasIcon || hasRef;
             }).map(s => {
                const name = (s.name || s.n || '').trim();
                const desc = chooseDescFrom(s).replace(/'''(.*?)'''/g, '<b>$1</b>');
                const attrsHTML = renderSubAttributesFromObj(s, L);
                return {
                    name, level: (s.level || '').toString().trim(), desc, descPt: (s.descPt || (s.desc_i18n && s.desc_i18n.pt) || ''), descEn: (s.descEn || (s.desc_i18n && s.desc_i18n.en) || ''), descEs: (s.descEs || (s.desc_i18n && s.desc_i18n.es) || ''), descPl: (s.descPl || (s.desc_i18n && s.desc_i18n.pl) || ''), attrs: '', icon: (s.icon || ''), iconURL: (s.icon && s.icon !== 'Nada.png' && s.icon.toLowerCase() !== 'nada.png') ? filePathURL(s.icon) : '', video: s.video ? filePathURL(s.video) : '', subs: Array.isArray(s.subs) ? s.subs : null, subattrs: s, flags: Array.isArray(s.flags) ? s.flags : null, back: (s.back === true || s.back === 'true' || s.back === 'yes' || s.back === '1') ? 'true' : null, weapon: s.weapon || null
                };
            });
            const fragment = document.createDocumentFragment();
            items.forEach((it, iIdx) => {
                const node = document.createElement('div');
                node.className = 'skill-icon';
                node.dataset.nested = '1';
                node.dataset.nome = it.name || '';
                node.dataset.parentIndex = parentIndexSnapshot;
                node.dataset.subName = it.name || '';
                const subSlug = slugify(it.name || '');
                if (subSlug) node.dataset.slug = subSlug;
                if (it.level) node.dataset.level = it.level;
                if (it.desc) node.dataset.desc = it.desc;
                if (it.descPt) node.dataset.descPt = it.descPt;
                if (it.descEn) node.dataset.descEn = it.descEn;
                if (it.descEs) node.dataset.descEs = it.descEs;
                if (it.descPl) node.dataset.descPl = it.descPl;
                if (it.video) node.dataset.video = it.video;
                if (it.subs) node.dataset.subs = JSON.stringify(it.subs);
                if (it.subattrs) node.dataset.subattrs = JSON.stringify(it.subattrs);
                if (it.flags) node.dataset.flags = JSON.stringify(it.flags);
                if (it.back) node.dataset.back = it.back;
                if (it.weapon) {
                    try {
                        node.dataset.weapon = JSON.stringify(it.weapon);
                    } catch (e) {
                        console.error('[Skills] Erro ao serializar weapon de subskill', it.name, e);
                    }
                }
                 const img = document.createElement('img');
                img.alt = '';
                img.src = it.iconURL;
                img.decoding = 'async';
                img.loading = 'lazy';
                img.width = 50;
                img.height = 50;
                node.appendChild(img);
                fragment.appendChild(node);
            });
            const templateClone = fragment.cloneNode(true);
            iconsBar.innerHTML = '';
            iconsBar.appendChild(fragment);
            animateIconsBarEntrance();
            wireClicksForCurrentBar();
            // Remove qualquer toggle antigo que possa aparecer
            const oldToggle3 = iconsBar.querySelector('.weapon-bar-toggle');
            if (oldToggle3) oldToggle3.remove();
            // Reaplica classes de weapon após renderizar subskills
            reapplyWeaponClassesToBar();
            const b2 = ensureBackButton();
            if (b2) b2.classList.add('peek');
            // Atualiza a posição do botão back após subskills serem renderizadas
            requestAnimationFrame(() => {
                const backWrap = document.querySelector('.skills-back-wrapper');
                if (backWrap && backWrap.style.display !== 'none') {
                     const rail = iconsBar.closest('.top-rail.skills');
                    const wrap = rail ? rail.parentElement : null;
                    if (rail && wrap && wrap.classList.contains('skills-rail-wrap')) {
                        const railRect = rail.getBoundingClientRect();
                        const wrapRect = wrap.getBoundingClientRect();
                        const railLeft = railRect.left - wrapRect.left;
                        // Posiciona na borda esquerda do rail (botão fica atrás com translateX)
                        backWrap.style.left = railLeft + 'px';
                    }
                }
            });
            if (cacheKey) {
                subBarTemplateCache.set(cacheKey, {
                    template: templateClone, lang: langKey
                 });
                 });
             }
             }
        } window.addEventListener('gla:langChanged', () => {
 
             subBarTemplateCache.clear();
             // Observa mudanças nas barras de ícones para remover toggles antigos
             const skillsRoot = document.getElementById('skills');
             const iconBarObserver = new MutationObserver(() => {
            const i18nMap = skillsRoot ? JSON.parse(skillsRoot.dataset.i18nAttrs || '{}') : {
                 removeOldToggles();
            };
            const lang = getLangKey();
            Array.from(iconsBar.querySelectorAll('.skill-icon')).forEach(icon => {
                 const pack = {
                    pt: icon.dataset.descPt || '', en: icon.dataset.descEn || '', es: icon.dataset.descEs || '', pl: icon.dataset.descPl || ''
                };
                const chosen = (pack[lang] || pack.pt || pack.en || pack.es || pack.pl || icon.dataset.desc || '').trim();
                if (chosen) icon.dataset.desc = chosen;
             });
             });
             barStack.forEach(frame => {
 
                 (frame.items || []).forEach(it => {
            // Observa todas as barras de ícones existentes e futuras
                     const pack = {
             const observeAllIconBars = () => {
                        pt: it.descPt, en: it.descEn, es: it.descEs, pl: it.descPl
                 document.querySelectorAll('.icon-bar').forEach(bar => {
                    };
                     iconBarObserver.observe(bar, { childList: true, subtree: true });
                    const chosen = (pack[lang] || pack.pt || pack.en || pack.es || pack.pl || it.desc || '');
                    it.desc = chosen;
                 });
                 });
             });
             };
            if (descBox) {
 
                applyFlagTooltips(descBox);
             // Remove toggles antigos imediatamente
             } const activeIcon = window.__lastActiveSkillIcon;
             removeOldToggles();
             if (activeIcon && activeIcon.dataset.weapon) {
                activateSkill(activeIcon, {
                    openSubs: false
                });
            }
        });
        wireClicksForCurrentBar();
        const b0 = ensureBackButton();
        if (b0) {
            b0.classList.add('peek');
            b0.style.alignSelf = 'stretch';
        }


        // Move inicialização de tooltip para requestIdleCallback (não crítico)
             // Observa barras existentes
        if ('requestIdleCallback' in window) {
             observeAllIconBars();
            requestIdleCallback(() => {
                (function initSkillTooltip() {
                    if (document.querySelector('.skill-tooltip')) return;
                    const tip = document.createElement('div');
                    tip.className = 'skill-tooltip';
                    tip.setAttribute('role', 'tooltip');
                    tip.setAttribute('aria-hidden', 'true');
                    document.body.appendChild(tip);
                    const lockUntilRef = {
                        value: 0
                    };
                    function measureAndPos(el) {
                        if (!el || tip.getAttribute('aria-hidden') === 'true') return;
                        tip.style.left = '0px';
                        tip.style.top = '0px';
                        const rect = el.getBoundingClientRect();
                        const tr = tip.getBoundingClientRect();
                        let left = Math.round(rect.left + (rect.width - tr.width) / 2);
                        left = Math.max(8, Math.min(left, window.innerWidth - tr.width - 8));
                        const coarse = (window.matchMedia && matchMedia('(pointer: coarse)').matches) || (window.innerWidth <= 600);
                        let top = coarse ? Math.round(rect.bottom + 10) : Math.round(rect.top - tr.height - 8);
                        if (top < 8) top = Math.round(rect.bottom + 10);
                        tip.style.left = left + 'px';
                        tip.style.top = top + 'px';
                    } function show(el, text) {
                        tip.textContent = text || '';
                        tip.setAttribute('aria-hidden', 'false');
                        measureAndPos(el);
                        tip.style.opacity = '1';
                    } function hide() {
                        tip.setAttribute('aria-hidden', 'true');
                        tip.style.opacity = '0';
                        tip.style.left = '-9999px';
                        tip.style.top = '-9999px';
                    } window.__globalSkillTooltip = {
                        show, hide, measureAndPos, lockUntil: lockUntilRef
                    };
                    Array.from(document.querySelectorAll('.icon-bar .skill-icon')).forEach(icon => {
                        if (icon.dataset.weaponToggle === '1' || icon.classList.contains('weapon-bar-toggle')) return;
                        if (icon.dataset.tipwired) return;
                        icon.dataset.tipwired = '1';
                        const label = icon.dataset.nome || icon.dataset.name || icon.title || '';
                        if (label && !icon.hasAttribute('aria-label')) icon.setAttribute('aria-label', label);
                        if (icon.hasAttribute('title')) icon.removeAttribute('title');
                        const img = icon.querySelector('img');
                        if (img) {
                            const imgAlt = img.getAttribute('alt') || '';
                            const imgTitle = img.getAttribute('title') || '';
                            if (!label && (imgAlt || imgTitle)) icon.setAttribute('aria-label', imgAlt || imgTitle);
                            img.setAttribute('alt', '');
                            if (img.hasAttribute('title')) img.removeAttribute('title');
                        } icon.addEventListener('mouseenter', () => show(icon, label));
                        icon.addEventListener('mousemove', () => {
                            if (performance.now() >= lockUntilRef.value) measureAndPos(icon);
                        });
                        icon.addEventListener('click', () => {
                            lockUntilRef.value = performance.now() + 240;
                            measureAndPos(icon);
                        });
                        icon.addEventListener('mouseleave', hide);
                    });
                    Array.from(document.querySelectorAll('.subskills-rail .subicon')).forEach(sub => {
                        if (sub.dataset.tipwired) return;
                        sub.dataset.tipwired = '1';
                        const label = sub.getAttribute('title') || sub.getAttribute('aria-label') || '';
                        if (label && !sub.hasAttribute('aria-label')) sub.setAttribute('aria-label', label);
                        if (sub.hasAttribute('title')) sub.removeAttribute('title');
                        sub.addEventListener('mouseenter', () => show(sub, label));
                        sub.addEventListener('mousemove', () => {
                            if (performance.now() >= lockUntilRef.value) measureAndPos(sub);
                        });
                        sub.addEventListener('click', () => {
                            lockUntilRef.value = performance.now() + 240;
                            measureAndPos(sub);
                        });
                        sub.addEventListener('mouseleave', hide);
                    });
                    window.addEventListener('scroll', () => {
                        const visible = document.querySelector('.skill-tooltip[aria-hidden="false"]');
                        if (!visible) return;
                        const target = document.querySelector('.subskills-rail .subicon:hover') || document.querySelector('.subskills-rail .subicon.active') || document.querySelector('.icon-bar .skill-icon:hover') || document.querySelector('.icon-bar .skill-icon.active');
                        measureAndPos(target);
                    }, true);
                    window.addEventListener('resize', () => {
                        const target = document.querySelector('.subskills-rail .subicon:hover') || document.querySelector('.subskills-rail .subicon.active') || document.querySelector('.icon-bar .skill-icon:hover') || document.querySelector('.icon-bar .skill-icon.active');
                        measureAndPos(target);
                    });
                })();
            }, { timeout: 2000 });
        } else {
             // Fallback para navegadores sem requestIdleCallback
             setTimeout(() => {
                (function initSkillTooltip() {
                    if (document.querySelector('.skill-tooltip')) return;
                    const tip = document.createElement('div');
                    tip.className = 'skill-tooltip';
                    tip.setAttribute('role', 'tooltip');
                    tip.setAttribute('aria-hidden', 'true');
                    document.body.appendChild(tip);
                    window.__globalSkillTooltip = {
                        show: (el, text) => {
                            if (!el || !text) return;
                            tip.textContent = text;
                            tip.setAttribute('aria-hidden', 'false');
                            measureAndPos(el);
                        },
                        hide: () => {
                            tip.setAttribute('aria-hidden', 'true');
                            tip.style.left = '-9999px';
                            tip.style.top = '-9999px';
                        },
                        measureAndPos: (el) => {
                            if (!el || tip.getAttribute('aria-hidden') === 'true') return;
                            const rect = el.getBoundingClientRect();
                            const tipRect = tip.getBoundingClientRect();
                            let left = rect.left + (rect.width / 2) - (tipRect.width / 2);
                            let top = rect.top - tipRect.height - 8;
                            if (left < 8) left = 8;
                            if (left + tipRect.width > window.innerWidth - 8) left = window.innerWidth - tipRect.width - 8;
                            if (top < 8) top = rect.bottom + 8;
                            tip.style.left = left + 'px';
                            tip.style.top = top + 'px';
                        },
                        lockUntil: { value: 0 }
                    };
                    const { measureAndPos } = window.__globalSkillTooltip;
                    window.addEventListener('scroll', () => {
                        const visible = document.querySelector('.skill-tooltip[aria-hidden="false"]');
                        if (!visible) return;
                        const target = document.querySelector('.subskills-rail .subicon:hover') || document.querySelector('.subskills-rail .subicon.active') || document.querySelector('.icon-bar .skill-icon:hover') || document.querySelector('.icon-bar .skill-icon.active');
                        measureAndPos(target);
                    }, true);
                    window.addEventListener('resize', () => {
                        const target = document.querySelector('.subskills-rail .subicon:hover') || document.querySelector('.subskills-rail .subicon.active') || document.querySelector('.icon-bar .skill-icon:hover') || document.querySelector('.icon-bar .skill-icon.active');
                        measureAndPos(target);
                    });
                })();
            }, 100);
        }


        (function initTabs() {
             // Observa criação de novas barras
            const tabs = Array.from(document.querySelectorAll('.tab-btn'));
             const bodyObserver = new MutationObserver((mutations) => {
             if (!tabs.length) return;
                 mutations.forEach((mutation) => {
             const contents = Array.from(document.querySelectorAll('.tab-content'));
                     mutation.addedNodes.forEach((node) => {
            const characterBox = document.querySelector('.character-box');
                         if (node.nodeType === 1) {
            let wrapper = characterBox.querySelector('.tabs-height-wrapper');
                             if (node.classList && node.classList.contains('icon-bar')) {
            if (!wrapper) {
                                iconBarObserver.observe(node, { childList: true, subtree: true });
                 wrapper = document.createElement('div');
                                removeOldToggles();
                wrapper.className = 'tabs-height-wrapper';
                            } else if (node.querySelector && node.querySelector('.icon-bar')) {
                contents.forEach(c => {
                                observeAllIconBars();
                    wrapper.appendChild(c);
                                 removeOldToggles();
                });
                const tabsElement = characterBox.querySelector('.character-tabs');
                if (tabsElement && tabsElement.nextSibling) {
                    characterBox.insertBefore(wrapper, tabsElement.nextSibling);
                } else {
                    characterBox.appendChild(wrapper);
                }
            } async function smoothHeightTransition(fromTab, toTab) {
                if (!wrapper) return Promise.resolve();
                const scrollY = window.scrollY;
                const currentHeight = wrapper.getBoundingClientRect().height;
                await new Promise((resolve) => {
                     const videoContainers = toTab.querySelectorAll('.video-container');
                    const contentCard = toTab.querySelector('.content-card');
                    if (videoContainers.length === 0) {
                        requestAnimationFrame(() => {
                            requestAnimationFrame(() => {
                                requestAnimationFrame(() => resolve());
                            });
                        });
                        return;
                    } let lastHeight = 0;
                    let stableCount = 0;
                    const checksNeeded = 3;
                    let totalChecks = 0;
                    const maxChecks = 15;
                    function checkStability() {
                        totalChecks++;
                        const currentTabHeight = toTab.scrollHeight;
                         if (Math.abs(currentTabHeight - lastHeight) < 5) {
                            stableCount++;
                        } else {
                            stableCount = 0;
                        } lastHeight = currentTabHeight;
                        if (stableCount >= checksNeeded || totalChecks >= maxChecks) {
                             resolve();
                        } else {
                            setTimeout(checkStability, 50);
                        }
                    } setTimeout(checkStability, 50);
                });
                const nextHeight = toTab.getBoundingClientRect().height;
                const finalHeight = Math.max(nextHeight, 100);
                if (Math.abs(finalHeight - currentHeight) < 30) {
                    wrapper.style.height = '';
                    return Promise.resolve();
                } wrapper.style.overflow = 'hidden';
                wrapper.style.height = currentHeight + 'px';
                wrapper.offsetHeight;
                wrapper.style.transition = 'height 0.3s cubic-bezier(0.4, 0, 0.2, 1)';
                requestAnimationFrame(() => {
                    wrapper.style.height = finalHeight + 'px';
                });
                return new Promise(resolve => {
                    setTimeout(() => {
                        wrapper.style.height = '';
                        wrapper.style.transition = '';
                        wrapper.style.overflow = '';
                        resolve();
                    }, 320);
                });
            } tabs.forEach(btn => {
                if (btn.dataset.wiredTab) return;
                btn.dataset.wiredTab = '1';
                btn.addEventListener('click', () => {
                    const target = btn.getAttribute('data-tab');
                    const currentActive = contents.find(c => c.classList.contains('active'));
                    const nextActive = contents.find(c => c.id === target);
                    if (currentActive === nextActive) return;
                    document.body.classList.add('transitioning-tabs');
                    if (currentActive) {
                        currentActive.style.opacity = '0';
                        currentActive.style.transform = 'translateY(-8px)';
                    } setTimeout(async () => {
                        contents.forEach(c => {
                            if (c !== nextActive) {
                                 c.style.display = 'none';
                                c.classList.remove('active');
                             }
                             }
                        });
                        tabs.forEach(b => b.classList.toggle('active', b === btn));
                        if (nextActive) {
                            nextActive.classList.add('active');
                            nextActive.style.display = 'block';
                            nextActive.style.opacity = '0';
                            nextActive.style.visibility = 'hidden';
                            nextActive.offsetHeight;
                            try {
                                if (target === 'skills') {
                                    const tabEl = document.getElementById(target);
                                    if (tabEl) {
                                        const activeIcon = tabEl.querySelector('.icon-bar .skill-icon.active');
                                        const firstIcon = tabEl.querySelector('.icon-bar .skill-icon');
                                        const toClick = activeIcon || firstIcon;
                                        if (toClick) {
                                            const had = document.body.dataset.suppressSkillPlay;
                                            document.body.dataset.suppressSkillPlay = '1';
                                            toClick.click();
                                            if (had) document.body.dataset.suppressSkillPlay = had;
                                        }
                                    }
                                }
                            } catch (e) {
                            }
                        } if (currentActive && nextActive) {
                            await smoothHeightTransition(currentActive, nextActive);
                        } if (nextActive) {
                            nextActive.style.visibility = '';
                            nextActive.style.transform = 'translateY(12px)';
                            requestAnimationFrame(() => {
                                nextActive.style.opacity = '1';
                                nextActive.style.transform = 'translateY(0)';
                                setTimeout(() => {
                                    nextActive.style.opacity = '';
                                    nextActive.style.transform = '';
                                    document.body.classList.remove('transitioning-tabs');
                                    try {
                                        delete document.body.dataset.suppressSkillPlay;
                                    } catch {
                                    }
                                }, 300);
                            });
                         }
                         }
                     }, 120);
                     });
                    setTimeout(() => {
                        syncDescHeight();
                        if (target === 'skins') {
                            videosCache.forEach(v => {
                                try {
                                    v.pause();
                                } catch (e) {
                                } v.style.display = 'none';
                            });
                            if (videoBox) {
                                videoBox.querySelectorAll('video.skill-video').forEach(v => {
                                    try {
                                        v.pause();
                                    } catch (e) {
                                    } v.style.display = 'none';
                                });
                            } if (window.__subskills) window.__subskills.hideAll?.(videoBox);
                            const placeholder = videoBox?.querySelector('.video-placeholder');
                            if (videoBox && placeholder) {
                                placeholder.style.display = 'none';
                                placeholder.classList.add('fade-out');
                            }
                        } else {
                            const activeIcon = document.querySelector('.icon-bar .skill-icon.active');
                            if (activeIcon) activeIcon.click();
                        }
                    }, 450);
                 });
                 });
             });
             });
        })();
 
        (function initSkinsArrows() {
             bodyObserver.observe(document.body, { childList: true, subtree: true });
            const carousel = $('.skins-carousel');
 
            const wrapper = $('.skins-carousel-wrapper');
             // Escuta mudanças no estado do weapon para atualizar visual
            const left = $('.skins-arrow.left');
             window.addEventListener('gla:weaponToggled', () => {
            const right = $('.skins-arrow.right');
                 setTimeout(updateToggleVisualState, 50);
            if (!carousel || !left || !right || !wrapper) return;
            if (wrapper.dataset.wired) return;
            wrapper.dataset.wired = '1';
            const scrollAmt = () => Math.round(carousel.clientWidth * 0.6);
            function setState() {
                const max = carousel.scrollWidth - carousel.clientWidth;
                const x = carousel.scrollLeft;
                const hasLeft = x > 5, hasRight = x < max - 5;
                left.style.display = hasLeft ? 'inline-block' : 'none';
                right.style.display = hasRight ? 'inline-block' : 'none';
                wrapper.classList.toggle('has-left', hasLeft);
                wrapper.classList.toggle('has-right', hasRight);
                carousel.style.justifyContent = (!hasLeft && !hasRight) ? 'center' : '';
            } function go(dir) {
                const max = carousel.scrollWidth - carousel.clientWidth;
                const next = dir < 0 ? Math.max(0, carousel.scrollLeft - scrollAmt()) : Math.min(max, carousel.scrollLeft + scrollAmt());
                carousel.scrollTo({
                    left: next, behavior: 'smooth'
                });
             } left.addEventListener('click', () => go(-1));
            right.addEventListener('click', () => go(1));
            carousel.addEventListener('scroll', setState);
            new ResizeObserver(setState).observe(carousel);
            setState();
        })();
        function renderAttributes(str) {
            const skillsRoot = document.getElementById('skills');
            const i18nMap = skillsRoot ? JSON.parse(skillsRoot.dataset.i18nAttrs || '{}') : {
            };
            const langRaw = (document.documentElement.lang || skillsRoot?.dataset.i18nDefault || 'pt').toLowerCase();
            const langKey = i18nMap[langRaw] ? langRaw : (i18nMap[langRaw.split('-')[0]] ? langRaw.split('-')[0] : 'pt');
            const L = i18nMap[langKey] || i18nMap.pt || {
                cooldown: 'Recarga', energy_gain: 'Ganho de energia', energy_cost: 'Custo de energia', power: 'Poder', power_pvp: 'Poder PvP', level: 'Nível'
            };
            const vals = (str || '').split(',').map(v => v.trim());
            // Processa valores, tratando strings vazias como NaN
            // IMPORTANTE: ordem fixa é [powerpve, powerpvp, energy, cooldown]
            const pve = (vals[0] && vals[0] !== '') ? parseFloat(vals[0]) : NaN;
            const pvp = (vals[1] && vals[1] !== '') ? parseFloat(vals[1]) : NaN;
            const ene = (vals[2] && vals[2] !== '') ? parseFloat(vals[2]) : NaN;
            const cd = (vals[3] && vals[3] !== '') ? parseFloat(vals[3]) : NaN;
            // Debug: log se houver problema na ordem
            if (str && str.includes(',') && !isNaN(cd) && !isNaN(pvp) && cd === pvp) {
                console.warn('[Skills] renderAttributes: possível problema na ordem dos atributos', { str, vals, pve, pvp, ene, cd });
            }
            const rows = [];
            // Ordem de exibição: cooldown, energy, power, power_pvp
            if (!isNaN(cd)) rows.push([L.cooldown, cd]);
            if (!isNaN(ene) && ene !== 0) {
                const label = ene > 0 ? L.energy_gain : L.energy_cost;
                rows.push([label, Math.abs(ene)]);
            }
            if (!isNaN(pve)) rows.push([L.power, pve]);
            if (!isNaN(pvp)) rows.push([L.power_pvp, pvp]);
             // Debug: log se houver valores suspeitos (desabilitado para performance)
            // if (str && str.includes(',')) {
             //    console.log('[Skills] renderAttributes processed', {
            //        str,
            //        vals: vals.slice(0, 4),
            //        parsed: { pve, pvp, ene, cd },
            //        rows: rows.map(r => r[0])
            //    });
            // }
            if (!rows.length) return '';
            const html = rows.map(([rowLabel, rowValue]) => `<div class="attr-row"><span class="attr-label">${rowLabel}</span><span class="attr-value">${rowValue}</span></div>`).join('');
            return `<div class="attr-list">${html}</div>`;
        } function syncDescHeight() {
        } window.addEventListener('resize', syncDescHeight);
        if (videoBox) new ResizeObserver(syncDescHeight).observe(videoBox);
        iconItems.forEach(el => {
            const wired = !!el.dataset._sync_wired;
            if (wired) return;
            el.dataset._sync_wired = '1';
            el.addEventListener('click', () => {
                 Promise.resolve().then(syncDescHeight);
             });
             });
        });
 
        if (iconsBar) {
             // Escuta mudanças de idioma
             const scrollWrapper = iconsBar.closest('.icon-scroll-x') || iconsBar.parentElement;
             window.addEventListener('gla:langChanged', () => {
             const scrollContainer = scrollWrapper && scrollWrapper.classList.contains('icon-scroll-x') ? scrollWrapper : iconsBar;
                 updateToggleVisualState();
            addOnce(scrollContainer, 'wheel', (e) => {
                 if (e.deltaY) {
                    e.preventDefault();
                    scrollContainer.scrollLeft += e.deltaY;
                }
             });
             });
            // Estado inicial do toggle
            let init = false;
            try {
                if (localStorage.getItem('glaWeaponEnabled') === '1') init = true;
            } catch (x) { }
            setTimeout(() => {
                applyWeaponState(init);
                updateToggleVisualState();
            }, 150);
        };
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', boot);
        } else {
            boot();
         }
         }
         wireClicksForCurrentBar();
    })();
         if (iconItems.length) {
</script>
            const first = iconItems[0];
<style>
            if (first) {
    /* Character-box precisa de position relative para conter o modal */
                activateSkill(first, {
    .character-box {
                    openSubs: false
        position: relative;
                });
    }
             }
 
    /* Modal posicionado dentro da character-box */
    .weapon-modal {
        position: absolute;
         inset: 0;
        z-index: 100;
        display: flex;
        align-items: center;
        justify-content: center;
        pointer-events: none;
    }
 
    .weapon-modal.show {
        pointer-events: all;
    }
 
    /* Overlay escurece apenas a character-box - aparece PRIMEIRO */
    .weapon-modal-overlay {
        position: absolute;
        inset: 0;
        background: rgba(0, 0, 0, .65);
        -webkit-backdrop-filter: blur(4px);
         backdrop-filter: blur(4px);
        opacity: 0;
        transition: opacity .15s ease;
    }
 
    .weapon-modal.show .weapon-modal-overlay {
        opacity: 1;
    }
 
    /* Conteúdo aparece DEPOIS do overlay */
    .weapon-modal-content {
        position: relative;
        z-index: 1;
        transform: scale(0.96);
        background: linear-gradient(145deg, #2d1a1a, #1e1212);
        border: 1px solid rgba(255, 100, 100, .2);
        border-radius: 14px;
        max-width: 420px;
        width: 90%;
        opacity: 0;
        transition: transform .18s ease .08s, opacity .15s ease .08s;
        overflow: hidden;
    }
 
    .weapon-modal.show .weapon-modal-content {
        transform: scale(1);
        opacity: 1;
    }
 
    .weapon-modal-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 16px 20px;
        border-bottom: 1px solid rgba(255, 100, 100, .12);
        background: linear-gradient(90deg, rgba(255, 80, 80, .06), transparent);
    }
 
    .weapon-modal-header h3 {
        margin: 0;
        font-size: 16px;
        font-weight: 600;
        color: #fff;
    }
 
    .weapon-modal-close {
        background: transparent;
        border: 1px solid rgba(255, 255, 255, .1);
        color: rgba(255, 255, 255, .5);
        font-size: 18px;
        font-family: Arial, sans-serif;
        line-height: 1;
        cursor: pointer;
        padding: 0;
        width: 28px;
        height: 28px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        text-align: center;
        border-radius: 6px;
        transition: background .15s, color .15s, border-color .15s;
    }
 
    .weapon-modal-close:hover {
        background: rgba(255, 80, 80, .15);
        border-color: rgba(255, 80, 80, .3);
        color: #FF7043;
    }
 
    .weapon-modal-body {
        padding: 20px;
        color: rgba(255, 255, 255, .85);
        line-height: 1.65;
        font-size: 14px;
    }
 
    .weapon-modal-body p {
        margin: 0 0 12px;
        display: block !important;
    }
 
    .weapon-modal-body p:last-child,
    .weapon-modal-body p.weapon-info-link {
        margin: 0;
    }
 
    .weapon-modal-body p.weapon-info-link:empty {
        display: none !important;
    }
 
    .weapon-modal-body strong {
        color: #FF7043;
        font-weight: 600;
    }
 
    .weapon-modal-body .weapon-info-link a {
        color: #FF7043;
        text-decoration: none;
        font-weight: 600;
    }
 
    .weapon-modal-body .weapon-info-link a:hover {
        text-decoration: underline;
    }
 
    .weapon-modal-footer {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 14px 20px;
        border-top: 1px solid rgba(255, 100, 100, .1);
        background: rgba(0, 0, 0, .1);
        gap: 12px;
    }
 
    .weapon-modal-checkbox {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        font-size: 12px;
        color: rgba(255, 255, 255, .5);
        cursor: pointer;
        transition: color .15s;
    }
 
    .weapon-modal-checkbox:hover {
        color: rgba(255, 255, 255, .75);
    }
 
    .weapon-modal-checkbox input[type="checkbox"] {
        accent-color: #FF5722;
        margin: 0;
        flex-shrink: 0;
    }
 
    .weapon-modal-checkbox span {
        line-height: 1;
    }
 
    .weapon-modal-btn {
        background: #BF360C;
        border: none;
        color: #fff;
        padding: 10px 24px;
        border-radius: 6px;
        font-weight: 600;
        font-size: 13px;
        line-height: 1;
        cursor: pointer;
        transition: background .15s;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }
 
    .weapon-modal-btn:hover {
        background: #D84315;
    }
 
    .weapon-modal-btn:active {
        background: #A52714;
    }
 
    @media (max-width: 600px) {
        .weapon-modal-content {
            width: 92%;
             max-width: none;
        }
 
        .weapon-modal-header,
        .weapon-modal-body,
        .weapon-modal-footer {
            padding: 14px 16px;
        }
 
        .weapon-modal-footer {
            flex-direction: column;
            gap: 12px;
        }
 
        .weapon-modal-btn {
            width: 100%;
         }
         }
    }
    /* =========================== NOVO WEAPON TOGGLE =========================== */
    .weapon-toggle-container {
        display: flex;
        align-items: center;
        z-index: 10;
        background: transparent;
        padding: 0;
        border-radius: 0;
        border: none;
        box-shadow: none;
        cursor: pointer;
        transition: transform .08s ease;
        overflow: visible;
        height: 44px;
        box-sizing: border-box;
    }
    .weapon-toggle-container:hover {
        transform: translateY(-1px);
    }


         // Aplica lazy loading em imagens fora do viewport inicial
    .weapon-toggle-sprite {
         (function applyLazyLoading() {
        width: 44px;
            if ('IntersectionObserver' in window) {
        height: 44px;
                const imageObserver = new IntersectionObserver((entries, observer) => {
        flex-shrink: 0;
                    entries.forEach(entry => {
        border-radius: 50%;
                        if (entry.isIntersecting) {
        overflow: visible;
                            const img = entry.target;
        position: relative;
                            if (img.tagName === 'IMG' && !img.hasAttribute('loading')) {
        background: rgb(40, 40, 48);
                                img.loading = 'lazy';
        border: 2px solid rgba(255, 255, 255, 0.15);
                            }
        display: flex;
                            observer.unobserve(img);
        align-items: center;
                        }
        justify-content: center;
                    });
        z-index: 2;
                });
        margin: 0;
        padding: 0;
        box-sizing: border-box;
        box-shadow: 0 4px 12px rgba(0, 0, 0, .4);
        transition: background-color 0.15s cubic-bezier(0.4, 0, 0.2, 1), border-color 0.15s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.15s cubic-bezier(0.4, 0, 0.2, 1);
        will-change: background-color;
    }
 
    .weapon-toggle-sprite img {
        width: 64px;
        height: 64px;
        display: block;
         /* Força redimensionamento pixelado (nearest neighbor) - ordem importante */
         -ms-interpolation-mode: nearest-neighbor;
        /* IE/Edge antigo - deve vir primeiro */
        image-rendering: -moz-crisp-edges;
        /* Firefox */
        image-rendering: -webkit-optimize-contrast;
        /* Safari/Chrome antigo */
        image-rendering: pixelated;
        /* Chrome/Edge moderno */
        image-rendering: crisp-edges !important;
        /* Fallback padrão - força sem suavização */
        /* Garante que não há suavização por transform ou filter */
        transform: translateZ(0);
        backface-visibility: hidden;
        /* Mantém proporção sem suavização */
        object-fit: contain;
        object-position: center;
        /* Força renderização sem suavização - importante para sprites pixelados */
        -webkit-font-smoothing: none;
        font-smoothing: none;
    }
 
    .weapon-toggle-bar {
        background: rgb(40, 40, 48);
        padding: 5px 14px 5px 28px;
        border-radius: 0 7px 7px 0;
        border: 2px solid rgba(255, 255, 255, 0.15);
        border-left: none;
        display: flex;
        align-items: center;
        width: 180px;
        position: relative;
        overflow: hidden;
        margin: 0;
        margin-left: -22px;
        height: 34px;
        box-sizing: border-box;
        box-shadow: 0 4px 12px rgba(0, 0, 0, .4);
        transition: background-color 0.15s cubic-bezier(0.4, 0, 0.2, 1), background-image 0.15s cubic-bezier(0.4, 0, 0.2, 1), border-color 0.15s cubic-bezier(0.4, 0, 0.2, 1);
        will-change: background-color, background-image;
    }
 
    .weapon-toggle-name {
        color: #fff;
        font-size: 14px;
        font-weight: 600;
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
        position: relative;
        z-index: 2;
        letter-spacing: 0.3px;
        display: inline-block;
    }
 
    /* Textos i18n - usando ::after para mostrar o texto baseado no data-lang e estado */
    .weapon-toggle-name::after {
        content: "Equipar Arma";
        /* Default PT */
    }
 
    .weapon-toggle-name[data-lang="pt"]::after {
        content: "Equipar Arma";
    }
 
    .weapon-toggle-name[data-lang="en"]::after {
        content: "Equip Weapon";
    }
 
    .weapon-toggle-name[data-lang="es"]::after {
        content: "Equipar Arma";
    }
 
    .weapon-toggle-name[data-lang="pl"]::after {
        content: "Wyposaż Broń";
    }
 
    /* Estado ATIVO (arma equipada) - muda o texto */
    .weapon-toggle-container.weapon-active .weapon-toggle-name::after {
        content: "Desequipar Arma";
        /* Default PT */
    }
 
    .weapon-toggle-container.weapon-active .weapon-toggle-name[data-lang="pt"]::after {
        content: "Desequipar Arma";
    }
 
    .weapon-toggle-container.weapon-active .weapon-toggle-name[data-lang="en"]::after {
        content: "Unequip Weapon";
    }
 
    .weapon-toggle-container.weapon-active .weapon-toggle-name[data-lang="es"]::after {
        content: "Desequipar Arma";
    }
 
    .weapon-toggle-container.weapon-active .weapon-toggle-name[data-lang="pl"]::after {
        content: "Zdjęć Broń";
    }
 
    /* Estado ativo - destaque vermelho */
    .weapon-toggle-container.weapon-active .weapon-toggle-sprite {
        background-color: rgb(200, 60, 40) !important;
        border: 2px solid rgba(255, 255, 255, 0.15);
        box-shadow: 0 4px 12px rgba(0, 0, 0, .4);
    }


                // Observa imagens que não estão no viewport inicial
    .weapon-toggle-container.weapon-active .weapon-toggle-bar {
                document.querySelectorAll('img:not(.topbar-icon):not([loading])').forEach(img => {
        background-color: rgb(200, 60, 40);
                    const rect = img.getBoundingClientRect();
        background-image: linear-gradient(135deg, rgb(200, 60, 40), rgb(160, 45, 30));
                    if (rect.bottom > window.innerHeight || rect.top < 0) {
        border-color: rgba(255, 87, 34, 0.3);
                        imageObserver.observe(img);
        border-left: none;
                    }
         border-radius: 0 7px 7px 0;
                });
    }
            }
         })();


        setTimeout(() => {
    .weapon-toggle-container.weapon-active .weapon-toggle-name {
            Array.from(document.querySelectorAll('.skill-icon')).forEach(el => {
        color: #fff;
            });
        text-shadow: 0 0 4px rgba(255, 87, 34, 0.5);
            videosCache.forEach((v, idx) => {
     }
                const src = v.querySelector('source') ? v.querySelector('source').src : v.src;
</style>
                v.addEventListener('error', (ev) => {
                });
                v.addEventListener('loadedmetadata', () => {
                });
            });
        }, 600);
     })();
</script>

Edição das 11h44min de 1 de janeiro de 2026

<script>

   (() => {
       let modalListenersBound = false;
       // Variável global para o ícone do weapon toggle
       let globalWeaponToggleIcon = null;
       // Função helper para construir URL de arquivo (mesmo sistema usado em Character.Skills.html)
       function filePathURL(fileName) {
           // Evita requisições para Nada.png que não existe
           if (!fileName || fileName.trim() ===  || fileName === 'Nada.png' || fileName.toLowerCase() === 'nada.png') {
               return ;
           }
           // Remove prefixos e decodifica se já estiver codificado (evita double encoding)
           let cleanName = fileName.replace(/^Arquivo:|^File:/, );
           try {
               // Tenta decodificar primeiro (caso já venha codificado como %27)
               cleanName = decodeURIComponent(cleanName);
           } catch (e) {
               // Se falhar, usa o nome original
           }
           // Agora codifica corretamente
           const f = encodeURIComponent(cleanName);
           const base = (window.mw && mw.util && typeof mw.util.wikiScript === 'function') ? mw.util.wikiScript() : (window.mw && window.mw.config ? (mw.config.get('wgScript') || '/index.php') : '/index.php');
           // Garante HTTPS para evitar Mixed Content
           let url = `${base}?title=Especial:FilePath/${f}`;
           if (window.location.protocol === 'https:' && url.startsWith('http://')) {
               url = url.replace('http://', 'https://');
           }
           return url;
       }
       // Função para resolver o ícone do weapon toggle do character-box
       function resolveCharacterWeaponIcon() {
           const root = document.querySelector('.character-box');
           if (!root) return;
           const raw = root.dataset.weaponicon;
           if (!raw || raw.trim() ===  || raw === 'Nada.png') {
               globalWeaponToggleIcon = null;
               return;
           }
           globalWeaponToggleIcon = filePathURL(raw.trim());
           // console.log('[WeaponToggle] Resolved weaponicon:', raw, '->', globalWeaponToggleIcon);
       }
       // Textos i18n para o popup
       const i18nTexts = {
           pt: {
               title: 'Visualização com Arma Especial',
               body1: 'Este modo ativa a visualização do personagem equipado com sua arma especial.',
               body2: 'Algumas habilidades são diferentes enquanto estão com a arma equipada, essas habilidades ficam destacadas com borda vermelha.',
               dontShow: 'Não mostrar novamente',
               ok: 'Entendi',
               weaponLink: 'Ver página da arma:'
           },
           en: {
               title: 'Special Weapon View',
               body1: 'This mode activates the view of the character equipped with their special weapon.',
               body2: 'Some abilities are different while equipped with the weapon, these abilities are highlighted with a red border.',
               dontShow: "Don't show again",
               ok: 'Got it',
               weaponLink: 'View weapon page:'
           },
           es: {
               title: 'Visualización con Arma Especial',
               body1: 'Este modo activa la visualización del personaje equipado con su arma especial.',
               body2: 'Algunas habilidades son diferentes mientras están con el arma equipada, estas habilidades quedan destacadas con borde rojo.',
               dontShow: 'No mostrar de nuevo',
               ok: 'Entendido',
               weaponLink: 'Ver página del arma:'
           },
           pl: {
               title: 'Widok z Bronią Specjalną',
               body1: 'Ten tryb aktywuje widok postaci wyposażonej w broń specjalną.',
               body2: 'Niektóre umiejętności różnią się podczas posiadania broni, te umiejętności są podświetlone czerwoną obwódką.',
               dontShow: 'Nie pokazuj ponownie',
               ok: 'Rozumiem',
               weaponLink: 'Zobacz stronę broni:'
           }
       };
       const getCurrentLang = () => {
           const html = document.documentElement.lang || 'pt-br';
           const norm = html.toLowerCase().split('-')[0];
           return i18nTexts[norm] ? norm : 'pt';
       };
       const bindModalEvents = () => {
           if (modalListenersBound) return;
           modalListenersBound = true;
           document.addEventListener('click', (ev) => {
               if (ev.target.closest('.weapon-modal-close') || ev.target.closest('.weapon-modal-btn')) {
                   const checkbox = document.getElementById('weapon-dont-show');
                   if (checkbox && checkbox.checked) {
                       try { localStorage.setItem('glaWeaponPopupDismissed', '1'); } catch (x) { }
                   }
                   hidePopup();
                   return;
               }
               if (ev.target.classList.contains('weapon-modal-overlay')) {
                   hidePopup();
               }
           });
       };
       const applyWeaponState = (enabled) => {
           if (typeof window.__setGlobalWeaponEnabled === 'function') {
               window.__setGlobalWeaponEnabled(enabled);
           }
           try {
               localStorage.setItem('glaWeaponEnabled', enabled ? '1' : '0');
           } catch (x) { }
           // Dispara evento para atualizar subskills
           window.dispatchEvent(new CustomEvent('gla:weaponToggled', { detail: { enabled } }));
           // SISTEMA UNIFICADO: Aplica toggle em skills E subskills
           // Skills principais e subskills usam data-weapon (padronizado)
           document.querySelectorAll('.skill-icon[data-weapon], .subicon[data-weapon]').forEach(el => {
               if (enabled) {
                   el.classList.add('has-weapon-available');
               } else {
                   el.classList.remove('has-weapon-available');
                   el.classList.remove('weapon-equipped');
                   el.style.removeProperty('--weapon-badge-url');
                   const ind = el.querySelector('.weapon-indicator');
                   if (ind) ind.remove();
               }
           });
           // Atualiza descrição da skill/subskill selecionada (se houver) para refletir estado da arma
           // Aguarda um pouco mais para garantir que o estado global foi sincronizado
           setTimeout(() => {
               // Atualiza skill principal se houver - força reativação completa incluindo vídeo
               const sel = document.querySelector('.skill-icon.active:not(.weapon-bar-toggle)');
               if (sel) {
                   // Força uma reativação completa da skill para garantir que vídeo seja atualizado
                   if (typeof window.__subskills !== 'undefined' && window.__subskills.hideAll) {
                       const videoBox = document.querySelector('.video-container') || document.querySelector('.skills-video-box');
                       if (videoBox) window.__subskills.hideAll(videoBox);
                   }
                   // Reativa a skill para atualizar vídeo, descrição e atributos
                   if (typeof window.__lastActiveSkillIcon !== 'undefined' && window.__lastActiveSkillIcon === sel) {
                       sel.dispatchEvent(new Event('click', { bubbles: true }));
                   } else {
                       sel.dispatchEvent(new Event('click', { bubbles: true }));
                   }
               }
               // Atualiza subskill ativa se houver - força reativação completa incluindo vídeo
               const activeSub = document.querySelector('.subicon.active');
               if (activeSub) {
                   activeSub.dispatchEvent(new Event('click', { bubbles: true }));
               }
           }, 100);
       };
       const updateModalTexts = (modal) => {
           const lang = getCurrentLang();
           const t = i18nTexts[lang];
           const title = modal.querySelector('.weapon-modal-header h3');
           if (title) title.textContent = t.title;
           const body = modal.querySelector('.weapon-modal-body');
           if (body) {
               const p1 = body.querySelector('p:first-child');
               const p2 = body.querySelector('p:nth-child(2)');
               if (p1) p1.innerHTML = t.body1;
               if (p2) p2.innerHTML = t.body2;
           }
           const checkbox = modal.querySelector('.weapon-modal-checkbox span');
           if (checkbox) checkbox.textContent = t.dontShow;
           const btn = modal.querySelector('.weapon-modal-btn');
           if (btn) btn.textContent = t.ok;
           // Atualiza link da arma se existir
           try {
               const firstWithWeapon = document.querySelector('.skill-icon[data-weapon]');
               if (firstWithWeapon) {
                   const raw = firstWithWeapon.getAttribute('data-weapon');
                   const obj = JSON.parse(raw || '{}');
                   const nm = (obj && obj.name) ? String(obj.name).trim() : ;
                   if (nm) {
                       const linkHost = (window.mw && mw.util && typeof mw.util.getUrl === 'function') ? mw.util.getUrl(nm) : ('/index.php?title=' + encodeURIComponent(nm));
                       const holder = modal.querySelector('.weapon-info-link');
                       if (holder) {
                           holder.style.display = 'block';
                           holder.innerHTML = `<a href="${linkHost}">${t.weaponLink} ${nm}</a>`;
                       }
                   }
               }
           } catch (_) { }
       };
       const ensureModal = () => {
           let modal = document.getElementById('weapon-info-modal');
           if (modal) {
               updateModalTexts(modal);
               return modal;
           }
           // Insere dentro da character-box para isolar completamente
           const container = document.querySelector('.character-box') || document.querySelector('#mw-content-text') || document.body;
           modal = document.createElement('div');
           modal.id = 'weapon-info-modal';
           modal.className = 'weapon-modal';
           modal.innerHTML = `

                   <button class="weapon-modal-close" type="button" aria-label="Fechar">×</button>

       `;
           container.appendChild(modal);
           updateModalTexts(modal);
           bindModalEvents();
           return modal;
       };
       const showPopup = () => {
           const modal = ensureModal();
           if (modal) {
               updateModalTexts(modal);
               // Força reflow antes de adicionar classe para garantir transição
               void modal.offsetHeight;
               modal.classList.add('show');
           }
       };
       const hidePopup = () => {
           const m = document.getElementById('weapon-info-modal');
           if (m) m.classList.remove('show');
       };
       window.__applyWeaponState = applyWeaponState;
       window.__glaWeaponShowPopup = showPopup;
       window.__glaWeaponHidePopup = hidePopup;
       try {
           window.dispatchEvent(new CustomEvent('weapon:ready', { detail: { applyWeaponState, showPopup, hidePopup } }));
       } catch (err) {
       }
       // Escuta mudanças de idioma
       window.addEventListener('gla:langChanged', () => {
           const modal = document.getElementById('weapon-info-modal');
           if (modal) updateModalTexts(modal);
       });
       // Função para obter o nome da arma
       function getWeaponName() {
           let weaponName = 'Arma Especial';
           try {
               const firstWithWeapon = document.querySelector('.skill-icon[data-weapon]');
               if (firstWithWeapon) {
                   const raw = firstWithWeapon.getAttribute('data-weapon');
                   const obj = JSON.parse(raw || '{}');
                   if (obj && obj.name) {
                       weaponName = String(obj.name).trim();
                   }
               }
           } catch (e) { }
           return weaponName;
       }
       // Função para criar o novo toggle abaixo do char-translator
       function createWeaponToggle() {
           // Remove toggle antigo se existir
           const oldToggle = document.querySelector('.weapon-bar-toggle');
           if (oldToggle) oldToggle.remove();
           const existingContainer = document.querySelector('.weapon-toggle-container');
           if (existingContainer) return existingContainer;
           const characterHeader = document.querySelector('.character-header');
           if (!characterHeader) return null;
           // Resolve o ícone
           resolveCharacterWeaponIcon();
           const weaponName = getWeaponName();
           // Cria o container do toggle
           const container = document.createElement('div');
           container.className = 'weapon-toggle-container';
           container.setAttribute('role', 'button');
           container.setAttribute('aria-pressed', 'false');
           container.setAttribute('aria-label', weaponName);
           // Cria o sprite (círculo com imagem)
           const sprite = document.createElement('div');
           sprite.className = 'weapon-toggle-sprite';
           if (globalWeaponToggleIcon) {
               const img = document.createElement('img');
               img.src = globalWeaponToggleIcon;
               img.alt = weaponName;
               img.className = 'weapon-toggle-icon';
               img.decoding = 'async';
               img.loading = 'eager'; // Ícone do toggle é crítico - carrega imediatamente
               img.onerror = function () {
                   // console.error('[WeaponToggle] Erro ao carregar imagem:', globalWeaponToggleIcon);
               };
               img.onload = function () {
                   // console.log('[WeaponToggle] Imagem carregada com sucesso:', globalWeaponToggleIcon);
               };
               sprite.appendChild(img);
           }
           // Cria a barra com texto
           const bar = document.createElement('div');
           bar.className = 'weapon-toggle-bar';
           const nameSpan = document.createElement('span');
           nameSpan.className = 'weapon-toggle-name';
           nameSpan.setAttribute('data-lang', getCurrentLang());
           bar.appendChild(nameSpan);
           container.appendChild(sprite);
           container.appendChild(bar);
           // Adiciona evento de clique
           container.addEventListener('click', () => {
               let currentState = false;
               try {
                   currentState = localStorage.getItem('glaWeaponEnabled') === '1';
               } catch (e) { }
               const nextState = !currentState;
               if (nextState) {
                   // Verifica se o popup foi dispensado antes de mostrar
                   let shouldShowPopup = true;
                   try {
                       if (localStorage.getItem('glaWeaponPopupDismissed') === '1') {
                           shouldShowPopup = false;
                       }
                   } catch (e) { }
                   if (shouldShowPopup && typeof window.__glaWeaponShowPopup === 'function') {
                       window.__glaWeaponShowPopup();
                   }
               }
               if (typeof window.__applyWeaponState === 'function') {
                   window.__applyWeaponState(nextState);
               }
           });
           // Insere no container de controles (character-header-controls)
           const controlsContainer = document.querySelector('.character-header-controls');
           if (controlsContainer) {
               controlsContainer.appendChild(container);
           } else {
               // Fallback: insere no character-header se o container não existir
               characterHeader.appendChild(container);
           }
           // Atualiza estado visual inicial
           updateToggleVisualState();
           return container;
       }
       // Função para atualizar o estado visual do toggle
       function updateToggleVisualState() {
           const container = document.querySelector('.weapon-toggle-container');
           if (!container) return;
           let isEnabled = false;
           try {
               isEnabled = localStorage.getItem('glaWeaponEnabled') === '1';
           } catch (e) { }
           if (isEnabled) {
               container.classList.add('weapon-active');
               container.setAttribute('aria-pressed', 'true');
           } else {
               container.classList.remove('weapon-active');
               container.setAttribute('aria-pressed', 'false');
           }
           // Atualiza idioma do texto
           const nameSpan = container.querySelector('.weapon-toggle-name');
           if (nameSpan) {
               nameSpan.setAttribute('data-lang', getCurrentLang());
           }
       }
       // Observa quando o container de controles é criado para posicionar o toggle
       function observeCharacterHeader() {
           const controlsContainer = document.querySelector('.character-header-controls');
           const characterHeader = document.querySelector('.character-header');
           if (controlsContainer) {
               // Container existe - cria o toggle imediatamente
               createWeaponToggle();
           } else if (characterHeader) {
               // Header existe mas container não - cria o container e depois o toggle
               const newContainer = document.createElement('div');
               newContainer.className = 'character-header-controls';
               characterHeader.appendChild(newContainer);
               // Aguarda um frame para garantir que o container foi adicionado
               requestAnimationFrame(() => {
                   createWeaponToggle();
               });
           } else {
               // Nada existe ainda - tenta novamente após um delay
               setTimeout(observeCharacterHeader, 100);
           }
       }
       // Observa mudanças no DOM para detectar quando o container de controles é criado
       function observeDOMForHeader() {
           const observer = new MutationObserver((mutations) => {
               mutations.forEach((mutation) => {
                   mutation.addedNodes.forEach((node) => {
                       if (node.nodeType === 1) {
                           if (node.classList && (node.classList.contains('character-header-controls') || node.classList.contains('character-header'))) {
                               setTimeout(() => createWeaponToggle(), 10);
                           } else if (node.querySelector && (node.querySelector('.character-header-controls') || node.querySelector('.character-header'))) {
                               setTimeout(() => createWeaponToggle(), 10);
                           }
                       }
                   });
               });
           });
           observer.observe(document.body, { childList: true, subtree: true });
       }
       const boot = () => {
           // Resolve o ícone do character antes de tudo
           resolveCharacterWeaponIcon();
           // Verificar se existe alguma skill ou subskill com arma
           function checkHasAnyWeapon() {
               // PRIORIDADE 1: Verifica se há weaponicon global no character-box
               const characterBox = document.querySelector('.character-box');
               if (characterBox && characterBox.dataset.weaponicon) {
                   const weaponIcon = characterBox.dataset.weaponicon.trim();
                   if (weaponIcon && weaponIcon !==  && weaponIcon !== 'Nada.png') {
                       return true;
                   }
               }
               // PRIORIDADE 2: Verifica skills principais
               const mainSkills = document.querySelectorAll('.skill-icon[data-weapon]');
               for (const el of mainSkills) {
                   const weapon = el.dataset.weapon;
                   if (weapon && weapon.trim() !==  && weapon !== '{}') {
                       try {
                           const weaponObj = JSON.parse(weapon);
                           if (weaponObj && typeof weaponObj === 'object' && Object.keys(weaponObj).length > 0) {
                               return true;
                           }
                       } catch (e) {
                           // Se não for JSON válido mas não está vazio, considera válido
                           return true;
                       }
                   }
               }
               // PRIORIDADE 3: Verifica weaponicon em skills principais
               const skillsWithWeaponIcon = document.querySelectorAll('.skill-icon[data-weaponicon]');
               for (const el of skillsWithWeaponIcon) {
                   const weaponIcon = el.dataset.weaponicon;
                   if (weaponIcon && weaponIcon.trim() !==  && weaponIcon !== 'Nada.png') {
                       return true;
                   }
               }
               // PRIORIDADE 4: Verifica subskills
               const skillIcons = document.querySelectorAll('.skill-icon[data-subs]');
               for (const el of skillIcons) {
                   try {
                       const subs = JSON.parse(el.getAttribute('data-subs') || '[]');
                       if (Array.isArray(subs) && subs.some(s => s && s.weapon && typeof s.weapon === 'object' && Object.keys(s.weapon).length > 0)) {
                           return true;
                       }
                   } catch (e) { }
               }
               return false;
           }
           const hasAnyWeapon = checkHasAnyWeapon();
           if (!hasAnyWeapon) {
               // Limpar estado visual para chars sem arma (previne cache entre páginas)
               const topRail = document.querySelector('.top-rail.skills');
               if (topRail) {
                   topRail.classList.remove('weapon-mode-on');
               }
               document.querySelectorAll('.skill-icon.has-weapon-available').forEach(el => {
                   el.classList.remove('has-weapon-available');
                   el.classList.remove('weapon-equipped');
                   el.style.removeProperty('--weapon-badge-url');
                   const ind = el.querySelector('.weapon-indicator');
                   if (ind) ind.remove();
               });
               // Remover toggle se existir
               const toggleContainer = document.querySelector('.weapon-toggle-container');
               if (toggleContainer) toggleContainer.remove();
               // Atualizar estado global para desligado
               if (typeof window.__setGlobalWeaponEnabled === 'function') {
                   window.__setGlobalWeaponEnabled(false);
               }
               return;
           }
           ensureModal();
           // Cria o novo toggle - tenta múltiplas vezes para garantir
           observeCharacterHeader();
           observeDOMForHeader();
           // Tenta criar novamente após um delay maior para garantir que o translator já criou o container
           setTimeout(() => {
               const existing = document.querySelector('.weapon-toggle-container');
               if (!existing) {
                   observeCharacterHeader();
               }
           }, 500);
           // Última tentativa após 1 segundo
           setTimeout(() => {
               const existing = document.querySelector('.weapon-toggle-container');
               if (!existing) {
                   observeCharacterHeader();
               }
           }, 1000);
           // Remove qualquer toggle antigo que apareça nas barras de skills/subskills
           function removeOldToggles() {
               document.querySelectorAll('.weapon-bar-toggle').forEach(toggle => {
                   toggle.remove();
               });
           }
           // Observa mudanças nas barras de ícones para remover toggles antigos
           const iconBarObserver = new MutationObserver(() => {
               removeOldToggles();
           });
           // Observa todas as barras de ícones existentes e futuras
           const observeAllIconBars = () => {
               document.querySelectorAll('.icon-bar').forEach(bar => {
                   iconBarObserver.observe(bar, { childList: true, subtree: true });
               });
           };
           // Remove toggles antigos imediatamente
           removeOldToggles();
           // Observa barras existentes
           observeAllIconBars();
           // Observa criação de novas barras
           const bodyObserver = new MutationObserver((mutations) => {
               mutations.forEach((mutation) => {
                   mutation.addedNodes.forEach((node) => {
                       if (node.nodeType === 1) {
                           if (node.classList && node.classList.contains('icon-bar')) {
                               iconBarObserver.observe(node, { childList: true, subtree: true });
                               removeOldToggles();
                           } else if (node.querySelector && node.querySelector('.icon-bar')) {
                               observeAllIconBars();
                               removeOldToggles();
                           }
                       }
                   });
               });
           });
           bodyObserver.observe(document.body, { childList: true, subtree: true });
           // Escuta mudanças no estado do weapon para atualizar visual
           window.addEventListener('gla:weaponToggled', () => {
               setTimeout(updateToggleVisualState, 50);
           });
           // Escuta mudanças de idioma
           window.addEventListener('gla:langChanged', () => {
               updateToggleVisualState();
           });
           // Estado inicial do toggle
           let init = false;
           try {
               if (localStorage.getItem('glaWeaponEnabled') === '1') init = true;
           } catch (x) { }
           setTimeout(() => {
               applyWeaponState(init);
               updateToggleVisualState();
           }, 150);
       };
       if (document.readyState === 'loading') {
           document.addEventListener('DOMContentLoaded', boot);
       } else {
           boot();
       }
   })();

</script> <style>

   /* Character-box precisa de position relative para conter o modal */
   .character-box {
       position: relative;
   }
   /* Modal posicionado dentro da character-box */
   .weapon-modal {
       position: absolute;
       inset: 0;
       z-index: 100;
       display: flex;
       align-items: center;
       justify-content: center;
       pointer-events: none;
   }
   .weapon-modal.show {
       pointer-events: all;
   }
   /* Overlay escurece apenas a character-box - aparece PRIMEIRO */
   .weapon-modal-overlay {
       position: absolute;
       inset: 0;
       background: rgba(0, 0, 0, .65);
       -webkit-backdrop-filter: blur(4px);
       backdrop-filter: blur(4px);
       opacity: 0;
       transition: opacity .15s ease;
   }
   .weapon-modal.show .weapon-modal-overlay {
       opacity: 1;
   }
   /* Conteúdo aparece DEPOIS do overlay */
   .weapon-modal-content {
       position: relative;
       z-index: 1;
       transform: scale(0.96);
       background: linear-gradient(145deg, #2d1a1a, #1e1212);
       border: 1px solid rgba(255, 100, 100, .2);
       border-radius: 14px;
       max-width: 420px;
       width: 90%;
       opacity: 0;
       transition: transform .18s ease .08s, opacity .15s ease .08s;
       overflow: hidden;
   }
   .weapon-modal.show .weapon-modal-content {
       transform: scale(1);
       opacity: 1;
   }
   .weapon-modal-header {
       display: flex;
       align-items: center;
       justify-content: space-between;
       padding: 16px 20px;
       border-bottom: 1px solid rgba(255, 100, 100, .12);
       background: linear-gradient(90deg, rgba(255, 80, 80, .06), transparent);
   }
   .weapon-modal-header h3 {
       margin: 0;
       font-size: 16px;
       font-weight: 600;
       color: #fff;
   }
   .weapon-modal-close {
       background: transparent;
       border: 1px solid rgba(255, 255, 255, .1);
       color: rgba(255, 255, 255, .5);
       font-size: 18px;
       font-family: Arial, sans-serif;
       line-height: 1;
       cursor: pointer;
       padding: 0;
       width: 28px;
       height: 28px;
       display: inline-flex;
       align-items: center;
       justify-content: center;
       text-align: center;
       border-radius: 6px;
       transition: background .15s, color .15s, border-color .15s;
   }
   .weapon-modal-close:hover {
       background: rgba(255, 80, 80, .15);
       border-color: rgba(255, 80, 80, .3);
       color: #FF7043;
   }
   .weapon-modal-body {
       padding: 20px;
       color: rgba(255, 255, 255, .85);
       line-height: 1.65;
       font-size: 14px;
   }
   .weapon-modal-body p {
       margin: 0 0 12px;
       display: block !important;
   }
   .weapon-modal-body p:last-child,
   .weapon-modal-body p.weapon-info-link {
       margin: 0;
   }
   .weapon-modal-body p.weapon-info-link:empty {
       display: none !important;
   }
   .weapon-modal-body strong {
       color: #FF7043;
       font-weight: 600;
   }
   .weapon-modal-body .weapon-info-link a {
       color: #FF7043;
       text-decoration: none;
       font-weight: 600;
   }
   .weapon-modal-body .weapon-info-link a:hover {
       text-decoration: underline;
   }
   .weapon-modal-footer {
       display: flex;
       align-items: center;
       justify-content: space-between;
       padding: 14px 20px;
       border-top: 1px solid rgba(255, 100, 100, .1);
       background: rgba(0, 0, 0, .1);
       gap: 12px;
   }
   .weapon-modal-checkbox {
       display: inline-flex;
       align-items: center;
       gap: 6px;
       font-size: 12px;
       color: rgba(255, 255, 255, .5);
       cursor: pointer;
       transition: color .15s;
   }
   .weapon-modal-checkbox:hover {
       color: rgba(255, 255, 255, .75);
   }
   .weapon-modal-checkbox input[type="checkbox"] {
       accent-color: #FF5722;
       margin: 0;
       flex-shrink: 0;
   }
   .weapon-modal-checkbox span {
       line-height: 1;
   }
   .weapon-modal-btn {
       background: #BF360C;
       border: none;
       color: #fff;
       padding: 10px 24px;
       border-radius: 6px;
       font-weight: 600;
       font-size: 13px;
       line-height: 1;
       cursor: pointer;
       transition: background .15s;
       display: inline-flex;
       align-items: center;
       justify-content: center;
   }
   .weapon-modal-btn:hover {
       background: #D84315;
   }
   .weapon-modal-btn:active {
       background: #A52714;
   }
   @media (max-width: 600px) {
       .weapon-modal-content {
           width: 92%;
           max-width: none;
       }
       .weapon-modal-header,
       .weapon-modal-body,
       .weapon-modal-footer {
           padding: 14px 16px;
       }
       .weapon-modal-footer {
           flex-direction: column;
           gap: 12px;
       }
       .weapon-modal-btn {
           width: 100%;
       }
   }
   /* =========================== NOVO WEAPON TOGGLE =========================== */
   .weapon-toggle-container {
       display: flex;
       align-items: center;
       z-index: 10;
       background: transparent;
       padding: 0;
       border-radius: 0;
       border: none;
       box-shadow: none;
       cursor: pointer;
       transition: transform .08s ease;
       overflow: visible;
       height: 44px;
       box-sizing: border-box;
   }
   .weapon-toggle-container:hover {
       transform: translateY(-1px);
   }
   .weapon-toggle-sprite {
       width: 44px;
       height: 44px;
       flex-shrink: 0;
       border-radius: 50%;
       overflow: visible;
       position: relative;
       background: rgb(40, 40, 48);
       border: 2px solid rgba(255, 255, 255, 0.15);
       display: flex;
       align-items: center;
       justify-content: center;
       z-index: 2;
       margin: 0;
       padding: 0;
       box-sizing: border-box;
       box-shadow: 0 4px 12px rgba(0, 0, 0, .4);
       transition: background-color 0.15s cubic-bezier(0.4, 0, 0.2, 1), border-color 0.15s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.15s cubic-bezier(0.4, 0, 0.2, 1);
       will-change: background-color;
   }
   .weapon-toggle-sprite img {
       width: 64px;
       height: 64px;
       display: block;
       /* Força redimensionamento pixelado (nearest neighbor) - ordem importante */
       -ms-interpolation-mode: nearest-neighbor;
       /* IE/Edge antigo - deve vir primeiro */
       image-rendering: -moz-crisp-edges;
       /* Firefox */
       image-rendering: -webkit-optimize-contrast;
       /* Safari/Chrome antigo */
       image-rendering: pixelated;
       /* Chrome/Edge moderno */
       image-rendering: crisp-edges !important;
       /* Fallback padrão - força sem suavização */
       /* Garante que não há suavização por transform ou filter */
       transform: translateZ(0);
       backface-visibility: hidden;
       /* Mantém proporção sem suavização */
       object-fit: contain;
       object-position: center;
       /* Força renderização sem suavização - importante para sprites pixelados */
       -webkit-font-smoothing: none;
       font-smoothing: none;
   }
   .weapon-toggle-bar {
       background: rgb(40, 40, 48);
       padding: 5px 14px 5px 28px;
       border-radius: 0 7px 7px 0;
       border: 2px solid rgba(255, 255, 255, 0.15);
       border-left: none;
       display: flex;
       align-items: center;
       width: 180px;
       position: relative;
       overflow: hidden;
       margin: 0;
       margin-left: -22px;
       height: 34px;
       box-sizing: border-box;
       box-shadow: 0 4px 12px rgba(0, 0, 0, .4);
       transition: background-color 0.15s cubic-bezier(0.4, 0, 0.2, 1), background-image 0.15s cubic-bezier(0.4, 0, 0.2, 1), border-color 0.15s cubic-bezier(0.4, 0, 0.2, 1);
       will-change: background-color, background-image;
   }
   .weapon-toggle-name {
       color: #fff;
       font-size: 14px;
       font-weight: 600;
       white-space: nowrap;
       text-overflow: ellipsis;
       overflow: hidden;
       position: relative;
       z-index: 2;
       letter-spacing: 0.3px;
       display: inline-block;
   }
   /* Textos i18n - usando ::after para mostrar o texto baseado no data-lang e estado */
   .weapon-toggle-name::after {
       content: "Equipar Arma";
       /* Default PT */
   }
   .weapon-toggle-name[data-lang="pt"]::after {
       content: "Equipar Arma";
   }
   .weapon-toggle-name[data-lang="en"]::after {
       content: "Equip Weapon";
   }
   .weapon-toggle-name[data-lang="es"]::after {
       content: "Equipar Arma";
   }
   .weapon-toggle-name[data-lang="pl"]::after {
       content: "Wyposaż Broń";
   }
   /* Estado ATIVO (arma equipada) - muda o texto */
   .weapon-toggle-container.weapon-active .weapon-toggle-name::after {
       content: "Desequipar Arma";
       /* Default PT */
   }
   .weapon-toggle-container.weapon-active .weapon-toggle-name[data-lang="pt"]::after {
       content: "Desequipar Arma";
   }
   .weapon-toggle-container.weapon-active .weapon-toggle-name[data-lang="en"]::after {
       content: "Unequip Weapon";
   }
   .weapon-toggle-container.weapon-active .weapon-toggle-name[data-lang="es"]::after {
       content: "Desequipar Arma";
   }
   .weapon-toggle-container.weapon-active .weapon-toggle-name[data-lang="pl"]::after {
       content: "Zdjęć Broń";
   }
   /* Estado ativo - destaque vermelho */
   .weapon-toggle-container.weapon-active .weapon-toggle-sprite {
       background-color: rgb(200, 60, 40) !important;
       border: 2px solid rgba(255, 255, 255, 0.15);
       box-shadow: 0 4px 12px rgba(0, 0, 0, .4);
   }
   .weapon-toggle-container.weapon-active .weapon-toggle-bar {
       background-color: rgb(200, 60, 40);
       background-image: linear-gradient(135deg, rgb(200, 60, 40), rgb(160, 45, 30));
       border-color: rgba(255, 87, 34, 0.3);
       border-left: none;
       border-radius: 0 7px 7px 0;
   }
   .weapon-toggle-container.weapon-active .weapon-toggle-name {
       color: #fff;
       text-shadow: 0 0 4px rgba(255, 87, 34, 0.5);
   }

</style>