This page is "edit" protected. The "sysop" right is required to "edit" this page.<ul class='mw-logevent-loglines'> <li data-mw-logid="296" data-mw-logaction="protect/protect" class="mw-logline-protect"> <a href="/wiki/Special:Log?logid=296" title="Special:Log">03:53, 9 January 2021</a> <a href="/wiki/User:Celeste" class="mw-userlink" title="User:Celeste"><bdi>Celeste</bdi></a> <span class="mw-usertoollinks mw-changeslist-links"><span><a href="/wiki/User_talk:Celeste" class="mw-usertoollinks-talk" title="User talk:Celeste">talk</a></span> <span><a href="/wiki/Special:Contributions/Celeste" class="mw-usertoollinks-contribs" title="Special:Contributions/Celeste">contribs</a></span></span> protected <a href="/wiki/User:Celeste/common.js" title="User:Celeste/common.js">User:Celeste/common.js</a> [Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite) [Delete=Allow only administrators] (indefinite) [Protect=Allow only administrators] (indefinite) <span class="comment">(Probably recursive)</span> <span class="mw-logevent-actionlink">(<a href="/wiki/User:Celeste/common.js?action=history&amp;offset=20210109035320" title="User:Celeste/common.js">hist</a>)</span> </li> </ul></ul>
This page is "move" protected. The "sysop" right is required to "move" this page.<ul class='mw-logevent-loglines'> <li data-mw-logid="296" data-mw-logaction="protect/protect" class="mw-logline-protect"> <a href="/wiki/Special:Log?logid=296" title="Special:Log">03:53, 9 January 2021</a> <a href="/wiki/User:Celeste" class="mw-userlink" title="User:Celeste"><bdi>Celeste</bdi></a> <span class="mw-usertoollinks mw-changeslist-links"><span><a href="/wiki/User_talk:Celeste" class="mw-usertoollinks-talk" title="User talk:Celeste">talk</a></span> <span><a href="/wiki/Special:Contributions/Celeste" class="mw-usertoollinks-contribs" title="Special:Contributions/Celeste">contribs</a></span></span> protected <a href="/wiki/User:Celeste/common.js" title="User:Celeste/common.js">User:Celeste/common.js</a> [Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite) [Delete=Allow only administrators] (indefinite) [Protect=Allow only administrators] (indefinite) <span class="comment">(Probably recursive)</span> <span class="mw-logevent-actionlink">(<a href="/wiki/User:Celeste/common.js?action=history&amp;offset=20210109035320" title="User:Celeste/common.js">hist</a>)</span> </li> </ul></ul>

User:Celeste/common.js

From Celeste Wiki
Jump to navigation Jump to search

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)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
// Highlight admins
;(function($, mw){
	$.getJSON(mw.config.get('wgScriptPath')+'/index.php?action=raw&ctype=application/json&title=User:Amalthea_(bot)/userhighlighter.js/sysop.js', function(data){
		ADMINHIGHLIGHT_EXTLINKS = window.ADMINHIGHLIGHT_EXTLINKS || false;
		ADMINHIGHLIGHT_NAMESPACES = [-1,2,3];
		mw.loader.using(['mediawiki.util','mediawiki.Uri', 'mediawiki.Title'], function() {
			mw.util.addCSS(".userhighlighter_sysop.userhighlighter_sysop {background-color: #00FFFF !important}");
			$('#bodyContent a').each(function(index,linkraw){
				try {
					var link = $(linkraw);
					var url = link.attr('href');
					if (!url || url.charAt(0) === '#') return; // Skip <a> elements that aren't actually links; skip anchors
					if (url.lastIndexOf("http://", 0) != 0 && url.lastIndexOf("https://", 0) != 0 && url.lastIndexOf("/", 0) != 0) return; //require http(s) links, avoid "javascript:..." etc. which mw.Uri does not support
					var uri = new mw.Uri(url);
					if (!ADMINHIGHLIGHT_EXTLINKS && !$.isEmptyObject(uri.query)) return; // Skip links with query strings if highlighting external links is disabled
					if (uri.host == 'en.wikipedia.org') {
						var mwtitle = new mw.Title(mw.util.getParamValue('title',url) || decodeURIComponent(uri.path.slice(6))); // Try to get the title parameter of URL; if not available, remove '/wiki/' and use that
						if ($.inArray(mwtitle.getNamespaceId(), ADMINHIGHLIGHT_NAMESPACES)>=0) {
							var user = mwtitle.getMain().replace(/_/g," ");
							if (mwtitle.getNamespaceId() === -1) user = user.replace('Contributions/',''); // For special page "Contributions/<username>"
							if (data[user] == 1) {
								link.addClass('userhighlighter_sysop'); // Override the above color by using `a.userhighlighter_sysop.userhighlighter_sysop {background-color: COLOR !important}`
							}
						}
					}
				} catch (e) {
					// Sometimes we will run into unparsable links, so just log these and move on
					window.console && console.error('Admin highlighter recoverable error',e.message);
				}
			});
		});
	});
}(jQuery, mediaWiki));

/**
 * SkinSwitcher.js
 * @file Allows for easy switching between seven main skins, and Timeless
 * @author Eizzen <en.wikipedia.org/wiki/User_talk:Eizzen>
 * @timeless added by Zombiebaron
 * @license Apache-2.0
 * @external "jQuery"
 * @external "mediawiki.util"
 */

/*jslint browser, this:true */
/*global mw, jQuery, window */

mw.loader.using("mediawiki.util", function () {
    "use strict";

    /**
     * @class SkinSwitcher
     * @classdesc The central SkinSwitcher class
     */
    var SkinSwitcher = {
        lang: {
            script: "Skin Switcher",
            viewIn: "View this page in $1 skin"
        },
        skins: {
            "vector": "Vector",
            "monobook": "MonoBook",
            "modern": "Modern",
            "minerva": "Minerva",
            "minervaneue": "MinervaNeue",
            "cologneblue": "CologneBlue",
            "apioutput": "ApiOutput",
            "timeless": "Timeless"
        },
        /**
         * @method constructElement
         * @param {string} $selectedSkin
         * @param {string} $itemText
         * @returns {html}
         */
        constructElement: function ($selectedSkin, $itemText) {
            var $href = window.location.href;
            var $param = (window.location.search)
                ? "&"
                : "?";

            return mw.html.element("li", {
                "id": "skinSwitcher-li-" + $selectedSkin,
                "class": "skinSwitcher-li"
            }, new mw.html.Raw(
                mw.html.element("a", {
                    "href": $href.replace(/#.*/, "") +
                            $param + jQuery.param({useskin: $selectedSkin}),
                    "title": this.lang.viewIn.replace("$1", $itemText),
                    "id": "skinSwitcher-a-" + $selectedSkin,
                    "class": "skinSwitcher-a"
                }, $itemText)
            ));
        },
        /**
         * @method assembleElements
         * @returns {string[] } $elementsArray
         */
        assembleElements: function () {
            var $elementsArray = [];

            Object.keys(this.skins).forEach(function ($property) {
                $elementsArray.push(
                    this.constructElement($property, this.skins[$property])
                );
            }, this);

            return $elementsArray;
        },
        /**
         * @method cloneMenu
         * @param {string} $template
         * @returns {void}
         */
        cloneMenu: function ($template) {
            jQuery($template)
                .clone()
                .attr("id", "skinSwitcher")
                .insertAfter($template);
            jQuery("#skinSwitcher h3")
                .html("<span>" + this.lang.script + "</span>");
            jQuery("#skinSwitcher ul").empty();
        },
        /**
         * @method experimentalPlacement
         * @returns {void}
         */
        experimentalPlacement: function () {
            // Experimental CSS to center links horizontally in header
            mw.util.addCSS(
                "#skinSwitcher {" +
                    "display: flex;" +
                    "justify-content: center;" +
                    "flex-direction: row;" +
                    "align-items: center;" +
                "}" +
                ".skinSwitcher-li {" +
                    "display:inline-block;" +
                    "margin:5px 25px 0 25px;" +
                "}"
            );

            jQuery("<ul>", {
                id: "skinSwitcher"
            }).prependTo(".mw-body");
        },
        /**
         * @method determinePlacement
         * @param {string[] } $assembledElements
         * @returns {void}
         */
        determinePlacement: function ($assembledElements) {
            var $appendLocation;

            switch (this.currentSkin) {
            case "vector":
            case "monobook":
            case "modern":
            case "cologneblue":
                this.cloneMenu("#p-tb");
                $appendLocation = jQuery("#skinSwitcher ul");
                break;
            case "minerva":
            case "minervaneue":
            case "apioutput":
                this.experimentalPlacement();
                $appendLocation = jQuery("#skinSwitcher");
                break;
            case "timeless":
            }

            $assembledElements.forEach(function ($element) {
                jQuery($element).appendTo($appendLocation);
            });
        },
        /**
         * @method init
         * @returns {void}
         */
        init: function () {
            if (
                window.isSkinSwitcherLoaded ||
                jQuery("#skinSwitcher").length
            ) {
                return;
            }

            window.isSkinSwitcherLoaded = true;
            this.currentSkin = mw.config.get("skin");

            if (this.skins.hasOwnProperty(this.currentSkin)) {
                delete this.skins[this.currentSkin];
                this.determinePlacement(this.assembleElements());
            }
        }
    };

    jQuery(document).ready(function () {
        SkinSwitcher.init();
    });
});

// Creates a link and an html class to invert the screen
// Documentation at [[w:User:BrandonXLF/Invert]]

mw.loader.load('//en.uncyclopedia.co/w/index.php?title=User:Zombiebaron/Invert.css&action=raw&ctype=text/css', 'text/css'); // Import stylesheet

$(function() {
	function update(){                                                          // Function to update filter 
		if(mw.storage.get('InvertPage') == 'true'){  
			$(document.body).addClass('inverted-colors'); // Add CSS
		}else{
			$(document.body).removeClass('inverted-colors'); // Remove CSS
		} 
	}
	
	function set(e){                                                            // Function to set web storage and update filter
		e.preventDefault();                                                     // Pervent default action
		if(mw.storage.get('InvertPage') == 'true'){                        
			mw.storage.set('InvertPage','false');
		}else{
			mw.storage.set('InvertPage','true');
		} 
		update();                                                               // Update fiter
	}
	
	var node = mw.util.addPortletLink(                                          // Add link
	    'p-personal',
	    "https://en.wikipedia.org/wiki/User:BrandonXLF/Invert/select",          // Backup link to URL
	    '🌛',
	    'night mode',
	    'enter night mode',
	    'n',
	    '#pt-mytalk'
	);
	
	update();  
	
	$(node).on('click',function(e){                                         	// Make the dark mode link work
		set(e);
	});
	
	$('#ToggleWikiInvert').click(function(e){               					// Allow for id to toggle dark mode
		set(e);
	}); 
	
	$('.ToggleWikiInvert').click(function(e){                             		// Allow to CSS class to toggle dark mode
		set(e);
	}); 
});

mw.loader.using(['mediawiki.api', 'mediawiki.Title'], function () {
	"use strict";

	var config = mw.config.get(['wgNamespaceNumber', 'wgTitle', 'wgUserGroups', 'skin']);

	function removeBlanks(arr) {
		var ret = [];
		var i, len;
		for (i = 0, len = arr.length; i < len; i++) {
			var s = arr[i];
			s = s.trim();
			if (s) {
				ret.push(s);
			}
		}
		return ret;
	}

	function doMassDelete() {
		document.getElementById("wpMassDeleteSubmit").disabled = true;
		var articles = document.getElementById("wpMassDeletePages").value.split("\n");
		articles = removeBlanks(articles);
		if (!articles.length) {
			return;
		}
		var
			api = new mw.Api(),
			wpMassDeleteReasons = document.getElementById("wpMassDeleteReasons").value,
			wpMassDeleteReason = document.getElementById("wpMassDeleteReason").value,
			deleted = 0,
			failed = [],
			error = [],
			deferreds = [],
			reason = wpMassDeleteReasons == "other" ?
				wpMassDeleteReason :
				wpMassDeleteReasons + (wpMassDeleteReason ? " (" + wpMassDeleteReason + ")" : ""),
			onSuccess = function () {
				deleted++;
				document.getElementById("wpMassDeleteSubmit").value = "(" + deleted + ")";
			};

		function makeDeleteFunc(article) {
			return function () {
				return $.Deferred(function (deferred) {
					var promise = api.postWithToken('delete', {
						format: 'json',
						action: 'delete',
						title: article,
						reason: reason
					});
					promise.done(onSuccess);
					promise.fail(function (code, obj) {
						failed.push(article);
						error.push(obj.error.info);
					});
					promise.always(function () {
						deferred.resolve();
					});
				});
			};
		}

		// Make a chain of deferred objects. We chain them rather than execute them in
		// parallel so that we don't make 1000 simultaneous delete requests and bring the
		// site down. We use deferred objects rather than the promise objects returned
		// from the API request so that the chain continues even if some articles gave
		// errors.
		var deferred = makeDeleteFunc(articles[0])();
		for (var i = 1, len = articles.length; i < len; i++) {
			deferred = deferred.then(makeDeleteFunc(articles[i]));
		}

		// Show the output and do cleanup once all the requests are done.
		$.when(deferred).then(function () {
			document.getElementById("wpMassDeleteSubmit").value = "Done (" + deleted + ")";
			if (failed.length) {
				var $failedList = $('<ul>');
				for(var x = 0; x < failed.length; x++) {
					// Link the titles in the "failed" array
					var failedTitle = mw.Title.newFromText(failed[x]);
					var $failedItem = $('<li>');
					if (failedTitle) {
						$failedItem.append( $('<a>')
							.attr('href', failedTitle.getUrl())
							.text(failed[x])
						);
					} else {
						$failedItem.text(failed[x]);
					}
					$failedItem.append(document.createTextNode(': ' + error[x]));
					$failedList.append($failedItem);
				}
				$('#wpMassDeleteFailedContainer')
					.append($('<br />'))
					.append($('<b>')
						.text('Failed deletions:')
					)
					.append($failedList);
			}
		});
	}
	 
	function massdeleteform() {
		var bodyContent = (config.skin == "cologneblue" ? "article" : "bodyContent");
		document.getElementsByTagName("h1")[0].textContent = "Animum's mass-deletion tool";
		document.title = "Animum's mass-deletion tool - Wikipedia, the free encyclopedia";
		document.getElementById(bodyContent).innerHTML = '<h3 id="siteSub">From Wikipedia, the free encyclopedia</h3><br /><br />' +
			'<form id="wpMassDelete" name="wpMassDelete">' +
			'<b>If you abuse this tool, it\'s <i>your</i> fault, not mine.</b>' +
			'<div id="wpMassDeleteFailedContainer"></div>' +
			'<br /><br />' +
				'Pages to delete (one on each line, please):<br />' +
					'<textarea tabindex="1" accesskey="," name="wpMassDeletePages" id="wpMassDeletePages" rows="10" cols="80"></textarea>' +
				'<br /><br /><table style="background-color:transparent">' +
					'<tr><td>Common reasons:</td>' +
						'<td><select id="wpMassDeleteReasons">' +
							'<optgroup label="Other reason">' +
								'<option value="other">Other reason</option>' +
							'</optgroup>' +
							'<optgroup label="Criteria for speedy deletion">' +
								'<optgroup label="General criteria">' +
									'<option value="[[WP:CSD#G1|G1]]: [[WP:PN|Patent nonsense]], meaningless, or incomprehensible">G1: Patent nonsense</option>' +
									'<option value="[[WP:CSD#G2|G2]]: Test page">G2: Test page</option>' +
									'<option value="[[WP:CSD#G3|G3]]: [[WP:Vandalism|Vandalism]]">G3: Vandalism</option>' +
									'<option value="[[WP:CSD#G3|G3]]: Blatant [[WP:Do not create hoaxes|hoax]]">G3: Hoax</option>' +
									'<option value="[[WP:CSD#G4|G4]]: Recreation of a page that was [[WP:DEL|deleted]] per a [[WP:XFD|deletion discussion]]">G4: Repost</option>' +
									'<option value="[[WP:CSD#G5|G5]]: Creation by a [[WP:BLOCK|blocked]] or [[WP:BAN|banned]] user in violation of block or ban">G5: Banned</option>' +
									'<option value="[[WP:CSD#G6|G6]]: Housekeeping and routine (non-controversial) cleanup">G6: Maintenance</option>' +
									'<option value="[[WP:CSD#G7|G7]]: One author who has requested deletion or blanked the page">G7: Author</option>' +
									'<option value="[[WP:CSD#G8|G8]]: Page dependent on a deleted or nonexistent page">G8: Orphaned talk page</option>' +
									'<option value="[[WP:CSD#G10|G10]]: [[WP:ATP|Attack page]] or negative unsourced [[WP:BLP|BLP]]">G10: Attack page</option>' +
									'<option value="[[WP:CSD#G11|G11]]: Unambiguous [[WP:NOTADVERTISING|advertising]] or promotion">G11: Advertising</option>' +
									'<option value="[[WP:CSD#G12|G12]]: Unambiguous [[WP:CV|copyright infringement]]">G12: Copyvio</option>' +
									'<option value="[[WP:CSD#G13|G13]]: Abandoned draft or [[WP:AFC|Articles for Creation]] submission – to retrieve it, see [[WP:REFUND/G13]]">G13: Abandoned draft</option>' +
								'</optgroup>' +
								'<optgroup label="Articles">' +
									'<option value="[[WP:CSD#A1|A1]]: Short article without enough context to identify the subject">A1: No context</option>' +
									'<option value="[[WP:CSD#A2|A2]]: Article in a foreign language that exists on another project">A2: Foreign</option>' +
									'<option value="[[WP:CSD#A3|A3]]: Article that has no meaningful, substantive content">A3: No content</option>' +
									'<option value="[[WP:CSD#A5|A5]]: Article that has been transwikied to another project">A5: Transwiki</option>' +
									'<option value="[[WP:CSD#A7|A7]]: No credible indication of importance (individuals, animals, organizations, web content, events)">A7: Non-notable individual, animal, organization, web content, or event</option>' +
									'<option value="[[WP:CSD#A9|A9]]: Music recording by redlinked artist and no indication of importance or significance">A9: Non-notable recording by redlinked artist</option>' +
									'<option value="[[WP:CSD#A10|A10]]: Recently created article that duplicates an existing topic">A10: Recently created article that duplicates an existing topic</option>' +
									'<option value="[[WP:CSD#A11|A11]]: [[Wikipedia:Wikipedia is not for things made up one day|Made up]] by article creator or an associate, and no indication of importance/significance">A11: Made up</option>' +
								'</optgroup>' +
								'<optgroup label="Redirects">' +
									'<option value="[[WP:CSD#R2|R2]]: Cross-[[WP:NS|namespace]] [[WP:R|redirect]] from mainspace">R2: Cross-namespace</option>' +
									'<option value="[[WP:CSD#R3|R3]]: Recently created, implausible [[WP:R|redirect]]">R3: Implausible redirect</option>' +
								'</optgroup>' +
								'<optgroup label="Images and other media">' +
									'<option value="[[WP:CSD#F1|F1]]: File redundant to another on Wikipedia">F1: Redundant</option>' +
									'<option value="[[WP:CSD#F2|F2]]: Corrupt or empty file, or a file description page for a file on Commons">F2: Corrupt, empty. or Commons</option>' +
									'<option value="[[WP:CSD#F3|F3]]: File with improper license">F3: File with improper license</option>' +
									'<option value="[[WP:CSD#F4|F4]]: Lack of licensing information">F4: Lack of licensing information</option>' +
									'<option value="[[WP:CSD#F5|F5]]: Unused non-free media">F5: Unfree and unused</option>' +
									'<option value="[[WP:CSD#F6|F6]]: Non-free file without [[WP:RAT|fair-use rationale]]">F6: No rationale</option>' +
									'<option value="[[WP:CSD#F7|F7]]: [[WP:NFCC|Invalid]] fair-use claim">F7: Bad fair use rationale</option>' +
									'<option value="[[WP:CSD#F8|F8]]: Media file available on Commons">F8: On Commons</option>' +
									'<option value="[[WP:CSD#F9|F9]]: File [[WP:COPYVIO|copyright violation]]">F9: File copyvio</option>' +
									'<option value="[[WP:CSD#F10|F10]]: Useless media file">F10: Useless media file</option>' +
									'<option value="[[WP:CSD#F11|F11]]: No evidence of permission">F11: No permission</option>' +
								'</optgroup>' +
								'<optgroup label="Categories">' +
									'<option value="[[WP:CSD#C1|C1]]: Empty category">C1: Empty</option>' +
									'<option value="[[WP:CSD#C2|C2]]: Speedy renaming">C2: Speedy rename</option>' +
									'<option value="[[WP:CSD#G8|G8]]: Populated by deleted or retargeted template">G8: Populated by deleted or retargeted template</option>' +
								'</optgroup>' +
								'<optgroup label="User namespace">' +
									'<option value="[[WP:CSD#U1|U1]]: User request to delete page in own userspace">U1: User requests deletion</option>' +
									'<option value="[[WP:CSD#U2|U2]]: Userpage or subpage of a nonexistent user">U2: Non-existent user</option>' +
									'<option value="[[WP:CSD#U3|U3]]: [[WP:NFC|Non-free]] [[Help:Gallery|gallery]]">U3: Fair use gallery</option>' +
									'<option value="[[WP:CSD#U5|U5]]: [[WP:NOTWEBHOST|Misuse of Wikipedia as a web host]]">U5: Misuse as webhost</option>' +
								'</optgroup>' +
								'<optgroup label="Templates">' +
									'<option value="[[WP:CSD#T3|T3]]: Unused, redundant template">T3: Redundant and unused</option>' +
									'<option value="[[WP:CSD#G8|G8]]: Component or documentation of a deleted template">G8: component of deleted template</option>' +
								'</optgroup>' +
								'<optgroup label="Portals">' +
									'<option value="[[WP:CSD#P1|P1]]: [[WP:P|Portal]] page that would be subject to speedy deletion as an article">P1: Deletion as article</option>' +
									'<option value="[[WP:CSD#P2|P2]]: [[WP:P|Portal]] without a substantial topic base">P2: Underpopulated</option>' +
								'</optgroup>' +
								'<optgroup label="Other">' +
									'<option value="[[WP:PROD]]: Nominated for seven days with no objection">PRODded for more than 7 days without objection</option>' +
									'<option value="[[WP:BLPPROD]]: Nominated for seven days with no reliable sources present in the article">BLPPRODded for more than seven days without a source</option>' +
									'<option value="Listed at [[Wikipedia:Copyright problems]] for over seven days">Listed at Copyright problems for over seven days</option>' +
								'</optgroup>' +
							'</optgroup>' +
						'</select></td></tr>' +
				'<tr><td>Other/additional reason:</td>' +
					'<td><input type="text" id="wpMassDeleteReason" name="wpMassDeleteReason" maxlength="255" /></td></tr>' +
					'<tr><td><input type="button" id="wpMassDeleteSubmit" name="wpMassDeleteSubmit" value="Delete" /></td>' +
			'</form>';
		document.getElementById("wpMassDeleteReasons").onchange = function() {
			var maxlength = (document.getElementById("wpMassDeleteReasons").value == "other" ? 255 : 252-document.getElementById("wpMassDeleteReasons").value.length); //It's 252 because of the three characters (" ()") in addition to the selected summary.
			document.getElementById("wpMassDeleteReason").setAttribute("maxlength", maxlength);
		};
		document.getElementById("wpMassDeleteSubmit").addEventListener("click", function (e) {
			doMassDelete();
		});
	}
	 
	if (config.wgNamespaceNumber == -1 &&
		config.wgTitle.toLowerCase() == "massdelete" &&
		/sysop/.test(config.wgUserGroups)
	) {
		massdeleteform();
	}

});

/** This script contains the code required for loading [[User:Joeytje50/JWB.js]].
 *  All other code is located at that page.
 */

//Idea by [[User:Epicgenius]]
$.when(mw.loader.using(['mediawiki.util'], $.ready)).done( function() {
	mw.util.addPortletLink("p-tb", mw.config.get('wgArticlePath').replace('$1', "Project:AutoWikiBrowser/Script"), "JS Wiki Browser", "tb-awbscript", "Run Javascript Wiki Browser");
});

if (mw.config.get('wgCanonicalNamespace')+':'+mw.config.get('wgTitle') === 'Project:AutoWikiBrowser/Script' && mw.config.get('wgAction') == 'view')
	mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.js&action=raw&ctype=text/javascript');
	
function DateSub(Date1,Date2) {
    var timeDifference = Date2 - Date1;
    var minutesAgo = Math.round(timeDifference / 1000 / 60);
    var hoursAgo = 0
    var daysAgo = 0
    var hoursText = 'hour'
    var daysText = 'day'

    while (minutesAgo >= 60) {
        minutesAgo = minutesAgo-60;
        hoursAgo++;
    }

    while (hoursAgo >= 24) {
        hoursAgo = hoursAgo-24;
        daysAgo++;
    }

    if (hoursAgo!=1)
        hoursText = hoursText + 's';

    if (daysAgo!=1)
        daysText = daysText + 's';

    if (daysAgo > 0) {
        if (hoursAgo > 0) {
            if (minutesAgo <=1 ) {
                minutesAgo = daysAgo + ' ' + daysText + ', ' + hoursAgo + ' ' + hoursText;
            }
            else {
                minutesAgo = daysAgo + ' ' + daysText + ', ' + hoursAgo + ' ' + hoursText + ', ' + minutesAgo + ' minutes';
            }
        }
        else {
            if (minutesAgo <=1 ) {
                minutesAgo = daysAgo + ' ' + daysText;
            }
            else {
                minutesAgo = daysAgo + ' ' + daysText + ', ' + minutesAgo + ' minutes';
            }
        }
    }
    else {
        if (hoursAgo > 0) {
            if (minutesAgo <=1 ) {
                minutesAgo = hoursAgo + ' ' + hoursText;
            }
            else {
                minutesAgo = hoursAgo + ' ' + hoursText + ', ' + minutesAgo + ' minutes';
            }
        }
        else {
            if (minutesAgo <=1 ) {
                minutesAgo = 'Less than a minute';
            }
            else {
                minutesAgo = minutesAgo + ' minutes';
            }
        }
    }
    return minutesAgo;
}

if (document.getElementById('mw-diff-otitle1') || document.getElementById('mw-diff-ntitle1')) {

function convertTimestampStringToDate(id) {
    var timestamp = document.getElementById(id).firstChild.firstChild.firstChild.nodeValue;
    var str = /evision as of /g
    str.lastIndex = 0;
    str.test(timestamp)
    var date = timestamp.substring(str.lastIndex)
/*

All this following bogus crap is because Safari
doesn't recognize Wikipedia's date format.
Every other browser can just use the date string
object above, but Safari is retarded

*/
    var str1 = /[A-z]+/
    var str2 = /\d+/g
    var monthtext = date.match(str1);
    var testdate = date.match(str2);
    var hours = testdate[0];
    var minutes = testdate[1];
    var day = testdate[2];
    var year = testdate[3];
    var months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
    for (i in months) {
        if (monthtext==months[i]) {
            var month = i;
            break;
        }
        i++
    }
/*

End Safari madness

*/
    date = new Date(year,month,day,hours,minutes);
    return date;
}

var leftNode = document.getElementById('mw-diff-otitle1');
var rightNode = document.getElementById('mw-diff-ntitle1');
var firstDate = convertTimestampStringToDate('mw-diff-otitle1');
var secondDate = convertTimestampStringToDate('mw-diff-ntitle1');

function TimeBetweenDiffs() {

    var minutesAgo = DateSub(firstDate,secondDate);

    var newNode = document.createElement('span');
    newNode.setAttribute('style', 'font-weight:bold; color:red;')
    newNode.appendChild(document.createTextNode('(' + minutesAgo + ' later)'));
    newNode.appendChild(document.createElement('br'));

    rightNode.insertBefore(newNode, rightNode.firstChild);
}

function TimeSinceDiff() {
    var DateNow = new Date();

    var minutesAgo1 = DateSub(firstDate,DateNow);
    var minutesAgo2 = DateSub(secondDate,DateNow);

    document.getElementById('mw-diff-otitle1').title=minutesAgo1 + ' ago';
    document.getElementById('mw-diff-ntitle1').title=minutesAgo2 + ' ago';

    var t = setTimeout("TimeSinceDiff()",60000);
}

$(window).load(TimeSinceDiff);                                  // Adds time since displayed diffs as tooltip
$(window).load(TimeBetweenDiffs);                               // Adds time between diffs

}

// Modified from [[User:Gary King/link intermediate revisions.js]]

if (typeof(unsafeWindow) != 'undefined')
{
	var console = unsafeWindow.console;
	importScriptURI = unsafeWindow.importScriptURI;
	mw = unsafeWindow.mw;
}

mw.loader.using( ['mediawiki.util'], function () {
	$(createDiffMultiLink);
});

function createDiffMultiLink()
{
	if (!mw.util.getParamValue('diff') || !mw.util.getParamValue('oldid')) return false;
	$.get(mw.config.get('wgScriptPath') + '/api.php', { 
             action: 'query', 
             prop: 'revisions', 
             titles: mw.config.get('wgPageName'), 
             rvprop: 'timestamp', 
             rvstartid: mw.util.getParamValue('diff'), 
             rvendid: mw.util.getParamValue('oldid'), 
             rvlimit: '5000',
             format: 'json', 
             indexpageids: 1 
        }, diffMultiCallback);
}
 
function twoDigitPadding(integer)
{
	var string = integer.toString();
	if (string.length == 1) return '0' + integer;
	else return integer;
}
 
function diffMultiCallback(response)
{
	if (!response['query'] || !response['query']['pages'] || response['query']['pageids'][0] == -1) return false;
 
	var diffMultis = $('#bodyContent .diff-multi');
	if (!diffMultis.length) return false;
	var pageId = response['query']['pageids'][0];
	var page = response['query']['pages'][pageId];
	var revisions = page['revisions'];
	if (!revisions) return false;
 
	var oldid = new Date(revisions[revisions.length - 1]['timestamp']);
	oldid = oldid.getUTCFullYear().toString() + twoDigitPadding(oldid.getUTCMonth() + 1).toString() + oldid.getUTCDate().toString() + twoDigitPadding(oldid.getUTCHours() + 1).toString() + twoDigitPadding(oldid.getUTCMinutes() + 1).toString() + twoDigitPadding(oldid.getUTCSeconds() + 1).toString();
	var diff = new Date(revisions[0]['timestamp']);
	diff = diff.getUTCFullYear().toString() + twoDigitPadding(diff.getUTCMonth() + 1).toString() + diff.getUTCDate().toString() + twoDigitPadding(diff.getUTCHours() + 1).toString() + twoDigitPadding(diff.getUTCMinutes() + 1).toString() + twoDigitPadding(diff.getUTCSeconds() + 1).toString();
 
	var diffMulti = diffMultis.eq(0);
	var a = $('<a href="' + mw.config.get('wgScript') + '?title=' + mw.config.get('wgPageName') + '&action=history&offset=' + diff + '&limit=' + revisions.length + '"></a>').append(diffMulti.contents().eq(0));
	diffMulti.append(a);
}

if (typeof inspectText == "undefined")
{
	inspectText = "inspect&nbsp;diff";
}
if (typeof showText == "undefined")
{
	showText = "show&nbsp;diff";
}
if (typeof hideText == "undefined")
{
	hideText = "hide&nbsp;diff";
}
var specialPageName = mw.config.get("wgCanonicalSpecialPageName");
if (specialPageName  == "Watchlist" ||
	specialPageName  == "Recentchanges" ||
	specialPageName  == "Contributions" ||
	mw.config.get("wgAction") == "history" || 
	specialPageName == "Recentchangeslinked" ||
	(specialPageName == "Blankpage" && mw.config.get("wgTitle").indexOf("section-watchlist") > 0))
{
	function inspectionEachHelper(index, element)
	{
		var findString;
		if (mw.config.get("wgAction") == "history" || $(element).hasClass("mw-enhanced-rc-nested"))
		{
			findString = 'a:contains("prev")';
		}
		else
		{
			findString = 'a:contains("diff")';
		}

		var regex;

		if (specialPageName == "Contributions")
		{
			regex = /&oldid=(\d+)$/;

		}
		else
		{
			regex = /(?:&diff=(\d+)&oldid=|&diff=prev&oldid=(\d+))/;
		}
		var diffLink = $(element).find(findString);
		if (diffLink.length > 0)
		{
			var regexResult = regex.exec(diffLink[0].href);
			if (regexResult != null && regexResult.length >= 2)
			{
				var diffID = regexResult[1] || regexResult[2];
				//don't re-add if it already exists
				if ($("#" + diffID).length > 0)
				{
					return;
				}
				var inlineDiffButton;
				if (typeof inlineDiffBigUI === "undefined")
				{
					inlineDiffButton = document.createElement("a");
					inlineDiffButton.href = "#";
					inlineDiffButton.innerHTML = '<b><span style="color:black;"> [</span><span style="color:#008A00;">' + inspectText + '</span><span style="color:black;">] </span></b>';
				}
				else
				{
					inlineDiffButton = document.createElement("input");
					inlineDiffButton.type = "button";
					inlineDiffButton.value = "Inspect edit";
				}
				inlineDiffButton.id = diffID;
				$(inlineDiffButton).addClass("inspectDiffButton");
				$(inlineDiffButton).click(function ()
				{
					return inspectWatchlistDiff(this);
				}
				);
				if ($(element).find("tr:first").length == 0)
				{
					$(element).find(".mw-changeslist-separator:first").css("padding-right", 0);
					$(inlineDiffButton).insertAfter($(element).find(".mw-changeslist-separator:first"));
				}
				else
				{
					$(inlineDiffButton).insertBefore($(element).find(".mw-title"));
					$(inlineDiffButton).addClass("mw-enhanced-rc-diff");
					/*
					$(element).find("tr:first").append("<td></td>");
					$(element).find("tr:first>td:last").append(inlineDiffButton);
					*/
				}
			}
		}
	}
	function addWatchlistInspectionBoxes()
	{
		mw.loader.using("mediawiki.diff.styles").done(function()
		{
			var entries = $("#mw-content-text table.mw-enhanced-rc");
			if (entries.length == 0)
			{
				$("#mw-content-text ul").each(function (ind, el)
				{
					$(el).children("li").each(inspectionEachHelper);
				});
			}
			else
			{
				entries.each(inspectionEachHelper);
				$("td.mw-enhanced-rc-nested").each(inspectionEachHelper);
			}
		});
	}

	function inspectWatchlistDiff(button)
	{
		mw.loader.using(['mediawiki.api']).done(function ()
		{
			var mwApi = new mw.Api();
			mwApi.get(
			{
				action: "query",
				prop: "revisions",
				format: "json",
				rvprop: "timestamp",
				rvdiffto: "prev",
				revids: button.id
			}
			).done(function (response)
			{
				if (response == null)
				{
					alert("Request failed!");
					return false;
				}

				var diffString = response.query.pages[Object.keys(response.query.pages)[0]].revisions[0].diff["*"];

				if (diffString == null)
				{
					alert("Request failed!");
					return false;
				}

				var newTable = document.createElement("table");
				newTable.className = "diff";
				$(newTable).html('<colgroup><col class="diff-marker"><col class="diff-content"><col class="diff-marker"><col class="diff-content"></colgroup>');

				$(newTable).append(diffString);
				diffParent = null;
				if ($("#" + button.id).hasClass("mw-enhanced-rc-diff"))
				{
					$("#" + button.id).parents("table").after(newTable);
				}
				else
				{
					diffParent = $("#" + button.id).parent();
					diffParent.append(newTable);
				}
				newTable.id = button.id + "display";

				mw.hook('new-diff-table').fire(newTable);

				$(button).unbind("click");
				if (typeof inlineDiffBigUI === "undefined")
				{
					$(button).html('<b><span style="color:black;"> [</span><span style="color:#008A00;">' + hideText + '</span><span style="color:black;">] </span></b>');
					$(button).click(function ()
					{
						return hideSmallEditInspection(this);
					}
					);
				}
				else
				{
					$(button).attr("value", "Hide edit");
					$(button).click(function ()
					{
						return hideEditInspection(this);
					}
					);
				}
				if (typeof markAsViewed != "undefined" && markAsViewed)
				{
					mwApi.postWithToken('csrf',
					{
						action: "setnotificationtimestamp",
						revids: button.id
					}
					).done(function (data)
					{
						if (diffParent != null)
						{
							diffParent.removeClass("mw-changeslist-line-watched");
							diffParent.addClass("mw-changeslist-line-not-watched");
						}
					}
					);
				}
			}
			);
		}
		);
		return false;
	}

	function showEditInspection(button)
	{
		$("#" + button.id + "display").css("display", "");
		$(button).attr("value", "Hide edit");
		$(button).unbind("click");
		$(button).click(function ()
		{
			return hideEditInspection(this);
		}
		);
		return false;
	}

	function hideEditInspection(button)
	{
		$("#" + button.id + "display").css("display", "none");
		$(button).attr("value", "Show edit");
		$(button).unbind("click");
		$(button).click(function ()
		{
			return showEditInspection(this);
		}
		);
		return false;
	}

	function showSmallEditInspection(button)
	{
		$("#" + button.id + "display").css("display", "");
		$(button).html('<b><span style="color:black;"> [</span><span style="color:#008A00;">' + hideText + '</span><span style="color:black;">] </span></b>');
		$(button).unbind("click");
		$(button).click(function ()
		{
			return hideSmallEditInspection(this);
		}
		);
		return false;
	}

	function hideSmallEditInspection(button)
	{
		$("#" + button.id + "display").css("display", "none");
		$(button).html('<b><span style="color:black;"> [</span><span style="color:#008A00;">' + showText + '</span><span style="color:black;">] </span></b>');
		$(button).unbind("click");
		$(button).click(function ()
		{
			return showSmallEditInspection(this);
		}
		);
		return false;
	}

	mw.hook('wikipage.content').add(addWatchlistInspectionBoxes);
}

/*
*	Pages Created -- finds all the pages created by a user
*	see [[User:Jfmantis/pagesCreated]]
*/

(function() {

/*
*	create <li> list item for one article
*	right now, just a link to the page & the date
*/
function makeCreatedPageItem(contrib) {
	var item = document.createElement("li");

	var link = document.createElement("a");
	link.href = mw.util.getUrl(contrib.title);
	link.innerHTML = contrib.title;

	item.appendChild(link);

	item.innerHTML += " . . " + new Date(contrib.timestamp).toDateString();

	return item;
}

/*
*	looks through all of a user's non-minor namespace 0 edits,
*	looking for edits tagged as "new"
*
*	the arguments all in one object so that it can be expanded
*	in the future without having to add a bunch more parameters
*/
function findPagesCreated(bundle) {
	bundle.api.get({
		action: "query",
		rawcontinue: '',
		list: "usercontribs",
		ucuser: bundle.user,
		ucstart: bundle.start,
		ucprop: "flags|title|timestamp",
		ucshow: "!minor",
		uclimit: 500,
		ucnamespace: 0
	}).done( function(data) {
		$.each(data.query.usercontribs, function(index, contrib) {
			if (contrib.new != undefined) {
				bundle.list.appendChild(makeCreatedPageItem(contrib));
				bundle.count++;
			}
		});

		if (data["query-continue"]) {	// more contributions
			bundle.start = data["query-continue"].usercontribs.ucstart
			setTimeout(function() { findPagesCreated(bundle); }, 3000);
		} else {	// done
			$("#pc-status")[0].innerHTML = "<br />" + bundle.user + " has created " + bundle.count + " articles";
		}
	}).fail( function(error) {
		alert(error);
	});
}

/*
*	change title, clear content area, etc.
*/
function setupPagesCreated(user) {
	// set new title
	mw.util.$content.find("#firstHeading")[0].innerHTML = "Pages created by " + user;

	// status bar (text + waiting gif)
	var status = document.createElement("span");
	status.id = "pc-status";
	status.innerHTML = "<br />Fetching user data...";

	// heading for results
	var heading = document.createElement("h3");
	heading.innerHTML = "Articles";

	// list of results
	var articles = document.createElement("ul");
	articles.id = "pc-articles";

	var body = mw.util.$content.find("#bodyContent")[0];
	body.innerHTML = "";
	body.appendChild(status);
	body.appendChild(heading);
	body.appendChild(articles);

	var api = new mw.Api();
	api.get({
		action: "query",
		list: "users",
		ususers: user,
		usprop: "editcount"
	}).done(function(data) {
		// 500 results per request, 1 request every 3 seconds
		var count = data.query.users[0].editcount;
		status.innerHTML = "<br />User has " + count + " edits, this should take less than ";
		status.innerHTML += (3 * Math.round(count / 500)) + " seconds &nbsp;&nbsp;&nbsp;";

		var waitgif = document.createElement("img");
		waitgif.src = "https://upload.wikimedia.org/wikipedia/commons/4/42/Loading.gif";
		status.appendChild(waitgif);

		findPagesCreated(
			{"api": api,
			"user": user,
			"list": articles,
			"start": "",
			"count": 0}
		);
	}).fail(function(error) {
		alert(error);
	});

	return false;
}

mw.loader.using("mediawiki.util", function() {
	// add portlet when page is User or User_talk, but not on subpages
	if ((wgNamespaceNumber == 2 || wgNamespaceNumber == 3) && (wgTitle.indexOf("/") == -1)) {
		if (mw.util.getParamValue("pagesCreated")) {
			setupPagesCreated(wgTitle);
		} else {
			mw.util.addPortletLink("p-tb",
				document.location.toString() + "?pagesCreated=true",
				"Pages created", "pc-pages",
				"Get a list of all pages created by this user"
			);
		}
	}
});

})();

if ( mw.config.get( "wgAction" ) === "history" ) {
	$( document ).ready( function() {
		"use strict";
		const HC = document.getElementById( "mw-history-compare" );
		if ( HC ) {
			const PH = document.getElementById( "pagehistory" ),
				BTNS = HC.querySelectorAll( 'input[value="Compare selected revisions"]' ),
				TOP = BTNS[ 0 ],
				BTM = BTNS[ 1 ],
				encapsulate = function() {
					const LSB = PH.querySelector( 'li.selected.before' ),
						LSA = PH.querySelector( 'li.selected.after' );
					if ( TOP && LSB ) {
						PH.insertBefore( TOP, LSB );
					}
					if ( BTM && LSA ) {
						const NES = LSA.nextElementSibling;
						if ( NES ) {
							PH.insertBefore( BTM, NES );
						} else {
							PH.appendChild( BTM );
						}
					}
					/* move buttons added by User:Enterprisey/cv-revdel.js along with the "Compare selected revisions" buttons */
					HC.querySelectorAll( "button.cv-rd-add-range" ).forEach( function( b, i ) { PH.insertBefore( b, BTNS[ i ] ) } );
				};
			encapsulate();
			HC.addEventListener( "change", encapsulate );
		}
	} );
}

/* Rollback all */
$( function() {
	if ( $('span.mw-rollback-link')[0] && mw.config.get( 'wgCanonicalSpecialPageName' ) == 'Contributions' )
		mw.util.addPortletLink( 'p-cactions', 'javascript:rollbackEverything()', "rollback all", "ca-rollbackeverything", "Rollback all top edits displayed here" );
} );
function rollbackEverything() {
	for ( var i in document.links ) {
		if ( document.links[i].href.indexOf( 'action=rollback' ) != -1 )
			window.open( document.links[i].href+'&bot=1' );
	}
}

/* Interface modifications */

$( function(){ 

// These add action tabs at the top of a page

	if( mw.config.get( 'wgNamespaceNumber' ) > -1 ) {  
 		mw.util.addPortletLink( 'p-cactions', '/wiki/Special:PrefixIndex/' + wgPageName, 'Subpages', 'd-subpages', 'List subpages and other pages starting with this title' ); 
 		mw.util.addPortletLink( 'p-cactions', '/w/index.php?title=Special:Log&page=' + wgPageName, 'Logs', 'd-logs', 'Show any relevant logs for this title' );
 		mw.util.addPortletLink( 'p-cactions', '/wiki/' + wgPageName + '?action=purge', 'Purge', 'd-purge', 'Purge the current page' ); 
// 		mw.util.addPortletLink( 'p-cactions', '/wiki/' + wgPageName + '?useskin=vector', 'Vector', 'd-vector', 'View page in the Vector skin' ); 
	}

// These add personal links at the top right of every page

	mw.util.addPortletLink( 'p-personal', '/wiki/Special:ListFiles/' + wgUserName, 'Uploads', 'pt-uploads' );
	mw.util.addPortletLink( 'p-personal', '/wiki/Special:Log/' + wgUserName, 'Logs', 'pt-logs' ); 
	mw.util.addPortletLink( 'p-personal', '/wiki/Special:PrefixIndex/User:'+ wgUserName, 'Subpages', 'pt-subpages' );

	$("#pt-logout").hide();

// These add toolbox links to the sidebar of every page

	mw.util.addPortletLink( 'p-tb', 'https://en.uncyclopedia.co/wiki/User:Zombiebaron/2019.js', '2019.js Project', 't-2019' );
	mw.util.addPortletLink( 'p-tb', 'https://en.uncyclopedia.co/wiki/User:Zombiebaron/Images', 'Images', 't-images' );
	mw.util.addPortletLink( 'p-tb', 'https://en.uncyclopedia.co/wiki/Special:MassDelete', 'mass delete', 't-massdelete' );



	$('#n-currentevents').after($('#n-recentchanges'));
	$('#n-recentchanges').css({ 'font-weight': 'bold' });

} );

/* Edit counter in top bar - by Wikipedia:User:Mvolz */

$(document).ready( function () { 
	mw.loader.using( 'mediawiki.user', function() {
	    ( new mw.Api() ).get( {
	        action: 'query',
	        meta: 'userinfo',
	        uiprop: 'editcount'
	    } ).done( function( result ) {
	    	document.getElementById( 'pt-mycontris' ).append( ' (' + result.query.userinfo.editcount + ')' );
	    } );
	} );
} );

// Stolen from https://en.wikipedia.org/w/index.php?title=User:PleaseStand/userinfo.js&oldid=803890891 to tweak some options
// See also [[User:Equazcion/sysopdetector.js]] and [[User:Anomie/useridentifier.js]]
// based on [[User:Fran Rogers/dimorphism.js]] and [[User:Splarka/sysopdectector.js]]

// Display on all user (sub)pages and contribs, logs, etc.
// Edit counter link for current project
// Show a symbol if no gender pronoun selected
// Don't show the "From Wikipedia" if showing userinfo
// Add option to disable for self



// userinfoHideSelf defaults to off
if (window.userinfoHideSelf === undefined || typeof window.userinfoHideSelf !== 'boolean') {
	window.userinfoHideSelf = false;
}


function UserinfoJsFormatQty(qty, singular, plural) {
    return String(qty).replace(/\d{1,3}(?=(\d{3})+(?!\d))/g, "$&,") + "\u00a0" + (qty == 1 ? singular : plural);
}

function UserinfoJsFormatDateRel(old) {
    // The code below requires the computer's clock to be set correctly.
    var age = new Date().getTime() - old.getTime();
    var ageNumber, ageRemainder, ageWords;
    if(age < 60000) {
	// less than one minute old
	ageNumber = Math.floor(age / 1000);
	ageWords = UserinfoJsFormatQty(ageNumber, "second", "seconds");
    } else if(age < 3600000) {
	// less than one hour old
	ageNumber = Math.floor(age / 60000);
	ageWords = UserinfoJsFormatQty(ageNumber, "minute", "minutes");
    } else if(age < 86400000) {
	// less than one day old
	ageNumber = Math.floor(age / 3600000);
	ageWords = UserinfoJsFormatQty(ageNumber, "hour", "hours");
	ageRemainder = Math.floor((age - ageNumber * 3600000) / 60000);
    } else if(age < 604800000) {
	// less than one week old
	ageNumber = Math.floor(age / 86400000);
	ageWords = UserinfoJsFormatQty(ageNumber, "day", "days");
    } else if(age < 2592000000) {
	// less than one month old
	ageNumber = Math.floor(age / 604800000);
	ageWords = UserinfoJsFormatQty(ageNumber, "week", "weeks");
    } else if(age < 31536000000) {
	// less than one year old
	ageNumber = Math.floor(age / 2592000000);
	ageWords = UserinfoJsFormatQty(ageNumber, "month", "months");
    } else {
	// one year or older
	ageNumber = Math.floor(age / 31536000000);
	ageWords = UserinfoJsFormatQty(ageNumber, "year", "years");
	ageRemainder =
	    Math.floor((age - ageNumber * 31536000000) / 2592000000);
	if(ageRemainder) {
	    ageWords += " " +
		UserinfoJsFormatQty(ageRemainder, "month", "months");
	}
    }
    return ageWords;
}

// If on a user or user talk page
if (mw.config.exists('wgRelevantUserName') && !(window.userinfoHideSelf && mw.config.get('wgRelevantUserName') === mw.config.get('wgUserName'))) {
    // add a hook to...
    mw.loader.using( ['mediawiki.util'], function() { $(function(){
	// Request the user's information from the API.
	// Note that this is allowed to be up to 5 minutes old.
	var et = encodeURIComponent(mw.config.get("wgRelevantUserName"));

	$.getJSON(mw.config.get("wgScriptPath") + "/api.php?format=json&action=query&list=users|usercontribs&usprop=blockinfo|editcount|gender|registration|groups&uclimit=1&ucprop=timestamp&ususers=" + et + "&ucuser=" + et + "&meta=allmessages&amprefix=grouppage-&amincludelocal=1")
	    .done(function(query) {
		// When response arrives extract the information we need.
		if(!query.query) { return; } // Suggested by Gary King to avoid JS errors --PS 2010-08-25
		query = query.query;
		var user, invalid, missing, groups, groupPages={}, editcount, registration, blocked, partial, gender, lastEdited;
		try {
		    user = query.users[0];
		    invalid = typeof user.invalid != "undefined";
		    missing = typeof user.missing != "undefined";
		    groups = (typeof user.groups == "object") ? user.groups : [];
		    editcount = (typeof user.editcount == "number") ? user.editcount : null;
		    registration = (typeof user.registration == "string") ?
			new Date(user.registration) : null;
		    blocked = typeof user.blockedby != "undefined";
		    partial = typeof user.blockpartial != "undefined";
		    gender = (typeof user.gender == "string") ? user.gender : null;
		    lastEdited = (typeof query.usercontribs[0] == "object") &&
			(typeof query.usercontribs[0].timestamp == "string") ?
			new Date(query.usercontribs[0].timestamp) : null;
		    for (var am=0; am<query.allmessages.length; am++) {
			groupPages[query.allmessages[am]["name"].replace("grouppage-","")] = query.allmessages[am]["*"].replace("{{ns:project}}:","Project:");
		    }
		} catch(e) {
		    return; // Not much to do if the server is returning an error (e.g. if the username is malformed).
		}

		// Format the information for on-screen display

		var statusText = "";
		var ipUser = false;
		var ipv4User = false;
		var ipv6User = false;

		// User status
		if(blocked) {
		    statusText += "<a href=\"" + mw.config.get("wgScript") +
			"?title=Special:Log&amp;page=" +
			encodeURIComponent(mw.config.get("wgFormattedNamespaces")[2] + ":" + user.name) +
			"&amp;type=block\">" + (partial ? 'partially ' : '') + "blocked</a> ";
		}
		if (missing) {
		    statusText += "username not registered";
		} else if (invalid) {
		    ipv4User = mw.util.isIPv4Address(user.name);
		    ipv6User = mw.util.isIPv6Address(user.name);
		    ipUser = ipv4User || ipv6User;
		    if (ipv4User) {
			statusText += "anonymous IPv4 user";
		    } else if (ipv6User) {
			statusText += "anonymous IPv6 user";
		    } else {
			statusText += "invalid username";
		    }
		} else {
		    // User is registered and may be in a privileged group. Below we have a list of user groups.
		    // Only need the ones different from the software's name (or ones to exclude), though.
		    var friendlyGroupNames = {
			// Exclude implicit user group information provided by MW 1.17 --PS 2010-02-17
			'*': false,
			'user': false,
			'autoconfirmed': false,
			abusefilter: "edit filter manager",
			'abusefilter-helper': "abuse filter helper",
			autopatrolled: "autopatrolled user",
			bureaucrat: "bureaucrat",
			extendedconfirmed: "extended confirmed user",
			'interface-admin': "interface op",
			'empress': "empress",
			'ipblock-exempt': "IP block exemption",
			rollback: "rollbacker",
			sysop: "administrator",
			'sysadmin': "sysadmin",
		    };

		    var friendlyGroups = [];
		    for(var i = 0; i < groups.length; ++i) {
			var s = groups[i];
			var t = friendlyGroupNames.hasOwnProperty(s) ? friendlyGroupNames[s] : s;
			if (t) {
			    if (groupPages.hasOwnProperty(s)) {
				friendlyGroups.push("<a href=\"" +  mw.config.get("wgArticlePath").replace("$1", encodeURIComponent( groupPages[s] )) + "\">" + t + "</a>");
			    } else {
				friendlyGroups.push(t);
			    }
			}
		    }
		    switch(friendlyGroups.length) {
		    case 0:
			// User not in a privileged group
			// Changed to "registered user" by request of [[User:Svanslyck]]
			// --PS 2010-05-16

			// statusText += "user";
			if(blocked) {
			    statusText += "user";
			} else {
			    statusText += "registered user";
			}
			break;
		    case 1:
			statusText += friendlyGroups[0];
			break;
		    case 2:
			statusText += friendlyGroups[0] + " and " + friendlyGroups[1];
			break;
		    default:
			statusText += friendlyGroups.slice(0, -1).join(", ") +
			    ", and " + friendlyGroups[friendlyGroups.length - 1];
			break;
		    }
		}

		// Registration date
		if(registration) {
		    var firstLoggedUser = new Date("09 07, 2005 22:16Z"); // When the [[Special:Log/newusers]] was first activated
		    if(registration >= firstLoggedUser) {
			statusText += ", <a href='" + mw.config.get("wgScript") +
			    "?title=Special:Log&amp;type=newusers&amp;dir=prev&amp;limit=1&amp;user=" +
			    et + "'>" + UserinfoJsFormatDateRel(registration) + "</a> old";
		    } else {
			statusText += ", <a href='" + mw.config.get("wgScript") +
			    "?title=Special:ListUsers&amp;limit=1&amp;username=" +
			    et + "'>" + UserinfoJsFormatDateRel(registration) + "</a> old";
		    }
		}

		// Edit count
		if(editcount !== null) {
		    statusText += ", with " +
			"<a href=\"//celeste.ink/wiki/Special:Editcount" +
			"/" + encodeURIComponent(user.name) + "\">" +
			UserinfoJsFormatQty(editcount, "edit", "edits") + "</a>";
		}

		// Prefix status text with correct article
		if("AEIOaeio".indexOf(statusText.charAt(statusText.indexOf('>')+1)) >= 0) {
		    statusText = "An " + statusText;
		} else {
		    statusText = "A " + statusText;
		}

		// Add full stop to status text
		statusText += ".";

		// Last edited --PS 2010-06-27
		// Added link to contributions page --PS 2010-07-03
		if(lastEdited) {
		    statusText += "  Last edited <a href=\"" + mw.config.get("wgArticlePath").replace("$1", "Special:Contributions/" + encodeURIComponent(user.name)) + "\">" + UserinfoJsFormatDateRel(lastEdited) + " ago</a>.";
		}

		// Show the correct gender symbol
		var fh = document.getElementById("firstHeading") ||
		    document.getElementById("section-0");
		// Add classes for blocked, registered, and anonymous users
		var newClasses = [];
		if(blocked) {
		    newClasses.push("ps-blocked");
		}
		if(ipUser) {
		    newClasses.push("ps-anonymous");
		} else if(invalid) {
		    newClasses.push("ps-invalid");
		} else {
		    newClasses.push("ps-registered");
		}
		fh.className += (fh.className.length ? " " : "") + groups.map(function(s) {
		    return "ps-group-" + s;
		}).concat(newClasses).join(" ");
		var genderSpan = document.createElement("span");
		genderSpan.id = "ps-gender-" + (gender || "unknown");
		genderSpan.style.paddingLeft = "0.25em";
		genderSpan.style.fontFamily = '"Lucida Grande", "Lucida Sans Unicode", "sans-serif"';
		genderSpan.style.fontSize = "75%";
		var genderSymbol;
		switch(gender) {
		case "male": genderSymbol = "\u2642"; break;
		case "female": genderSymbol = "\u2640"; break;
		default: genderSymbol = "\u2609"; break;
		    //See https://en.wikipedia.org/wiki/Miscellaneous_Symbols
		}
		genderSpan.appendChild(document.createTextNode(genderSymbol));
		fh.appendChild(genderSpan);

		// Now show the other information. Non-standard? Yes, but it gets the job done.
		// Add a period after the tagline when doing so. --PS 2010-07-03

		var ss = document.getElementById("siteSub");
		if(!ss) {
		    ss = document.createElement("div");
		    ss.id = "siteSub";
		    ss.innerHTML = "";
		    var bc = document.getElementById("bodyContent");
		    bc.insertBefore(ss, bc.firstChild);
		}
		//            ss.innerHTML = '<span id="ps-userinfo">' + statusText + '</span> ' + ss.innerHTML + '.';
		ss.innerHTML = '<span id="ps-userinfo">' + statusText + '</span>';
		ss.style.display = "block";
	    });
    }); });
}