<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://horizonffxi.wiki/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=HuginBot</id>
	<title>HorizonXI Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://horizonffxi.wiki/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=HuginBot"/>
	<link rel="alternate" type="text/html" href="https://horizonffxi.wiki/Special:Contributions/HuginBot"/>
	<updated>2026-04-16T21:38:35Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://horizonffxi.wiki/w/index.php?title=MediaWiki:Common.js&amp;diff=118881</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://horizonffxi.wiki/w/index.php?title=MediaWiki:Common.js&amp;diff=118881"/>
		<updated>2026-04-10T17:43:17Z</updated>

		<summary type="html">&lt;p&gt;HuginBot: Added OAuth popup&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;mw.loader.getScript( &#039;https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js&#039; );&lt;br /&gt;
mw.loader.getScript( &#039;/w/index.php?action=raw&amp;amp;ctype=text/javascript&amp;amp;title=MediaWiki:VanaTime.js&#039; );&lt;br /&gt;
mw.loader.getScript( &#039;/w/index.php?action=raw&amp;amp;ctype=text/javascript&amp;amp;title=MediaWiki:ASBSearch.js&#039; );&lt;br /&gt;
//mw.loader.getScript( &#039;/w/index.php?action=raw&amp;amp;ctype=text/javascript&amp;amp;title=MediaWiki:FFXIWeatherForecast.js&#039; );&lt;br /&gt;
&lt;br /&gt;
var tooltips = {&lt;br /&gt;
    debug: false,&lt;br /&gt;
    &lt;br /&gt;
    api: false,&lt;br /&gt;
    types: [],&lt;br /&gt;
    classes: [&#039;basic-tooltip&#039;, &#039;advanced-tooltip&#039;],&lt;br /&gt;
    advancedCounter: 1,&lt;br /&gt;
    &lt;br /&gt;
    events: [],&lt;br /&gt;
    timeouts: [],&lt;br /&gt;
    &lt;br /&gt;
    offsetX: 20,&lt;br /&gt;
    offsetY: 20,&lt;br /&gt;
    waitForImages: true,&lt;br /&gt;
    noCSS: false,&lt;br /&gt;
    &lt;br /&gt;
    flip: false,&lt;br /&gt;
    &lt;br /&gt;
    init: function() {&lt;br /&gt;
        if($(document.body).hasClass(&#039;mw-special-InfoboxBuilder&#039;)) return;&lt;br /&gt;
        if(location.search.search(/ttdebug=(1|[Tt]rue)/) != -1 || (typeof tooltips_debug != &#039;undefined&#039; &amp;amp;&amp;amp; tooltips_debug)) tooltips.debug = true;&lt;br /&gt;
&lt;br /&gt;
        url = new URL($(&#039;link[rel=&amp;quot;canonical&amp;quot;]&#039;).attr(&#039;href&#039;));&lt;br /&gt;
&lt;br /&gt;
        if(typeof url == &#039;undefined&#039; || !url) {&lt;br /&gt;
            console.log(&#039;Tooltips: script couldn\&#039;t find required  link[rel=&amp;quot;canonical&amp;quot;]  tag&#039;);&lt;br /&gt;
            tooltips.disabled = true;&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
        tooltips.api = url.host+&#039;/api.php?format=json&amp;amp;action=parse&amp;amp;disablelimitreport=true&amp;amp;prop=text&amp;amp;title=&#039;+url.pathname;&lt;br /&gt;
        if(mw.util.getParamValue(&#039;uselang&#039;)) tooltips.api += &#039;&amp;amp;uselang=&#039;+mw.util.getParamValue(&#039;uselang&#039;);&lt;br /&gt;
		// Cache tooltip contents on the CDN for 10 minutes for anonymous users&lt;br /&gt;
		tooltips.api += &#039;&amp;amp;maxage=600&amp;amp;smaxage=600&#039;&lt;br /&gt;
        tooltips.api += &#039;&amp;amp;text=&#039;;&lt;br /&gt;
        &lt;br /&gt;
        tooltips.types[&#039;basic-tooltip&#039;] = {};&lt;br /&gt;
        tooltips.types[&#039;advanced-tooltip&#039;] = {};&lt;br /&gt;
        &lt;br /&gt;
        if(!tooltips.config()) {&lt;br /&gt;
            console.log(&#039;Tooltips: missing config&#039;);&lt;br /&gt;
            tooltips.disabled = true;&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        var content = $(&#039;#WikiaMainContent&#039;);&lt;br /&gt;
        if(!content.length) content = $(&#039;#mw-content-text&#039;);&lt;br /&gt;
                &lt;br /&gt;
        if($(&#039;#tooltip-wrapper&#039;).length === 0) $(&#039;&amp;lt;div id=&amp;quot;tooltip-wrapper&amp;quot; class=&amp;quot;WikiaArticle&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;).appendTo(document.body);&lt;br /&gt;
        if($(&#039;#tooltip-storage&#039;).length === 0) $(&#039;&amp;lt;div id=&amp;quot;tooltip-storage&amp;quot; class=&amp;quot;WikiaArticle&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;).append(&#039;&amp;lt;div class=&amp;quot;main-tooltip tt-basic-tooltip&amp;quot; id=&amp;quot;tooltip-basic-tooltip&amp;quot;&amp;gt;Lorem ipsum dolor sit amet&amp;lt;/div&amp;gt;&#039;).appendTo(content);&lt;br /&gt;
        &lt;br /&gt;
        $(&#039;#tooltip-wrapper&#039;)&lt;br /&gt;
            .css({&#039;margin&#039;:&#039;0px&#039;,&#039;position&#039;:&#039;fixed&#039;,&#039;height&#039;:&#039;auto&#039;,&#039;min-height&#039;:&#039;0&#039;,&#039;z-index&#039;: 6000000,&#039;font-size&#039;:&#039;14px&#039;})&lt;br /&gt;
            .hide();&lt;br /&gt;
        &lt;br /&gt;
        $(&#039;#tooltip-storage&#039;)&lt;br /&gt;
            .css({&#039;height&#039;:&#039;0px&#039;,&#039;min-height&#039;:&#039;0&#039;,&#039;visibility&#039;:&#039;hidden&#039;,&#039;overflow&#039;:&#039;hidden&#039;,&#039;position&#039;:&#039;static&#039;,&#039;font-size&#039;:&#039;14px&#039;});&lt;br /&gt;
&lt;br /&gt;
        $(&#039;#tooltip-basic-tooltip&#039;).data(&#039;type&#039;, &#039;basic-tooltip&#039;);&lt;br /&gt;
        &lt;br /&gt;
        tooltips.applyTooltips(document);&lt;br /&gt;
        &lt;br /&gt;
        mw.hook(&#039;wikipage.content&#039;).add(function(elem) {&lt;br /&gt;
            tooltips.applyTooltips($(elem));&lt;br /&gt;
        });&lt;br /&gt;
        &lt;br /&gt;
        if(typeof tooltips.events == &#039;string&#039;) tooltips.events = [tooltips.events];&lt;br /&gt;
        for(var x=0; x&amp;lt;tooltips.events.length; x++) { $(window).on(tooltips.events[x], function(ev, elem) { tooltips.applyTooltips(elem || this) }) }&lt;br /&gt;
        &lt;br /&gt;
        if(tooltips.debug) {&lt;br /&gt;
            $(&#039;#tooltip-wrapper&#039;).css({&#039;background-color&#039;:&#039;rgba(255,0,0,0.2)&#039;});&lt;br /&gt;
            $(&#039;#tooltip-storage&#039;).css({&#039;background-color&#039;:&#039;rgba(0,255,0,0.2)&#039;,&#039;height&#039;:&#039;500px&#039;,&#039;overflow-y&#039;:&#039;scroll&#039;,&#039;visibility&#039;:&#039;visible&#039;});&lt;br /&gt;
        }&lt;br /&gt;
    },&lt;br /&gt;
    config: function() {&lt;br /&gt;
        if(typeof tooltips_list != &#039;undefined&#039;) {&lt;br /&gt;
            $(tooltips_list).each(function(i, v) { tooltips.addType(v) });&lt;br /&gt;
        }&lt;br /&gt;
        if(typeof tooltips_config == &#039;object&#039;) {&lt;br /&gt;
            tooltips.offsetX = tooltips_config.offsetX || tooltips.offsetX;&lt;br /&gt;
            tooltips.offsetY = tooltips_config.offsetY || tooltips.offsetY;&lt;br /&gt;
            tooltips.waitForImages = (tooltips_config.waitForImages || tooltips.waitForImages) &amp;amp;&amp;amp; true;&lt;br /&gt;
            tooltips.noCSS = tooltips_config.noCSS || tooltips.noCSS;&lt;br /&gt;
            tooltips.events = tooltips_config.events || tooltips.events;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return true;&lt;br /&gt;
    },&lt;br /&gt;
    applyTooltips: function(elem) {&lt;br /&gt;
        $(elem).find(&#039;.&#039;+tooltips.classes.join(&#039;, .&#039;)).each(function() {&lt;br /&gt;
            $this = $(this);&lt;br /&gt;
            if($this.hasClass(&#039;tooltips-init-complete&#039;)) return;&lt;br /&gt;
            &lt;br /&gt;
            $this.find(&#039;*&#039;).removeAttr(&#039;title&#039;);&lt;br /&gt;
            $this.mouseover(tooltips.handlers.mouseOver);&lt;br /&gt;
            $this.mouseout(tooltips.handlers.mouseOut);&lt;br /&gt;
            $this.mousemove(tooltips.handlers.mouseMove);&lt;br /&gt;
            &lt;br /&gt;
            $this.data(&#039;tooltip-contents&#039;, $(this).attr(&#039;title&#039;));&lt;br /&gt;
            $this.removeAttr(&#039;title&#039;);&lt;br /&gt;
            &lt;br /&gt;
            tooltips.advancedTooltip($this);&lt;br /&gt;
            &lt;br /&gt;
            $(this).addClass(&#039;tooltips-init-complete&#039;);&lt;br /&gt;
        });&lt;br /&gt;
    },&lt;br /&gt;
    advancedTooltip: function(elem) {&lt;br /&gt;
        elem = $(elem);&lt;br /&gt;
        if(!elem.hasClass(&#039;advanced-tooltip&#039;)) return;&lt;br /&gt;
        var tips = elem.find(&#039;.tooltip-contents&#039;);&lt;br /&gt;
        if(!tips.length) return;&lt;br /&gt;
        var tip = $(&#039;&amp;lt;div class=&amp;quot;main-tooltip tt-advanced-tooltip&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;).attr(&#039;id&#039;, &#039;tooltip-advanced-tooltip-&#039;+tooltips.advancedCounter).appendTo(&#039;#tooltip-storage&#039;).data(&#039;type&#039;, &#039;advanced-tooltip&#039;).append($(tips[0]).contents()).each(tooltips.calcSize);&lt;br /&gt;
        tips.remove();&lt;br /&gt;
        elem.data(&#039;tooltip-id-advanced-tooltip&#039;, tooltips.advancedCounter);&lt;br /&gt;
        tooltips.advancedCounter++;&lt;br /&gt;
    },&lt;br /&gt;
    addType: function(tt) {&lt;br /&gt;
        if(typeof tooltips.types[tt.classname] == &#039;undefined&#039;) {&lt;br /&gt;
            var obj = {};&lt;br /&gt;
            &lt;br /&gt;
            if(typeof tt.parse == &#039;string&#039; || typeof tt.parse == &#039;function&#039;) var parse = tt.parse; else var parse = false;&lt;br /&gt;
            if(typeof tt.text == &#039;string&#039; || typeof tt.text == &#039;function&#039;) var text = tt.text; else var text = false;&lt;br /&gt;
            &lt;br /&gt;
            if(parse) {&lt;br /&gt;
                obj.text = parse;&lt;br /&gt;
                obj.parse = true;&lt;br /&gt;
            } else if(text) {&lt;br /&gt;
                obj.text = text;&lt;br /&gt;
                obj.parse = false;&lt;br /&gt;
            } else return;&lt;br /&gt;
            &lt;br /&gt;
            if(typeof obj.text == &#039;string&#039;) obj.parameters = tooltips.getParameters(obj.text); else obj.parameters = [];&lt;br /&gt;
            &lt;br /&gt;
            if(typeof tt.delay == &#039;string&#039; || typeof tt.delay == &#039;number&#039;) obj.delay = parseInt(tt.delay); else obj.delay = false;&lt;br /&gt;
            if(typeof tt.onParsed == &#039;function&#039;) obj.onParsed = tt.onParsed;&lt;br /&gt;
            if(typeof tt.onShow == &#039;function&#039;) obj.onShow = tt.onShow;&lt;br /&gt;
            if(typeof tt.onHide == &#039;function&#039;) obj.onHide = tt.onHide;&lt;br /&gt;
            &lt;br /&gt;
            tooltips.types[tt.classname] = obj;&lt;br /&gt;
            if(tooltips.classes.indexOf(tt.classname) == -1) tooltips.classes.push(tt.classname);&lt;br /&gt;
        } else {&lt;br /&gt;
            if(typeof tt.delay == &#039;string&#039; || typeof tt.delay == &#039;number&#039;) tooltips.types[tt.classname].delay = parseInt(tt.delay);&lt;br /&gt;
            if(typeof tt.onParsed == &#039;function&#039;) tooltips.types[tt.classname].onParsed = tt.onParsed;&lt;br /&gt;
            if(typeof tt.onShow == &#039;function&#039;) tooltips.types[tt.classname].onShow = tt.onShow;&lt;br /&gt;
            if(typeof tt.onHide == &#039;function&#039;) tooltips.types[tt.classname].onHide = tt.onHide;&lt;br /&gt;
        }&lt;br /&gt;
    },&lt;br /&gt;
    getParameters: function(text) {&lt;br /&gt;
        var list = [];&lt;br /&gt;
        var matches = text.match(/&amp;lt;#\s*[a-z0-9_\-]+?\s*#&amp;gt;/gi);&lt;br /&gt;
        if(matches) {&lt;br /&gt;
            for(var x=0; x&amp;lt;matches.length; x++) {&lt;br /&gt;
                list.push(/&amp;lt;#\s*([a-z0-9_\-]+?)\s*#&amp;gt;/i.exec(matches[x])[1]);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        return list;&lt;br /&gt;
    },&lt;br /&gt;
    getAPI: function(text) {&lt;br /&gt;
        return tooltips.api+encodeURIComponent(text);&lt;br /&gt;
    },&lt;br /&gt;
    getText: function(type, elem) {&lt;br /&gt;
        if(typeof tooltips.types[type].text == &#039;function&#039;) {&lt;br /&gt;
            var text = tooltips.types[type].text($(elem)[0]);&lt;br /&gt;
        } else {&lt;br /&gt;
            var text = tooltips.types[type].text;&lt;br /&gt;
            for(var x=0; x&amp;lt;tooltips.types[type].parameters.length; x++) {&lt;br /&gt;
                var param = tooltips.types[type].parameters[x];&lt;br /&gt;
                var value = $(elem).data(param);&lt;br /&gt;
                if(typeof value == &#039;undefined&#039;) value = &#039;&#039;;&lt;br /&gt;
                var rx = new RegExp(&#039;&amp;lt;#\\s*&#039;+param.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, &amp;quot;\\$&amp;amp;&amp;quot;)+&#039;\\s*#&amp;gt;&#039;, &#039;g&#039;);&lt;br /&gt;
                text = text.replace(rx, value);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        return text;&lt;br /&gt;
    },&lt;br /&gt;
    getTooltip: function(type, elem) {&lt;br /&gt;
        elem = $(elem);&lt;br /&gt;
        if(elem.data(&#039;tooltip-id-&#039;+type)) return $(&#039;#tooltip-&#039;+type+&#039;-&#039;+elem.data(&#039;tooltip-id-&#039;+type));&lt;br /&gt;
        &lt;br /&gt;
        var text = tooltips.getText(type, elem);&lt;br /&gt;
        var id = tooltips.hash(text);&lt;br /&gt;
        elem.data(&#039;tooltip-id-&#039;+type, id);&lt;br /&gt;
        &lt;br /&gt;
        var tip = $(&#039;#tooltip-&#039;+type+&#039;-&#039;+elem.data(&#039;tooltip-id-&#039;+type));&lt;br /&gt;
        if(tip.length) return tip;&lt;br /&gt;
        &lt;br /&gt;
        tip = $(&#039;&amp;lt;div class=&amp;quot;main-tooltip&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;).attr(&#039;id&#039;, &#039;tooltip-&#039;+type+&#039;-&#039;+id).appendTo(&#039;#tooltip-storage&#039;).data(&#039;type&#039;, type).addClass(&#039;tt-&#039;+type);&lt;br /&gt;
        &lt;br /&gt;
        tooltips.wrapperPosition(tooltips.lastKnownMousePos[0], tooltips.lastKnownMousePos[1]);&lt;br /&gt;
        tooltips.sameWidth();&lt;br /&gt;
        &lt;br /&gt;
        if(!tooltips.types[type].parse) {&lt;br /&gt;
            tip.html(text).each(tooltips.calcSize);&lt;br /&gt;
            tooltips.wrapperPosition(tooltips.lastKnownMousePos[0], tooltips.lastKnownMousePos[1]);&lt;br /&gt;
            tooltips.sameWidth();&lt;br /&gt;
        } else {&lt;br /&gt;
            tip.addClass(&#039;tooltip-loading&#039;);&lt;br /&gt;
            var api = tooltips.getAPI(text);&lt;br /&gt;
            if(tooltips.debug) tip.html(&#039;&amp;lt;pre style=&amp;quot;padding:2px 3px;font-size:11px;&amp;quot;&amp;gt;&#039;+api+&#039;&amp;lt;/pre&amp;gt;&#039;);&lt;br /&gt;
            tip.attr(&#039;title&#039;, api);&lt;br /&gt;
            $.ajax({&lt;br /&gt;
                url: api,&lt;br /&gt;
                dataType: &#039;json&#039;,&lt;br /&gt;
                context: tip,&lt;br /&gt;
                success: function(data, textStatus, jqXHR) {&lt;br /&gt;
                    $(this).html(data[&#039;parse&#039;][&#039;text&#039;][&#039;*&#039;]).each(tooltips.calcSize);&lt;br /&gt;
                    tooltips.wrapperPosition(tooltips.lastKnownMousePos[0], tooltips.lastKnownMousePos[1]);&lt;br /&gt;
                    tooltips.sameWidth();&lt;br /&gt;
                    var images = $(this).find(&#039;img&#039;);&lt;br /&gt;
                    images.fadeTo(0, 0).one(&#039;load&#039;, function() {&lt;br /&gt;
                        if(tooltips.waitForImages) {&lt;br /&gt;
                            $(this).fadeTo(0,1);&lt;br /&gt;
                            $(this).addClass(&#039;image-loaded&#039;);&lt;br /&gt;
                            tip = $(this).closest(&#039;.main-tooltip&#039;);&lt;br /&gt;
                            if(tip.find(&#039;img&#039;).length == tip.find(&#039;img.image-loaded&#039;).length) {&lt;br /&gt;
                                tip.removeClass(&#039;tooltip-loading&#039;).each(tooltips.calcSize);&lt;br /&gt;
                                tooltips.wrapperPosition(tooltips.lastKnownMousePos[0], tooltips.lastKnownMousePos[1]);&lt;br /&gt;
                                tooltips.sameWidth();&lt;br /&gt;
                            }&lt;br /&gt;
                        } else $(this).fadeTo(100,1);&lt;br /&gt;
                    });&lt;br /&gt;
                    if(tooltips.waitForImages) {&lt;br /&gt;
                        if(images.length === 0) {&lt;br /&gt;
                            $(this).removeClass(&#039;tooltip-loading&#039;).each(tooltips.calcSize);&lt;br /&gt;
                        }&lt;br /&gt;
                    } else {&lt;br /&gt;
                        $(this).removeClass(&#039;tooltip-loading&#039;).each(tooltips.calcSize);&lt;br /&gt;
                    }&lt;br /&gt;
                    var type = $(this).data(&#039;type&#039;) || false;&lt;br /&gt;
                    if(type &amp;amp;&amp;amp; typeof tooltips.types[type].onParsed == &#039;function&#039;) {&lt;br /&gt;
                        tooltips.types[type].onParsed.call(this);&lt;br /&gt;
                        tip.each(tooltips.calcSize);&lt;br /&gt;
                    }&lt;br /&gt;
                    if($(this).find(&#039;a.new&#039;).length &amp;gt; 0) $(this).addClass(&#039;has-redlinks&#039;);&lt;br /&gt;
                    tooltips.wrapperPosition(tooltips.lastKnownMousePos[0], tooltips.lastKnownMousePos[1]);&lt;br /&gt;
                    tooltips.sameWidth();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
        return tip;&lt;br /&gt;
    },&lt;br /&gt;
    getBasicTooltip: function(elem) {&lt;br /&gt;
        return $(&amp;quot;#tooltip-basic-tooltip&amp;quot;).html(mw.html.escape($(elem).data(&#039;tooltip-contents&#039;)).replace(/\\n/g,&#039;&amp;lt;br /&amp;gt;&#039;)).each(tooltips.calcSize);&lt;br /&gt;
    },&lt;br /&gt;
    getAdvancedTooltip: function(elem) {&lt;br /&gt;
        return $(&amp;quot;#tooltip-advanced-tooltip-&amp;quot;+$(elem).data(&#039;tooltip-id-advanced-tooltip&#039;));&lt;br /&gt;
    },&lt;br /&gt;
    getTooltips: function(elem) {&lt;br /&gt;
        elem = $(elem);&lt;br /&gt;
        var classes = elem.attr(&#039;class&#039;).split(&#039; &#039;);&lt;br /&gt;
        var tips = [];&lt;br /&gt;
        for(var i=0;i&amp;lt;classes.length;i++) {&lt;br /&gt;
            var tip = false;&lt;br /&gt;
            if(classes[i] == &#039;advanced-tooltip&#039;) tip = tooltips.getAdvancedTooltip(elem);&lt;br /&gt;
            else if(classes[i] == &#039;basic-tooltip&#039;) tip = tooltips.getBasicTooltip(elem);&lt;br /&gt;
            else if(typeof tooltips.types[classes[i]] != &#039;undefined&#039;) tip = tooltips.getTooltip(classes[i], elem);&lt;br /&gt;
            if(tip) tips.push(tip[0]);&lt;br /&gt;
        }&lt;br /&gt;
        return $(tips);&lt;br /&gt;
    },&lt;br /&gt;
    setOwnWidth: function() {&lt;br /&gt;
        $this = $(this);&lt;br /&gt;
        if(typeof $this.data(&#039;width&#039;) != &#039;undefined&#039;) $this.css(&#039;width&#039;, $this.data(&#039;width&#039;)+&#039;px&#039;);&lt;br /&gt;
        else $this.css(&#039;width&#039;, &#039;&#039;);&lt;br /&gt;
    },&lt;br /&gt;
    calcSize: function() {&lt;br /&gt;
        $this = $(this);&lt;br /&gt;
        $this.css(&#039;position&#039;, &#039;absolute&#039;);&lt;br /&gt;
        var temp = $this.css(&#039;width&#039;);&lt;br /&gt;
        $this.css(&#039;width&#039;, &#039;&#039;);&lt;br /&gt;
        $this.data(&#039;width&#039;, parseFloat(window.getComputedStyle($this[0]).width));&lt;br /&gt;
        $this.data(&#039;height&#039;, parseFloat(window.getComputedStyle($this[0]).height));&lt;br /&gt;
        $this.data(&#039;outerwidth&#039;, $this.outerWidth(true));&lt;br /&gt;
        $this.data(&#039;outerheight&#039;, $this.outerHeight(true));&lt;br /&gt;
        $this.css(&#039;width&#039;, $this.data(&#039;width&#039;)+&#039;px&#039;);&lt;br /&gt;
        $this.css(&#039;position&#039;, &#039;&#039;);&lt;br /&gt;
        $this.css(&#039;width&#039;, temp);&lt;br /&gt;
    },&lt;br /&gt;
    sameWidth: function() {&lt;br /&gt;
        if($(&amp;quot;#tooltip-wrapper&amp;quot;).find(&#039;.main-tooltip&#039;).length == 1) {&lt;br /&gt;
            $(&amp;quot;#tooltip-wrapper&amp;quot;).find(&#039;.main-tooltip&#039;).each(tooltips.setOwnWidth);&lt;br /&gt;
        } else {&lt;br /&gt;
            var width = 0;&lt;br /&gt;
            $(&amp;quot;#tooltip-wrapper&amp;quot;).find(&#039;.main-tooltip&#039;).each(function() { width = Math.max(width, $(this).data(&#039;width&#039;) || 0); });&lt;br /&gt;
            $(&amp;quot;#tooltip-wrapper&amp;quot;).find(&#039;.main-tooltip&#039;).each(function() { $(this).css(&#039;width&#039;, width+&#039;px&#039;); });&lt;br /&gt;
        }&lt;br /&gt;
    },&lt;br /&gt;
    wrapperPosition: function(mouseX, mouseY) {&lt;br /&gt;
        var tipH = parseInt($(&amp;quot;#tooltip-wrapper&amp;quot;).css(&#039;padding-top&#039;)) + parseInt($(&amp;quot;#tooltip-wrapper&amp;quot;).css(&#039;padding-bottom&#039;));&lt;br /&gt;
        var tipW = 0;&lt;br /&gt;
       &lt;br /&gt;
        $(&amp;quot;#tooltip-wrapper&amp;quot;).find(&#039;.main-tooltip&#039;).each( function(){ if(typeof $(this).data(&#039;outerheight&#039;) != &#039;undefined&#039;) tipH += $(this).data(&#039;outerheight&#039;); });&lt;br /&gt;
        $(&amp;quot;#tooltip-wrapper&amp;quot;).find(&#039;.main-tooltip&#039;).each( function(){ if(typeof $(this).data(&#039;outerwidth&#039;) != &#039;undefined&#039;) tipW = Math.max(tipW, $(this).data(&#039;outerwidth&#039;) + parseInt($(&amp;quot;#tooltip-wrapper&amp;quot;).css(&#039;padding-left&#039;)) + parseInt($(&amp;quot;#tooltip-wrapper&amp;quot;).css(&#039;padding-right&#039;))); });&lt;br /&gt;
        &lt;br /&gt;
        var spaceTop = mouseY - tooltips.offsetY;&lt;br /&gt;
        var spaceLeft = mouseX - tooltips.offsetX;&lt;br /&gt;
        var spaceRight = $(window).width() - mouseX - tooltips.offsetX;&lt;br /&gt;
        var spaceBottom = $(window).height() - mouseY - tooltips.offsetY;&lt;br /&gt;
        &lt;br /&gt;
        var coordX = mouseX + tooltips.offsetX;&lt;br /&gt;
        var coordY = mouseY + tooltips.offsetY;&lt;br /&gt;
        &lt;br /&gt;
        if(spaceRight &amp;lt; tipW &amp;amp;&amp;amp; spaceBottom &amp;lt; tipH) {&lt;br /&gt;
            if(spaceLeft &amp;gt;= tipW &amp;amp;&amp;amp; tooltips.flip != &#039;h&#039;) {&lt;br /&gt;
                coordX = mouseX - tipW - tooltips.offsetX;&lt;br /&gt;
                tooltips.flip = &#039;v&#039;;&lt;br /&gt;
            } else if(spaceTop &amp;gt;= tipH) {&lt;br /&gt;
                coordY = mouseY - tipH - tooltips.offsetY;&lt;br /&gt;
                tooltips.flip = &#039;h&#039;;&lt;br /&gt;
            } else {&lt;br /&gt;
                coordX = mouseX - tipW - tooltips.offsetX;&lt;br /&gt;
                coordY = mouseY - tipH - tooltips.offsetY;&lt;br /&gt;
                tooltips.flip = &#039;vh&#039;;&lt;br /&gt;
            }&lt;br /&gt;
        } else {&lt;br /&gt;
            tooltips.flip = false;&lt;br /&gt;
        }&lt;br /&gt;
        if ($(&amp;quot;#tooltip-wrapper&amp;quot;).css(&#039;position&#039;) == &#039;fixed&#039;) {&lt;br /&gt;
            coordX = coordX-$(window).scrollLeft();&lt;br /&gt;
            coordY = coordY-$(window).scrollTop();&lt;br /&gt;
            &lt;br /&gt;
            coordX = Math.min(coordX, $(window).width() - tipW);&lt;br /&gt;
            coordY = Math.min(coordY, $(window).height() - tipH);&lt;br /&gt;
        } else {&lt;br /&gt;
            coordX = Math.min(coordX, $(window).width() - tipW);&lt;br /&gt;
            coordY = Math.min(coordY, $(window).height() - tipH + $(window).scrollTop());&lt;br /&gt;
        }&lt;br /&gt;
        $(&amp;quot;#tooltip-wrapper&amp;quot;).css({left: coordX + &#039;px&#039;, top: coordY + &#039;px&#039;});&lt;br /&gt;
    },&lt;br /&gt;
    handlers: {&lt;br /&gt;
        mouseOver: function(e) {&lt;br /&gt;
            tooltips.lastKnownMousePos = [e.pageX, e.pageY];&lt;br /&gt;
            tooltips.wrapperPosition(e.pageX, e.pageY);&lt;br /&gt;
            &lt;br /&gt;
            var tips = tooltips.getTooltips(this);&lt;br /&gt;
            $(&amp;quot;#tooltip-wrapper&amp;quot;).prepend(tips).show();&lt;br /&gt;
            tooltips.sameWidth();&lt;br /&gt;
            &lt;br /&gt;
            var handle = this;&lt;br /&gt;
            tips.each(function() {&lt;br /&gt;
                var $this = $(this);&lt;br /&gt;
                var type = $(this).data(&#039;type&#039;) || false;&lt;br /&gt;
                &lt;br /&gt;
                $this.show();&lt;br /&gt;
                $(window).trigger(&#039;scroll&#039;);// trigger image lazy loader&lt;br /&gt;
                if(type &amp;amp;&amp;amp; typeof tooltips.types[type] != &#039;undefined&#039; &amp;amp;&amp;amp; tooltips.types[type].delay) {&lt;br /&gt;
                    $this.hide();&lt;br /&gt;
                    tooltips.timeouts[$(this).attr(&#039;id&#039;)] = setTimeout(function(){&lt;br /&gt;
                        $this.show();&lt;br /&gt;
                        if(type &amp;amp;&amp;amp; typeof tooltips.types[type].onShow == &#039;function&#039;) tooltips.types[type].onShow.call($this[0], handle);&lt;br /&gt;
                    }, tooltips.types[type].delay);&lt;br /&gt;
                } else if(type &amp;amp;&amp;amp; typeof tooltips.types[type].onShow == &#039;function&#039;) tooltips.types[type].onShow.call(this, handle);&lt;br /&gt;
            });&lt;br /&gt;
        },&lt;br /&gt;
        mouseOut: function(e) {&lt;br /&gt;
            tooltips.lastKnownMousePos = [e.pageX, e.pageY];&lt;br /&gt;
            tooltips.wrapperPosition(e.pageX, e.pageY);&lt;br /&gt;
            &lt;br /&gt;
            var handle = this;&lt;br /&gt;
            $(&amp;quot;#tooltip-wrapper&amp;quot;).hide();&lt;br /&gt;
            $(&amp;quot;#tooltip-wrapper&amp;quot;).find(&#039;.main-tooltip&#039;).appendTo(&#039;#tooltip-storage&#039;).each(function() {&lt;br /&gt;
                var type = $(this).data(&#039;type&#039;) || false;&lt;br /&gt;
                if(type &amp;amp;&amp;amp; typeof tooltips.types[type].onHide == &#039;function&#039;) tooltips.types[type].onHide.call(this, handle);&lt;br /&gt;
                $(this).show();&lt;br /&gt;
                clearTimeout(tooltips.timeouts[$(this).attr(&#039;id&#039;)]);&lt;br /&gt;
                delete tooltips.timeouts[$(this).attr(&#039;id&#039;)];&lt;br /&gt;
            });&lt;br /&gt;
        },&lt;br /&gt;
        mouseMove: function(e) {&lt;br /&gt;
            tooltips.lastKnownMousePos = [e.pageX, e.pageY];&lt;br /&gt;
            tooltips.wrapperPosition(e.pageX, e.pageY);&lt;br /&gt;
        },&lt;br /&gt;
    },&lt;br /&gt;
    hash: function(text) {&lt;br /&gt;
        /* Source: https://archive.is/nq2F9 */&lt;br /&gt;
        var hash = 0, i, char;&lt;br /&gt;
        if (text.length === 0) return hash;&lt;br /&gt;
        for (i = 0, l = text.length; i &amp;lt; l; i++) {&lt;br /&gt;
            char  = text.charCodeAt(i);&lt;br /&gt;
            hash  = ((hash&amp;lt;&amp;lt;5)-hash)+char;&lt;br /&gt;
            hash |= 0; // Convert to 32bit integer&lt;br /&gt;
        }&lt;br /&gt;
        return hash;&lt;br /&gt;
    },&lt;br /&gt;
};&lt;br /&gt;
$(tooltips.init);&lt;br /&gt;
&lt;br /&gt;
$(document).keydown(function() {&lt;br /&gt;
  var nothingIsFocused = document.activeElement === document.body;&lt;br /&gt;
  if (nothingIsFocused) {&lt;br /&gt;
&lt;br /&gt;
    if(event.code == &#039;Slash&#039;) {&lt;br /&gt;
      $(&#039;#searchInput&#039;).focus();&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if(event.code == &#039;KeyE&#039;) {&lt;br /&gt;
      window.location.href = $(&#039;*[accesskey=&amp;quot;e&amp;quot;]&#039;).prop(&#039;href&#039;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // if(event.code == &#039;KeyF&#039;) {&lt;br /&gt;
    //   window.location.href = &#039;https://test.vana.wiki/Special:Upload&#039;;&lt;br /&gt;
    // }&lt;br /&gt;
    &lt;br /&gt;
    if(event.code == &#039;KeyH&#039;) {&lt;br /&gt;
      window.location.href = $(&#039;*[accesskey=&amp;quot;h&amp;quot;]&#039;).prop(&#039;href&#039;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if(event.code == &#039;KeyM&#039;) {&lt;br /&gt;
      window.location.href = $(&#039;*[accesskey=&amp;quot;m&amp;quot;]&#039;).prop(&#039;href&#039;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if(event.code == &#039;KeyN&#039;) {&lt;br /&gt;
      $(&amp;quot;#new-page-modal-content,#new-page-modal-background&amp;quot;).fadeIn(200);&lt;br /&gt;
      $(&#039;#new-page-create-name-input&#039;).focus();&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if(event.code == &#039;Escape&#039;) {&lt;br /&gt;
       $(&amp;quot;#new-page-modal-content,#new-page-modal-background&amp;quot;).fadeOut(200);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$(&amp;quot;#new-page-modal-background&amp;quot;).click(function () {&lt;br /&gt;
  $(&amp;quot;#new-page-modal-content,#new-page-modal-background&amp;quot;).fadeOut(200);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$(&amp;quot;#new-page-create-button&amp;quot;).click(function () {&lt;br /&gt;
  url = new URL($(&#039;link[rel=&amp;quot;canonical&amp;quot;]&#039;).attr(&#039;href&#039;));&lt;br /&gt;
  window.location.href = &#039;https://&#039;+url.host+&#039;/w/index.php?title=&#039; + $(&#039;#new-page-create-name-input&#039;).val() + &#039;&amp;amp;action=edit&#039;;&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////&lt;br /&gt;
///////     Move to Top: Button   //////&lt;br /&gt;
const button_scrollToTop = document.createElement(&#039;button&#039;);&lt;br /&gt;
button_scrollToTop.className = &amp;quot;mainpage-button-scrollToTop&amp;quot;;&lt;br /&gt;
button_scrollToTop.innerHTML = &#039;&amp;lt;img src=&amp;quot;https://horizonffxi.wiki/w/images/0/06/Up_arrow.png&amp;quot; style=&amp;quot;width: 25px; height: 25px;&amp;quot;/&amp;gt;&#039;;&lt;br /&gt;
//button_scrollToTop.style = &amp;quot;right: 2%; background: #FFFFFF; opacity: 1; position: fixed; display: none; border-radius: 10px; border: 0.5px solid #a7a7a7; box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.5);  z-index: 1000;&amp;quot;&lt;br /&gt;
document.body.appendChild(button_scrollToTop);&lt;br /&gt;
&lt;br /&gt;
button_scrollToTop.addEventListener(&amp;quot;click&amp;quot;, function() {&lt;br /&gt;
  $(&amp;quot;html, body&amp;quot;).animate({ scrollTop: 0 }, &amp;quot;slow&amp;quot;);&lt;br /&gt;
  return false;&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// //https://stackoverflow.com/questions/31223341/detecting-scroll-direction&lt;br /&gt;
// function scrollEventThrottle(fn) {&lt;br /&gt;
//   var last_known_scroll_position = 0;&lt;br /&gt;
//   var ticking = false;&lt;br /&gt;
//   window.addEventListener(&amp;quot;scroll&amp;quot;, function () {&lt;br /&gt;
//     var previous_known_scroll_position = last_known_scroll_position;&lt;br /&gt;
//     last_known_scroll_position = window.scrollY;&lt;br /&gt;
//     if (!ticking) {&lt;br /&gt;
//       window.requestAnimationFrame(function () {&lt;br /&gt;
//         fn(last_known_scroll_position, previous_known_scroll_position);&lt;br /&gt;
//         ticking = false;&lt;br /&gt;
//       });&lt;br /&gt;
//       ticking = true;&lt;br /&gt;
//     }&lt;br /&gt;
//   });&lt;br /&gt;
// }&lt;br /&gt;
&lt;br /&gt;
// scrollEventThrottle(function(scrollPos, previousScrollPos) {&lt;br /&gt;
//     if (previousScrollPos &amp;gt; scrollPos &amp;amp;&amp;amp; scrollPos &amp;gt;= 400) {&lt;br /&gt;
// 		if(window.getComputedStyle(button_scrollToTop).display !== &amp;quot;block&amp;quot;) {&lt;br /&gt;
// 			button_scrollToTop.style.display = &amp;quot;block&amp;quot;;&lt;br /&gt;
// 			if (document.body.clientWidth &amp;gt;= 850) button_scrollToTop.style.top = &amp;quot;60px&amp;quot;;&lt;br /&gt;
// 			else button_scrollToTop.style.top = &amp;quot;5px&amp;quot;;&lt;br /&gt;
// 		}&lt;br /&gt;
//     } else {&lt;br /&gt;
//       button_scrollToTop.style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
//     }&lt;br /&gt;
// });&lt;br /&gt;
&lt;br /&gt;
var previousScrollPos = 0;&lt;br /&gt;
var lastScrollPos = 0;&lt;br /&gt;
var performing = false;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * show the button #scroll-to-top only&lt;br /&gt;
 * on bottom part of the page &lt;br /&gt;
 */&lt;br /&gt;
const b = document.querySelector(&#039;.mainpage-button-scrollToTop&#039;);&lt;br /&gt;
//console.log(document.querySelector(&#039;.mainpage-button-scrollToTop&#039;));&lt;br /&gt;
function toggleVisibility(scrollPos, buttonId) {&lt;br /&gt;
	//console.log(previousScrollPos, scrollPos);&lt;br /&gt;
  if(previousScrollPos &amp;gt; scrollPos &amp;amp;&amp;amp; scrollPos &amp;gt; 500) {&lt;br /&gt;
  	//console.log(&amp;quot;showing&amp;quot; + $(buttonId));&lt;br /&gt;
    	if(window.getComputedStyle(b).display !== &amp;quot;block&amp;quot;) {&lt;br /&gt;
			button_scrollToTop.style.display = &amp;quot;block&amp;quot;;&lt;br /&gt;
			if (document.body.clientWidth &amp;gt;= 850) button_scrollToTop.style.top = &amp;quot;60px&amp;quot;;&lt;br /&gt;
			else button_scrollToTop.style.top = &amp;quot;5px&amp;quot;;&lt;br /&gt;
		}&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
	button_scrollToTop.style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
document.addEventListener(&#039;scroll&#039;, function(evt) {&lt;br /&gt;
  //console.log(performance.now())&lt;br /&gt;
	previousScrollPos = lastScrollPos;&lt;br /&gt;
	lastScrollPos = window.scrollY;&lt;br /&gt;
  if(!performing) {&lt;br /&gt;
    setTimeout(function () {&lt;br /&gt;
      toggleVisibility(lastScrollPos, &#039;mainpage-button-scrollToTop&#039;);&lt;br /&gt;
      performing = false;&lt;br /&gt;
    }, 100);&lt;br /&gt;
  }&lt;br /&gt;
  performing = true;&lt;br /&gt;
}, {passive: true}) ;&lt;br /&gt;
////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
// function that sorts a table on page load&lt;br /&gt;
// based on the column header which has one of the classes sort-col-1, sort-col-2, ...&lt;br /&gt;
&lt;br /&gt;
window.addEventListener(&#039;load&#039;, function() {&lt;br /&gt;
    // Add a small delay to ensure everything is loaded, especially on slower mobile networks&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
        // Select all tables with classes that match &amp;quot;sort-col-1&amp;quot; through &amp;quot;sort-col-6&amp;quot;&lt;br /&gt;
        var tables = document.querySelectorAll(&#039;.sortable.sort-col-1, .sortable.sort-col-2, .sortable.sort-col-3, .sortable.sort-col-4, .sortable.sort-col-5, .sortable.sort-col-6&#039;);&lt;br /&gt;
&lt;br /&gt;
        // Loop through each table and determine the column to sort by based on its class&lt;br /&gt;
        Array.prototype.forEach.call(tables, function(table) {&lt;br /&gt;
            // Find which &amp;quot;sort-col-X&amp;quot; class is applied to the table&lt;br /&gt;
            var classList = Array.prototype.slice.call(table.classList);&lt;br /&gt;
            var sortClass = null;&lt;br /&gt;
&lt;br /&gt;
            for (var i = 0; i &amp;lt; classList.length; i++) {&lt;br /&gt;
                if (classList[i].indexOf(&#039;sort-col-&#039;) === 0) {&lt;br /&gt;
                    sortClass = classList[i];&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            if (sortClass) {&lt;br /&gt;
                // Extract the column number from the class name (e.g., &amp;quot;sort-col-3&amp;quot; =&amp;gt; 3)&lt;br /&gt;
                var columnIndex = parseInt(sortClass.replace(&#039;sort-col-&#039;, &#039;&#039;), 10) - 1;  // Convert to 0-based index&lt;br /&gt;
                &lt;br /&gt;
                // Find the header cell for the specified column index&lt;br /&gt;
                var headerCell = table.querySelectorAll(&#039;th&#039;)[columnIndex];&lt;br /&gt;
                &lt;br /&gt;
                // If the header cell exists, simulate a click on it to trigger sorting&lt;br /&gt;
                if (headerCell) {&lt;br /&gt;
                    headerCell.click()&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }, 500); // 500ms delay to help on slower devices&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// OAuth Popup&lt;br /&gt;
$(&#039;li#pt-anon_oauth_login a&#039;).click(function(){&lt;br /&gt;
	articlePath = mw.config.get(&#039;wgArticlePath&#039;);&lt;br /&gt;
	url = articlePath.replace(&#039;$1&#039;, &#039;Special:OAuth2Client/redirect?returnto=Special:OAuth2Client/close&#039;);&lt;br /&gt;
	var left = (screen.width/2) - 200;&lt;br /&gt;
	var above = (screen.height/2) - 200;&lt;br /&gt;
	newwindow = window.open(url, &amp;quot;_blank&amp;quot;, &amp;quot;resizable=yes, scrollbars=yes, titlebar=yes, width=400, height=400, top=&amp;quot;+above+&amp;quot;, left=&amp;quot;+left);&lt;br /&gt;
	return false;&lt;br /&gt;
})&lt;br /&gt;
if (mw.config.get(&#039;wgTitle&#039;) == &#039;OAuth2Client/close&#039;) {&lt;br /&gt;
	window.opener.location.reload();&lt;br /&gt;
	window.close();&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>HuginBot</name></author>
	</entry>
</feed>