MediaWiki:Common.js: mudanças entre as edições

De Farmland
Ir para navegação Ir para pesquisar
Sem resumo de edição
Sem resumo de edição
 
(4 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
Linha 1: Linha 1:
/* =======================================================
/* =======================================================
   ARVORE HABILIDADE - WIKI EVERLIGHT
   ARVORE DE HABILIDADE
   ======================================================= */
   ======================================================= */
 
document.addEventListener('DOMContentLoaded', function () {
 
     var cards = document.querySelectorAll('.skill-card');
document.addEventListener('DOMContentLoaded', () => {
     cards.forEach(function (card) {
     const cards = document.querySelectorAll('.skill-card');
         card.addEventListener('click', function () {
 
             card.style.filter = 'brightness(1.2)';
     cards.forEach(card => {
             setTimeout(function () { card.style.filter = 'brightness(1)'; }, 150);
         card.addEventListener('click', () => {
            const skillName = card.querySelector('.skill-name').innerText;
            console.log(`Habilidade clicada: ${skillName}`);
           
            // Exemplo de efeito visual simples
             card.style.filter = "brightness(1.2)";
             setTimeout(() => {
                card.style.filter = "brightness(1)";
            }, 150);
         });
         });
     });
     });
Linha 23: Linha 14:


/* =======================================================
/* =======================================================
   BOTAO SUBIR TOPO DA PAGINA
   BOTAO VOLTAR AO TOPO
   ======================================================= */
   ======================================================= */
$(function() {
$(function () {
     var $button = $('<button id="back-to-top" title="Voltar ao Topo">↑ Topo</button>');
     var $button = $('<button id="back-to-top" title="Voltar ao Topo">↑ Topo</button>');
     $('body').append($button);
     $('body').append($button);


     $(window).scroll(function() {
     $(window).scroll(function () {
        // Verifica se a posição atual + altura da janela é maior que o tamanho total - 100px
         if ($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
         if ($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
             $button.fadeIn();
             $button.fadeIn();
Linha 38: Linha 28:
     });
     });


     $button.click(function() {
     $button.click(function () {
         $('html, body').animate({scrollTop: 0}, 'slow');
         $('html, body').animate({ scrollTop: 0 }, 'slow');
         return false;
         return false;
     });
     });
Linha 46: Linha 36:


/* =======================================================
/* =======================================================
   clases testee
   ARVORE DE CLASSES
   ======================================================= */
   ======================================================= */
document.addEventListener('DOMContentLoaded', function() {
document.addEventListener('DOMContentLoaded', function () {
     const cells = document.querySelectorAll('.ragnarok-tree td[class^="evo-"]');
     var cells = document.querySelectorAll('.ragnarok-tree td[class^="evo-"]');


     cells.forEach(cell => {
     cells.forEach(function (cell) {
         // 1. Tornar a célula inteira clicável (redirecionar para o link de texto)
         var link = cell.querySelector('a');
        const link = cell.querySelector('a');
         if (link) {
         if (link) {
             cell.style.cursor = 'pointer';
             cell.style.cursor = 'pointer';
             cell.addEventListener('click', () => { window.location.href = link.href; });
             cell.addEventListener('click', function () { window.location.href = link.href; });
         }
         }


        // 2. Lógica de Hover (Conexão Hierárquica)
         cell.addEventListener('mouseenter', function () {
         cell.addEventListener('mouseenter', function() {
             var familyClass = Array.from(this.classList).find(function (c) { return c.startsWith('evo-'); });
             const familyClass = Array.from(this.classList).find(c => c.startsWith('evo-')); // ex: evo-sw
             if (!familyClass || familyClass === 'evo-all') return;
             if (!familyClass || familyClass === 'evo-all') return;


             const myPos = this.getAttribute('data-pos'); // Pega 0, 1 ou 2
             var myPos   = this.getAttribute('data-pos');
             const isClass1 = this.closest('table').previousElementSibling?.innerText.includes('Classe 1');
             var prevEl  = this.closest('table').previousElementSibling;
             const isClass2 = this.closest('table').previousElementSibling?.innerText.includes('Classe 2');
            var isClass1 = prevEl && prevEl.innerText.includes('Classe 1');
             var isClass2 = prevEl && prevEl.innerText.includes('Classe 2');


             if (isClass1) {
             if (isClass1) {
                // Passou no Espadachim: Acende Cav/Temp e Lorde/Paladino
                 document.querySelectorAll('.' + familyClass).forEach(function (el) {
                 document.querySelectorAll(`.${familyClass}`).forEach(el => el.classList.add('highlight-active'));
                    el.classList.add('highlight-active');
                });
             } else if (isClass2) {
             } else if (isClass2) {
                // Passou no Cavaleiro (pos 0): Acende ele mesmo e o Lorde (pos 0 na Trans)
                 this.classList.add('highlight-active');
                 this.classList.add('highlight-active'); // Acende si mesmo
                 var table3 = document.querySelector('table:nth-of-type(3)');
                 const transRelated = document.querySelector('table:nth-of-type(3)').querySelectorAll(`.${familyClass}`);
                if (table3) {
               
                    table3.querySelectorAll('.' + familyClass).forEach(function (el) {
                // Procura na Transclasse quem tem a mesma posição
                        if (el.getAttribute('data-pos') === myPos) el.classList.add('highlight-active');
                transRelated.forEach(el => {
                     });
                    if(el.getAttribute('data-pos') === myPos) {
                 }
                        el.classList.add('highlight-active');
                     }
                 });
             } else {
             } else {
                // Passou na Trans: Acende apenas ela mesma
                 this.classList.add('highlight-active');
                 this.classList.add('highlight-active');
             }
             }
         });
         });


         cell.addEventListener('mouseleave', function() {
         cell.addEventListener('mouseleave', function () {
             document.querySelectorAll('.highlight-active').forEach(el => el.classList.remove('highlight-active'));
             document.querySelectorAll('.highlight-active').forEach(function (el) {
                el.classList.remove('highlight-active');
            });
         });
         });
     });
     });
Linha 95: Linha 83:




$(document).ready(function() {
    // Evita duplicar se a página recarregar
    if ($('.sidebar-logo').length === 0) {
        var logoHtml = '<div class="sidebar-logo">' +
                      '<a href="/everlight/index.php/Página_principal">' +
                      '<img src="http://78.142.242.9/everlight/images/b/b0/Logo_Quadrada.png" alt="Logo Everlight">' +
                      '</a>' +
                      '</div>';
       
        // Coloca a logo no topo do painel lateral
        $('#mw-panel').prepend(logoHtml);
    }
});




mw.loader.using('mediawiki.util').then(function () {
/* =======================================================
 
  CARROSSEL FARMLAND
    const carousel = document.getElementById("farmlandCarousel");
  ======================================================= */
mw.hook('wikipage.content').add(function () {


    var carousel = document.getElementById('farmlandCarousel');
     if (!carousel) return;
     if (!carousel) return;


     const container = carousel.querySelector(".carousel-container");
     var wrapper  = carousel.querySelector('.carousel-wrapper');
     const slides = carousel.querySelectorAll(".carousel-slide");
     var container = carousel.querySelector('.carousel-container');
 
     var slides  = carousel.querySelectorAll('.carousel-slide');
    const prev = carousel.querySelector(".left");
     var dotsWrap = carousel.querySelector('.carousel-dots');
    const next = carousel.querySelector(".right");
     var progBar  = carousel.querySelector('.carousel-progress');
 
     var nextBtn = carousel.querySelector('.carousel-arrow.right');
    const dotsContainer = carousel.querySelector(".carousel-dots");
     var prevBtn = carousel.querySelector('.carousel-arrow.left');
 
    let index = 0;
    let interval;
 
    // DOTS
    slides.forEach((slide, i) => {
 
        const dot = document.createElement("span");
 
        dot.className = "carousel-dot";
 
        if (i === 0) {
            dot.classList.add("active");
        }
 
        dot.addEventListener("click", function () {
            index = i;
            updateCarousel();
        });
 
        dotsContainer.appendChild(dot);
    });
 
    const dots = carousel.querySelectorAll(".carousel-dot");
 
    function updateCarousel() {
 
        container.style.transform =
            "translateX(-" + (index * 100) + "%)";
 
        dots.forEach(function(dot) {
            dot.classList.remove("active");
        });
 
        dots[index].classList.add("active");
    }
 
    function nextSlide() {
 
        index++;
 
        if (index >= slides.length) {
            index = 0;
        }
 
        updateCarousel();
    }
 
     function prevSlide() {
 
        index--;
 
        if (index < 0) {
            index = slides.length - 1;
        }
 
        updateCarousel();
    }
 
    next.onclick = nextSlide;
    prev.onclick = prevSlide;
 
    // AUTO PLAY
    function startCarousel() {
 
        interval = setInterval(function () {
            nextSlide();
        }, 4000);
    }
 
    function stopCarousel() {
        clearInterval(interval);
    }
 
    carousel.addEventListener("mouseenter", stopCarousel);
    carousel.addEventListener("mouseleave", startCarousel);
 
    startCarousel();
 
});
 
 
 
 
 
 
mw.loader.using(['jquery'], function () {
   $(function () {
 
    let index = 0;
 
    const container = document.querySelector(".carousel-container");
    const items = document.querySelectorAll(".carousel-slide");
     const total = items.length;
 
    if (!container || total === 0) return;
 
    function updateSlide() {
      container.style.transform = `translateX(-${index * 100}%)`;
    }
 
    // SETA DIREITA
    const right = document.querySelector(".carousel-arrow.right");
    if (right) {
      right.addEventListener("click", () => {
        index++;
        if (index >= total) index = 0;
        updateSlide();
      });
    }
 
    // SETA ESQUERDA
    const left = document.querySelector(".carousel-arrow.left");
    if (left) {
      left.addEventListener("click", () => {
        index--;
        if (index < 0) index = total - 1;
        updateSlide();
      });
    }
 
    // AUTO SLIDE
    setInterval(() => {
      index++;
      if (index >= total) index = 0;
      updateSlide();
    }, 3000);
 
  });
});
 
 
 
 
 
mw.loader.using(['jquery'], function () {
  $(function () {
 
    const wrapper = document.querySelector(".carousel-wrapper");
     const container = document.querySelector(".carousel-container");
    const slides = document.querySelectorAll(".carousel-slide");
    const dotsContainer = document.querySelector(".carousel-dots");
     const nextBtn = document.querySelector(".carousel-arrow.right");
     const prevBtn = document.querySelector(".carousel-arrow.left");


     if (!container || slides.length === 0) return;
     if (!container || slides.length === 0) return;


     let index = 1;
     var DELAY = 3500;
    let interval;
     var total = slides.length;
     let isTransitioning = false;
     var idx  = 1;
 
     var timer, busy = false;
    /* =========================
      CLONAR PARA LOOP INFINITO
    ========================= */
    const firstClone = slides[0].cloneNode(true);
     const lastClone = slides[slides.length - 1].cloneNode(true);
 
     firstClone.classList.add("clone");
    lastClone.classList.add("clone");


    /* Clones para loop infinito sem flash */
    var firstClone = slides[0].cloneNode(true);
    var lastClone  = slides[total - 1].cloneNode(true);
    firstClone.classList.add('clone');
    lastClone.classList.add('clone');
     container.appendChild(firstClone);
     container.appendChild(firstClone);
     container.insertBefore(lastClone, slides[0]);
     container.insertBefore(lastClone, slides[0]);


     const allSlides = document.querySelectorAll(".carousel-slide");
     var allSlides = container.querySelectorAll('.carousel-slide');
 
    /* =========================
      POSIÇÃO INICIAL
    ========================= */
    container.style.transform = `translateX(-${index * 100}%)`;
 
    /* =========================
      CRIAR DOTS
    ========================= */
    const dots = [];


     slides.forEach((_, i) => {
     /* Força layout correto (crítico no MediaWiki) */
      const dot = document.createElement("span");
    container.style.display    = 'flex';
      dot.classList.add("dot");
    container.style.transition = 'none';
      dotsContainer.appendChild(dot);
    allSlides.forEach(function (s) {
      dots.push(dot);
         s.style.minWidth  = '100%';
 
         s.style.flexShrink = '0';
      dot.addEventListener("click", () => {
         index = i + 1;
         updateSlide();
        resetAuto();
      });
     });
     });
    container.style.transform = 'translateX(-' + (idx * 100) + '%)';


     function updateDots() {
     /* Dots */
      dots.forEach(d => d.classList.remove("active"));
    dotsWrap.innerHTML = '';
 
    var dots = [];
      let activeIndex = index - 1;
    for (var i = 0; i < total; i++) {
      if (activeIndex < 0) activeIndex = slides.length - 1;
        var dot = document.createElement('span');
      if (activeIndex >= slides.length) activeIndex = 0;
        dot.className = 'dot';
 
        dotsWrap.appendChild(dot);
      if (dots[activeIndex]) {
        dots.push(dot);
        dots[activeIndex].classList.add("active");
        (function (n) {
      }
            dot.onclick = function () { goTo(n + 1); resetAuto(); };
        })(i);
     }
     }


    /* =========================
     function updateDots() {
      SLIDE UPDATE
        var ai = idx - 1;
    ========================= */
        if (ai < 0) ai = total - 1;
     function updateSlide(animate = true) {
         if (ai >= total) ai = 0;
      if (animate) {
        dots.forEach(function (d, i) {
         container.style.transition = "transform 0.5s ease";
            d.classList.toggle('active', i === ai);
      }
        });
 
      container.style.transform = `translateX(-${index * 100}%)`;
      updateDots();
     }
     }


     /* =========================
     function goTo(i, animate) {
      LOOP INFINITO SEM FLASH
        if (busy) return;
    ========================= */
        busy = true;
    container.addEventListener("transitionend", () => {
        idx  = i;
      if (allSlides[index].classList.contains("clone")) {
         container.style.transition = (animate === false)
 
            ? 'none'
         container.style.transition = "none";
            : 'transform 0.5s cubic-bezier(.4,0,.2,1)';
 
         container.style.transform = 'translateX(-' + (idx * 100) + '%)';
        if (index === 0) {
        updateDots();
          index = slides.length;
        } else if (index === allSlides.length - 1) {
          index = 1;
        }
 
         container.style.transform = `translateX(-${index * 100}%)`;
      }
      isTransitioning = false;
    });
 
    /* =========================
      NEXT / PREV
    ========================= */
    function next() {
      if (isTransitioning) return;
      isTransitioning = true;
      index++;
      updateSlide();
      resetAuto();
     }
     }


     function prev() {
     container.addEventListener('transitionend', function () {
      if (isTransitioning) return;
        if (allSlides[idx] && allSlides[idx].classList.contains('clone')) {
      isTransitioning = true;
            container.style.transition = 'none';
      index--;
            idx = (idx === 0) ? total : 1;
      updateSlide();
            container.style.transform = 'translateX(-' + (idx * 100) + '%)';
      resetAuto();
            updateDots();
    }
 
    nextBtn?.addEventListener("click", next);
    prevBtn?.addEventListener("click", prev);
 
    /* =========================
      AUTO SLIDE
    ========================= */
    function startAuto() {
      interval = setInterval(next, 3000);
    }
 
    function resetAuto() {
      clearInterval(interval);
      startAuto();
    }
 
    /* =========================
      PAUSA NO HOVER
    ========================= */
    wrapper.addEventListener("mouseenter", () => clearInterval(interval));
    wrapper.addEventListener("mouseleave", startAuto);
 
    /* =========================
      SWIPE MOBILE
    ========================= */
    let startX = 0;
    let endX = 0;
 
    wrapper.addEventListener("touchstart", (e) => {
      startX = e.touches[0].clientX;
    });
 
    wrapper.addEventListener("touchmove", (e) => {
      endX = e.touches[0].clientX;
    });
 
    wrapper.addEventListener("touchend", () => {
      const diff = startX - endX;
 
      if (Math.abs(diff) > 50) {
        if (diff > 0) {
          next();
        } else {
          prev();
         }
         }
      }
        busy = false;
     });
     });


     /* =========================
     function next() { goTo(idx + 1); resetAuto(); }
      INICIAR
     function prev() { goTo(idx - 1); resetAuto(); }
    ========================= */
    updateSlide(false);
    startAuto();
    updateDots();
 
  });
});
 
mw.loader.using(['jquery'], function () {
  $(function () {
 
    const container = document.querySelector(".carousel-container");
    const slides = document.querySelectorAll(".carousel-slide");
    const dotsContainer = document.querySelector(".carousel-dots");
    const wrapper = document.querySelector(".carousel-wrapper");
 
    const nextBtn = document.querySelector(".carousel-arrow.right");
    const prevBtn = document.querySelector(".carousel-arrow.left");
 
    if (!container || slides.length === 0) return;
 
    let index = 0;
    let interval;
 
    /* =========================
      DOTS
    ========================= */
    const dots = [];
 
    slides.forEach((_, i) => {
      const dot = document.createElement("span");
      dot.className = "dot";
      dotsContainer.appendChild(dot);
      dots.push(dot);
 
      dot.addEventListener("click", () => {
        index = i;
        update();
        resetAuto();
      });
    });
 
    function updateDots() {
      dots.forEach(d => d.classList.remove("active"));
      if (dots[index]) dots[index].classList.add("active");
    }
 
    /* =========================
      SLIDE
    ========================= */
    function update() {
      container.style.transform = `translateX(-${index * 100}%)`;
      updateDots();
    }
 
    /* =========================
      NEXT / PREV
    ========================= */
    function next() {
      index++;
      if (index >= slides.length) index = 0;
      update();
      resetAuto();
    }
 
    function prev() {
      index--;
      if (index < 0) index = slides.length - 1;
      update();
      resetAuto();
    }
 
    nextBtn?.addEventListener("click", next);
    prevBtn?.addEventListener("click", prev);
 
    /* =========================
      AUTOPLAY
    ========================= */
    function startAuto() {
      interval = setInterval(next, 3000);
    }
 
    function resetAuto() {
      clearInterval(interval);
      startAuto();
    }
 
    /* =========================
      PAUSA NO HOVER
    ========================= */
    wrapper?.addEventListener("mouseenter", () => clearInterval(interval));
    wrapper?.addEventListener("mouseleave", startAuto);
 
    /* =========================
      SWIPE MOBILE
    ========================= */
    let startX = 0;
 
    wrapper?.addEventListener("touchstart", (e) => {
      startX = e.touches[0].clientX;
    });
 
    wrapper?.addEventListener("touchend", (e) => {
      const endX = e.changedTouches[0].clientX;
      const diff = startX - endX;
 
      if (Math.abs(diff) > 50) {
        if (diff > 0) next();
        else prev();
      }
    });
 
    /* =========================
      INIT
    ========================= */
    update();
    startAuto();
 
  });
});
mw.loader.using(['jquery'], function () {
  $(function () {
 
    const container = document.querySelector(".carousel-container");
    const slides = document.querySelectorAll(".carousel-slide");
    const wrapper = document.querySelector(".carousel-wrapper");
    const dotsContainer = document.querySelector(".carousel-dots");
    const nextBtn = document.querySelector(".carousel-arrow.right");
    const prevBtn = document.querySelector(".carousel-arrow.left");
 
    if (!container || slides.length === 0) return;
 
    let index = 0;
    let interval;
 
    /* =========================
      GARANTE LAYOUT CORRETO
    ========================= */
    container.style.display = "flex";
 
    slides.forEach(s => {
      s.style.minWidth = "100%";
      s.style.flexShrink = "0";
    });
 
    /* =========================
      DOTS
    ========================= */
    const dots = [];
 
    slides.forEach((_, i) => {
      const dot = document.createElement("span");
      dot.className = "dot";
      dotsContainer.appendChild(dot);
      dots.push(dot);
 
      dot.addEventListener("click", () => {
        index = i;
        update();
        resetAuto();
      });
    });
 
    function updateDots() {
      dots.forEach(d => d.classList.remove("active"));
      if (dots[index]) dots[index].classList.add("active");
    }
 
    /* =========================
      UPDATE SLIDE (IMPORTANTE)
    ========================= */
    function update() {
      container.style.transform = `translate3d(-${index * 100}%, 0, 0)`;
      updateDots();
    }
 
    /* =========================
      CONTROLES
    ========================= */
    function next() {
      index++;
      if (index >= slides.length) index = 0;
      update();
      resetAuto();
    }
 
     function prev() {
      index--;
      if (index < 0) index = slides.length - 1;
      update();
      resetAuto();
    }
 
    nextBtn?.addEventListener("click", next);
    prevBtn?.addEventListener("click", prev);
 
    /* =========================
      AUTOPLAY
    ========================= */
    function startAuto() {
      interval = setInterval(next, 3000);
    }
 
    function resetAuto() {
      clearInterval(interval);
      startAuto();
    }
 
    /* =========================
      PAUSA NO HOVER
    ========================= */
    wrapper?.addEventListener("mouseenter", () => clearInterval(interval));
    wrapper?.addEventListener("mouseleave", startAuto);
 
    /* =========================
      SWIPE MOBILE (ROBUSTO)
    ========================= */
    let startX = 0;
 
    wrapper?.addEventListener("touchstart", (e) => {
      startX = e.touches[0].clientX;
    });
 
    wrapper?.addEventListener("touchend", (e) => {
      const endX = e.changedTouches[0].clientX;
      const diff = startX - endX;
 
      if (Math.abs(diff) > 40) {
        diff > 0 ? next() : prev();
      }
    });
 
    /* =========================
      INIT
    ========================= */
    update();
    startAuto();
 
  });
});
 
 
 
 
 
(function () {
 
  function initCarousel() {
 
    const container = document.querySelector(".carousel-container");
    const slides = document.querySelectorAll(".carousel-slide");
    const wrapper = document.querySelector(".carousel-wrapper");
    const dotsContainer = document.querySelector(".carousel-dots");
    const nextBtn = document.querySelector(".carousel-arrow.right");
    const prevBtn = document.querySelector(".carousel-arrow.left");
 
    if (!container || slides.length === 0 || !wrapper) return;
 
    let index = 0;
    let timer;
 
    /* =========================
      FORÇA LAYOUT (CRÍTICO MEDIAWIKI)
    ========================= */
    container.style.display = "flex";
    container.style.transition = "transform 0.5s ease";
 
    slides.forEach(slide => {
      slide.style.minWidth = "100%";
      slide.style.flexShrink = "0";
    });
 
    /* =========================
      DOTS
    ========================= */
    dotsContainer.innerHTML = "";
    const dots = [];
 
    slides.forEach((_, i) => {
      const dot = document.createElement("span");
      dot.className = "dot";
      dotsContainer.appendChild(dot);
      dots.push(dot);
 
      dot.onclick = () => {
        index = i;
        update();
        restart();
      };
    });
 
    function updateDots() {
      dots.forEach(d => d.classList.remove("active"));
      if (dots[index]) dots[index].classList.add("active");
    }
 
    /* =========================
      MOVE SLIDE
    ========================= */
    function update() {
      container.style.transform = "translateX(-" + (index * 100) + "%)";
      updateDots();
    }
 
    /* =========================
      CONTROLES
    ========================= */
    function next() {
      index++;
      if (index >= slides.length) index = 0;
      update();
      restart();
    }
 
    function prev() {
      index--;
      if (index < 0) index = slides.length - 1;
      update();
      restart();
    }


     if (nextBtn) nextBtn.onclick = next;
     if (nextBtn) nextBtn.onclick = next;
     if (prevBtn) prevBtn.onclick = prev;
     if (prevBtn) prevBtn.onclick = prev;


     /* =========================
     /* Barra de progresso */
      AUTO PLAY
    function startProg() {
    ========================= */
        if (!progBar) return;
    function start() {
        progBar.style.transition = 'none';
      timer = setInterval(next, 3000);
        progBar.style.width = '0%';
        setTimeout(function () {
            progBar.style.transition = 'width ' + DELAY + 'ms linear';
            progBar.style.width = '100%';
        }, 30);
     }
     }


     function stop() {
     function startAuto() {
      clearInterval(timer);
        timer = setInterval(function () { goTo(idx + 1); startProg(); }, DELAY);
        startProg();
     }
     }


     function restart() {
     function stopAuto() {
      stop();
        clearInterval(timer);
      start();
        if (progBar) { progBar.style.transition = 'none'; progBar.style.width = '0%'; }
     }
     }


     /* =========================
     function resetAuto() { clearInterval(timer); startAuto(); }
      PAUSA NO HOVER
    ========================= */
    wrapper.onmouseenter = stop;
    wrapper.onmouseleave = start;
 
    /* =========================
      SWIPE MOBILE (ROBUSTO)
    ========================= */
    let startX = 0;
 
    wrapper.ontouchstart = function (e) {
      startX = e.touches[0].clientX;
    };
 
    wrapper.ontouchend = function (e) {
      let endX = e.changedTouches[0].clientX;
      let diff = startX - endX;
 
      if (Math.abs(diff) > 50) {
        diff > 0 ? next() : prev();
      }
    };
 
    /* =========================
      INIT
    ========================= */
    update();
    start();
  }
 
  /* =========================
    MEDIAWIKI SAFE LOAD
  ========================= */
  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", initCarousel);
  } else {
    initCarousel();
  }
 
})();
 
 
/* ===========================
  CARROSSEL FARMLAND
  =========================== */
(function () {
    var DELAY = 3500;
 
    function initCarousel() {
        var carousel  = document.getElementById('farmlandCarousel');
        if (!carousel) return;
 
        var wrapper    = carousel.querySelector('.carousel-wrapper');
        var container  = carousel.querySelector('.carousel-container');
        var slides    = carousel.querySelectorAll('.carousel-slide');
        var dotsWrap  = carousel.querySelector('.carousel-dots');
        var progBar    = carousel.querySelector('.carousel-progress');
        var nextBtn    = carousel.querySelector('.carousel-arrow.right');
        var prevBtn    = carousel.querySelector('.carousel-arrow.left');
 
        if (!container || slides.length === 0) return;
 
        var total = slides.length;
        var idx  = 1;
        var timer, progTimer, busy = false;


        /* Clones para loop infinito */
    /* Pausa no hover */
        var firstClone = slides[0].cloneNode(true);
    if (wrapper) {
        var lastClone  = slides[total - 1].cloneNode(true);
        firstClone.classList.add('clone');
        lastClone.classList.add('clone');
        container.appendChild(firstClone);
        container.insertBefore(lastClone, slides[0]);
 
        var allSlides = container.querySelectorAll('.carousel-slide');
 
        container.style.transition = 'none';
        container.style.transform  = 'translateX(-' + (idx * 100) + '%)';
 
        /* Dots */
        var dots = [];
        for (var i = 0; i < total; i++) {
            var dot = document.createElement('span');
            dot.className = 'dot';
            dotsWrap.appendChild(dot);
            dots.push(dot);
            (function (n) {
                dot.onclick = function () { goTo(n + 1); resetAuto(); };
            })(i);
        }
 
        function updateDots() {
            var ai = idx - 1;
            if (ai < 0) ai = total - 1;
            if (ai >= total) ai = 0;
            dots.forEach(function (d, i) {
                d.classList.toggle('active', i === ai);
            });
        }
 
        function goTo(i, animate) {
            if (busy) return;
            busy = true;
            idx  = i;
            container.style.transition = (animate === false)
                ? 'none'
                : 'transform 0.5s cubic-bezier(.4,0,.2,1)';
            container.style.transform = 'translateX(-' + (idx * 100) + '%)';
            updateDots();
        }
 
        container.addEventListener('transitionend', function () {
            if (allSlides[idx].classList.contains('clone')) {
                container.style.transition = 'none';
                idx = (idx === 0) ? total : 1;
                container.style.transform = 'translateX(-' + (idx * 100) + '%)';
                updateDots();
            }
            busy = false;
        });
 
        function next() { goTo(idx + 1); resetAuto(); }
        function prev() { goTo(idx - 1); resetAuto(); }
 
        nextBtn && (nextBtn.onclick = next);
        prevBtn && (prevBtn.onclick = prev);
 
        /* Barra de progresso */
        function startProg() {
            clearInterval(progTimer);
            progBar.style.transition = 'none';
            progBar.style.width = '0%';
            setTimeout(function () {
                progBar.style.transition = 'width ' + DELAY + 'ms linear';
                progBar.style.width = '100%';
            }, 30);
        }
 
        function startAuto() {
            timer = setInterval(function () { goTo(idx + 1); startProg(); }, DELAY);
            startProg();
        }
 
        function stopAuto() {
            clearInterval(timer);
            progBar.style.transition = 'none';
            progBar.style.width = '0%';
        }
 
        function resetAuto() { clearInterval(timer); startAuto(); }
 
        /* Pausa no hover */
         wrapper.addEventListener('mouseenter', stopAuto);
         wrapper.addEventListener('mouseenter', stopAuto);
         wrapper.addEventListener('mouseleave', startAuto);
         wrapper.addEventListener('mouseleave', startAuto);
    }


        /* Swipe mobile */
    /* Swipe mobile */
        var startX = 0;
    var startX = 0;
         wrapper.addEventListener('touchstart', function (e) {
    if (wrapper) {
            startX = e.touches[0].clientX;
         wrapper.addEventListener('touchstart', function (e) { startX = e.touches[0].clientX; });
        });
         wrapper.addEventListener('touchend', function (e) {
         wrapper.addEventListener('touchend', function (e) {
             var diff = startX - e.changedTouches[0].clientX;
             var diff = startX - e.changedTouches[0].clientX;
             if (Math.abs(diff) > 40) { diff > 0 ? next() : prev(); }
             if (Math.abs(diff) > 40) { diff > 0 ? next() : prev(); }
         });
         });
        updateDots();
        startAuto();
     }
     }


     /* Compatível com MediaWiki */
     updateDots();
    if (typeof mw !== 'undefined') {
     startAuto();
        mw.loader.using(['mediawiki.util'], initCarousel);
});
     } else if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initCarousel);
    } else {
        initCarousel();
    }
})();

Edição atual tal como às 21h15min de 16 de maio de 2026

/* =======================================================
   ARVORE DE HABILIDADE
   ======================================================= */
document.addEventListener('DOMContentLoaded', function () {
    var cards = document.querySelectorAll('.skill-card');
    cards.forEach(function (card) {
        card.addEventListener('click', function () {
            card.style.filter = 'brightness(1.2)';
            setTimeout(function () { card.style.filter = 'brightness(1)'; }, 150);
        });
    });
});


/* =======================================================
   BOTAO VOLTAR AO TOPO
   ======================================================= */
$(function () {
    var $button = $('<button id="back-to-top" title="Voltar ao Topo">↑ Topo</button>');
    $('body').append($button);

    $(window).scroll(function () {
        if ($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
            $button.fadeIn();
        } else {
            $button.fadeOut();
        }
    });

    $button.click(function () {
        $('html, body').animate({ scrollTop: 0 }, 'slow');
        return false;
    });
});


/* =======================================================
   ARVORE DE CLASSES
   ======================================================= */
document.addEventListener('DOMContentLoaded', function () {
    var cells = document.querySelectorAll('.ragnarok-tree td[class^="evo-"]');

    cells.forEach(function (cell) {
        var link = cell.querySelector('a');
        if (link) {
            cell.style.cursor = 'pointer';
            cell.addEventListener('click', function () { window.location.href = link.href; });
        }

        cell.addEventListener('mouseenter', function () {
            var familyClass = Array.from(this.classList).find(function (c) { return c.startsWith('evo-'); });
            if (!familyClass || familyClass === 'evo-all') return;

            var myPos    = this.getAttribute('data-pos');
            var prevEl   = this.closest('table').previousElementSibling;
            var isClass1 = prevEl && prevEl.innerText.includes('Classe 1');
            var isClass2 = prevEl && prevEl.innerText.includes('Classe 2');

            if (isClass1) {
                document.querySelectorAll('.' + familyClass).forEach(function (el) {
                    el.classList.add('highlight-active');
                });
            } else if (isClass2) {
                this.classList.add('highlight-active');
                var table3 = document.querySelector('table:nth-of-type(3)');
                if (table3) {
                    table3.querySelectorAll('.' + familyClass).forEach(function (el) {
                        if (el.getAttribute('data-pos') === myPos) el.classList.add('highlight-active');
                    });
                }
            } else {
                this.classList.add('highlight-active');
            }
        });

        cell.addEventListener('mouseleave', function () {
            document.querySelectorAll('.highlight-active').forEach(function (el) {
                el.classList.remove('highlight-active');
            });
        });
    });
});




/* =======================================================
   CARROSSEL FARMLAND
   ======================================================= */
mw.hook('wikipage.content').add(function () {

    var carousel = document.getElementById('farmlandCarousel');
    if (!carousel) return;

    var wrapper  = carousel.querySelector('.carousel-wrapper');
    var container = carousel.querySelector('.carousel-container');
    var slides   = carousel.querySelectorAll('.carousel-slide');
    var dotsWrap = carousel.querySelector('.carousel-dots');
    var progBar  = carousel.querySelector('.carousel-progress');
    var nextBtn  = carousel.querySelector('.carousel-arrow.right');
    var prevBtn  = carousel.querySelector('.carousel-arrow.left');

    if (!container || slides.length === 0) return;

    var DELAY = 3500;
    var total = slides.length;
    var idx   = 1;
    var timer, busy = false;

    /* Clones para loop infinito sem flash */
    var firstClone = slides[0].cloneNode(true);
    var lastClone  = slides[total - 1].cloneNode(true);
    firstClone.classList.add('clone');
    lastClone.classList.add('clone');
    container.appendChild(firstClone);
    container.insertBefore(lastClone, slides[0]);

    var allSlides = container.querySelectorAll('.carousel-slide');

    /* Força layout correto (crítico no MediaWiki) */
    container.style.display    = 'flex';
    container.style.transition = 'none';
    allSlides.forEach(function (s) {
        s.style.minWidth   = '100%';
        s.style.flexShrink = '0';
    });
    container.style.transform = 'translateX(-' + (idx * 100) + '%)';

    /* Dots */
    dotsWrap.innerHTML = '';
    var dots = [];
    for (var i = 0; i < total; i++) {
        var dot = document.createElement('span');
        dot.className = 'dot';
        dotsWrap.appendChild(dot);
        dots.push(dot);
        (function (n) {
            dot.onclick = function () { goTo(n + 1); resetAuto(); };
        })(i);
    }

    function updateDots() {
        var ai = idx - 1;
        if (ai < 0) ai = total - 1;
        if (ai >= total) ai = 0;
        dots.forEach(function (d, i) {
            d.classList.toggle('active', i === ai);
        });
    }

    function goTo(i, animate) {
        if (busy) return;
        busy = true;
        idx  = i;
        container.style.transition = (animate === false)
            ? 'none'
            : 'transform 0.5s cubic-bezier(.4,0,.2,1)';
        container.style.transform = 'translateX(-' + (idx * 100) + '%)';
        updateDots();
    }

    container.addEventListener('transitionend', function () {
        if (allSlides[idx] && allSlides[idx].classList.contains('clone')) {
            container.style.transition = 'none';
            idx = (idx === 0) ? total : 1;
            container.style.transform = 'translateX(-' + (idx * 100) + '%)';
            updateDots();
        }
        busy = false;
    });

    function next() { goTo(idx + 1); resetAuto(); }
    function prev() { goTo(idx - 1); resetAuto(); }

    if (nextBtn) nextBtn.onclick = next;
    if (prevBtn) prevBtn.onclick = prev;

    /* Barra de progresso */
    function startProg() {
        if (!progBar) return;
        progBar.style.transition = 'none';
        progBar.style.width = '0%';
        setTimeout(function () {
            progBar.style.transition = 'width ' + DELAY + 'ms linear';
            progBar.style.width = '100%';
        }, 30);
    }

    function startAuto() {
        timer = setInterval(function () { goTo(idx + 1); startProg(); }, DELAY);
        startProg();
    }

    function stopAuto() {
        clearInterval(timer);
        if (progBar) { progBar.style.transition = 'none'; progBar.style.width = '0%'; }
    }

    function resetAuto() { clearInterval(timer); startAuto(); }

    /* Pausa no hover */
    if (wrapper) {
        wrapper.addEventListener('mouseenter', stopAuto);
        wrapper.addEventListener('mouseleave', startAuto);
    }

    /* Swipe mobile */
    var startX = 0;
    if (wrapper) {
        wrapper.addEventListener('touchstart', function (e) { startX = e.touches[0].clientX; });
        wrapper.addEventListener('touchend', function (e) {
            var diff = startX - e.changedTouches[0].clientX;
            if (Math.abs(diff) > 40) { diff > 0 ? next() : prev(); }
        });
    }

    updateDots();
    startAuto();
});