Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/* Any JavaScript here will be loaded for all users on every page load. */

/* DRUID */
$(function () {
    $(".druid-main-images-label").off("click");
    $(".druid-main-images-label").click(function () {
      var $parent = $(this).closest(".druid-container");
      $parent.find(".druid-toggleable").removeClass("focused");
      var i = $(this).attr("data-druid");
      $parent.find(".druid-toggleable[data-druid=" + i + "]").addClass("focused");
    });
  
    $(".druid-collapsible").off("click");
    $(".druid-collapsible").click(function () {
      var kind = $(this).attr("data-druid-section");
      $(this).toggleClass("druid-collapsible-collapsed");
      $(this)
        .closest(".druid-container")
        .find("[data-druid-section-row=" + kind + "]")
        .toggleClass("druid-collapsed");
    });
  });
  /* End DRUID */
  
  /* [[Template:Spoiler]] */
  $(function () {
      $('.spoiler-content')
      .off('click') // in case this code is loaded twice
      .on('click', function(e){
          $(this).toggleClass('show');
      }).find('a').on('click', function(e){
          e.stopPropagation();
      });
  
  });
  /* End Template:Spoiler */
  
  
  /* Link to imported modules from Lua code */
  $(function() {
      var config = mw.config.get([
          'wgCanonicalNamespace',
          'wgFormattedNamespaces'
      ]);
      if (config.wgCanonicalNamespace !== 'Module') {
          return;
      }
      var localizedNamespace = config.wgFormattedNamespaces[828];
      $('.s1, .s2, .s').each(function() {
          var $this = $(this);
          var html = $this.html();
          var quote = html[0];
          var isLongStringQuote = quote === '[';
          var quoteRE = new RegExp('^\\' + quote + '|\\' + quote + '$', 'g');
          if (isLongStringQuote) {
              quoteRE = /^\[\[|\]\]$/g;
          }
          var name = html.replace(quoteRE, '');
          var isEnglishPrefix = name.startsWith('Module:');
          var isLocalizedPrefix = name.startsWith(localizedNamespace + ':');
          var isDevPrefix = name.startsWith('Dev:');
          if (isEnglishPrefix || isLocalizedPrefix || isDevPrefix) {
              var attrs = {
                  href: mw.util.getUrl(name)
              };
              if (isDevPrefix) {
                  attrs.href = 'https://commons.wiki.gg/wiki/Module:' + mw.util.wikiUrlencode(name.replace('Dev:', ''));
                  attrs.target = '_blank';
                  attrs.rel = 'noopener';
              }
              var link = mw.html.element('a', attrs, name);
              var str = quote + link + quote;
              if (isLongStringQuote) {
                  str = '[[' + link + ']]';
              }
              $this.html(str);
          }
      });
  });
  
  /* dynamic gif displayer ONLY TOUCH IF YOU KNOW WHAT YOU ARE DOING */
  
  (function() {
      'use strict';
      
      console.log('Dynamic GIF Displayer: Script loading...');
      
      // Configuration
      const CONFIG = {
          containerClass: 'dynamic-gif-container',
          displayClass: 'gif-display-area',
          autoExpand: true,
          expandDelay: 200,
          collapseDelay: 1000
      };
      
      let expandTimer = null;
      let collapseTimer = null;
      let currentGif = null;
      
      function safeCreateError(message) {
          const div = document.createElement('div');
          div.className = 'gif-error';
          div.textContent = message;
          return div;
      }
      
      function safeCreatePlaceholder(message) {
          const div = document.createElement('div');
          div.className = 'gif-placeholder';
          div.textContent = message;
          return div;
      }
      
      function init() {
          console.log('Dynamic GIF Displayer: Initializing...');
          
          const containers = document.querySelectorAll('.' + CONFIG.containerClass);
          console.log('Dynamic GIF Displayer: Found', containers.length, 'containers');
          
          containers.forEach(container => {
              console.log('Dynamic GIF Displayer: Setting up container', container.id);
              setupContainer(container);
              attachTooltipListeners(container);
          });
      }
      
      function setupContainer(container) {
          const displayArea = container.querySelector('.' + CONFIG.displayClass);
          if (!displayArea) {
              console.error('Dynamic GIF Displayer: No display area found');
              return;
          }
          
          displayArea.addEventListener('mouseenter', () => {
              clearTimeout(collapseTimer);
          });
          
          displayArea.addEventListener('mouseleave', () => {
              scheduleCollapse(container);
          });
      }
      
      function attachTooltipListeners(container) {
          console.log('Dynamic GIF Displayer: Attaching tooltip listeners...');
          
          const gifMap = buildGifMap(container);
          console.log('Dynamic GIF Displayer: GIF map', gifMap);
          
          const tooltips = document.querySelectorAll('.advanced-tooltip');
          console.log('Dynamic GIF Displayer: Found', tooltips.length, 'tooltips');
          
          tooltips.forEach((tooltip) => {
              const skillTitle = tooltip.querySelector('.skill-title');
              if (!skillTitle) return;
              
              const skillName = skillTitle.textContent.trim();
              const gifUrl = gifMap[skillName];
              
              console.log('Dynamic GIF Displayer: Processing tooltip:', skillName, 'GIF:', gifUrl);
              
              if (gifUrl) {
                  // Remove old listeners if they exist
                  if (tooltip._gifHoverHandler) {
                      tooltip.removeEventListener('mouseenter', tooltip._gifHoverHandler);
                  }
                  if (tooltip._gifLeaveHandler) {
                      tooltip.removeEventListener('mouseleave', tooltip._gifLeaveHandler);
                  }
                  
                  tooltip._gifHoverHandler = () => handleTooltipHover(container, gifUrl, skillName);
                  tooltip._gifLeaveHandler = () => scheduleCollapse(container);
                  
                  tooltip.addEventListener('mouseenter', tooltip._gifHoverHandler);
                  tooltip.addEventListener('mouseleave', tooltip._gifLeaveHandler);
                  
                  console.log('Dynamic GIF Displayer: Attached listeners to', skillName);
              }
          });
      }
      
      function buildGifMap(container) {
          const gifMap = {};
          const listData = container.getAttribute('data-gif-list');
          
          if (!listData) {
              console.error('Dynamic GIF Displayer: No data-gif-list attribute found');
              return gifMap;
          }
          
          console.log('Dynamic GIF Displayer: Raw list data:', listData);
          
          const entries = listData.split(';').filter(e => e.trim());
          console.log('Dynamic GIF Displayer: Found', entries.length, 'entries');
          
          entries.forEach(entry => {
              const parts = entry.split(':');
              if (parts.length >= 2) {
                  const skillName = parts[0].trim();
                  const gifFile = parts.slice(1).join(':').trim();
                  
                  if (skillName && gifFile) {
                      let gifUrl;
                      if (typeof mw !== 'undefined' && mw.config) {
                          const scriptPath = mw.config.get('wgScriptPath') || '';
                          gifUrl = scriptPath + '/index.php?title=Special:Redirect/file/' + encodeURIComponent(gifFile);
                      } else {
                          gifUrl = '/index.php?title=Special:Redirect/file/' + encodeURIComponent(gifFile);
                      }
                      
                      gifMap[skillName] = gifUrl;
                      console.log('Dynamic GIF Displayer: Mapped "' + skillName + '" to', gifUrl);
                  }
              }
          });
          
          return gifMap;
      }
      
    function handleTooltipHover(container, gifUrl, skillName) {
        console.log('Dynamic GIF Displayer: Hovering', skillName);
        clearTimeout(collapseTimer);
        clearTimeout(expandTimer);
        
        // Show GIF after delay (allows checking if different from current)
        expandTimer = setTimeout(() => {
            showGif(container, gifUrl, skillName);
        }, CONFIG.expandDelay);
    }
  
    function showGif(container, gifUrl, skillName) {
        console.log('Dynamic GIF Displayer: Showing GIF for', skillName, gifUrl);
        
        const displayArea = container.querySelector('.' + CONFIG.displayClass);
        if (!displayArea) return;
        
        if (!container.classList.contains('expanded')) {
            container.classList.add('expanded');
            console.log('Dynamic GIF Displayer: Expanded container');
        }
        
        const imgContainer = displayArea.querySelector('.gif-image-container');
        const caption = displayArea.querySelector('.gif-caption');
        
        // Update caption immediately
        if (caption) {
            caption.textContent = skillName;
            caption.style.display = 'block';
        }
        
        // Only reload if different GIF
        if (currentGif === gifUrl) {
            console.log('Dynamic GIF Displayer: Already showing', skillName);
            return;
        }
        
        // Set currentGif IMMEDIATELY to prevent race conditions
        currentGif = gifUrl;
        
        if (imgContainer) {
            const placeholder = imgContainer.querySelector('.gif-placeholder');
            if (placeholder) {
                placeholder.remove();
            }
            
            // Don't set dynamic height - let CSS handle fixed sizing
            
            const gifFilename = gifUrl.split('/').pop();
            const decodedFilename = decodeURIComponent(gifFilename);
            
            if (decodedFilename.toLowerCase() === 'blank' || decodedFilename.toLowerCase() === 'blank.gif') {
                imgContainer.innerHTML = '';
                imgContainer.appendChild(safeCreatePlaceholder('This node does not require a GIF due to its simplicity.'));
                imgContainer.classList.remove('loading');
            } else {
                // Cancel any existing image loads
                const existingImg = imgContainer.querySelector('img');
                if (existingImg) {
                    existingImg.onload = null;
                    existingImg.onerror = null;
                }
                
                imgContainer.classList.add('loading');
                
                const img = document.createElement('img');
                img.src = gifUrl;
                img.alt = skillName;
                // CSS handles sizing via .gif-image-container img rules
                
                // Store reference for validation
                const targetGif = gifUrl;
                
                img.onload = () => {
                    // Only update if this is still the current target GIF
                    if (currentGif === targetGif) {
                        imgContainer.innerHTML = '';
                        imgContainer.appendChild(img);
                        imgContainer.classList.remove('loading');
                        console.log('Dynamic GIF Displayer: GIF loaded successfully');
                    } else {
                        console.log('Dynamic GIF Displayer: Discarded outdated load for', skillName);
                    }
                };
                
                img.onerror = () => {
                    // Only update if this is still the current target GIF
                    if (currentGif === targetGif) {
                        imgContainer.innerHTML = '';
                        imgContainer.appendChild(safeCreateError('GIF not found: ' + decodedFilename));
                        imgContainer.classList.remove('loading');
                        console.error('Dynamic GIF Displayer: Failed to load GIF', gifUrl);
                    }
                };
            }
        }
    }
      
      function scheduleCollapse(container) {
          // Keep the most recent GIF displayed instead of clearing it
          // GIF will only change when a different skill node is hovered
          clearTimeout(collapseTimer);
          console.log('Dynamic GIF Displayer: Keeping current GIF displayed');
      }
      
      window.toggleGifDisplay = function(containerId) {
          console.log('Dynamic GIF Displayer: Toggle clicked for', containerId);
          const container = document.getElementById(containerId);
          if (!container) {
              console.error('Dynamic GIF Displayer: Container not found', containerId);
              return;
          }
          
          clearTimeout(collapseTimer);
          
          if (container.style.display === 'none') {
              container.style.display = 'block';
          } else {
              container.style.display = 'none';
          }
          
          // Only clear the GIF when manually toggling the display off
          if (container.style.display === 'none') {
              const displayArea = container.querySelector('.' + CONFIG.displayClass);
              if (displayArea) {
                  const imgContainer = displayArea.querySelector('.gif-image-container');
                  const caption = displayArea.querySelector('.gif-caption');
                  
                  if (imgContainer) {
                      imgContainer.innerHTML = '';
                      imgContainer.appendChild(safeCreatePlaceholder('Hover over a skill node to see its demonstration'));
                      imgContainer.style.height = '';
                      imgContainer.style.minHeight = '';
                  }
                  
                  if (caption) {
                      caption.textContent = '';
                      caption.style.display = 'none';
                  }
              }
              
              container.classList.remove('expanded');
              currentGif = null;
          }
      };
      
      if (document.readyState === 'loading') {
          document.addEventListener('DOMContentLoaded', init);
      } else {
          init();
      }
      
      window.addEventListener('load', init);
      
      if (typeof mw !== 'undefined' && mw.hook) {
          mw.hook('wikipage.content').add(init);
      }
      
      const observer = new MutationObserver(function(mutations) {
          let shouldReinit = false;
          mutations.forEach(function(mutation) {
              if (mutation.addedNodes.length) {
                  mutation.addedNodes.forEach(function(node) {
                      if (node.nodeType === 1 && (
                          node.classList && node.classList.contains('advanced-tooltip') ||
                          node.querySelector && node.querySelector('.advanced-tooltip')
                      )) {
                          shouldReinit = true;
                      }
                  });
              }
          });
          if (shouldReinit) {
              console.log('Dynamic GIF Displayer: Content changed, reinitializing...');
              setTimeout(init, 100);
          }
      });
      
      observer.observe(document.body, {
          childList: true,
          subtree: true
      });
      
      console.log('Dynamic GIF Displayer: Script loaded');
})();

/* Make mp-links clickable anywhere in the box */
(function() {
    'use strict';
    
    function initMpLinksClick() {
        const mpLinkItems = document.querySelectorAll('.mp-links > ul > li');
        
        mpLinkItems.forEach(item => {
            // Remove any existing click handler
            if (item._clickHandlerAttached) return;
            
            item.addEventListener('click', function(e) {
                // Find the first anchor tag in this li
                const link = this.querySelector('a');
                if (link && e.target !== link) {
                    // Trigger a click on the link
                    link.click();
                }
            });
            
            item._clickHandlerAttached = true;
        });
    }
    
    // Initialize on page load
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initMpLinksClick);
    } else {
        initMpLinksClick();
    }
    
    // Reinitialize when content changes
    window.addEventListener('load', initMpLinksClick);
    
    if (typeof mw !== 'undefined' && mw.hook) {
        mw.hook('wikipage.content').add(initMpLinksClick);
    }
    
    // Watch for DOM changes
    const observer = new MutationObserver(function(mutations) {
        let shouldReinit = false;
        mutations.forEach(function(mutation) {
            if (mutation.addedNodes.length) {
                mutation.addedNodes.forEach(function(node) {
                    if (node.nodeType === 1 && (
                        node.classList && node.classList.contains('mp-links') ||
                        node.querySelector && node.querySelector('.mp-links')
                    )) {
                        shouldReinit = true;
                    }
                });
            }
        });
        if (shouldReinit) {
            setTimeout(initMpLinksClick, 100);
        }
    });
    
    observer.observe(document.body, {
        childList: true,
        subtree: true
    });
})();

(function() {
      'use strict';
      
      console.log('Tab GIF Display: Script loading...');
      
      // Configuration
      const CONFIG = {
          containerClass: 'tab-gif-container',
          displayClass: 'tab-gif-display-area',
          tabsClass: 'tab-gif-tabs',
          tabClass: 'tab-gif-tab',
          activeTabClass: 'tab-gif-active'
      };
      
      let currentContainers = new Map();
      let initAttempts = 0;
      const MAX_INIT_ATTEMPTS = 5;
      
      function safeCreateError(message) {
          const div = document.createElement('div');
          div.className = 'gif-error';
          div.textContent = message;
          return div;
      }
      
      function safeCreatePlaceholder(message) {
          const div = document.createElement('div');
          div.className = 'gif-placeholder';
          div.textContent = message;
          return div;
      }
      
      function init() {
          initAttempts++;
          console.log('Tab GIF Display: Initializing... (attempt ' + initAttempts + ')');
          
          const containers = document.querySelectorAll('.' + CONFIG.containerClass);
          console.log('Tab GIF Display: Found', containers.length, 'containers');
          
          if (containers.length === 0 && initAttempts < MAX_INIT_ATTEMPTS) {
              console.log('Tab GIF Display: No containers found yet, will retry...');
              setTimeout(init, 500);
              return;
          }
          
          let setupCount = 0;
          containers.forEach(container => {
              const containerId = container.id;
              console.log('Tab GIF Display: Checking container', containerId);
              
              if (!currentContainers.has(containerId)) {
                  console.log('Tab GIF Display: Setting up NEW container', containerId);
                  const success = setupContainer(container);
                  if (success) {
                      currentContainers.set(containerId, container);
                      setupCount++;
                  }
              } else {
                  console.log('Tab GIF Display: Container already initialized', containerId);
              }
          });
          
          console.log('Tab GIF Display: Successfully set up', setupCount, 'containers');
      }
      
      function setupContainer(container) {
          console.log('Tab GIF Display: setupContainer called for', container.id);
          
          const gifMap = buildGifMap(container);
          console.log('Tab GIF Display: GIF map built', gifMap);
          
          if (Object.keys(gifMap).length === 0) {
              console.error('Tab GIF Display: No GIFs found for container', container.id);
              const displayArea = container.querySelector('.' + CONFIG.displayClass);
              if (displayArea) {
                  const imgContainer = displayArea.querySelector('.gif-image-container');
                  if (imgContainer) {
                      imgContainer.innerHTML = '';
                      imgContainer.appendChild(safeCreateError('No GIFs configured. Check your list parameter.'));
                  }
              }
              return false;
          }
          
          createTabs(container, gifMap);
          
          // Display the first GIF by default
          const firstTabName = Object.keys(gifMap)[0];
          console.log('Tab GIF Display: Showing first tab:', firstTabName);
          showGif(container, gifMap[firstTabName], firstTabName);
          
          return true;
      }
      
      function buildGifMap(container) {
          const gifMap = {};
          const listData = container.getAttribute('data-gif-list');
          
          console.log('Tab GIF Display: Building map for container', container.id);
          console.log('Tab GIF Display: data-gif-list attribute:', listData);
          
          if (!listData) {
              console.error('Tab GIF Display: No data-gif-list attribute found on', container.id);
              return gifMap;
          }
          
          if (listData.trim() === '') {
              console.error('Tab GIF Display: data-gif-list is empty on', container.id);
              return gifMap;
          }
          
          const entries = listData.split(';').filter(e => e.trim());
          console.log('Tab GIF Display: Found', entries.length, 'entries in list');
          
          entries.forEach((entry, index) => {
              console.log('Tab GIF Display: Processing entry', index, ':', entry);
              const parts = entry.split(':');
              
              if (parts.length < 2) {
                  console.warn('Tab GIF Display: Invalid entry format (no colon):', entry);
                  return;
              }
              
              const tabName = parts[0].trim();
              const gifFile = parts.slice(1).join(':').trim();
              
              console.log('Tab GIF Display: Parsed - Tab:', tabName, 'File:', gifFile);
              
              if (!tabName) {
                  console.warn('Tab GIF Display: Empty tab name in entry:', entry);
                  return;
              }
              
              if (!gifFile) {
                  console.warn('Tab GIF Display: Empty gif file in entry:', entry);
                  return;
              }
              
              let gifUrl;
              if (typeof mw !== 'undefined' && mw.config) {
                  const scriptPath = mw.config.get('wgScriptPath') || '';
                  gifUrl = scriptPath + '/index.php?title=Special:Redirect/file/' + encodeURIComponent(gifFile);
              } else {
                  gifUrl = '/index.php?title=Special:Redirect/file/' + encodeURIComponent(gifFile);
              }
              
              gifMap[tabName] = gifUrl;
              console.log('Tab GIF Display: Mapped "' + tabName + '" to', gifUrl);
          });
          
          console.log('Tab GIF Display: Final map has', Object.keys(gifMap).length, 'entries');
          return gifMap;
      }
      
      function createTabs(container, gifMap) {
          const tabsContainer = container.querySelector('.' + CONFIG.tabsClass);
          if (!tabsContainer) {
              console.error('Tab GIF Display: No tabs container found in', container.id);
              return;
          }
          
          console.log('Tab GIF Display: Creating tabs in', container.id);
          
          tabsContainer.innerHTML = '';
          
          let isFirst = true;
          let tabCount = 0;
          
          Object.keys(gifMap).forEach(tabName => {
              const tab = document.createElement('button');
              tab.className = CONFIG.tabClass;
              tab.textContent = tabName;
              tab.setAttribute('data-tab-name', tabName);
              tab.type = 'button';
              
              if (isFirst) {
                  tab.classList.add(CONFIG.activeTabClass);
                  isFirst = false;
              }
              
              tab.addEventListener('click', () => {
                  console.log('Tab GIF Display: Tab clicked:', tabName);
                  handleTabClick(container, gifMap, tabName);
              });
              
              tabsContainer.appendChild(tab);
              tabCount++;
              console.log('Tab GIF Display: Created tab button for', tabName);
          });
          
          console.log('Tab GIF Display: Created', tabCount, 'tabs total');
      }
      
      function handleTabClick(container, gifMap, tabName) {
          console.log('Tab GIF Display: Handling tab click for', tabName);
          
          const tabs = container.querySelectorAll('.' + CONFIG.tabClass);
          tabs.forEach(tab => {
              if (tab.getAttribute('data-tab-name') === tabName) {
                  tab.classList.add(CONFIG.activeTabClass);
              } else {
                  tab.classList.remove(CONFIG.activeTabClass);
              }
          });
          
          const gifUrl = gifMap[tabName];
          showGif(container, gifUrl, tabName);
      }
      
      function showGif(container, gifUrl, tabName) {
          console.log('Tab GIF Display: Showing GIF for', tabName, '-', gifUrl);
          
          const displayArea = container.querySelector('.' + CONFIG.displayClass);
          if (!displayArea) {
              console.error('Tab GIF Display: No display area found');
              return;
          }
          
          const rawSize = container.getAttribute('data-gif-size') || '400';
          const gifSize = rawSize.replace(/[^0-9]/g, '') || '400';
          
          const imgContainer = displayArea.querySelector('.gif-image-container');
          const caption = displayArea.querySelector('.gif-caption');
          
          if (imgContainer) {
              const placeholder = imgContainer.querySelector('.gif-placeholder');
              if (placeholder) {
                  placeholder.remove();
              }
              
              imgContainer.style.height = gifSize + 'px';
              imgContainer.style.minHeight = gifSize + 'px';
              
              const gifFilename = gifUrl.split('/').pop();
              const decodedFilename = decodeURIComponent(gifFilename);
              
              if (decodedFilename.toLowerCase() === 'blank' || decodedFilename.toLowerCase() === 'blank.gif') {
                  imgContainer.innerHTML = '';
                  imgContainer.appendChild(safeCreatePlaceholder('No GIF available for this tab.'));
                  imgContainer.classList.remove('loading');
              } else {
                  const oldImg = imgContainer.querySelector('img');
                  
                  const img = document.createElement('img');
                  img.src = gifUrl;
                  img.alt = tabName;
                  img.style.maxHeight = gifSize + 'px';
                  img.style.opacity = '0';
                  img.style.position = 'absolute';
                  img.style.transition = 'opacity 0.2s ease';
                  
                  img.onload = () => {
                      if (oldImg) {
                          oldImg.style.transition = 'opacity 0.15s ease';
                          oldImg.style.opacity = '0';
                          setTimeout(() => {
                              imgContainer.innerHTML = '';
                              img.style.position = 'relative';
                              img.style.opacity = '1';
                              imgContainer.appendChild(img);
                              imgContainer.classList.remove('loading');
                          }, 150);
                      } else {
                          imgContainer.innerHTML = '';
                          img.style.position = 'relative';
                          img.style.opacity = '1';
                          imgContainer.appendChild(img);
                          imgContainer.classList.remove('loading');
                      }
                      console.log('Tab GIF Display: GIF loaded successfully');
                  };
                  
                  img.onerror = () => {
                      imgContainer.innerHTML = '';
                      imgContainer.appendChild(safeCreateError('GIF not found: ' + decodedFilename));
                      imgContainer.classList.remove('loading');
                      console.error('Tab GIF Display: Failed to load GIF', gifUrl);
                  };
                  
                  if (!oldImg) {
                      imgContainer.appendChild(img);
                      imgContainer.classList.add('loading');
                  }
              }
          }
          
          if (caption) {
              caption.textContent = tabName;
              caption.style.display = 'block';
          }
      }
      
      window.toggleTabGifDisplay = function(containerId) {
          console.log('Tab GIF Display: Toggle clicked for', containerId);
          const container = document.getElementById(containerId);
          if (!container) {
              console.error('Tab GIF Display: Container not found', containerId);
              return;
          }
          
          if (container.style.display === 'none') {
              container.style.display = 'block';
          } else {
              container.style.display = 'none';
          }
      };
      
      if (document.readyState === 'loading') {
          document.addEventListener('DOMContentLoaded', init);
      } else {
          init();
      }
      
      window.addEventListener('load', init);
      
      if (typeof mw !== 'undefined' && mw.hook) {
          mw.hook('wikipage.content').add(init);
      }
      
      const observer = new MutationObserver(function(mutations) {
          let shouldReinit = false;
          mutations.forEach(function(mutation) {
              if (mutation.addedNodes.length) {
                  mutation.addedNodes.forEach(function(node) {
                      if (node.nodeType === 1 && (
                          node.classList && node.classList.contains(CONFIG.containerClass) ||
                          node.querySelector && node.querySelector('.' + CONFIG.containerClass)
                      )) {
                          shouldReinit = true;
                      }
                  });
              }
          });
          if (shouldReinit) {
              console.log('Tab GIF Display: Content changed, reinitializing...');
              setTimeout(init, 100);
          }
      });
      
      observer.observe(document.body, {
          childList: true,
          subtree: true
      });
      
      console.log('Tab GIF Display: Script loaded and ready');
  })();
  
  (function () {
      const images = [
          'url(/wiki/Special:Redirect/file/Site-background-image.jpg)',
          'url(/wiki/Special:Redirect/file/Site-background-image2.jpg)',
          'url(/wiki/Special:Redirect/file/Site-background-image3.jpg)',
      ];
  
      // Pick deterministic daily seed
      const day = new Date().getDate();
  
      // Deterministic shuffle using day as seed
      function seededRandom(seed) {
          return Math.abs(Math.sin(seed)) % 1;
      }
  
      const pick1 = Math.floor(seededRandom(day) * images.length);
      let pick2 = Math.floor(seededRandom(day + 1) * images.length);
  
      if (pick2 === pick1) pick2 = (pick2 + 1) % images.length;
  
      document.body.style.backgroundImage = images[pick1];
  
      const footer = document.querySelector('.mw-footer');
      if (footer) footer.style.backgroundImage = images[pick2];
  })();