User:Marian Dan/vector.js

From wikishia

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.
//<pre><code>
//
// [[User:Gimmetrow/fixRefs.js]]
 
function fixRefMarks() {
   var qt = String.fromCharCode(34)
   // var hb = String.fromCharCode(124)
   var txt = document.editform.wpTextbox1;
 
   // fact and other templates (geographic reference template, ref/note)
   var FactTag = "({{[ ]*fact[ ]*}}|{{[ ]*fact[ ]*[\|][^}]*}}|{{[ ]*facts[ ]*}}|{{[ ]*citequote[ ]*}}|{{[ ]*citation needed[ ]*}}|{{[ ]*citation needed[ ]*[\|][^}]*}}|{{[ ]*cn[ ]*}}|{{[ ]*verification needed[ ]*}}|{{[ ]*verify source[ ]*}}|{{[ ]*verify credibility[ ]*}}|{{[ ]*who[ ]*}}|{{[ ]*failed verification[ ]*}}|{{[ ]*nonspecific[ ]*}}|{{[ ]*dubious[ ]*}}|{{[ ]*or[ ]*}}|{{[ ]*lopsided[ ]*}}|{{[ ]*GR[ ]*[\|][ ]*[^ ]+[ ]*}}|{{[ ]*[c]?r[e]?f[ ]*[\|][^}]*}}|{{[ ]*ref[ _]label[ ]*[\|][^}]*}}|{{[ ]*ref[ _]num[ ]*[\|][^}]*}})";
 
   txt.value = txt.value
   .replace(new RegExp("[\n\r\f\t ]+?"+FactTag, "gi"), "$1")
   // one+ space/linefeed, avoid matching references tag as a named ref
   .replace(new RegExp("[\n\r\f\t ]+?<ref([ >])", "gi"), "<ref$1")
   // remove trailing spaces from named refs
   .replace(new RegExp("<ref ([^>]*[^> ])[ ]*>", "gi"), "<ref $1>")
   // remove some superscripted punctuation between refs (is between necessary?)
   .replace(new RegExp("(</ref>|<ref[^>]*?/>)<sup>[ ]*[,;-]?[ ]*</sup><ref", "gi"), "$1<ref")
   .replace(new RegExp("(</ref>|<ref[^>]*?/>)[ ]*[,;-]?[ ]*<ref", "gi"), "$1<ref")
 
   .replace(new RegExp("(</ref>|<ref[^>]*?/>)[ \n\r\f\t]*([\.,])", "gi"), "$1$2");
 
   var LacksPunctuation = "([^\.,;:!\?"+qt+"'’])";
   var QuestionOrExclam = "([!\?])";
   var MinorPunctuation = "([\.,;:])";
   var Blockquote       = "(</blockquote>)";
 
   var Quote = "([" + qt + "'’]*)";
   //var Space = "[\n\r\f\t ]*"; // to handle  http://en.wikipedia.org/w/index.php?title=Cat&diff=99697351&oldid=99697026
   var Space = "[ ]*";
   var Space2 = "[\n\r\f\t ]*";
 
   var AnyPunctuation = "([\.,;:!\?])";
   var MajorPunctuation = "([,;:!\?])";
   var Period = "([\.])";
 
   // can this complicated close tag be simplified?
   //var closetag = "(([^<]|<[^/]|</[^r]|</r[^e]|</re[^f]|</ref[^>])*?)</ref>";
   //var closetag = "((.*?))</ref>";
   var RefTag1 = "(<ref>([^<]|<[^/]|</[^r]|</r[^e]|</re[^f]|</ref[^>])*?</ref>)";
   var RefTag2 = "(<ref[^>]*?[^/]>([^<]|<[^/]|</[^r]|</r[^e]|</re[^f]|</ref[^>])*?</ref>)";
   var RefTag3 = "(<ref[^>]*?/>)";
   //var Note = "("+RefTag1 + "|(" + RefTag2 + ")|(" + FactTag + "))";
 
   var match0a = LacksPunctuation+Quote+FactTag+Space+AnyPunctuation;
   var match0b = QuestionOrExclam+Quote+FactTag+Space+MajorPunctuation;
   var match0c = MinorPunctuation+Quote+FactTag+Space+AnyPunctuation;
   var match0d = QuestionOrExclam+Quote+FactTag+Space+Period;
 
   var match1a = LacksPunctuation+Quote+RefTag1+Space+AnyPunctuation;
   var match1b = QuestionOrExclam+Quote+RefTag1+Space+MajorPunctuation;
   var match1c = MinorPunctuation+Quote+RefTag1+Space+AnyPunctuation;
   var match1d = QuestionOrExclam+Quote+RefTag1+Space+Period;
 
   var match2a = LacksPunctuation+Quote+RefTag2+Space+AnyPunctuation;
   var match2b = QuestionOrExclam+Quote+RefTag2+Space+MajorPunctuation;
   var match2c = MinorPunctuation+Quote+RefTag2+Space+AnyPunctuation;
   var match2d = QuestionOrExclam+Quote+RefTag2+Space+Period;
 
   var match3a = LacksPunctuation+Quote+RefTag3+Space+AnyPunctuation;
   var match3b = QuestionOrExclam+Quote+RefTag3+Space+MajorPunctuation;
   var match3c = MinorPunctuation+Quote+RefTag3+Space+AnyPunctuation;
   var match3d = QuestionOrExclam+Quote+RefTag3+Space+Period;
 
   for (var j=0; j<5; j++)  // repeat for multiple refs together
   {
      txt.value = txt.value
      .replace(new RegExp(match0a, "gi"), "$1$2$4$3")
      .replace(new RegExp(match0b, "gi"), "$1$2$4$3")
      .replace(new RegExp(match0c, "gi"), "$2$4$3")
      .replace(new RegExp(match0d, "gi"), "$1$2$3")
 
      .replace(new RegExp(match1a, "gi"), "$1$2$5$3")
      .replace(new RegExp(match1b, "gi"), "$1$2$5$3")
      .replace(new RegExp(match1c, "gi"), "$2$5$3")
      .replace(new RegExp(match1d, "gi"), "$1$2$3")
 
      .replace(new RegExp(match2a, "gi"), "$1$2$5$3")
      .replace(new RegExp(match2b, "gi"), "$1$2$5$3")
      .replace(new RegExp(match2c, "gi"), "$2$5$3")
      .replace(new RegExp(match2d, "gi"), "$1$2$3")
 
      .replace(new RegExp(match3a, "gi"), "$1$2$4$3")
      .replace(new RegExp(match3b, "gi"), "$1$2$4$3")
      .replace(new RegExp(match3c, "gi"), "$2$4$3")
      .replace(new RegExp(match3d, "gi"), "$1$2$3");
   }
   // blockquotes (if trapped punctuation exists, remove it, and move blockquote past at least one ref)
   txt.value = txt.value
   .replace(new RegExp(Blockquote + AnyPunctuation + FactTag, "gi"), "$3$1")
   .replace(new RegExp(Blockquote + AnyPunctuation + RefTag1, "gi"), "$3$1")
   .replace(new RegExp(Blockquote + AnyPunctuation + RefTag2, "gi"), "$3$1")
   .replace(new RegExp(Blockquote + AnyPunctuation + RefTag3, "gi"), "$3$1")
   .replace(new RegExp(Blockquote + FactTag, "gi"), "$2$1")
   .replace(new RegExp(Blockquote + RefTag1, "gi"), "$2$1")
   .replace(new RegExp(Blockquote + RefTag2, "gi"), "$2$1")
   .replace(new RegExp(Blockquote + RefTag3, "gi"), "$2$1");
 
   var summary = document.editform.wpSummary;
   //summary.value = summary.value + " various minor fixes ";
}
 
addOnloadHook(function () {
    if(document.forms.editform) {
        addPortletLink('p-tb', 'javascript:fixRefMarks()', 'Fix reference marks', 't-reffix', 'Ref fix', '', '');
    }
});
//</code></pre>
// SCRIPT:     NewPagePatrol
 
// The code for this was originally copied from User:TheJosh/Scripts/NewPagePatrol.js 
// User:Thingg tweaked it a little.
// I did literally nothing at all.
// I moved it to a subpage because it is SO LONG and I hate scrolling past it every time I look at this page
 
importScript('User:Marek69/newpage.js');
 
importScript('Wikipedia:WikiProject User scripts/Scripts/Watchlist since');
importScript('User:Jorgenev/scripts/EnhancedUserContribs.js');
//[[User:ais523/adminrights.js]]
//
// This script highlights bluelinks to admins' userpages or talkpages in bodyContent (that is, everything but the tabs, personal
// links at the top of the screen and sidebar) by giving them a cyan background. Please import this script using importScript,
// rather than copying the code, as the list of admins is hard-coded for performance and if you copy the code the list won't update
// with time (I update it from time to time). You can do this by substing Template:js with this script's name as an argument in your
// monobook.js.
//
// If you want a colour other than cyan, add
// .ais523_adminrights_admin {background-color: #FFFF00 !important}
// (or any other colour code) to your monobook.css file.
 
//Update this list at
//http://en.wikipedia.org/w/index.php?title=Special:Listusers&limit=5000&group=sysop&ais523update=y
var adminrights=new Array();
 
importScript('User:Ais523/adminrights-admins.js'); //[[User:Ais523/adminrights.js]]
 
//Updating script
addOnloadHook(function(){
  if(location.href=="http://en.wikipedia.org/w/index.php?title=Special:ListUsers&limit=5000&"+
                    "group=sysop&ais523update=y")
  {
    var h=document.getElementById('bodyContent').innerHTML;
    var a=new Array();
    h=h.split(/\< *li *\>/i);
    var i=0;
    while(++i<h.length)
    {
      a[h[i].split(">")[1].split("<")[0]]=h[i].split(/\< *\/ *li *\>/i)[0];
    }
    for(i in a)
    {
      document.write("adminrights['"+
        encodeURIComponent(i).split("\\").join("\\\\").split("'").join("%27")
                             .split("(").join("%28").split(")").join("%29")
                             .split("%21").join("!").split("%2C").join(",")
                             .split("%3A").join(":")+"']=1;<BR/>");
    }
  }
});
 
//Highlighting script. Based on [[User:ais523/highlightmyname.js]].
 
function highlightadmins_inner(n,h) //node, relevant hyperlink fragment
{
  if (n.nodeType!=1||n.tagName.toLowerCase()!="a") return 0; // not an anchor
  if (n.href.indexOf(wgScript+"?title="+h) == -1 &&
      n.href.indexOf(wgArticlePath.split("$1")[0]+h) == -1) return 0; // to the wrong target
  var u=n.href.split(h)[1];
  if(adminrights[u.split("_").join("%20")]==1)
  {
    n.style.backgroundColor="#00FFFF";
    if(n.className==null||n.className=="") n.className="ais523_adminrights_admin";
    else n.className+=" ais523_adminrights_admin";
  }
  return 1;
}
 
function highlightadmins(n) //node
{
  while(n!=null)
  {
    if(highlightadmins_inner(n,"User:")) n=n.nextSibling;
    else if(highlightadmins_inner(n,"User_talk:")) n=n.nextSibling;
    else if(highlightadmins_inner(n,"Special:Contributions:")) n=n.nextSibling;
    else
    {
      if(n.firstChild!=null) highlightadmins(n.firstChild);
      n=n.nextSibling;
    }
  }
}
 
addOnloadHook(function() {
  if(location.href.indexOf("?ais523")==-1&&location.href.indexOf("&ais523")==-1&&
     location.href.indexOf("?action=edit")==-1&&location.href.indexOf("?action=submit")==-1&&
     location.href.indexOf("&action=edit")==-1&&location.href.indexOf("&action=submit")==-1&&
     wgPageName!="Special:Preferences")
  {
    highlightadmins(document.getElementById('bodyContent'));
  }
});
 
//[[Category:Wikipedia scripts]]
importScript('User:Mr.Z-man/rollbackSummary.js'); // [[User:Mr.Z-man/rollbackSummary.js]]
importScript('User:Ale_jrb/Scripts/userhist.js');                           //User History
importScript('User:Manishearth/sidebartranslinks.js');                  //Sidebar Translate
if (wgCanonicalSpecialPageName == 'Watchlist')                        //Watchlist helper
     importScript('user:js/watchlist.js');
importScript('User:Marek69/sharebox.js');
importScript('User:Ohconfucius/script/EngvarB.js');  //[[User:Ohconfucius/script/EngvarB.js]]
importScript('User:Ohconfucius/script/formatgeneral.js');  //[[User:Ohconfucius/script/formatgeneral.js]]
importScript('User:Ohconfucius/script/Sources.js');  //[[User:Ohconfucius/script/Sources.js]]
importScript('User:Ohconfucius/script/MOSNUM dates.js');  //[[User:Ohconfucius/script/MOSNUM dates.js]]
importScript("User:GregU/dashes.js");
importScript("User:Smith609/toolbox.js");
importScript('User:Dr_pda/prosesize.js'); //[[User:Dr_pda/prosesize.js]]
importScript('User:Magnus Manske/add_fist_links.js');
addOnloadHook ( add_dabsolver_links ) ;
function add_dabsolver_links () {add2toolbox ( 'http://toolserver.org/~dispenser/cgi-bin/dab_solver.py?page=' + wgPageName , 'Disambiguate');}
importScript("User:EpochFail/No_Biting.js")
// lupin
// [[User:Lupin/popups.js]]
importScript('User:Lupin/popups.js');
autoEdClick = false;
simplePopups=true;
popupAdminLinks=true;
popupFixDabs=true;
importScript('Wikipedia:AutoEd/complete.js');
importScript('User:Lupin/recent2.js');
importScript('User:Gary King/tests.js'); // Tests
importScript('User:Gary King/custom functions.js'); // Custom functions
 
importScript('User:Dr pda/articlehistory.js'); // Article History
importScript('User:Dispenser/Checklinks/json.js'); // Check Links
importScript('User:Gary King/default summary.js'); // Default summary
importScript('User:Dr pda/editrefs.js'); // Edit References
importScript('User:Splarka/dabfinder.js'); // Disambiguation lookup script
importScript('User:Gimmetrow/fixRefs.js'); // Fix References
importScript('User:AzaToth/twinkle.js');
importScript('User:AzaToth/morebits.js');
importScript('User:AWeenieMan/furme.js');
importScript('User:AWeenieMan/furmeScroller.js');
importScript('User:Matma Rex/disFixer.js');
importScript("User:Smith609/toolbox.js");
importScript('User:Ioeth/friendlywelcome.js');
importScript('User:Ioeth/friendlyshared.js');
importScript('User:Ioeth/friendlytag.js');
importScript('User:Ioeth/friendly.js');
// igloo
importScript('User:Ale_jrb/Scripts/igloo.js'); // [[User:Ale_jrb/Scripts/igloo]]
importScript("User:TheDJ/Gadget-HotCat.js");
importScript('User:Drilnoth/codefixer.js'); //See [[User:Drilnoth/codefixer.js/doc]] for details
 
codefixerMinor = false;
importScript('User:Cameltrader/Advisor.js');
 
// install [[User:Cacycle/wikEd]] in-browser text editor
document.write('<script type="text/javascript" src="'
+ 'http://en.wikipedia.org/w/index.php?title=User:Cacycle/wikEd.js'
+ '&action=raw&ctype=text/javascript"></' + 'script>');
 
FriendlyConfig = {
    summaryAd            :    " using [[WP:FRIENDLY|Friendly]]",
    topWelcomes            :    false,
    watchWelcomes            :    false,
    markWelcomesAsMinor        :    true,
    insertHeadings            :    true,
    welcomeHeading            :    "== Welcome ==",
    insertUsername            :    true,
    insertSignature            :    true,
    quickWelcomeMode        :    "auto",
    quickWelcomeTemplate        :    "Welcome",
    maskTemplateInSummary        :    true,
    markSharedAsMinor        :    true,
    groupByDefault            :    true,
    watchTaggedPages        :    false,
    markTaggedPagesAsMinor        :    false,
    idsToRename = [
        { id: 'ca-nstab-main', name: 'Main', mainPageOnly: true },
        { id: 'ca-nstab-help', name: 'Help' },
        { id: 'ca-nstab-special', name: 'Special' },
        { id: 'ca-nstab-project', name: 'Project' },
        { id: 'ca-nstab-user', name: 'User' },
        { id: 'ca-edit', name: 'Edit' },
        { id: 'ca-viewsource', name: 'Source' },
        { id: 'ca-talk', name: 'Talk' },
        { id: 'ca-undelete', name: 'Undelete' },
        { id: 'ca-addsection', name: '+' }
    ]
};
TwinkleConfig = {
    batchdeleteChunks            :    50,
    batchDeleteMinCutOff            :    5,
    batchMax                :    5000,
    batchProtectChunks            :    50,
    batchProtectMinCutOff            :    5,
    batchundeleteChunks            :    50,
    batchUndeleteMinCutOff            :    5,
    blankTalkpageOnIndefBlock        :    false,
    defaultWarningGroup            :    1,
    deleteTalkPageOnDelete            :    false,
    deletionSummaryAd            :    ' using [[WP:TW|TW]]',
    deliChunks                :    500,
    deliMax                    :    5000,
    markAIVReportAsMinor            :    true,
    markSockReportAsMinor            :    false,
    markUAAReportAsMinor            :    true,
    markRevertedPagesAsMinor        :    [ 'vand' ],
    markSpeedyPagesAsMinor            :    false,
    markSpeedyPagesAsPatrolled        :    true,
    notifyUserOnDeli            :    true,
    notifyUserOnSpeedyDeletionNomination    :    [ 'g1', 'g2', 'g3', 'g4', 'g10', 'g11', 'g12', 'a1', 'a2', 'a3', 'a5', 'a7', 'a9', 'i1', 'i2', 'i3', 'i4', 'i5', 'i6', 'i7', 'i8', 'i9', 'i10', 'i11', 'u3', 't1', 't2', 't3', 'p2' ],
    offerReasonOnNormalRevert        :    true,
    openTalkPage                :    [ 'agf', 'norm', 'vand' ],
    openTalkPageOnAutoRevert        :    false,
    openUserTalkPageOnSpeedyDelete        :    [ 'g1', 'g2', 'g3', 'g4', 'g5', 'g10', 'g11', 'g12', 'a1', 'a3', 'a7', 'a9', 'i3', 'i4', 'i5', 'i6', 'i7', 'i9', 'i11', 'u3', 't1', 't2' ],
    orphanBacklinksOnSpeedyDelete        :    {exclude:['g6'], orphan:true},
    proddeleteChunks            :    50,
    protectionSummaryAd            :    ' using [[WP:TW|TW]]',
    revertMaxRevisions            :    50,
    showSharedIPNotice            :    true,
    summaryAd                :    ' using [[WP:TW|TW]]',
    userTalkPageMode            :    'window',
    watchProdPages                :    false,
    watchRevertedPages            :    [ 'agf', 'norm', 'vand', 'torev' ],
    watchSpeedyPages            :    [ 'g3', 'g5', 'g10', 'g11', 'g12', 't1' ],
    watchWarnings                :    true
};
 
addOnloadHook(function () {
    if (!wgCanonicalSpecialPageName || wgCanonicalSpecialPageName != "Watchlist") return;
    if (!document.forms[0] || !document.forms[0].namespace) return;
 
    var link = document.createElement('a');
    link.id = 'listSince';
    link.href = '#listSince';  // must have a href to show as link!
 
    var then = +(new Date());
    var fixLinkHref = function () {
        var url = window.location.href.split('#')[0];
        var days = (( +(new Date()) - then ) + (60 * 1000)) / (1000 * 3600 * 24);
        if (url.match(/[?&]days=/))
            this.href = url.replace(/([?&]days=)[^&]*/, '$1'+days);
        else
            this.href = url + (url.indexOf('?') < 0 ? '?':'&') + 'days=' + days;
        return true;
    };
    link.onclick = fixLinkHref;
    link.onmousedown = fixLinkHref;  // react to middle clicks too
 
    var frag = document.createDocumentFragment();
    frag.appendChild(document.createTextNode(' | '));
    frag.appendChild(link);
    link.appendChild(document.createTextNode('Changes'));
    frag.appendChild(document.createTextNode(' since last load.'));
 
    // just one little ID attribute would be _so_ nice...
    var nsSelectForm = document.getElementsByTagName('form')[0];
    nsSelectForm.parentNode.insertBefore(frag, nsSelectForm);
});
 
//
 
 
importScript('User:TheDJ/qui.js');
//////////STATUS CHANGER
// Creator: Misza13
// Credits: Voyagerfan5761 for some minor improvements
// Modified by Xenocidic to simply use /Status as a one word indicator,
// compatible with {{Statustop}} for display
 
addOnloadHook(function (){
  //Check if the config is defined
  if (typeof(statusChangerConfig) == 'undefined') {
    statusChangerConfig = {}
  }
 
  if (typeof(statusChangerConfig.statusList) == 'undefined') {
      statusChangerConfig.statusList = [ 'online', 'busy', 'around', 'offline' ];
  }
 
  if (typeof(statusChangerConfig.statusPage) == 'undefined') {
      statusChangerConfig.statusPage = 'User:' + wgUserName + '/Status';
  }
 
  //Add the links
  for (var i=0; i<statusChangerConfig.statusList.length; i++) {
    var stat = statusChangerConfig.statusList[i];
    addPortletLink(
      "p-personal", //target tab - personal links
      wgServer + wgScript + "?title=" + statusChangerConfig.statusPage + "&action=edit&newstatus=" + stat, //link URL
      stat, //link text
      "pt-status-" + stat, //id of new button
      "I'm " + stat + "!", //hover text
      "", //???
      document.getElementById("pt-logout")); //add before logout button
  }
 
  if (location.href.indexOf("&action=edit&newstatus=") == -1) return; //Are we here to auto-edit the status?
  //Get new status
  statusRegExp = /&action=edit&newstatus=(.*)/;
  status = statusRegExp.exec(location.href)[1];
  //Modify the form
  document.getElementById('wpTextbox1').value = status;
  document.getElementById('wpSummary').value = wgUserName + " is now " + status +".";
  document.getElementById('wpMinoredit').checked = true;
  //Submit it!
  document.getElementById('editform').submit();
});
 
//[[Category:Wikipedia scripts|statusChanger]]
 
importScript('User:VoA/monobook.js');
 
//[[Category:Wikipedians who use RC script]]
 
// -----------------------------------------------------------------------------
// Ãœbergodmode Monobook skin
// (c) 2005 Sam Hocevar <sam@zoy.org>
// $Id: ubergodmode.js 886 2005-05-14 23:56:48Z sam $
// -----------------------------------------------------------------------------
 
// -----------------------------------------------------------------------------
// Language support
// -----------------------------------------------------------------------------
var blocklink = 'Block this user';
switch (document.getElementsByTagName('html')[0].lang) {
case 'fr':
blocklink = 'Bloquer cet utilisateur';
break;
}
 
// -----------------------------------------------------------------------------
// Our nice Block functions
// -----------------------------------------------------------------------------
function PerformBlock() {
var l, target = '';
// Look for '&faketarget=XXX' in URL
url = location.pathname;
l = location.search.substring(1).split('&');
for (i = 0; i < l.length; i++) {
var n = l[i].indexOf('=');
if (l[i].substring(0, n) == 'faketarget') {
target = l[i].substring(n + 1);
}
}
if (!target)
return;
form = document.getElementById('blockip');
if (!form)
return;
input = form.getElementsByTagName('input')[0];
input.value = target;
}
 
// -----------------------------------------------------------------------------
// Add block buttons to the page
// -----------------------------------------------------------------------------
function AddBlockButtons() {
var l, article = '', vandal;
// Add 'block' links to a diff page
l = document.getElementById('t-emailuser');
if (l) {
clone = l.cloneNode(true);
l.id = 't-blockuser';
a = clone.getElementsByTagName('a')[0];
a.href = a.href.replace(/Special:Emailuser/, 'Special:Blockip');
a.href = a.href.replace(/target=/, 'faketarget=');
a.innerHTML = blocklink;
l.parentNode.insertBefore(clone, l.nextSibling);
}
}
 
// -----------------------------------------------------------------------------
// Modify the page once it is loaded
// -----------------------------------------------------------------------------
if (window.addEventListener) {
window.addEventListener("load", PerformBlock, false);
window.addEventListener("load", AddBlockButtons, false);
} else if (window.attachEvent) {
window.attachEvent("onload", PerformBlock);
window.attachEvent("onload", AddBlockButtons);
}
importScript('User:AndyZ/peerreviewer.js'); //[[User:AndyZ/peerreviewer.js]]
 
//
// Edit tools for the vandal whack-a-mole game
// [[User:Kbh3rd/whackamole.js]] - please include this line
//
document.write('<script type="text/javascript" src="' 
+ 'http://en.wikipedia.org/w/index.php?title=User:Kbh3rd/whackamole.js' 
+ '&action=raw&ctype=text/javascript&dontcountme=s"></script>');
 
 
 
 
 
//Ameliorating vandalism. Naught to do with the Belgian municipality.
//TODO: combine addRollback and addRestore into one function
//      use WikiTitle throughout the script
//      add history visualization to get around IE prompt "security" issue
 
var AmelPrefs = {
    data: {},
    set: function(name, value) {
        return this.data[name] = value;
    },
    get: function(name, alternate) {
        return this.contains(name) ? this.data[name] : alternate;
    },
    contains: function(name) {
        return (typeof this.data[name] != "undefined");
    }
};
 
AmelPrefs.set("summarySuffix", "");
AmelPrefs.set("watchReversion", false)
 
var isDiff = /[?&]diff=/.test(document.location.href);
 
if (isDiff) {
addOnloadHook(addRollback);
addOnloadHook(addRestore);
}
 
//combine these into one function.
function addRollback() {
    if(document.getElementById("mw-diff-ntitle1").getElementsByTagName("a")[0].firstChild.nodeValue.indexOf("Current revision") == -1) return;
    var roll = document.createElement("input");
    roll.type = "button";
    roll.onclick = AmelUtil.diffRollback(document);
    roll.value = "Rollback";
    getElementsByClassName(document, "td", "diff-otitle")[0].appendChild(roll);
}
 
function addRestore() {
    var rest = document.createElement("input")
    rest.type = "button";
    rest.onclick = AmelUtil.diffRestore(document);
    rest.value = "Restore revision";
    getElementsByClassName(document, "td", "diff-otitle")[0].appendChild(rest);
}
 
function AdminRollback(url) {
    if (!url || this == window)
        return; //no title given, or "new" keyword not used
    this.url = url;
    try {
        this.userFrom = decodeURIComponent(url.match(/[&?]from=([^&]*)/)[1]).replace(/_/g, " ");
        this.title = url.match(/[&?]title=([^&]*)/)[1];
    } catch (e) {
        return; //error in parsing link; not correct
    }
    this.init();
}
 
AdminRollback.prototype.init = function() {
    var me = this;
    AmelUtil.colorStatus("#EFE");
    var req = new XMLHttpRequest();
    req.open("HEAD", this.url, true);
    req.onreadystatechange = function() {
        if (req.readyState == 4 && req.status == 200) {
            AmelUtil.colorStatus("#EEF");
            new WikiEdit(me.title).getHistory(function(obj){showHistory(me.title, obj)});
        }
    };
    req.send(null);
    new Warning(this.title, this.userFrom);
}
 
function Rollback(title, revFrom, userFrom) {
    if (!title || this == window)
        return; //no title given, or "new" keyword not used
    this.title = title; //in encoded form
    this.from = { "revid" : revFrom || undefined, "user" : userFrom || undefined };
    this.revTo = undefined;
    this.revnum = 0;
    this.editor = new WikiEdit(title, this);
    this.init();
}
 
Rollback.prototype.init = function () {
AmelUtil.colorStatus("#FEE");
    this.editor.downloadEditFormData();
this.editor.getHistory(this.parseHistory);
}
 
Rollback.prototype.parseHistory = function(history) {
AmelUtil.colorStatus("#FFE");
 
    if (!history || !history[0]) {
alert("Error retriving page history"); //go modal boxes!
return;
}
this.editor.setTimes(AmelUtil.isoToNumerical(history[0]["timestamp"]));
 
    //some situations the reverter should check out
var cautionMode = undefined;
    if (this.from.revid) {
        if (history[0]["revid"] == this.from.revid)
            this.from.user = history[0]["user"]; //just in case it's not defined
        else
            cautionMode = "The revision amelvand was told to revert from is not the most recent one.";
}
else if (this.from.user && this.from.user != history[0]["user"]) 
        cautionMode = "The user amelvand was told to revert from is not the most recent editor of the article.";
    else
        cautionMode = "Neither a revision nor a user was received, so just making sure that we really want to revert.";
 
    i = 0;
    if (cautionMode) {
        j = [];
        var min = Math.min(history.length, 8);
        for (i = 0; i < min; i++) //add summary?
            j[i] = i + ". " + history[i]["user"] + (history[i]["revid"] == this.from.revid ? " (original)" : "");
        i = prompt(j.join("\n") + "\n\nCaution mode enabled. Reason: " + cautionMode + "\n\nFrom which revision do you wish to revert?", "0"); //moar options!
        if (isNaN(parseInt(i))) return;
        this.revid = history[i][0];
        this.user = history[i][1];
}
//cautionModeBox(cautionMode, history); } else {
 
this.revnum = i;
while (this.revnum < history.length && history[this.revnum]["user"] == this.from.user) {
this.revnum++;
}
 
if (this.revnum - i != 1) {
if(!confirm("Rollback " + (this.revnum - i) + " edits by " + this.from.user + "?")) {
j = prompt("Then rollback how many edits?", "1")
if (isNaN(parseInt(j)))
return;
else
this.revnum = j;
}
}
 
if (this.revnum < history.length) {
        this.revTo = history[this.revnum]["revid"];
this.commit();
    }
    else
        alert("Last revision not by user not found.");
}
 
Rollback.prototype.commit = function() {
    new Warning(this.title, this.from.user);
    var editSum = "Reverted " + AmelUtil.plural(this.revnum, "edit", "edits") + " by [[Special:Contributions/$2|$2]] ([[User talk:$2|talk]])".replace(/\$2/g, this.from.user) + " to last revision by $1"; //$1 is assigned by RestoreRevision
    new RestoreRevision(this.title, this.revTo, this.editor, editSum)
};
 
function RestoreRevision(title, revTo, editor, editSum) {
    if (!title || !revTo || this == window)
        return;
    AmelUtil.colorStatus("#EFE");
    this.title = title;
    this.revTo = revTo;
    this.editSum = editSum || "Restored revision " + this.revTo + " by [[Special:Contributions/$1|$1]]"; //$1 is assigned by commit(obj)
    if (!editor) {
        editor = new WikiEdit(title);
        editor.downloadEditFormData();
        editor.getHistory(function(obj) {
            editor.setTimes(AmelUtil.isoToNumerical(obj["timestamp"]));
        }, 1);
    }
    editor.setParent(this);
    this.editor = editor;
    this.init();
}
RestoreRevision.prototype.init = function() {
    this.editor.getText(this.commit, this.revTo);
}
 
RestoreRevision.prototype.commit = function(obj) {
    if (!obj) return;
    var text = obj["*"];
    if (!text && text != "") return;
    this.editSum = this.editSum.replace(/\$1/g, obj["user"]) + AmelPrefs.get("summarySuffix", "");
 
    var editor = this.editor; //short-hand reference
    var title = this.title;
    editor.setMinor(false);
    editor.setWatch(AmelPrefs.get("watchReversion", false));
    editor.setCallback(function() {
        AmelUtil.colorStatus("#EEF");
        editor.getHistory(function(obj){showHistory(title, obj)});
    });
    editor.setText(text);
    editor.setSummary(this.editSum);
    editor.submit();
}
 
//---------------------------------
//@Private
function WikiTitle(displayTitle, urlTitle) {
    this.displayTitle = displayTitle;
    this.urlTitle = urlTitle;
}
 
WikiTitle.fromURL = function(url, param) {
    var urlmatch = (!param && /\/wiki\/(.*)/.exec(url)) ||
                   new RegExp("[?&]" + (param || "title")  + "=([^&]*)").exec(url);
    if (urlmatch)
        return WikiEdit.fromEncoded(urlmatch[1]);
}
WikiTitle.fromEncoded = function(encoded) {
    return new WikiTitle(decodeURIComponent(encoded).replace(/_/g, " "),
encoded);
 
}
WikiTitle.fromDisplay = function(display) {
    return new WikiTitle(display,
                         encodeURIComponent(display.replace(/ /g, "_")));
}
 
//accessors
WikiTitle.prototype = {
    toEncoded : function() {
        return this.urlTitle;
    },
    toIndexUrl : function() {
        return wgServer + wgScript + "?title=" + this.urlTitle;
    },
    toApiUrl : function() {
        return wgServer + wgScriptPath + "/api.php?titles=" + this.urlTitle;
    },
    toString : function() {
        return this.displayTitle;
    }
};
 
function Warning(title, user) {
    if (!title || !user || this == window)
        return;
    var me = this;
    this.user = user;
    title = WikiTitle.fromEncoded(title);
    this.title = title;
    var warnTitle = WikiTitle.fromDisplay("User talk:" + user),
        aivTitle = WikiTitle.fromDisplay("Wikipedia:Administrator intervention against vandalism");
    this.data = new Object();
    this.data[Warning.WARN] = {
            "title": warnTitle,
            "editor": new WikiEdit(warnTitle, me),
            "summary": "Note: edits on [[" + title + "]]",
            "savedtext": undefined,
            "addtext": undefined,
            "infotext": "",
            "button": "Report to AIV",
            "init": Warning.warnInit,
            "editpage": title
    };
    this.data[Warning.AIV] = {
            "title": aivTitle,
            "editor": new WikiEdit(aivTitle, me),
            "summary": "Reporting [[Special:Contributions/$1|$1]]".replace(/\$1/g, user),
            "savedtext": undefined,
            "addtext": "*{{" + (AmelUtil.isIP(user) ? "IPvandal" : "Userlinks") + "|" + user + "}} vandalism past last warning ~~" + "~~",
            "infotext": "Reporting " + user + ". ",
            "button": "Warn User",
            "init": Warning.aivInit,
            "regex":  new RegExp(user + "\\}\\}") //bathic thenthing mechanithm
 
    };
    this.mode = Warning.NONE;
 
    //initialize GUI. no "live" elements have innerHTML changed.
    var warnDiv = document.createElement("div");
    warnDiv.innerHTML = '<strong id="warnPage"></strong> <span id="warnInfo"></span><br /><textarea rows="10" name="warnBox" id="warnBox"> </textarea><br /><input type="text" value="" id="warnSum" size="30" onkeypress="if (event.which == 13) warning.submit();" /> <input type="button" value="Submit" id="warnSubmit" /> <input type="button" value="" id="warnSwitch" />';
    var jumpToNav = document.getElementById("jump-to-nav");
    if (!jumpToNav) return false;
    jumpToNav.parentNode.insertBefore(warnDiv, jumpToNav);
    this.gui = {
        "warnBox": document.getElementById("warnBox"),
        "warnPage": document.getElementById("warnPage"),
        "warnInfo": document.getElementById("warnInfo"),
        "warnSwitch": document.getElementById("warnSwitch"),
        "warnSubmit": document.getElementById("warnSubmit"),
        "warnSum": document.getElementById("warnSum")
    }
    this.gui["warnBox"].value = "";
    this.gui["warnPage"].appendChild(document.createTextNode(""));
    this.gui["warnInfo"].appendChild(document.createTextNode(""));
    this.gui["warnSwitch"].onclick = function() {me.setNextMode();};
    this.gui["warnSubmit"].onclick = function() {me.submit();};
    this.setNextMode();
}
 
Warning.NONE = ["NONE"];
Warning.WARN = ["WARN"];
Warning.AIV = ["AIV"];
 
Warning.warnInit = function(text) {
    this.savedtext = text;
    var parser = new WarningsParser(text);
    if (parser.report())
        this.infotext += "NOTE! User is past last warning. ";
    var now = new Date();
    var warnDate = parser.previousDate();
    var secElapsed = Math.ceil((now.getTime() - warnDate.getTime()) / 1000);
    if (secElapsed < 0) secElapsed += 3600; //an hour. voodoo programming!
    if (secElapsed < 600) { //ten minuteth
        var minElapsed = Math.floor(secElapsed / 60);
        this.infotext += "Latest warning was left " + (minElapsed == 0 ? "" : AmelUtil.plural(minElapsed, "minute", "minutes") + " and ") + AmelUtil.plural(secElapsed % 60, "second", "seconds") + " ago. ";
    }//12
    var headers = parser.getHeaders(), prefixHeader = "";
    if (!headers.warning || (headers.warning && headers.page) || (headers.warning && (now.getMonth() != warnDate.getMonth() || now.getFullYear() != warnDate.getFullYear())))
        prefixHeader = "== " + AmelUtil.monthNames[now.getUTCMonth()] + " " + now.getUTCFullYear() + " ==\n";
    this.savedtext += (/^\s*$/.test(this.savedtext) ? "" : "\n\n") + 
        (this.addtext = prefixHeader + "{{subst:uw-v" + parser.nextWarning() + "|" + this.editpage + "|Thank you.|subst=subst:}} ~~" + "~~");
}
 
Warning.aivInit = function(text) {
    if (this.regex.test(text))
        this.infotext += "NOTE! \"" + this.user + "\" found on page. ";
    this.savedtext = text + "\n" + this.addtext;
}
 
Warning.nextMode = function(mode) {
    switch (mode) {
        case Warning.NONE: return Warning.WARN;
        case Warning.WARN: return Warning.AIV;
        case Warning.AIV: return Warning.WARN;
        default: return Warning.NONE;
    }
}
 
Warning.prototype.getDownloadCallback = function(mode) {
    var me = this;
    return function(obj) {
        me.set(obj, mode);
    }
}
Warning.prototype.setNextMode = function() {
    this.set(null, Warning.nextMode(this.mode));
}
 
Warning.prototype.set = function(obj, newMode) {
    var mData = this.data[newMode];
    var text = obj && obj["*"];
    if (!mData) return;
    if (!mData.savedtext || mData.savedtext == "") {
        if (text || text == "") {
            mData.init(text);
            mData.editor.setTimes(AmelUtil.isoToNumerical(obj["timestamp"]));
            this.gui["warnSwitch"].value += "...";
 
            this.showMode(newMode);
        }
        else {
            var func = this.getDownloadCallback(newMode);
            mData.editor.getText(func);
            mData.editor.downloadEditFormData();
        }
    }
    else {
        if (text) {
            if (confirm("The page \"" + mData.title + "\" is already initialized. Overwrite displayed text?"))
                mData.init(text);
            else
                return;
        }
        this.showMode(newMode);
    }
}
 
Warning.prototype.showMode = function(newMode) {
    var thisData = this.data[this.mode];
    var newData = this.data[newMode];
    var gui = this.gui;
    if (thisData) {
        thisData.savedtext = gui["warnBox"].value;
        thisData.summary = gui["warnSum"].value;
    }
    gui["warnBox"].value = newData.savedtext;
    gui["warnSum"].value = newData.summary;
    gui["warnPage"].firstChild.nodeValue = newData.title;
    gui["warnInfo"].firstChild.nodeValue = newData.infotext;
    gui["warnSwitch"].value = newData.button;
    this.mode = newMode;
}
 
Warning.prototype.submit = function() {
    var summary = this.gui["warnSum"].value;
    var text = this.gui["warnBox"].value;
    if (this.mode == Warning.WARN) {
        var re = /\{\{subst:uw-(.*?)(?:\|.*?)?\}\}/gi;
        if (summary.charAt(summary.length - 1) == "*") //shorthand for "no template plz"
            summary = summary.substring(0, summary.length - 1);
        else {
            var templateMatch, templateName;
            while (templateMatch = re.exec(text))
                templateName = templateMatch[1];
            if (templateName)
                summary += " (" + templateName + ")";
        }
    } else if (this.mode != Warning.AIV) {
        return; //only Warning.WARN and Warning.AIV allowed at the moment
    }
 
    var button = this.gui["warnSubmit"];
    button.disabled = true;
 
    var editor = this.data[this.mode].editor;
    editor.setText(text);
    editor.setSummary(summary);
    editor.setMinor(false);
    editor.setWatch(false);
    editor.setCallback(function() { button.disabled = false; });
    editor.submit();
}
//---------------------------------
//construct object: get in, get out. No need for state.
function showHistory(title, historyObj, showButtons, limit) {
    limit = Math.min(historyObj.length, limit || 5);
    if (!limit) return;
 
    var pageURL = WikiTitle.fromEncoded(title).toIndexUrl();
    var currentId = historyObj[0]["revid"];
    var newLink = function(url, title) {
        var link = document.createElement("a");
        link.href = url;
        link.title = title;
        link.appendChild(document.createTextNode(title));
        return link;
    }
    var historyItem = function(item, nextItem) {
        //more pretty list under construction
        var liItem = document.createElement("li");
        if (nextItem) {
            liItem.appendChild(document.createTextNode("("));
            liItem.appendChild(newLink(pageURL + "&diff=" + currentId + "&oldid=" + item["revid"], "cur"));
            liItem.appendChild(document.createTextNode(") ("));
        } else {
            liItem.appendChild(document.createTextNode("(cur) ("));
        }
        liItem.appendChild(newLink(pageURL + "&diff=" + item["revid"] + "&dir=prev", "last"));
        liItem.appendChild(document.createTextNode(") "));
        liItem.appendChild(newLink(pageURL + "&oldid=" + item["revid"], AmelUtil.isoToStandard(item.timestamp)));
        liItem.appendChild(document.createTextNode(" "));
        liItem.appendChild(newLink(WikiTitle.fromDisplay("Special:Contributions/" + item.user).toIndexUrl(), item.user));
        if (item["comment"]) {
            var summary = item["comment"].replace(/\[\[([^\|\]]+)\|?(.*?)\]\]/g, function (ignore, link, display) { return "<a href=\"" + WikiTitle.fromDisplay(link).toIndexUrl() + "\">" + (display || link) + "</a>"});
            summary = summary.replace(/\/\*\s+(.+?)\s+\*\//g, function(ignore, anchor) { return "<a href=\"#" + WikiTitle.fromDisplay(anchor).toEncoded() + "\">→</a><span class=\"autocomment\">" + anchor + "</span> - "});
            var summaryElem = document.createElement("span");
summaryElem.innerHTML = " | " + summary;
            liItem.appendChild(summaryElem);
        }
        return liItem;
    }
    var historyDiv = document.getElementById("historyDiv");
    if (historyDiv && historyDiv.firstChild) {
        historyDiv.removeChild(historyDiv.firstChild);
    } else {
        historyDiv = document.createElement("div");
        historyDiv.id = "historyDiv";
        var jumpToNav = document.getElementById("jump-to-nav");
        if (!jumpToNav) return false;
        jumpToNav.parentNode.insertBefore(historyDiv, jumpToNav);
        historyDiv = document.getElementById("historyDiv");
    }
    var historyList = document.createElement("ol");
    var currentItem, nextItem;
    for (var i = 0; i < limit; i++) {
        currentItem = historyObj[i];
        historyList.appendChild(historyItem(currentItem, nextItem));
        nextItem = currentItem;
    }
    historyDiv.appendChild(historyList);
}
//---------------------------------
function WarningsParser(text) {
    var state = { header: false, hasWarnings: false };
    //if the latest header contains the most recent warning, if warnings can be found
    var recent = { header: undefined, text: undefined, date: new Date(0), level: 0 };
    //the header under which the latest warning appears, the warning's text,
    //the date of the warning, its level.
    var warningMatch = 0, warning;
    var dayAgo = new Date();
    dayAgo.setTime(dayAgo.getTime() - (24*60*60*1000));
    var re = /<!-- Template:(.*?) -->.*?(\d{2}:\d{2}, \d+ \w+ \d{4}) \(UTC\)/gi;
    var warning;
    while (warning = re.exec(text)) {
        if (!warning)
            break;
        recent.date = new Date(warning[2] + " UTC"); //UTC can't be in parentheses :|
        if (recent.date > dayAgo)
            recent.text = warning[1];
        state.hasWarnings = true;
        warningMatch = re.lastIndex;
    }
    //find the header the warning is under
    var headerRe = /^(={2,6}).+?\1\s*?$/mg;
    var warningH = text.substring(0, warningMatch).match(headerRe);
    var pageH = text.substring(warningMatch).match(headerRe);
    recent.header = warningH && warningH.pop();
    state.header = !!pageH;
 
    if (recent.text) {
        var levels = recent.text.match(/^.*?(\d)(im)?$/);
        if (levels && levels[1])
            recent.level = parseInt(levels[1]);
        else if (/first/i.test(recent.text)) recent.level = 1;
        else if (/second/i.test(recent.text)) recent.level = 2;
        else if (/third/i.test(recent.text)) recent.level = 3;
        else if (/fourth/i.test(recent.text)) recent.level = 4;
    } else if (state.hasWarnings) {
        recent.level = 1; //if there are warnings there, use a level 2. put this in prefs?
    }
    this.pageData = state;
    this.warningData = recent;
}
//encapsulate state
WarningsParser.prototype = {
    report : function() {
        return this.warningData.level == 4;
    },
    hasWarnings: function() {
        return this.pageData.hasWarnings;
    },
    nextWarning: function() {
        var recent = this.warningData;
        if (recent.level < 4)
            return recent.level + 1;
        else if (recent.level == 4)
            return 4;
        else //not sure what we have; stick with level 1.
            return 1; 
    },
    previousDate: function() {
        return this.warningData.date;
    },
    getHeaders: function() {
        return { page: this.pageData.header, warning: this.warningData.header };
    }
}
 
var AmelUtil = new Object();
 
AmelUtil.plural = function(num, singular, plural) {
    return num + " " + (num == 1 ? singular : plural);
}
 
//previously named AmelUtil.yetAnotherJsMonthNameArray. too long, though :P
AmelUtil.monthNames = ["January", "February", "March", "April",
                       "May", "June", "July", "August",
                       "September", "October", "November", "December"];
 
AmelUtil.isIP = function(str) {
    var rangeCheck = function(num) {
        return (!/\D/.test(num) && parseInt(num) >> 8 == 0);
    }
    var nums = str.split("."), index = nums.length;
    if (index != 4 && index != 6) return false;
    while (--index >= 0)
        if (!rangeCheck(nums[index])) return false;
    return true;
}
 
AmelUtil.numericalTsNow = function() {
    var now = new Date();
    var padDD = function(num) { //double-digit pad
        return ("0" + num).slice(-2);
    }
    return now.getUTCFullYear() + padDD(now.getUTCMonth() + 1) + padDD(now.getUTCDate()) +
           padDD(now.getUTCHours()) + padDD(now.getUTCMinutes()) + padDD(now.getUTCSeconds());
}
 
AmelUtil.isoToNumerical = function(timestamp) {
    return timestamp && timestamp.replace( /(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z/, "$1$2$3$4$5$6")
}
 
AmelUtil.isoToStandard = function(timestamp) {
    return timestamp && timestamp.replace( /(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z/, function(ignore, year, month, date, hour, minute) { return hour + ":" + minute + ", " + date + " " + AmelUtil.monthNames[month - 1] + " " + year});
}
 
AmelUtil.getPageObj = function(jsonObj) {
    try {
        jsonObj = jsonObj.query.pages;
        for (var pageObj in jsonObj)
            return jsonObj[pageObj];
    } catch (e) {
    }
}
 
AmelUtil.colorStatus = function(color) {
    document.getElementById("content").style.background = color;
}
 
AmelUtil.rollbackPerm = function() {
    if (wgUserGroups.indexOf)
        return wgUserGroups.indexOf("sysop") != -1 || wgUserGroups.indexOf("rollbacker") != -1;
    for (var i = 0, length = wgUserGroups.length; i < length; i++)
        if (wgUserGroups[i] == "sysop" || wgUserGroups[i] == "rollbacker") return true;
    return false;
}
 
AmelUtil.diffRollback = function() {
    var checkExist = document.getElementById("mw-diff-ntitle1");
    if (!checkExist) return null;
    if (AmelUtil.rollbackPerm()) {
        var rb = document.getElementById("mw-diff-ntitle2").getElementsByTagName("span");
        if (rb.length > 1) {
            var rbUrl = rb[1].getElementsByTagName("a")[0].href
            return function() {
                new AdminRollback(rbUrl);
            };
        } //else, continue along with normal revert
    }
    var link = checkExist.getElementsByTagName("a");
    link = link[link.length - 1].href;
    var revFrom = link.match(/[&?]undo=([^&]*)/);
    var pageName = link.match(/[&?]title=([^&]*)/);
    var userFrom = document.getElementById("mw-diff-ntitle2")
        .getElementsByTagName("a")[0].title.match(/(?:User:|Special:Contributions\/)(.*$)/);
    if (pageName)
        return function() {
            new Rollback(pageName[1], (revFrom ? revFrom[1] : undefined), (userFrom ? userFrom[1] : undefined));
        }
};
 
AmelUtil.diffRestore = function(container) {
    var checkExist = container.getElementById("mw-diff-otitle1");
    if (!checkExist) return null;
    var link = checkExist.getElementsByTagName("a")[0].href;
    var pageName = link.match(/[&?]title=([^&]*)/);
    var revTo = link.match(/[&?]oldid=([^&]*)/);
    var userTo = container.getElementById("mw-diff-otitle2")
        .getElementsByTagName('a')[0].title.match(/(?:User:|Special:Contributions\/)(.*$)/);
 
    if (pageName && revTo)
return function() {
        latest = new RestoreRevision(pageName[1], revTo[1]);
}
};
 
//-------------------------------------
//Mode: press spacebar to revert
var AmelKeyFuncs = {};
AmelKeyFuncs.enabled = document.cookie.indexOf("amelKeys=true") != -1;
AmelKeyFuncs.formatOnLoad = function() {
    addPortletLink("p-tb", "javascript:AmelKeyFuncs.toggleUse()", (AmelKeyFuncs.enabled ? "Don't use" : "Use") + " spacebar reversion", "t-amelkeys", "Enable reversion on diffs using the spacebar");
    window.onkeypress = AmelKeyFuncs.checkToRevert;
    window.focus();
 
}
AmelKeyFuncs.pageEnabled = true;
AmelKeyFuncs.checkToRevert = function(e) {
    if (!AmelKeyFuncs.enabled || !AmelKeyFuncs.pageEnabled)
        return true;
    e = e || window.event;
    if (e.charCode == 32) {
        var func = AmelUtil.diffRollback();
        AmelKeyFuncs.pageEnabled = false;
        if (func) {
            func.call(this);
            return false;
        }
    }
    return true;
}
AmelKeyFuncs.toggleUse = function() {
    var now = new Date();
    if (!AmelKeyFuncs.enabled)
        now.setTime(now.getTime() + 365*24*60*60*1000);
    AmelKeyFuncs.enabled = !AmelKeyFuncs.enabled;
    document.cookie = "amelKeys=" + AmelKeyFuncs.enabled + "; expires=" + now.toGMTString() + "; path=/"
    document.getElementById("t-amelkeys").firstChild.firstChild.nodeValue = (AmelKeyFuncs.enabled ? "Don't use" : "Use") + " spacebar reversion";
}
 
if (isDiff && AmelKeyFuncs.enabled)
    addOnloadHook(AmelKeyFuncs.formatOnLoad);
 
 
//-------------------------------------
 
var WikiEdit = function(title, parent, autosubmit) {
    if (!title)
        throw new Error("title needed for WikiEdit");
    this.title = title;
    this.autosubmit = autosubmit;
    this.submitCallback = function(){};
    this.closed = false;
    this.editMonitor = false;
    this.submitData = {}; //the form fields
    this.onSubmitHooks = []; //to be processed immediately before submitting
    this.submitXHR = null;
    this.parent = parent;
 
}
 
WikiEdit.needToSubmit = ["wpTextbox1", "wpSummary", "wpEditToken", "wpStarttime", "wpEdittime"];
WikiEdit.prototype.setCallback = function(callback) {
    this.submitCallback = callback;
}
 
WikiEdit.prototype.cancel = function() {
    this.closed = true;
    if (this.submitXHR)
        this.submitXHR.abort();
}
 
WikiEdit.prototype.addSubmitHook = function(func) {
    if (this.closed)
        return false;
    this.onSubmitHooks.push(func);
    return true;
}
 
WikiEdit.prototype.doPreSubmitHook = function(func) {
    if (this.closed)
        return false;
    this.editMonitor = true;
    func.call(this);
    this.editMonitor = false;
    this.addSubmitData({});
    return true;
}
 
WikiEdit.prototype.downloadEditFormData = function() {
    if (this.closed)
        return;
    var me = this;
    var req = new XMLHttpRequest();
    req.open("GET", wgServer + wgScriptPath + "/api.php?action=query&prop=info&intoken=edit&format=json&titles=" + this.title, true);
    req.onreadystatechange = function() {
        if (req.readyState == 4 && req.status == 200) {
            var pageObj = AmelUtil.getPageObj(eval("(" + req.responseText + ")"));
            if (pageObj) {
                me.addSubmitData({"wpEditToken" : pageObj["edittoken"]});
            }
            else
                alert("Could not retrieve edit form data");
        }
    }
    req.send(null);
}
 
WikiEdit.prototype.setParent = function(parent) {
    this.parent = parent;
}
WikiEdit.prototype.setText = function(wikitext) {
    this.addSubmitData({"wpTextbox1" : wikitext});
}
WikiEdit.prototype.setTimes = function(edittime) {
    var tsNow = AmelUtil.numericalTsNow();
    this.addSubmitData({"wpEdittime" : edittime || tsNow,
                       "wpStarttime" : tsNow});
}
 
WikiEdit.prototype.setSummary = function(text) {
    this.addSubmitData({"wpSummary" : text});
}
WikiEdit.prototype.setMinor = function(boole) {
    if (boole) this.addSubmitData({"wpMinoredit" : "1"});
}
WikiEdit.prototype.setWatch = function(boole) {
    if (boole) this.addSubmitData({"wpWatchthis" : "1"});
}
WikiEdit.prototype.getHistory = function(callback, limit) {
    this.getRevInformation(callback, ["user", "ids", "comment", "timestamp"], limit || 20, undefined);
}
WikiEdit.prototype.getText = function(callback, oldid) {
    this.getRevInformation(callback, ["content", "user", "timestamp"], 1, oldid);
}
 
//@Private. precondition: props are properly encoded
WikiEdit.prototype.getRevInformation = function(callback, props, limit, revid) {
    if (!callback)
        return;
    var me = this;
    var req = new XMLHttpRequest();
    req.open("GET", wgServer + wgScriptPath +  
             "/api.php?action=query&prop=revisions&format=json&rvprop=" + props.join("|") +
             (revid ? "&rvstartid=" + revid : "") + (limit ? "&rvlimit=" + limit : "") +
             "&titles=" + this.title, true);
    req.onreadystatechange = function() {
        if (req.readyState == 4 && req.status == 200) {
            var pageObj = AmelUtil.getPageObj(eval("(" + req.responseText + ")"));
            if (!pageObj) return;
            if (pageObj.revisions) {
                var returnObj = pageObj["revisions"];
                if (limit == 1) returnObj = returnObj[0];
                returnObj.title = pageObj.title;
                callback.call(me.parent, returnObj);
            } else if (pageObj.missing == "") {
                callback.call(me.parent, {"user":"", "*":""});    
            }            
        }
    }
    req.send(null);
}
 
WikiEdit.prototype.submit = function() {
    this.autosubmit = true;
    if (this.closed || this.editMonitor)
        return false;
 
    var submitData = this.submitData, onSubmitHooks = this.onSubmitHooks;
    for (var i = 0, nts = WikiEdit.needToSubmit; i < nts.length; i++)
        if (!(nts[i] in submitData)) return false;
 
    this.closed = true;
    while (onSubmitHooks.length > 0)
        onSubmitHooks.shift().call(this);
    var parameters = [];
    for (var property in submitData)
        parameters.push(encodeURIComponent(property) + "=" + encodeURIComponent(submitData[property]));
 
    var me = this;
    var req = this.submitXHR = new XMLHttpRequest();
    req.open("POST", wgServer + wgScript + "?title=" + this.title + "&action=submit", true);
    req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    req.onreadystatechange = function() {
        if (req.readyState == 4 && req.status == 200) {
            me.submitCallback.call(me.parent);
        }
    };
    req.send(parameters.join("&"));
    return true;
}
 
//@Private. Adds data; submits to index.php if has all information
WikiEdit.prototype.addSubmitData = function(obj) {
    var submitData = this.submitData;
    if (this.closed)
        return;
    for (var property in obj) //merge into submitData
        submitData[property] = obj[property];
    if (this.autosubmit)
        this.submit();
}
 
 
 
function hidevfd(){
    var divs = document.getElementsByTagName("div");
    for(var x = 0; x < divs.length; ++x)
        if(divs[x].className.indexOf("vfd") != -1)
            divs[x].style.display = "none";
    document.getElementById('footer').style.display = 'none';
}
 
function showvfd(){
    var divs = document.getElementsByTagName("div");
    for(var x = 0; x < divs.length; ++x)
        if(divs[x].className.indexOf("vfd") != -1)
            divs[x].style.display = "";
    document.getElementById('footer').style.display = '';
}
 
function addlilink(tabs, url, name){
    var na = document.createElement('a');
    na.href = url;
    na.appendChild(document.createTextNode(name));
    var li = document.createElement('li');
    li.appendChild(na);
    tabs.appendChild(li);
    return li;
}
 
function vfdlinks(){
    var tabs = document.getElementById('p-cactions').getElementsByTagName('ul')[0];
    if(document.title.indexOf("Wikipedia:Articles for deletion") == 0){
        addlilink(tabs, 'javascript:hidevfd()', 'Hide');
        addlilink(tabs, 'javascript:showvfd()', 'Show');
    }
}
 
if (window.addEventListener) window.addEventListener("load",vfdlinks,false);
else if (window.attachEvent) window.attachEvent("onload",vfdlinks);
 
//Adds "unwatch" links to watchlist and recentchanges.
//Seems good for FF; not tested elsewhere.
//Todo: Add links for watchlist's log-entry lines also. (Difficulty is finding the right pagename.)
function unwatchlinks() {
 aitchone = document.getElementById('firstHeading').firstChild.nodeValue;
 switch(aitchone){
  case 'My watchlist':
   lists=document.getElementsByTagName('ul');
   for (i=0;i<lists.length;i++) {
    if (lists[i].hasAttribute('class')) {
     if (lists[i].getAttribute('class')=='special') {//It's a day's watchlist.
      items=lists[i].childNodes;//li elements and whitespace
      for (j=items.length-1;j>-1;j--) {
       if (items[j].nodeType>1) continue;//li elements, not whitespace
       difflink=items[j].firstChild;
       while (difflink.nodeType>1) difflink=difflink.nextSibling;//first element sub the li
       diffurl=difflink.getAttribute('href');// /w/index.php?title=TITLE&amp;OTHERPARAMS if not a log entry
       if (diffurl.indexOf('/wiki/')) {//not a log entry
        title=diffurl.split('=')[1];
        title=title.split('&')[0];//pagename of the watchlist item
        newurl='/wiki/'+title+'?action=unwatch';
        anch=document.createElement('a');
        anch.setAttribute('href',newurl);
        anch.appendChild(document.createTextNode('unwatch'));
        items[j].insertBefore(anch,difflink);
        spacer=document.createTextNode(') (');
        items[j].insertBefore(spacer,difflink);
       }//end if indexOf
      }//end for j
     }//end if special
    }//end if hasAttr
   };//end for i
  break;//case 'My watchlist'
  case 'Recent changes':
   strongs=document.getElementsByTagName('strong');
   for (i=0;i<strongs.length;i++) {
    strong=strongs[i];
    if (strong.getAttribute('class')=='mw-watched') {//page is on watchlist
     children=strong.childNodes;//a element and whitespace
     for (j=0;j<children.length;j++) {
      if (children[j].nodeType>1) continue;//elements only, so a element
      pageurl=children[j].getAttribute('href');// /wiki/TITLE
      unwatchurl=pageurl+'?action=unwatch';
      anch=document.createElement('a');
      anch.setAttribute('href',unwatchurl);
      anch.appendChild(document.createTextNode('(unwatch)'));
      strong.parentNode.insertBefore(anch,strong);
      spacer=document.createTextNode(' ');
      strong.parentNode.insertBefore(spacer,strong);
      break;//for j, don't look at subsequent whitespace
     }//end for j
    }//end if mw-watched
   }//end for i
  break;//case 'Recent changes'
 }//end switch
};//end function
addOnloadHook(unwatchlinks);
 
 
function ajaxPatrolLinks() {
    var a = document.evaluate('//div[@class="patrollink"]/a', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue;
    if (a) {
        var div = a.parentNode;
        var url = a.href;
        a.onclick = function (event) {
            var aj = sajax_init_object();
            if (aj) {
                while (div.firstChild) { div.removeChild(div.firstChild) };
                div.appendChild(document.createTextNode('[Marking as patrolled...]'));
                aj.onreadystatechange = function () {
                    if (aj.readyState == 4 && aj.status == 200) {
                        while (div.firstChild) { div.removeChild(div.firstChild) };
                        div.appendChild(document.createTextNode('[Marked as patrolled]'));
                        aj.onreadystatechange = null;
                    }
                }                
                aj.open("GET", url, true);
                aj.send(null);
                return false;
            }
        }
    }
}
 
addOnloadHook(ajaxPatrolLinks);
 
// This script changes the "Your signature with timestamp" edit button to use a real em dash instead of two hyphens.
 
(function () {
    var oldAddButton = window.addButton;
    if (typeof(oldAddButton) != 'function') return;
    window.addButton = function () {
        if (arguments.length > 2)
            arguments[2] = arguments[2].replace(/^--(~+)$/, '—$1');
        oldAddButton.apply(this, arguments);
    };
})();
 
//
 
importScript('user:js/patroller.js')
 
//<pre><nowiki>
 function aivlist(type) {
  var f = document.editform, t = f.wpTextbox1;
  if (t.value.length > 0)
    t.value += '\n';
  var ip = prompt("Enter IP address", "");
  var reason = prompt("Enter reason for listing", "");
  t.value += "*{{" + type + "|" + ip +"}} " + reason + "--~" + "~" + "~" + "~";
  f.wpSummary.value = "Listing " + ip;
  f.submit();
 }
 
addOnloadHook(
 function addaivlink() { 
  if (document.title.indexOf("Editing Wikipedia:Administrator intervention against vandalism") != -1)
  {
    addPortletLink("p-cactions", "javascript:aivlist('vandal')", "vandal", "ca-vandal", "Report a vandal", "");
    addPortletLink("p-cactions", "javascript:aivlist('ipvandal')", "ipvandal", "ca-ipvandal", "Report an ipvandal", "");
  } }
);
//</nowiki></pre>
 
 
*/
//On diff pages this script replaces ''(Difference between revisions)''with
//different tools for reverting the edit and warning the user that made the edit.
//For instructions see talk page.
// Revert tools by Lorian
function getElementsByClass(searchClass,node,tag) {
  // Function from http://www.dustindiaz.com/getelementsbyclass/
  var classElements = new Array();
  if ( node == null )
    node = document;
  if ( tag == null )
    tag = '*';
  var els = node.getElementsByTagName(tag);
  var elsLen = els.length;
  var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
  for (i = 0, j = 0; i < elsLen; i++) {
    if ( pattern.test(els[i].className) ) {
      classElements[j] = els[i];
      j++;
    }
  }
  return classElements;
}
 
// _GET code from NoGray JS Library http://www.nogray.com/new_site/
var _GET = new Array();
var _uri = location.href;
 
var _temp_get_arr = _uri.substring(_uri.indexOf('?')+1, _uri.length).split("&");
 
var _temp_get_arr_1 = new Array();
 
for(_get_arr_i=0; _get_arr_i<_temp_get_arr.length; _get_arr_i++){
  _temp_get_arr_1 = _temp_get_arr[_get_arr_i].split("=");
  _GET[decodeURI(_temp_get_arr_1[0])] = decodeURI(_temp_get_arr_1[1]);
}
 
delete _uri; delete _temp_get_arr; delete _temp_get_arr_1;
 
function getMessage (where, user1, user2) {
  var message = prompt ('What message would you like to leave?', '');
  window.location = 'http://en.wikipedia.org/w/index.php?title=' + _GET['title'] + '&action=edit&oldid=' + _GET['oldid'] + '&'+where+'=2&user1='+user1+'&user2='+user2+'&message='+message;
}
 
addOnloadHook(function (){
  if (location.href.match(/diff=/)) {
    // Get username of submitter
    var user1 = getElementsByClass('diff-otitle',null,'td'); user1 = user1[0].getElementsByTagName('a')[2].innerHTML;
    var user2 = getElementsByClass('diff-ntitle',null,'td'); user2 = user2[0].getElementsByTagName('a')[3].innerHTML;
    document.getElementById('contentSub').innerHTML = '(<a href="http://en.wikipedia.org/w/index.php?title=' + _GET['title'] + '&action=edit&oldid=' + _GET['oldid'] + '&revert=1&user1='+user1+'&user2='+user2+'">Revert</a> / <a href="javascript:var message = getMessage(\'revert\', \''+user1+'\', \''+user2+'\');">Message</a>) (<a href="http://en.wikipedia.org/w/index.php?title=' + _GET['title'] + '&action=edit&oldid=' + _GET['oldid'] + '&vandalism=1&user1='+user1+'&user2='+user2+'">Vandalism</a> / <a href="javascript:var message = getMessage(\'vandalism\', \''+user1+'\', \''+user2+'\');">Message</a>) (Warn: <a href="http://en.wikipedia.org/w/index.php?title=User_talk:'+user2+'&action=edit&section=new&warn=1">Test</a> / <a href="http://en.wikipedia.org/w/index.php?title=User_talk:'+user2+'&action=edit&section=new&warn=2">Blatant</a> / <a href="http://en.wikipedia.org/w/index.php?title=User_talk:'+user2+'&action=edit&section=new&warn=3">Nonsense</a> / <a href="http://en.wikipedia.org/w/index.php?title=User_talk:'+user2+'&action=edit&section=new&warn=4">Blanking</a>)';
  } else if (location.href.match(/revert=1/)) {
    document.getElementById('wpSummary').value = 'Reverted edits by [[Special:Contributions/'+_GET['user2']+'|'+_GET['user2']+']] to version ' + _GET['oldid']+' by [[Special:Contributions/'+_GET['user1']+'|'+_GET['user1']+']]';
    document.getElementById('editform').submit();
  } else if (location.href.match(/revert=2/)) {
    document.getElementById('wpSummary').value = 'Reverted edits by [[Special:Contributions/'+_GET['user2']+'|'+_GET['user2']+']] to version ' + _GET['oldid']+' by [[Special:Contributions/'+_GET['user1']+'|'+_GET['user1']+']] ('+_GET['message']+')';
    document.getElementById('editform').submit();
  } else if (location.href.match(/vandalism=1/)) {
    document.getElementById('wpSummary').value = 'Reverted vandalism by [[Special:Contributions/'+_GET['user2']+'|'+_GET['user2']+']] to version ' + _GET['oldid']+' by [[Special:Contributions/'+_GET['user1']+'|'+_GET['user1']+']]';
    document.getElementById('editform').submit();
  } else if (location.href.match(/vandalism=2/)) {
    document.getElementById('wpSummary').value = 'Reverted vandalism by [[Special:Contributions/'+_GET['user2']+'|'+_GET['user2']+']] to version ' + _GET['oldid']+' by [[Special:Contributions/'+_GET['user1']+'|'+_GET['user1']+']] ('+_GET['message']+')';
    document.getElementById('editform').submit();
  } else if (location.href.match(/warn=1/)) {
    document.getElementById('wpSummary').value = 'Vandalism warning';
    document.getElementById('wpTextbox1').value = '{{sub'+'st:test}} ~~'+'~~';
    document.getElementById('editform').submit();
  } else if (location.href.match(/warn=2/)) {
    document.getElementById('wpSummary').value = 'Vandalism warning';
    document.getElementById('wpTextbox1').value = '{{sub'+'st:blatantvandal}} ~~'+'~~';
    document.getElementById('editform').submit();
  } else if (location.href.match(/warn=3/)) {
    document.getElementById('wpSummary').value = 'Vandalism warning';
    document.getElementById('wpTextbox1').value = '{{sub'+'st:test2}} ~~'+'~~';
    document.getElementById('editform').submit();
  } else if (location.href.match(/warn=4/)) {
    document.getElementById('wpSummary').value = 'Vandalism warning';
    document.getElementById('wpTextbox1').value = '{{sub'+'st:test2a}} ~~'+'~~';
    document.getElementById('editform').submit();
  }
});
/*
 
*/
//Wikipedia:WikiProject User scripts | Scripts
 
function format() {
    var txt = document.editform.wpTextbox1;
    txt.value = catFixer(txt.value);
    txt.value = entities(txt.value);
    txt.value = fixheadings(txt.value);
    txt.value = fixsyntax(txt.value);
    txt.value = linkfixer(txt.value, false);
    //txt.value = imagefixer(txt.value);
    txt.value = whitespace(txt.value);
    txt.value = linksimplifyer(txt.value);
    txt.value = trim(txt.value);
}
 
function whitespace(str){
    str = str.replace(/\t/g, " ");
 
    str = str.replace(/^ ? ? \n/gm, "\n");
    str = str.replace(/(\n\n)\n+/g, "$1");
    str = str.replace(/== ? ?\n\n==/g, "==\n==");
    str = str.replace(/\n\n(\* ?\[?http)/g, "\n$1");
 
    str = str.replace(/^ ? ? \n/gm, "\n");
    str = str.replace(/\n\n\*/g, "\n*");
    str = str.replace(/[ \t][ \t]+/g, " ");
    str = str.replace(/([=\n]\n)\n+/g, "$1");
    str = str.replace(/ \n/g, "\n");
 
    //* bullet points
    str = str.replace(/^([\*#]+) /gm, "$1");
    str = str.replace(/^([\*#]+)/gm, "$1 ");
 
    //==Headings==
    str = str.replace(/^(={1,4}) ?(.*?) ?(={1,4})$/gm, "$1$2$3");
 
    //dash — spacing
    str = str.replace(/ ?(–|&#150;|&ndash;|&#8211;|&#x2013;) ?/g, "$1");
    str = str.replace(/ ?(—|&#151;|&mdash;|&#8212;|&#x2014;) ?/g, "$1");
    str = str.replace(/([^1-9])(—|&#151;|&mdash;|&#8212;|&#x2014;|–|&#150;|&ndash;|&#8211;|&#x2013;)([^1-9])/g, "$1 $2 $3");
 
    return trim(str);
}
 
function entities(str){
    //str = str.replace(//g, "");
    str = str.replace(/&#150;|&#8211;|&#x2013;/g, "&ndash;");
    str = str.replace(/&#151;|&#8212;|&#x2014;/g, "&mdash;");
   // str = str.replace(/(cm| m|km|mi)<sup>2</sup>/g, "$1²");
    str = str.replace(/&sup2;/g, "²");
    str = str.replace(/&deg;/g, "°");
 
    return trim(str);
}
 
//Fix ==See also== and similar section common errors.
function fixheadings(str)
{
  if( !str.match(/= ?See also ?=/) )
    str = str.replace(/(== ?)(see also:?|related topics:?|related articles:?|internal links:?|also see:?)( ?==)/gi, "$1See also$3");
 
  str = str.replace(/(== ?)(external links?:?|outside links?|web ?links?:?|exterior links?:?)( ?==)/gi, "$1External links$3");
  str = str.replace(/(== ?)(references?:?)( ?==)/gi, "$1References$3");
  str = str.replace(/(== ?)(sources?:?)( ?==)/gi, "$1Sources$3");
  str = str.replace(/(== ?)(further readings?:?)( ?==)/gi, "$1Further reading$3");
 
  return str;
}
 
function catFixer(str){
    str = str.replace(/\[\[ ?[Cc]ategory ?: ?/g, "[[Category:");
 
    return trim(str);
}
 
//fixes many common syntax problems
function fixsyntax(str)
{
  //replace html with wiki syntax
  if( !str.match(/'<\/?[ib]>|<\/?[ib]>'/gi) )
  {
    str = str.replace(/<i>(.*?)<\/i>/gi, "''$1''");
    str = str.replace(/<b>(.*?)<\/b>/gi, "'''$1'''");
  }
  str = str.replace(/<br\/>/gi, "<br />");
  str = str.replace(/<br>/gi, "<br />");
 
  return trim(str);
}
 
//formats links in standard fashion
function linkfixer(str, checkImages)
{ 
  str = str.replace(/\]\[/g, "] [");
  var m = str.match(/\[?\[[^\]]*?\]\]?/g);
  if (m)
  {
    for (var i = 0; i < m.length; i++)
    {
      var x = m[i].toString();
      var y = x;
 
      //internal links only
      if ( !y.match(/^\[?\[http:\/\//i) && !y.match(/^\[?\[image:/i) )
      {
        if (y.indexOf(":") == -1 && y.substr(0,3) != "[[_" && y.indexOf("|_") == -1)
        {
          if (y.indexOf("|") == -1)
            y = y.replace(/_/g, " ");
          else
            y = y.replace( y.substr(0, y.indexOf("|")), y.substr(0, y.indexOf("|")).replace(/_/g, " "));
        }  
 
        y = y.replace(/ ?\| ?/, "|").replace("|]]", "| ]]");
 
      }
 
      str = str.replace(x, y);
    }
  }
 
  //repair bad internal links
  str = str.replace(/\[\[ ?([^\]]*?) ?\]\]/g, "[[$1]]");
  str = str.replace(/\[\[([^\]]*?)( |_)#([^\]]*?)\]\]/g, "[[$1#$3]]");
 
  //repair bad external links
  str = str.replace(/\[?\[http:\/\/([^\]]*?)\]\]?/gi, "[http://$1]");
  str = str.replace(/\[http:\/\/([^\]]*?)\|([^\]]*?)\]/gi, "[http://$1 $2]");
 
  return trim(str);
}
 
//fixes images
function imagefixer(str)
{
 
  //remove external images
  str = str.replace(/\[?\[image:http:\/\/([^\]]*?)\]\]?/gi, "[http://$1]");
 
  //fix links within internal images
  var m = str.match(/\[?\[image:[^\[\]]*?(\[?\[[^\]]*?\]*?[^\[\]]*?)*?\]+/gi);
  if (m)
  {
    for (var i = 0; i < m.length; i++)
    {
      var x = m[i].toString();
      var y = x;
 
      y = y.replace(/^\[\[i/i, "I").replace(/\]\]$/, "");
      y = y.replace(/(\[[^\]]*?)$/, "$1]");
      y = linkfixer(y, true);
      y = "[[" + y + "]]";
 
      str = str.replace(x, y);
    }
  }
 
  return trim(str);
}
 
//simplifies some links e.g. [[Dog|dog]] to [[dog]] and [[Dog|dogs]] to [[dog]]s
function linksimplifyer(str){
  var m = str.match(/\[\[([^[]*?)\|([^[]*?)\]\]/g);
  if (m)
  {
    for (var i = 0; i < m.length; i++)
    {
      var n_arr = m[i].toString().match(/\[\[([^[]*?)\|([^[]*?)\]\]/);
      var n = n_arr[0];
      var a = n_arr[1];
      var b = n_arr[2];
 
      if (b.indexOf(a) == 0 || b.indexOf(TurnFirstToLower(a)) == 0)
      {
        var k = n.replace(/\[\[([^\]\|]*?)\|(\1)([\w]*?)\]\]/i, "[[$2]]$3");
        str = str.replace(n, k);
      }
    }
  }
 
  str = str.replace(/\[\[([^\]\|]+)\|([^\]\|]+)\]\]([A-Za-z\'][A-Za-z]*)([\.\,\;\:\"\!\?\s\n])/g, "[[$1|$2$3]]$4"); // ' // Help the syntax highlighter...
 
  return str;
}
 
//trim start and end, trim spaces from the end of lines
function trim(str) {
   str = str.replace(/ $/gm, "");
   return str.replace(/^\s*|\s*$/g, "");
}
 
//turns first character to lowercase
function TurnFirstToLower(input) {
  if (input != "")
  {
    var input = trim(input);
    var temp = input.substr(0, 1);
    return temp.toLowerCase() + input.substr(1, input.length);
  }
  else
    return "";
}
 
//entities that should never be unicoded
function noUnicodify(str) {
  str = str.replace(" &amp; ", " & ");
  str = str.replace("&amp;", "&amp;amp;").replace("&amp;lt;", "&amp;amp;lt;").replace("&amp;gt;", "&amp;amp;gt;").replace("&amp;quot;", "&amp;amp;quot;").replace("&amp;apos;", "&amp;amp;apos;");
  str = str.replace("&minus;", "&amp;minus;").replace("&times;", "&amp;times;");
 
  str = str.replace("&nbsp;", "&amp;nbsp;").replace("&thinsp;", "&amp;thinsp;").replace("&shy;", "&amp;shy;");
  str = str.replace("&prime;", "&amp;prime;");
  str = str.replace(/&(#0?9[13];)/, "&amp;$1");
  str = str.replace(/&(#0?12[345];)/, "&amp;$1");
 
  return str;
}
 
addOnloadHook(function () {
  if(document.forms.editform) {
    addPortletLink('p-cactions', 'javascript:format()', 'format', 'ca-format', 'Format article', '', document.getElementById('ca-edit'));
  }
});
 
/*
 
 
/*
<pre> <nowiki>
Note: After saving, you have to bypass your browser's cache to see the changes.
To do this in Firefox/Mozilla/Safari: hold down Shift while clicking Reload, 
or press Ctrl-Shift-R). 
If you use Internet Explorer: press Ctrl-F5, Opera/Konqueror: press F5.
 
</nowiki> </pre>
==AzaToth's reversion tools ==
<pre> <nowiki> */
// importScript('User:AzaToth/twinkle.js');
 
/*
</nowiki> </pre>
==WikEd, replaces Firefox's text edit window ==
<pre> <nowiki> */
 
// install [[User:Cacycle/wikEd]] in-browser text editor
document.write('<script type="text/javascript" src="'
+ 'http://en.wikipedia.org/w/index.php?title=User:Cacycle/wikEd.js'
+ '&action=raw&ctype=text/javascript&dontcountme=s"></script>');
 
/*
</nowiki> </pre>
==Lupin's anti-vandal tools ==
<pre> <nowiki> */
 
 
// Script from [[User:Lupin/recent2.js]]
document.write('<script type="text/javascript" src="' 
             + 'http://en.wikipedia.org/w/index.php?title=User:Lupin/recent2.js' 
             + '&action=raw&ctype=text/javascript&dontcountme=s"></s'+'cript>');
 
/*
</nowiki> </pre>
==Popups==
<pre> <nowiki> */
/* [[User:Lupin/popups.js]] */
 
document.write('<script type="text/javascript" src="' 
             + 'http://en.wikipedia.org/w/index.php?title=User:Lupin/popups.js' 
             + '&action=raw&ctype=text/javascript&dontcountme=s"></script>'); 
 
/*{{User:AndyZ/peerreviewer.js}}*/
/*
</nowiki> </pre>
== Watchlist sorter ==
<pre> <nowiki>
Sorts your watchlist by namespace, and also adds spaces for readability.
*/
 
addOnloadHook(function (){
  if (location.href.indexOf('Special:Watchlist') == -1) return; //Are we on a watchlist?
  //days = document.getElementById('bodyContent').getElementsByTagName('ul');
  days = document.evaluate( //Hell knows how it works - found in "Dive into Greasemonkey"
    "//ul[@class='special']",
    document,
    null,
    XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
    null);
  for (d = 0; d < days.snapshotLength; d++) { //For each day
    day = days.snapshotItem(d);
    newday = document.createElement('ul'); //This will replace the old listing
    while ((diffs = day.getElementsByTagName('li')).length > 0) { //Are there any diffs left?
      //Try to extract the namespace
      As = diffs[0].getElementsByTagName('a');
      if (As[0].innerHTML == 'diff')
        pagename = As[2].innerHTML;
      else
        pagename = As[1].innerHTML;
      if (pagename.indexOf(':') == -1)
        namespace = 'Main';
      else
        namespace = pagename.split(':')[0]; //This will fail for articles which contain ":" in name
      hdrs = newday.getElementsByTagName('h5'); //Get the list of namespace headers
      hdr = null;
      for (j=0; j<hdrs.length; j++) //Find the header
        if (hdrs[j].innerHTML==namespace) {
          hdr = hdrs[j]; break;
        }
      if (hdr==null) { //Not found? Make a new one!
        hdr = document.createElement('h5');
        hdr.innerHTML = namespace;
        newday.appendChild(hdr);
        namespacesub = document.createElement('ul');
        newday.appendChild(namespacesub);
      }
      hdr.nextSibling.appendChild(diffs[0]); //Move the diff
    }
    newday.appendChild(document.createElement('hr')); //For readablility
    day.parentNode.replaceChild(newday,day);
  }
});
 
*/
 
function addForceSummary()
{
if(!/&action=edit/.test(window.location.href) && !/&action=submit/.test(window.location.href)) return;
if(/&section=new/.test(window.location.href)) return;
if(!document.forms.editform) return;
document.forms.editform.wpSave.onclick = forceSummary;
// The second invocation of this will cause extra annoyance if there is no edit summary present. If there *is* an edit summary, the dialog box will not appear.
document.forms.editform.wpSave.onfocus = forceSummary;
}
 
function forceSummary()
{
if(!document.forms.editform.wpSummary.value.replace(/^(?:\/\\*.*\\*\/)? *(.*) *$/,'$1'))
{
var r = prompt('Are you sure you want to submit without adding a summary?\nTo add a summary, type it in the box below:',document.forms.editform.wpSummary.value);
if(r == null) { return false; }
document.forms.editform.wpSummary.value = r;
}
return true;
}
 
addOnloadHook(addForceSummary);
 
/*
 
 
// csd
importScript('User:Ale_jrb/Scripts/csdcheck.js');
importScript('User:Ale_jrb/Scripts/csdhelper.js');
 
var logOnDecline = true;
var logOnDeclinePath = 'User:Ale_jrb/Sandbox/Dec line';
 
// other
importScript('User:Ale_jrb/Scripts/userhist.js');
importScript('User:Ale_jrb/Scripts/statusCheck.js');
var enableRemoveInterface = true;
importScript('User:Ale_jrb/Scripts/myinterface.js');
importScript('User:Animum/easyblock.js');
importScript('User:EpochFail/HAPPI.js');
importScript('User:Splarka/dabfinder.js');
 
importScript("Wikipedia:Dazzle!/code.js");
importScript('User:Smith609/toolbox.js');
----
 //<nowiki> History tools
document.write('<script type="text/javascript" src="' 
             + 'http://en.wikipedia.org/w/index.php?title=User:Voice_of_All/History/monobook.js' 
             + '&action=raw&ctype=text/javascript&dontcountme=s"></script>');
 
//</nowiki>[[Category:Wikipedians who use VoA script|{{PAGENAME}}]]
 
//<pre>
//This function adds a link to the toolbox which, when clicked, displays the size of the page
//and the size of the prose. See the talk page for more details.
//
//To use this function add {{subst:js|User:Dr pda/prosesize.js}} to your monobook.js
//
function loadXMLDocPassingTemplate(url,handler, page)
{
    // branch for native XMLHttpRequest object
    if (window.XMLHttpRequest) {
        var req = new XMLHttpRequest();
    }
    // branch for IE/Windows ActiveX version
    else if (window.ActiveXObject) {
        var req = new ActiveXObject("Microsoft.XMLHTTP");
   }
   if (req) {
     req.onreadystatechange = function () {handler(req, page)};
     req.open("GET", url, true);
     req.send("");
   }
}
 
function getWikiText(req, page) {
    // only if req shows "loaded"
    if (req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) {
            // ...processing statements go here...
	 response = req.responseXML.documentElement;
         var rev = response.getElementsByTagName('rev');
	 if(rev.length > 0){
	   result = rev[0].getAttribute('size');
           if(result > 10240){
             result = (result/1024).toFixed(0)+'&nbsp;kB';
           }
           else{
             result = result+'&nbsp;B';
           }
           wiki_value = document.createElement("li");
	   wiki_value.id = "wiki-size";
	   wiki_value.innerHTML = '<b>Wiki text: </b>'+result;
	   var output = document.getElementById("document-size-stats");
	   prose_value = document.getElementById("prose-size");
	   output.insertBefore(wiki_value,prose_value);
	 }
	 else{
	  //alert("There was a problem using the Wikipedia Search to find the wiki text size\nEither the search is not working or the correct article did not appear on the first page of results");
           wiki_value = document.createElement("li");
	   wiki_value.id = "wiki-size";
	   wiki_value.innerHTML = '<b>Wiki text: </b>Problem getting wiki text size';
	   var output = document.getElementById("document-size-stats");
	   prose_value = document.getElementById("prose-size");
	   output.insertBefore(wiki_value,prose_value);
	 }
        } else {
            alert("There was a problem retrieving the XML data:\n" +
                req.statusText);
        }
    }
}
 
function getFileSize(req, page) {
    // only if req shows "loaded"
    if (req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) {
            // ...processing statements go here...
	  var fsize = req.responseText.length;
	  window.status = fsize;
	  var total_value = document.createElement("li");
	  total_value.id = "total-size";
	  total_value.innerHTML='<b>File size: </b>'+(fsize/1024).toFixed(0)+'&nbsp;kB';
	  var output = document.getElementById("document-size-stats");
	  var prose_html_value = document.getElementById("prose-size-html");
	  output.insertBefore(total_value,prose_html_value);
         } else {
            alert("There was a problem retrieving the XML data:\n" +
                req.statusText + "\n(" + url + ")");
        }
    }
}
 
function getLength(id){
 var textLength = 0;
 for(var i=0;i<id.childNodes.length; i++){
  if(id.childNodes[i].nodeName == '#text'){
   textLength += id.childNodes[i].nodeValue.length;
  }
  else if(id.childNodes[i].id == 'coordinates' || id.childNodes[i].className.indexOf('emplate') != -1){
    //special case for {{coord}} and {{fact}}-like templates
    //Exclude from length, and don't set background yellow
    id.childNodes[i].style.cssText = 'background-color:white';
  }
  else{
    textLength += getLength(id.childNodes[i]);
  }
 }
 return textLength;
}
 
function getRefMarkLength(id,html){
 var textLength = 0;
 for(var i=0;i<id.childNodes.length; i++){
  if(id.childNodes[i].className == 'reference'){
   textLength += (html)? id.childNodes[i].innerHTML.length : getLength(id.childNodes[i]);
  }
 }
 return textLength;
}
 
function getDocumentSize(){
 contentDivName = '';
 if(skin == 'vector' || skin == 'monobook' || skin == 'chick' || skin == 'myskin' || skin == 'simple'){
   contentDivName = 'bodyContent';
 }
 else if (skin == 'modern'){
   contentDivName = 'mw_contentholder';
 }
 else if (skin == 'standard' || skin == 'cologneblue' || skin == 'nostalgia'){
   contentDivName = 'article';
 }
 else{
   //fallback case; the above covers all currently existing skins
   contentDivName = 'bodyContent';
 }
 //Same for all skins if previewing page
 if(wgAction == 'submit') contentDivName = 'wikiPreview';
 
 var bodyContent = document.getElementById(contentDivName);
 if(document.getElementById("document-size-stats")){
   //if statistics already exist, turn them off and remove highlighting
   var output = document.getElementById("document-size-stats");
   var oldStyle = output.className;
   var pList = bodyContent.getElementsByTagName("p");
   for(var i=0;i<pList.length; i++){
     if(pList[i].parentNode.id == contentDivName || pList[i].parentNode.nodeName == "BLOCKQUOTE") pList[i].style.cssText = oldStyle;
   }
   output.parentNode.removeChild(output);
   var header = document.getElementById("document-size-header");
   header.parentNode.removeChild(header);
 }
 else{
 var output = document.createElement("ul");
 output.id = "document-size-stats";
 
 var prose_html_value = document.createElement("li");
 prose_html_value.id = "prose-size-html";
 output.appendChild(prose_html_value);
 
 var ref_html_value = document.createElement("li");
 ref_html_value.id = "ref-size-html";
 output.appendChild(ref_html_value);
 
 var prose_value = document.createElement("li");
 prose_value.id = "prose-size";
 output.appendChild(prose_value);
 output.className = bodyContent.getElementsByTagName("p").item(0).style.cssText;
 
 var ref_value = document.createElement("li");
 ref_value.id = "ref-size";
 output.appendChild(ref_value);
 
 var dummy = document.getElementById("siteSub");
 dummy.parentNode.insertBefore(output, dummy.nextSibling);
 
 var header = document.createElement("span");
 header.id = "document-size-header";
 header.innerHTML = '<br/>Document statistics: <small><i>(See <a href="http://en.wikipedia.org/wiki/User_talk:Dr_pda/prosesize.js">here</a> for details.)<i></small>';
 dummy.parentNode.insertBefore(header,output);
 
 //File size not well defined for preview mode or section edit
 if(wgAction != 'submit'){
   //If browser supports document.fileSize property (IE)
   if(document.fileSize){
     var total_value = document.createElement("li");
     total_value.id = "total-size";
     total_value.innerHTML='<b>File size: </b>'+(document.fileSize/1024).toFixed(0)+'&nbsp;kB';
     output.insertBefore(total_value,prose_html_value);
   }
   else{
    loadXMLDocPassingTemplate(location.pathname,getFileSize,'')
   }
 }
 
 //Get size of images only if browser supports filesize property (IE)
 var iList = bodyContent.getElementsByTagName("img");
 if(iList.length >0 && iList[0].fileSize){
 //Get size of images included in document
   var image_size = 0;
   var first_magnify = true;
 
   for (var i=0;i<iList.length; i++){
    var im = iList[i];
    if(im.getAttribute("src").indexOf("magnify-clip.png") != -1){
      if(first_magnify){
        image_size += im.fileSize*1;
        first_magnify = false;
      }
    }
    else{
      image_size += im.fileSize*1;
    }
   }
   var image_value = document.createElement("li");
   image_value.id = "image-size";
   image_value.innerHTML='<b>Images: </b>'+(image_size/1024).toFixed(0)+'&nbsp;kB';
   output.appendChild(image_value);
 
  }
 //Calculate prose size and size of reference markers ([1] etc)
 var pList = bodyContent.getElementsByTagName("p");
 
 prose_size = 0;
 prose_size_html = 0;
 refmark_size = 0;
 refmark_size_html = 0;
 word_count = 0;
 for(var i=0;i<pList.length; i++){
   var para = pList[i];
   if(para.parentNode.id == contentDivName || pList[i].parentNode.nodeName == "BLOCKQUOTE"){
    prose_size += getLength(para);
    prose_size_html += para.innerHTML.length;
    refmark_size += getRefMarkLength(para,false);
    refmark_size_html += getRefMarkLength(para,true);
    word_count += para.innerHTML.replace(/(<([^>]+)>)/ig,"").split(' ').length
    para.style.cssText = "background-color:yellow";
   }
 }
 
 if((prose_size-refmark_size)>10240){
   prose_value.innerHTML='<b>Prose size (text only): </b>'+((prose_size-refmark_size)/1024).toFixed(0)+'&nbsp;kB ('+word_count+' words) "readable prose size"';
 }
 else{
   prose_value.innerHTML='<b>Prose size (text only): </b>'+(prose_size-refmark_size)+'&nbsp;B ('+word_count+' words) "readable prose size"';
 }
 
 if((prose_size_html-refmark_size_html)>10240){
   prose_html_value.innerHTML='<b>Prose size (including all HTML code): </b>'+((prose_size_html-refmark_size_html)/1024).toFixed(0)+'&nbsp;kB';
 }
 else{
   prose_html_value.innerHTML='<b>Prose size (including all HTML code): </b>'+(prose_size_html-refmark_size_html)+'&nbsp;B';
 }
 
 //Calculate size of references (i.e. output of <references/>)
 var rList = bodyContent.getElementsByTagName("ol");
 var ref_size = 0;
 var ref_size_html = 0;
 for (var i=0; i<rList.length; i++){
   if(rList[i].parentNode.className == "references"){
     ref_size = getLength(rList[i]);
     ref_size_html = rList[i].innerHTML.length;
   }
 }
 
 if((ref_size+refmark_size)>10240){
   ref_value.innerHTML='<b>References (text only): </b>'+((ref_size+refmark_size)/1024).toFixed(0)+'&nbsp;kB';
 }
 else{
   ref_value.innerHTML='<b>References (text only): </b>'+(ref_size+refmark_size)+'&nbsp;B';
 }
 
 if((ref_size_html+refmark_size_html)>10240){
   ref_html_value.innerHTML='<b>References (including all HTML code): </b>'+((ref_size_html+refmark_size_html)/1024).toFixed(0)+'&nbsp;kB';
 }
 else{
   ref_html_value.innerHTML='<b>References (including all HTML code): </b>'+(ref_size_html+refmark_size_html)+'&nbsp;B';
 }
 
 //get correct name of article from wikipedia-defined global variables
 var pageNameUnderscores = wgPageName;
 var pageNameSpaces = pageNameUnderscores.replace(/_/g,' ')
 
 //if page is a permalink, diff, etc don't try to search
 if(!location.pathname.match('/w/index.php')){ 
  //Get revision size from API
  var searchURL = wgScriptPath + '/api.php?action=query&prop=revisions&rvprop=size&format=xml&revids=' + wgCurRevisionId;
  loadXMLDocPassingTemplate(searchURL,getWikiText,pageNameSpaces);
 }
 else if(wgAction == 'submit'){
   //Get size of text in edit box
   result = document.getElementById('wpTextbox1').value.length;
   if(result > 10240){
     result = (result/1024).toFixed(0)+'&nbsp;kB';
   }
   else{
     result = result+'&nbsp;B';
   }
   wiki_value = document.createElement("li");
   wiki_value.id = "wiki-size";
   wiki_value.innerHTML = '<b>Wiki text: </b>'+result;
   var output = document.getElementById("document-size-stats");
   prose_value = document.getElementById("prose-size");
   output.insertBefore(wiki_value,prose_value);
 }
}
}
 
addOnloadHook(function () {
  if(wgAction == 'edit' || (wgAction == 'submit' && document.getElementById('wikiDiff')) ){
    addPortletLink('p-tb', 'javascript:alert("You need to preview the text for the prose size script to work in edit mode.")', 'Page size', 't-page-size', 'Calculate page and prose size', '', '');
    document.getElementById("t-page-size").firstChild.style.cssText = "color:black;"
  }
  else if(wgAction == 'view' || wgAction == 'submit' || wgAction == 'historysubmit' || wgAction == 'purge'){
    addPortletLink('p-tb', 'javascript:getDocumentSize()', 'Page size', 't-page-size', 'Calculate page and prose size', '', '');
  }
});
 
 //</pre>