MediaWiki:Common.js: Difference between revisions

From Citizendium
Jump to navigation Jump to search
imported>Caesar Schinas
(remove some leftover WP code which doesn't work here)
(updating Google Analytics tag number)
 
(34 intermediate revisions by 3 users not shown)
Line 1: Line 1:
/** Tooltips and access keys ***************************************************
/* <nowiki> */
  *
  *  Ported straight from Wikipedia, substituted 'Citizendium' for both 'Wikipedia'
  *  and 'Wikimedia'--probably a lot of stuff is broken here
  *  Description: Adds tooltips and access keys to links part of the MediaWiki
  *              interface.
  *  Maintainers (on Wikipedia): [[User:Gwicke|Gwicke]]?, [[User:Simetrical|Simetrical]]?, [[User:Ruud Koot|Ruud Koot]]
  */
ta = new Object();
ta["n-mainpage"]            = new Array("z","Visit the main page");
ta["n-Main-page"]          = new Array("z","Visit the main page");
ta["n-Featured-content"]    = new Array("","Featured content — the best of Citizendium");
ta["n-help"]                = new Array("","The place to find out about Citizendium");
ta["n-contact"]            = new Array("","How to contact Citizendium");
ta["n-sitesupport"]        = new Array("","Help keep Citizendium running");
ta["t-print"]              = new Array("","Printable version of this page");
ta["t-permalink"]          = new Array("","Permanent link to this version of the page");
ta["t-cite"]                = new Array("","Cite this Citizendium article");
ta["ca-nstab-project"]      = new Array("c","View the project page");
ta["n-Contents"]            = new Array("","Guides to browsing Citizendium");


  /** Import module *************************************************************
  /** Import module *************************************************************
   *
   *
   *  Description: Includes a raw wiki page as javascript or CSS,  
   *  Description: Includes a raw wiki page as javascript or CSS, used for including user made modules.
  *              used for including user made modules.
   *   
   *  Maintainers: [[User:AzaToth]]
  *  Doesn't work in WebKit or IE7...
   */
   */
importedScripts = {}; // object keeping track of included scripts, so a script ain't included twice
var loadedScripts = {}; // included-scripts tracker
function importScript( page ) {
function importScript(page) {
    if( importedScripts[page] ) {
var url = wgScript + '?title=' + encodeURIComponent(page.replace(/ /g,'_')).replace(/%2F/ig,'/').replace(/%3A/ig,':') + '&action=raw&ctype=text/javascript';
        return;
    }
if (loadedScripts[url]) return null;
    importedScripts[page] = true;
loadedScripts[url] = true;
    var url = wgScriptPath
            + '/wiki?title='
var s = document.createElement('script');
            + encodeURIComponent( page.replace( ' ', '_' ) )
s.setAttribute('src',url);
            + '&action=raw&ctype=text/javascript';
s.setAttribute('type','text/javascript');
    var scriptElem = document.createElement( 'script' );
document.getElementsByTagName('head')[0].appendChild(s);
    scriptElem.setAttribute( 'src' , url );
}
    scriptElem.setAttribute( 'type' , 'text/javascript' );
 
    document.getElementsByTagName( 'head' )[0].appendChild( scriptElem );
}
   
   
  function importStylesheet( page ) {
  function importStylesheet( page ) {
Line 55: Line 33:
  }
  }


/* Test if an element has a certain class **************************************
/* Import more specific scripts if necessary */
//if (wgAction == 'edit' || wgAction == 'submit')
//    importScript("MediaWiki:Common.js/edit.js");
//if (wgPageName == 'Special:Upload')
//    importScript("MediaWiki:Common.js/upload.js");
 
 
 
/** Extra toolbar options ******************************************************
   *
   *
   * Description: Uses regular expressions and caching for better performance.
   * Description: UNDOCUMENTED
   * Maintainers: [[User:Mike Dillon]], [[User:R. Koot]], [[User:SG]]
   * Maintainers:  
   */
   */
var hasClass = (function () {
    var reCache = {};
    return function (element, className) {
        return (reCache[className] ? reCache[className] : (reCache[className] = new RegExp("(?:\\s|^)" + className + "(?:\\s|$)"))).test(element.className);
    };
})();


/* To disable this script, add    mwCustomEditButtons = [];    to [[Special:Mypage/Pinkwich5.js]] */
/** Upload Wizard ***************************************************
 
  *
function imageButons(){
  *  Adds many enhancements to the upload form
if (wgAction == 'edit' || wgAction == 'submit') {
  *
/* Make the Image insertion button use the CZ image template */
  *  Maintainer : [[User:Caesar Schinas]]
mwEditButtons[5].speedTip = 'Image';
  */
mwEditButtons[5].tagOpen = '{{Image|';
mwEditButtons[5].tagClose = '|right|250px|Image Caption}}';
function uploadForm() {
if ((wgPageName == 'Special:Upload') && (wgUserLanguage != 'advanced') && (wgUserLanguage != 'basic') && (document.getElementById('wpUploadDescription').value.indexOf('{{Image_Details') != -1)) {
/* Add extra image buttons */
/* get an array of licences */
if (mwCustomEditButtons) {
var license = document.getElementById('wpLicense');
mwCustomEditButtons[mwCustomEditButtons.length] = {
var licenses = Array();
"imageFile": "http://upload.wikimedia.org/wikipedia/en/c/c8/Button_redirect.png",
for (var i in license.childNodes) {
"speedTip": "Redirect",
if (license.childNodes[i].nodeName == 'OPTION' && license.childNodes[i].value != '') {
"tagOpen": "#REDIRECT [[",
licenses.push(license.childNodes[i].value);
"tagClose": "]]",
}
"sampleText": "Insert text"};
}
/* if there is only one licence available select it and hide the input */
mwCustomEditButtons[mwCustomEditButtons.length] = {
if (licenses.length == 1) {
"imageFile": "http://upload.wikimedia.org/wikipedia/en/c/c9/Button_strike.png",
license.value = licenses[0];
"speedTip": "Strike",
licenseSelectorCheck();
"tagOpen": "<s>",
license.style.display = 'none';
"tagClose": "</s>",
}
"sampleText": "Strike-through text"};
mwCustomEditButtons[mwCustomEditButtons.length] = {
/* Create individual fields for the image details */
"imageFile": "http://upload.wikimedia.org/wikipedia/en/1/13/Button_enter.png",
"speedTip": "Line break",
var labels = {
"tagOpen": "<br />",
'description' : 'Image description:',
"tagClose": "",
'author' : 'Creator name:',
"sampleText": ""};
'copyright' : 'Copyright holder:',
'source' : 'Source:',
mwCustomEditButtons[mwCustomEditButtons.length] = {
'date-created' : 'Date created:',
"imageFile": "http://upload.wikimedia.org/wikipedia/en/8/80/Button_upper_letter.png",
'pub-country' : 'Publication country:',
"speedTip": "Superscript",
'notes' : 'Notes:',
"tagOpen": "<sup>",
'versions' : 'Other versions:',
"tagClose": "</sup>",
};
"sampleText": "Superscript text"};
var sig = '~~'+'~';
mwCustomEditButtons[mwCustomEditButtons.length] = {
var summary = document.getElementById('wpUploadDescription');
"imageFile": "http://upload.wikimedia.org/wikipedia/en/7/70/Button_lower_letter.png",
var table = summary.parentNode.parentNode.parentNode;
"speedTip": "Subscript",
var next = summary.parentNode.parentNode.nextSibling;
"tagOpen": "<sub>",
"tagClose": "</sub>",
var args = summary.value.substring(summary.value.indexOf('Details|')+8,summary.value.indexOf('\n')).split('|');
"sampleText": "Subscript text"};
var details = summary.value.substring(summary.value.indexOf('\n|')+2,summary.value.indexOf('\n}}')).split('\n|');
mwCustomEditButtons[mwCustomEditButtons.length] = {
for (var i in details) {
"imageFile": "http://upload.wikimedia.org/wikipedia/en/5/58/Button_small.png",
details[i] = details[i].split('=');
"speedTip": "Small",
}
"tagOpen": "<small>",
for (var i in details) {
"tagClose": "</small>",
var tr = document.createElement('tr');
"sampleText": "Small Text"};
var td1 = document.createElement('td');
var td2 = document.createElement('td');
mwCustomEditButtons[mwCustomEditButtons.length] = {
tr.appendChild(td1);
"imageFile": "http://upload.wikimedia.org/wikipedia/en/6/60/Button_insert_table.png",
tr.appendChild(td2);
"speedTip": "Insert a table",
td1.setAttribute('class','mw-label');
"tagOpen": '{| class="wikitable"\n|-\n',
td2.setAttribute('class','mw-input');
"tagClose": "\n|}",
td1.style.width = '12em';
"sampleText": "! header 1\n! header 2\n! header 3\n|-\n| row 1, cell 1\n| row 1, cell 2\n| row 1, cell 3\n|-\n| row 2, cell 1\n| row 2, cell 2\n| row 2, cell 3"};
var input = document.createElement('input');
mwCustomEditButtons[mwCustomEditButtons.length] = {
input.setAttribute('type','text');
"imageFile": "http://upload.wikimedia.org/wikipedia/commons/7/79/Button_reflink.png",
input.setAttribute('id',details[i][0].replace(/^\s+|\s+$/g,''));
"speedTip": "Insert a reference",
input.setAttribute('name',details[i][0].replace(/^\s+|\s+$/g,''));
"tagOpen": "<ref>",
input.setAttribute('value',details[i][1].replace(/^\s+|\s+$/g,''));
"tagClose": "</ref>",
td2.appendChild(input);
"sampleText": "Insert footnote text here"};
input.style.width = '90%';
}
}
var label = document.createElement('label');
}
label.setAttribute('for',details[i][0].replace(/^\s+|\s+$/g,''));
addOnloadHook(imageButons);
label.appendChild(document.createTextNode(labels[details[i][0].replace(/^\s+|\s+$/g,'')]));
 
td1.appendChild(label);
table.insertBefore(tr,next);
if ((details[i][0].replace(/^\s+|\s+$/g,'')) == 'author' && (details[i][1].replace(/^\s+|\s+$/g,'') == sig)) tr.style.display = 'none';
}
summary.parentNode.parentNode.style.display = 'none';
var septr = document.createElement('tr');
var septd = document.createElement('td');
septr.appendChild(septd);
septd.appendChild(document.createElement('br'));
table.insertBefore(septr,summary.parentNode.parentNode);
document.getElementById('mw-upload-form').onsubmit = function(){
var temp = '{{Image_Details';
for (i in args) {
temp += '|' + args[i];
}
for (i in details) {
temp += '\n|' + details[i][0] + '= ' + document.getElementById(details[i][0].replace(/^\s+|\s+$/g,'')).value;
}
temp += '\n}}';
summary.value = temp;
if (license.value == '') {
alert('Please select a licence!');
return false;
}
}
}
}
addOnloadHook(uploadForm);


   
/** Upload Wizard ***************************************************
  *
*  Adds many enhancements to the upload form
*
*  Maintainer : [[User:Caesar Schinas]]
*/


/** Collapsible tables *********************************************************
function uploadForm() {
  *
if ((wgPageName == 'Special:Upload') && (wgUserLanguage != 'basic')) {
  Description: Allows tables to be collapsed, showing only the header. See
if ((document.getElementById('wpUploadDescription').value == '') && document.getElementById('preload')) {
  *               [[Citizendium:NavFrame]].
document.getElementById('wpUploadDescription').value = document.getElementById('preload').innerHTML;
  Maintainers: [[User:R. Koot]]
document.getElementById('preload').parentNode.innerHTML = 'Fill in all the details you know:';
  */
}
if (wgUserLanguage == 'replace') {
var autoCollapse = 2;
document.getElementById('wpDestFile').parentNode.parentNode.style.display = 'none';
var collapseCaption = "hide";
document.getElementById('wpUploadDescription').setAttribute('rows','5');
var expandCaption = "show";
}
if ((document.getElementById('wpUploadDescription').value.indexOf('{{Image_Details') != -1) && (wgUserLanguage != 'advanced')) {
function collapseTable( tableIndex )
/* get an array of licences */
{
var license = document.getElementById('wpLicense');
    var Button = document.getElementById( "collapseButton" + tableIndex );
var licenses = Array();
    var Table = document.getElementById( "collapsibleTable" + tableIndex );
for (var i in license.childNodes) {
if (license.childNodes[i].nodeName == 'OPTION' && license.childNodes[i].value != '') {
    if ( !Table || !Button ) {
licenses.push(license.childNodes[i].value);
        return false;
}
    }
}
/* if there is only one licence available select it and hide the input */
    var Rows = Table.getElementsByTagName( "tr" );  
if (licenses.length == 1) {
license.value = licenses[0];
    if ( Button.firstChild.data == collapseCaption ) {
licenseSelectorCheck();
        for ( var i = 1; i < Rows.length; i++ ) {
license.style.display = 'none';
            Rows[i].style.display = "none";
}
        }
        Button.firstChild.data = expandCaption;
    } else {
/* Create individual fields for the image details */
        for ( var i = 1; i < Rows.length; i++ ) {
            Rows[i].style.display = Rows[0].style.display;
var labels = {
        }
'description' : 'Image description:',
        Button.firstChild.data = collapseCaption;
'author' : 'Creator name:',
    }
'copyright' : 'Copyright holder:',
}
'source' : 'Source:',
'date-created' : 'Date created:',
function createCollapseButtons()
'pub-country' : 'Publication country:',
{
'notes' : 'Notes:',
    var tableIndex = 0;
'versions' : 'Other versions:'
    var NavigationBoxes = new Object();
};
    var Tables = document.getElementsByTagName( "table" );
var sig = '~~'+'~';
var summary = document.getElementById('wpUploadDescription');
var table = summary.parentNode.parentNode.parentNode;
var next = summary.parentNode.parentNode.nextSibling;
var args = Array();
if (summary.value.indexOf('Details|') != -1)
args = summary.value.substring(summary.value.indexOf('Details|')+8,summary.value.indexOf('\n')).split('|');
var details = summary.value.substring(summary.value.indexOf('\n|')+2,summary.value.indexOf('\n}}')).split('\n|');
for (var i in details) {
details[i] = details[i].split('=');
}
for (var i in details) {
var tr = document.createElement('tr');
var td1 = document.createElement('td');
var td2 = document.createElement('td');
tr.appendChild(td1);
tr.appendChild(td2);
td1.setAttribute('class','mw-label');
td2.setAttribute('class','mw-input');
td1.style.width = '12em';
 
// added by dnessett on 3/12/2010 to increase visible region for Notes
if ((details[i][0].replace(/^\s+|\s+$/g,'')) == 'notes') {
var textarea = document.createElement('textarea');
textarea.setAttribute('wrap','virtual');
textarea.setAttribute('id',details[i][0].replace(/^\s+|\s+$/g,''));
textarea.setAttribute('name',details[i][0].replace(/^\s+|\s+$/g,''));
textarea.setAttribute('value',details[i][1].replace(/^\s+|\s+$/g,''));
textarea.setAttribute('rows','5');
td2.appendChild(textarea);
textarea.style.width = '90%';
} else {
var input = document.createElement('input');
input.setAttribute('type','text');
input.setAttribute('id',details[i][0].replace(/^\s+|\s+$/g,''));
input.setAttribute('name',details[i][0].replace(/^\s+|\s+$/g,''));
input.setAttribute('value',details[i][1].replace(/^\s+|\s+$/g,''));
td2.appendChild(input);
input.style.width = '90%';
}
var label = document.createElement('label');
label.setAttribute('for',details[i][0].replace(/^\s+|\s+$/g,''));
label.appendChild(document.createTextNode(labels[details[i][0].replace(/^\s+|\s+$/g,'')]));
td1.appendChild(label);
table.insertBefore(tr,next);
if ((details[i][0].replace(/^\s+|\s+$/g,'')) == 'author' && (details[i][1].replace(/^\s+|\s+$/g,'') == sig)) tr.style.display = 'none';
}
summary.parentNode.parentNode.style.display = 'none';
var septr = document.createElement('tr');
var septd = document.createElement('td');
septr.appendChild(septd);
septd.appendChild(document.createElement('br'));
table.insertBefore(septr,summary.parentNode.parentNode);
document.getElementById('mw-upload-form').onsubmit = function(){
var temp = '{{Image_Details';
for (i in args) {
temp += '|' + args[i];
}
for (i in details) {
temp += '\n|' + details[i][0] + '= ' + document.getElementById(details[i][0].replace(/^\s+|\s+$/g,'')).value;
}
temp += '\n}}';
summary.value = temp;
if (license.value == '') {
alert('Please select a licence!');
return false;
}
}
}
}
}
addOnloadHook(uploadForm);
 
function uploadReplaceLink () {
if (wgNamespaceNumber == 6) {
var a = document.getElementsByTagName('a');
for (var i in a) {
if (a[i].getAttribute('href') && a[i].getAttribute('href').indexOf('wpDestFile') != -1)
a[i].setAttribute('href', a[i].getAttribute('href') + '&uselang=replace');
}
}
}
addOnloadHook(uploadReplaceLink);
 
 
/** Credit Line Editor ***************************************************
*
Creates a simple form for editing credit lines.
*
Maintainer : [[User:Caesar Schinas]]
*/
function creditEdit() {
  if ((wgPageName.indexOf('/credit') != -1) && (wgAction == 'edit')) {
var text = document.getElementById('wpTextbox1').value;
if (text.indexOf('{{creditline') == -1) return false;
var args = text.substring(text.indexOf('|')+1,text.indexOf('}}')).split('|');
var bodycontent = document.getElementById('bodycontent');
bodycontent.setAttribute('id','bodycontent-old');
bodycontent.style.display = 'none';
var div = document.createElement('div');
bodycontent.parentNode.appendChild(div);
div.setAttribute('id','bodycontent');
div.innerHTML = "\
<table>\n\
  <tr>\n\
<th style='text-align:right; padding-right:1em;'>\n\
  <label for='licence'>Licence Type</label>\n\
</th>\n\
<td>\n\
  <select id='licence' name='licence' style='width:25em;'>\n\
<option value='C'>C - Copyright, used by permission</option>\n\
<option value='CC'>CC - Creative Commons</option>\n\
<option value='GNU'>GNU</option>\n\
<option value='PD'>PD - Public Domain</option>\n\
<option value='other' selected='selected'>Other (please only enter letters)</option>\n\
  </select>\n\
  <input type='text' id='licence-other' name='imagetype-other' />\n\
</td>\n\
  </tr>\n\
  <tr>\n\
<th style='text-align:right; padding-right:1em;'>\n\
  <label for='imagetype'>Image Type</label>\n\
</th>\n\
<td>\n\
  <select id='imagetype' name='imagetype' style='width:25em;'>\n\
<option value='Image'>Image</option>\n\
<option value='Photo'>Photo</option>\n\
<option value='Diagram'>Diagram</option>\n\
<option value='Drawing'>Drawing</option>\n\
<option value='Painting'>Painting</option>\n\
<option value='Artwork'>Artwork</option>\n\
<option value='other' selected='selected'>Other</option>\n\
  </select>\n\
  <input type='text' id='imagetype-other' name='imagetype-other' />\n\
</td>\n\
  </tr>\n\
  <tr>\n\
<th style='text-align:right; padding-right:1em;'>\n\
  <label for='author'>Author</label>\n\
</th>\n\
<td>\n\
  <input type='text' id='author' name='author' style='width:25em;' />\n\
</td>\n\
  </tr>\n\
  <tr>\n\
<th>\n\
</th>\n\
<td>\n\
  <input type='button' id='save' value='Save Credit Line' />\n\
</td>\n\
  </tr>\n\
</table>\n\
";
// set form field values
if (args[0] && args[0] != 'licence') {
  document.getElementById('licence-other').value = args[0];
  for (var i=0; i<4; i++) {
if (args[0].toUpperCase() == Array('CC','GNU','PD','C')[i]) {
document.getElementById('licence').value = args[0].toUpperCase();
document.getElementById('licence-other').style.display = 'none';
}
  }
} else {
  document.getElementById('licence').value = 'C';
  document.getElementById('licence-other').style.display = 'none';
}
if (args[1] && args[1] != 'imagetype') {
  document.getElementById('imagetype-other').value = args[1];
  for (var i=0; i<6; i++) {
if (args[1].toLowerCase() == Array('Image','Photo','Diagram','Drawing','Painting','Artwork')[i].toLowerCase()) {
document.getElementById('imagetype').value = Array('Image','Photo','Diagram','Drawing','Painting','Artwork')[i];
document.getElementById('imagetype-other').style.display = 'none';
}
  }
} else {
  document.getElementById('imagetype').value = 'Image';
  document.getElementById('imagetype-other').style.display = 'none';
}
if (args[2] && args[2] != 'author')
  document.getElementById('author').value = args[2];
// onchange handlers for selects
document.getElementById('licence').onchange = function() {
  if (document.getElementById('licence').value == 'other')
document.getElementById('licence-other').style.display = 'inline';
  else
document.getElementById('licence-other').style.display = 'none';
}
document.getElementById('imagetype').onchange = function() {
  if (document.getElementById('imagetype').value == 'other')
document.getElementById('imagetype-other').style.display = 'inline';
  else
document.getElementById('imagetype-other').style.display = 'none';
}
// save the credit line
document.getElementById('save').onclick = function() {
  var value = '{{creditline';
 
  if (document.getElementById('licence').value != 'other')
value += '|' + document.getElementById('licence').value;
  else if (document.getElementById('licence-other').value != '')
value += '|' + document.getElementById('licence-other').value;
 
  if (document.getElementById('imagetype').value != 'Image' || document.getElementById('author').value != '') {
if (document.getElementById('imagetype').value != 'other')
value += '|' + document.getElementById('imagetype').value;
else if (document.getElementById('imagetype-other').value != '')
value += '|' + document.getElementById('imagetype-other').value;
if (document.getElementById('author').value != '')
value += '|' + document.getElementById('author').value;
  }
 
  value += '}}';
 
  document.getElementById('wpTextbox1').value = value;
  document.getElementById('editform').submit();
}
  }
}
addOnloadHook(creditEdit);
 
 
 
 
/* Test if an element has a certain class **************************************
  *
  * Description: Uses regular expressions and caching for better performance.
  * Maintainers: [[User:Mike Dillon]], [[User:R. Koot]], [[User:SG]]
  */
   
   
     for ( var i = 0; i < Tables.length; i++ ) {
var hasClass = (function () {
        if ( hasClass( Tables[i], "collapsible" ) ) {
     var reCache = {};
            NavigationBoxes[ tableIndex ] = Tables[i];
    return function (element, className) {
            Tables[i].setAttribute( "id", "collapsibleTable" + tableIndex );
        return (reCache[className] ? reCache[className] : (reCache[className] = new RegExp("(?:\\s|^)" + className + "(?:\\s|$)"))).test(element.className);
    };
})();
 
 
 
   
   
            var Button    = document.createElement( "span" );
 
            var ButtonLink = document.createElement( "a" );
/** Collapsible tables *********************************************************
            var ButtonText = document.createTextNode( collapseCaption );
  *
  *  Description: Allows tables to be collapsed, showing only the header. See
  *              [[Citizendium:NavFrame]].
  *  Maintainers: [[User:R. Koot]]
  */
   
   
            Button.style.styleFloat = "right";
var autoCollapse = 2;
            Button.style.cssFloat = "right";
var collapseCaption = "hide";
            Button.style.fontWeight = "normal";
var expandCaption = "show";
            Button.style.textAlign = "right";
            Button.style.width = "6em";
   
   
            ButtonLink.setAttribute( "id", "collapseButton" + tableIndex );
function collapseTable( tableIndex )
            ButtonLink.setAttribute( "href", "javascript:collapseTable(" + tableIndex + ");" );
{
            ButtonLink.appendChild( ButtonText );
    var Button = document.getElementById( "collapseButton" + tableIndex );
    var Table = document.getElementById( "collapsibleTable" + tableIndex );
   
   
            Button.appendChild( document.createTextNode( "[" ) );
    if ( !Table || !Button ) {
            Button.appendChild( ButtonLink );
        return false;
            Button.appendChild( document.createTextNode( "]" ) );
    }
   
   
            var Header = Tables[i].getElementsByTagName( "tr" )[0].getElementsByTagName( "th" )[0];
    var Rows = Table.getElementsByTagName( "tr" );  
            /* only add button and increment count if there is a header row to work with */
            if (Header) {
                Header.insertBefore( Button, Header.childNodes[0] );
                tableIndex++;
            }
        }
    }
   
   
     for ( var i = 0; i < tableIndex; i++ ) {
     if ( Button.firstChild.data == collapseCaption ) {
        if ( hasClass( NavigationBoxes[i], "collapsed" ) || ( tableIndex >= autoCollapse && hasClass( NavigationBoxes[i], "autocollapse" ) ) ) {
        for ( var i = 1; i < Rows.length; i++ ) {
             collapseTable( i );
            Rows[i].style.display = "none";
        }
        Button.firstChild.data = expandCaption;
    } else {
        for ( var i = 1; i < Rows.length; i++ ) {
             Rows[i].style.display = Rows[0].style.display;
         }
         }
        Button.firstChild.data = collapseCaption;
     }
     }
  }
  }
   
   
  addOnloadHook( createCollapseButtons );
  function createCollapseButtons()
 
{
  /** Dynamic Navigation Bars (experimental) *************************************
    var tableIndex = 0;
  *
    var NavigationBoxes = new Object();
  *  Description: See [[Citizendium:NavFrame]].
    var Tables = document.getElementsByTagName( "table" );
  *  Maintainers: UNMAINTAINED
   
  */
    for ( var i = 0; i < Tables.length; i++ ) {
        if ( hasClass( Tables[i], "collapsible" ) ) {
            NavigationBoxes[ tableIndex ] = Tables[i];
            Tables[i].setAttribute( "id", "collapsibleTable" + tableIndex );
   
   
  // set up the words in your language
            var Button     = document.createElement( "span" );
  var NavigationBarHide = '[' + collapseCaption + ']';
            var ButtonLink = document.createElement( "a" );
  var NavigationBarShow = '[' + expandCaption + ']';
            var ButtonText = document.createTextNode( collapseCaption );
 
  // set up max count of Navigation Bars on page,
            Button.style.styleFloat = "right";
  // if there are more, all will be hidden
            Button.style.cssFloat = "right";
  // NavigationBarShowDefault = 0; // all bars will be hidden
             Button.style.fontWeight = "normal";
  // NavigationBarShowDefault = 1; // on pages with more than 1 bar all bars will be hidden
             Button.style.textAlign = "right";
  var NavigationBarShowDefault = autoCollapse;
             Button.style.width = "6em";
 
 
            ButtonLink.setAttribute( "id", "collapseButton" + tableIndex );
  // shows and hides content and picture (if available) of navigation bars
            ButtonLink.setAttribute( "href", "javascript:collapseTable(" + tableIndex + ");" );
  // Parameters:
            ButtonLink.appendChild( ButtonText );
  //     indexNavigationBar: the index of navigation bar to be toggled
  function toggleNavigationBar(indexNavigationBar)
            Button.appendChild( document.createTextNode( "[" ) );
  {
             Button.appendChild( ButtonLink );
    var NavToggle = document.getElementById("NavToggle" + indexNavigationBar);
             Button.appendChild( document.createTextNode( "]" ) );
    var NavFrame = document.getElementById("NavFrame" + indexNavigationBar);
 
            var Header = Tables[i].getElementsByTagName( "tr" )[0].getElementsByTagName( "th" )[0];
    if (!NavFrame || !NavToggle) {
             /* only add button and increment count if there is a header row to work with */
        return false;
             if (Header) {
    }
                 Header.insertBefore( Button, Header.childNodes[0] );
 
                tableIndex++;
    // if shown now
    if (NavToggle.firstChild.data == NavigationBarHide) {
        for (
                var NavChild = NavFrame.firstChild;
                NavChild != null;
                NavChild = NavChild.nextSibling
             ) {
            if ( hasClass( NavChild, 'NavPic' ) ) {
                NavChild.style.display = 'none';
             }
            if ( hasClass( NavChild, 'NavContent') ) {
                NavChild.style.display = 'none';
             }
        }
    NavToggle.firstChild.data = NavigationBarShow;
 
    // if hidden now
    } else if (NavToggle.firstChild.data == NavigationBarShow) {
        for (
                var NavChild = NavFrame.firstChild;
                NavChild != null;
                NavChild = NavChild.nextSibling
             ) {
             if (hasClass(NavChild, 'NavPic')) {
                NavChild.style.display = 'block';
             }
             if (hasClass(NavChild, 'NavContent')) {
                 NavChild.style.display = 'block';
             }
             }
         }
         }
    NavToggle.firstChild.data = NavigationBarHide;
     }
     }
  }
 
     for ( var i = 0; i < tableIndex; i++ ) {
  // adds show/hide-button to navigation bars
         if ( hasClass( NavigationBoxes[i], "collapsed" ) || ( tableIndex >= autoCollapse && hasClass( NavigationBoxes[i], "autocollapse" ) ) ) {
  function createNavigationBarToggleButton()
             collapseTable( i );
  {
    var indexNavigationBar = 0;
    // iterate over all < div >-elements
    var divs = document.getElementsByTagName("div");
     for(
            var i=0;  
            NavFrame = divs[i];  
            i++
        ) {
        // if found a navigation bar
         if (hasClass(NavFrame, "NavFrame")) {
 
            indexNavigationBar++;
            var NavToggle = document.createElement("a");
            NavToggle.className = 'NavToggle';
            NavToggle.setAttribute('id', 'NavToggle' + indexNavigationBar);
            NavToggle.setAttribute('href', 'javascript:toggleNavigationBar(' + indexNavigationBar + ');');
           
            var NavToggleText = document.createTextNode(NavigationBarHide);
            NavToggle.appendChild(NavToggleText);
            // Find the NavHead and attach the toggle link (Must be this complicated because Moz's firstChild handling is borked)
            for(
              var j=0;
              j < NavFrame.childNodes.length;
              j++
            ) {
              if (hasClass(NavFrame.childNodes[j], "NavHead")) {
                NavFrame.childNodes[j].appendChild(NavToggle);
              }
            }
             NavFrame.setAttribute('id', 'NavFrame' + indexNavigationBar);
         }
         }
     }
     }
    // if more Navigation Bars found than Default: hide all
}
    if (NavigationBarShowDefault < indexNavigationBar) {
addOnloadHook( createCollapseButtons );
        for(
                var i=1;
                i<=indexNavigationBar;
                i++
        ) {
            toggleNavigationBar(i);
        }
    }
 
  }
 
  addOnloadHook( createNavigationBarToggleButton );




/** Extra toolbar options ******************************************************
/** Add dismiss button to watchlist-message *************************************
   *
   *
   *  Description: UNDOCUMENTED
   *  Description: Hide the watchlist message for one week.
   *  Maintainers:  
   *  Maintainers: [[User:Ruud Koot|Ruud Koot]]
   */
   */
   
   
  /* To disable this script, add  mwCustomEditButtons = [];   to [[Special:Mypage/Pinkwich5.js]] */
  function addDismissButton() {
    var watchlistMessage = document.getElementById("watchlist-message");
    if ( watchlistMessage == null ) return;
   
   
if (mwCustomEditButtons) {
    if ( document.cookie.indexOf( "hidewatchlistmessage=yes" ) != -1 ) {
  mwCustomEditButtons[mwCustomEditButtons.length] = {
        watchlistMessage.style.display = "none";
    "imageFile": "http://upload.wikimedia.org/wikipedia/en/c/c8/Button_redirect.png",
    }
    "speedTip": "Redirect",
    "tagOpen": "#REDIRECT [[",
    "tagClose": "]]",
    "sampleText": "Insert text"};
   
   
  mwCustomEditButtons[mwCustomEditButtons.length] = {
    var Button    = document.createElement( "span" );
    "imageFile": "http://upload.wikimedia.org/wikipedia/en/c/c9/Button_strike.png",
    var ButtonLink = document.createElement( "a" );
    "speedTip": "Strike",
    var ButtonText = document.createTextNode( "dismiss" );
    "tagOpen": "<s>",
    "tagClose": "</s>",
    "sampleText": "Strike-through text"};
   
   
  mwCustomEditButtons[mwCustomEditButtons.length] = {
    ButtonLink.setAttribute( "id", "dismissButton" );
    "imageFile": "http://upload.wikimedia.org/wikipedia/en/1/13/Button_enter.png",
    ButtonLink.setAttribute( "href", "javascript:dismissWatchlistMessage();" );
    "speedTip": "Line break",
    ButtonLink.setAttribute( "title", "Hide this message for one week" );
    "tagOpen": "<br />",
    ButtonLink.appendChild( ButtonText );
    "tagClose": "",
    "sampleText": ""};
   
   
  mwCustomEditButtons[mwCustomEditButtons.length] = {
    Button.appendChild( document.createTextNode( "[" ) );
    "imageFile": "http://upload.wikimedia.org/wikipedia/en/8/80/Button_upper_letter.png",
    Button.appendChild( ButtonLink );
    "speedTip": "Superscript",
    Button.appendChild( document.createTextNode( "]" ) );
    "tagOpen": "<sup>",
    "tagClose": "</sup>",
    "sampleText": "Superscript text"};
   
   
  mwCustomEditButtons[mwCustomEditButtons.length] = {
    watchlistMessage.appendChild( Button );
    "imageFile": "http://upload.wikimedia.org/wikipedia/en/7/70/Button_lower_letter.png",
}
    "speedTip": "Subscript",
    "tagOpen": "<sub>",
    "tagClose": "</sub>",
    "sampleText": "Subscript text"};
   
   
  mwCustomEditButtons[mwCustomEditButtons.length] = {
function dismissWatchlistMessage() {
     "imageFile": "http://upload.wikimedia.org/wikipedia/en/5/58/Button_small.png",
    var e = new Date();
     "speedTip": "Small",
     e.setTime( e.getTime() + (7*24*60*60*1000) );
     "tagOpen": "<small>",
     document.cookie = "hidewatchlistmessage=yes; expires=" + e.toGMTString() + "; path=/";
     "tagClose": "</small>",
     var watchlistMessage = document.getElementById("watchlist-message");
    "sampleText": "Small Text"};
     watchlistMessage.style.display = "none";
}
   
   
  mwCustomEditButtons[mwCustomEditButtons.length] = {
  addOnloadHook( addDismissButton );
    "imageFile": "http://upload.wikimedia.org/wikipedia/en/3/34/Button_hide_comment.png",
    "speedTip": "Insert hidden Comment",
    "tagOpen": "<!-- ",
    "tagClose": " -->",
    "sampleText": "Comment"};
   
//  mwCustomEditButtons[mwCustomEditButtons.length] = {
//    "imageFile": "http://upload.wikimedia.org/wikipedia/en/1/12/Button_gallery.png",
//    "speedTip": "Insert a picture gallery",
//    "tagOpen": "\n<gallery>\n",
//    "tagClose": "\n</gallery>",
//    "sampleText": "Image:Example.jpg|Caption1\nImage:Example.jpg|Caption2"};
  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "http://upload.wikimedia.org/wikipedia/en/f/fd/Button_blockquote.png",
    "speedTip": "Insert block of quoted text",
    "tagOpen": "<blockquote>\n",
    "tagClose": "\n</blockquote>",
    "sampleText": "Block quote"};
  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "http://upload.wikimedia.org/wikipedia/en/6/60/Button_insert_table.png",
    "speedTip": "Insert a table",
    "tagOpen": '{| class="wikitable"\n|-\n',
    "tagClose": "\n|}",
    "sampleText": "! header 1\n! header 2\n! header 3\n|-\n| row 1, cell 1\n| row 1, cell 2\n| row 1, cell 3\n|-\n| row 2, cell 1\n| row 2, cell 2\n| row 2, cell 3"};
  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "http://upload.wikimedia.org/wikipedia/commons/7/79/Button_reflink.png",
    "speedTip": "Insert a reference",
    "tagOpen": "<ref>",
    "tagClose": "</ref>",
    "sampleText": "Insert footnote text here"};
}


 
  /** Numeric sorting ***************************************************
  /** Add dismiss button to watchlist-message *************************************
   *
   *
   *  Description: Hide the watchlist message for one week.
   *  Description: Fixes a bug (part of [[bugzilla:8115]])
   *  Maintainers: [[User:Ruud Koot|Ruud Koot]]
  *  in http://svn.citizendium.org/viewvc/mediawiki/trunk/phase3/skins/common/wikibits.js
  *  regarding [[Help:Sorting|table sorting]]:
  *  it allows sorting of numbers with more than one comma (thousands separator).
   *  Maintainer: [[User:Patrick|Patrick]]
   */
   */
  function ts_parseFloat(num) {
  function addDismissButton() {
if (!num) return 0;
    var watchlistMessage = document.getElementById("watchlist-message");
num = parseFloat(num.replace(/,/g, ""));
    if ( watchlistMessage == null ) return;
return (isNaN(num) ? 0 : num);
}
    if ( document.cookie.indexOf( "hidewatchlistmessage=yes" ) != -1 ) {
 
        watchlistMessage.style.display = "none";
 
    }
 
// MediaWiki JavaScript support functions
    var Button    = document.createElement( "span" );
 
    var ButtonLink = document.createElement( "a" );
var clientPC = navigator.userAgent.toLowerCase(); // Get client info
    var ButtonText = document.createTextNode( "dismiss" );
var is_gecko = ((clientPC.indexOf('gecko')!=-1) && (clientPC.indexOf('spoofer')==-1)
                && (clientPC.indexOf('khtml') == -1) && (clientPC.indexOf('netscape/7.0')==-1));
    ButtonLink.setAttribute( "id", "dismissButton" );
var is_safari = ((clientPC.indexOf('applewebkit')!=-1) && (clientPC.indexOf('spoofer')==-1));
    ButtonLink.setAttribute( "href", "javascript:dismissWatchlistMessage();" );
var is_khtml = (navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled ));
    ButtonLink.setAttribute( "title", "Hide this message for one week" );
// For accesskeys
    ButtonLink.appendChild( ButtonText );
var is_ff2_win = (clientPC.indexOf('firefox/2')!=-1 || clientPC.indexOf('minefield/3')!=-1) && clientPC.indexOf('windows')!=-1;
var is_ff2_x11 = (clientPC.indexOf('firefox/2')!=-1 || clientPC.indexOf('minefield/3')!=-1) && clientPC.indexOf('x11')!=-1;
    Button.appendChild( document.createTextNode( "[" ) );
if (clientPC.indexOf('opera') != -1) {
    Button.appendChild( ButtonLink );
var is_opera = true;
    Button.appendChild( document.createTextNode( "]" ) );
var is_opera_preseven = (window.opera && !document.childNodes);
var is_opera_seven = (window.opera && document.childNodes);
    watchlistMessage.appendChild( Button );
var is_opera_95 = (clientPC.search(/opera\/(9.[5-9]|[1-9][0-9])/)!=-1);
}
}
 
function dismissWatchlistMessage() {
// Global external objects used by this script.
    var e = new Date();
/*extern ta, stylepath, skin */
    e.setTime( e.getTime() + (7*24*60*60*1000) );
 
    document.cookie = "hidewatchlistmessage=yes; expires=" + e.toGMTString() + "; path=/";
// add any onload functions in this hook (please don't hard-code any events in the xhtml source)
    var watchlistMessage = document.getElementById("watchlist-message");
var doneOnloadHook;
    watchlistMessage.style.display = "none";
}
addOnloadHook( addDismissButton );


/** Numeric sorting ***************************************************
if (!window.onloadFuncts) {
  *
var onloadFuncts = [];
  *  Description: Fixes a bug (part of [[bugzilla:8115]])
}
  *  in http://svn.citizendium.org/viewvc/mediawiki/trunk/phase3/skins/common/wikibits.js
  *  regarding [[Help:Sorting|table sorting]]:
  *  it allows sorting of numbers with more than one comma (thousands separator).
  *  Maintainer: [[User:Patrick|Patrick]]
  */
function ts_parseFloat(num) {
if (!num) return 0;
num = parseFloat(num.replace(/,/g, ""));
return (isNaN(num) ? 0 : num);
}


function addOnloadHook(hookFunct) {
// Allows add-on scripts to add onload functions
onloadFuncts[onloadFuncts.length] = hookFunct;
}


function hookEvent(hookName, hookFunct) {
if (window.addEventListener) {
window.addEventListener(hookName, hookFunct, false);
} else if (window.attachEvent) {
window.attachEvent("on" + hookName, hookFunct);
}
}


// MediaWiki JavaScript support functions
// document.write special stylesheet links
 
if (typeof stylepath != 'undefined' && typeof skin != 'undefined') {
var clientPC = navigator.userAgent.toLowerCase(); // Get client info
if (is_opera_preseven) {
var is_gecko = ((clientPC.indexOf('gecko')!=-1) && (clientPC.indexOf('spoofer')==-1)
document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera6Fixes.css">');
                && (clientPC.indexOf('khtml') == -1) && (clientPC.indexOf('netscape/7.0')==-1));
} else if (is_opera_seven && !is_opera_95) {
var is_safari = ((clientPC.indexOf('applewebkit')!=-1) && (clientPC.indexOf('spoofer')==-1));
document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera7Fixes.css">');
var is_khtml = (navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled ));
} else if (is_opera_95) {
// For accesskeys
document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera95Fixes.css">');
var is_ff2_win = (clientPC.indexOf('firefox/2')!=-1 || clientPC.indexOf('minefield/3')!=-1) && clientPC.indexOf('windows')!=-1;
} else if (is_khtml) {
var is_ff2_x11 = (clientPC.indexOf('firefox/2')!=-1 || clientPC.indexOf('minefield/3')!=-1) && clientPC.indexOf('x11')!=-1;
document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/KHTMLFixes.css">');
if (clientPC.indexOf('opera') != -1) {
}
var is_opera = true;
var is_opera_preseven = (window.opera && !document.childNodes);
var is_opera_seven = (window.opera && document.childNodes);
var is_opera_95 = (clientPC.search(/opera\/(9.[5-9]|[1-9][0-9])/)!=-1);
}
}


// Global external objects used by this script.
if (wgBreakFrames) {
/*extern ta, stylepath, skin */
// Un-trap us from framesets
 
if (window.top != window) {
// add any onload functions in this hook (please don't hard-code any events in the xhtml source)
window.top.location = window.location;
var doneOnloadHook;
}
 
if (!window.onloadFuncts) {
var onloadFuncts = [];
}
}


function addOnloadHook(hookFunct) {
// for enhanced RecentChanges
// Allows add-on scripts to add onload functions
function toggleVisibility(_levelId, _otherId, _linkId) {
onloadFuncts[onloadFuncts.length] = hookFunct;
var thisLevel = document.getElementById(_levelId);
var otherLevel = document.getElementById(_otherId);
var linkLevel = document.getElementById(_linkId);
if (thisLevel.style.display == 'none') {
thisLevel.style.display = 'block';
otherLevel.style.display = 'none';
linkLevel.style.display = 'inline';
} else {
thisLevel.style.display = 'none';
otherLevel.style.display = 'inline';
linkLevel.style.display = 'none';
}
}
}


function hookEvent(hookName, hookFunct) {
function historyRadios(parent) {
if (window.addEventListener) {
var inputs = parent.getElementsByTagName('input');
window.addEventListener(hookName, hookFunct, false);
var radios = [];
} else if (window.attachEvent) {
for (var i = 0; i < inputs.length; i++) {
window.attachEvent("on" + hookName, hookFunct);
if (inputs[i].name == "diff" || inputs[i].name == "oldid") {
radios[radios.length] = inputs[i];
}
}
}
return radios;
}
}


// document.write special stylesheet links
// check selection and tweak visibility/class onclick
if (typeof stylepath != 'undefined' && typeof skin != 'undefined') {
function diffcheck() {
if (is_opera_preseven) {
var dli = false; // the li where the diff radio is checked
document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera6Fixes.css">');
var oli = false; // the li where the oldid radio is checked
} else if (is_opera_seven && !is_opera_95) {
var hf = document.getElementById('pagehistory');
document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera7Fixes.css">');
if (!hf) {
} else if (is_opera_95) {
return true;
document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera95Fixes.css">');
}
} else if (is_khtml) {
var lis = hf.getElementsByTagName('li');
document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/KHTMLFixes.css">');
for (var i=0;i<lis.length;i++) {
}
var inputs = historyRadios(lis[i]);
}
if (inputs[1] && inputs[0]) {
 
if (inputs[1].checked || inputs[0].checked) { // this row has a checked radio button
if (wgBreakFrames) {
if (inputs[1].checked && inputs[0].checked && inputs[0].value == inputs[1].value) {
// Un-trap us from framesets
return false;
if (window.top != window) {
}
window.top.location = window.location;
if (oli) { // it's the second checked radio
}
if (inputs[1].checked) {
}
oli.className = "selected";
 
return false;
// for enhanced RecentChanges
}
function toggleVisibility(_levelId, _otherId, _linkId) {
} else if (inputs[0].checked) {
var thisLevel = document.getElementById(_levelId);
return false;
var otherLevel = document.getElementById(_otherId);
}
var linkLevel = document.getElementById(_linkId);
if (inputs[0].checked) {
if (thisLevel.style.display == 'none') {
dli = lis[i];
thisLevel.style.display = 'block';
}
otherLevel.style.display = 'none';
if (!oli) {
linkLevel.style.display = 'inline';
inputs[0].style.visibility = 'hidden';
} else {
}
thisLevel.style.display = 'none';
if (dli) {
otherLevel.style.display = 'inline';
inputs[1].style.visibility = 'hidden';
linkLevel.style.display = 'none';
}
}
lis[i].className = "selected";
}
oli = lis[i];
 
} else { // no radio is checked in this row
function historyRadios(parent) {
if (!oli) {
var inputs = parent.getElementsByTagName('input');
inputs[0].style.visibility = 'hidden';
var radios = [];
} else {
for (var i = 0; i < inputs.length; i++) {
inputs[0].style.visibility = 'visible';
if (inputs[i].name == "diff" || inputs[i].name == "oldid") {
}
radios[radios.length] = inputs[i];
if (dli) {
inputs[1].style.visibility = 'hidden';
} else {
inputs[1].style.visibility = 'visible';
}
lis[i].className = "";
}
}
}
}
}
return radios;
return true;
}
}


// check selection and tweak visibility/class onclick
// page history stuff
function diffcheck() {
// attach event handlers to the input elements on history page
var dli = false; // the li where the diff radio is checked
function histrowinit() {
var oli = false; // the li where the oldid radio is checked
var hf = document.getElementById('pagehistory');
var hf = document.getElementById('pagehistory');
if (!hf) {
if (!hf) {
return true;
return;
}
}
var lis = hf.getElementsByTagName('li');
var lis = hf.getElementsByTagName('li');
for (var i=0;i<lis.length;i++) {
for (var i = 0; i < lis.length; i++) {
var inputs = historyRadios(lis[i]);
var inputs = historyRadios(lis[i]);
if (inputs[1] && inputs[0]) {
if (inputs[0] && inputs[1]) {
if (inputs[1].checked || inputs[0].checked) { // this row has a checked radio button
inputs[0].onclick = diffcheck;
if (inputs[1].checked && inputs[0].checked && inputs[0].value == inputs[1].value) {
inputs[1].onclick = diffcheck;
return false;
}
}
}
if (oli) { // it's the second checked radio
diffcheck();
if (inputs[1].checked) {
}
oli.className = "selected";
 
return false;
// generate toc from prefs form, fold sections
}
// XXX: needs testing on IE/Mac and safari
} else if (inputs[0].checked) {
// more comments to follow
return false;
function tabbedprefs() {
}
var prefform = document.getElementById('preferences');
if (inputs[0].checked) {
if (!prefform || !document.createElement) {
dli = lis[i];
return;
}
}
if (!oli) {
if (prefform.nodeName.toLowerCase() == 'a') {
inputs[0].style.visibility = 'hidden';
return; // Occasional IE problem
}
}
if (dli) {
prefform.className = prefform.className + 'jsprefs';
inputs[1].style.visibility = 'hidden';
var sections = [];
}
var children = prefform.childNodes;
lis[i].className = "selected";
var seci = 0;
oli = lis[i];
for (var i = 0; i < children.length; i++) {
}  else { // no radio is checked in this row
if (children[i].nodeName.toLowerCase() == 'fieldset') {
if (!oli) {
children[i].id = 'prefsection-' + seci;
inputs[0].style.visibility = 'hidden';
children[i].className = 'prefsection';
} else {
if (is_opera || is_khtml) {
inputs[0].style.visibility = 'visible';
children[i].className = 'prefsection operaprefsection';
}
if (dli) {
inputs[1].style.visibility = 'hidden';
} else {
inputs[1].style.visibility = 'visible';
}
lis[i].className = "";
}
}
}
var legends = children[i].getElementsByTagName('legend');
}
sections[seci] = {};
return true;
legends[0].className = 'mainLegend';
}
if (legends[0] && legends[0].firstChild.nodeValue) {
 
sections[seci].text = legends[0].firstChild.nodeValue;
// page history stuff
} else {
// attach event handlers to the input elements on history page
sections[seci].text = '# ' + seci;
function histrowinit() {
}
var hf = document.getElementById('pagehistory');
sections[seci].secid = children[i].id;
if (!hf) {
seci++;
return;
if (sections.length != 1) {
children[i].style.display = 'none';
} else {
var selectedid = children[i].id;
}
}
}
}
var lis = hf.getElementsByTagName('li');
var toc = document.createElement('ul');
for (var i = 0; i < lis.length; i++) {
toc.id = 'preftoc';
var inputs = historyRadios(lis[i]);
toc.selectedid = selectedid;
if (inputs[0] && inputs[1]) {
for (i = 0; i < sections.length; i++) {
inputs[0].onclick = diffcheck;
var li = document.createElement('li');
inputs[1].onclick = diffcheck;
if (i === 0) {
li.className = 'selected';
}
}
var a = document.createElement('a');
a.href = '#' + sections[i].secid;
a.onmousedown = a.onclick = uncoversection;
a.appendChild(document.createTextNode(sections[i].text));
a.secid = sections[i].secid;
li.appendChild(a);
toc.appendChild(li);
}
}
diffcheck();
prefform.parentNode.insertBefore(toc, prefform.parentNode.childNodes[0]);
document.getElementById('prefsubmit').id = 'prefcontrol';
}
}


// generate toc from prefs form, fold sections
function uncoversection() {
// XXX: needs testing on IE/Mac and safari
var oldsecid = this.parentNode.parentNode.selectedid;
// more comments to follow
var newsec = document.getElementById(this.secid);
function tabbedprefs() {
if (oldsecid != this.secid) {
var prefform = document.getElementById('preferences');
var ul = document.getElementById('preftoc');
if (!prefform || !document.createElement) {
document.getElementById(oldsecid).style.display = 'none';
return;
newsec.style.display = 'block';
ul.selectedid = this.secid;
var lis = ul.getElementsByTagName('li');
for (var i = 0; i< lis.length; i++) {
lis[i].className = '';
}
this.parentNode.className = 'selected';
}
}
if (prefform.nodeName.toLowerCase() == 'a') {
return false;
return; // Occasional IE problem
}
}
 
prefform.className = prefform.className + 'jsprefs';
// Timezone stuff
var sections = [];
// tz in format [+-]HHMM
var children = prefform.childNodes;
function checkTimezone(tz, msg) {
var seci = 0;
var localclock = new Date();
for (var i = 0; i < children.length; i++) {
// returns negative offset from GMT in minutes
if (children[i].nodeName.toLowerCase() == 'fieldset') {
var tzRaw = localclock.getTimezoneOffset();
children[i].id = 'prefsection-' + seci;
var tzHour = Math.floor( Math.abs(tzRaw) / 60);
children[i].className = 'prefsection';
var tzMin = Math.abs(tzRaw) % 60;
if (is_opera || is_khtml) {
var tzString = ((tzRaw >= 0) ? "-" : "+") + ((tzHour < 10) ? "0" : "") + tzHour + ((tzMin < 10) ? "0" : "") + tzMin;
children[i].className = 'prefsection operaprefsection';
if (tz != tzString) {
}
var junk = msg.split('$1');
var legends = children[i].getElementsByTagName('legend');
document.write(junk[0] + "UTC" + tzString + junk[1]);
sections[seci] = {};
}
legends[0].className = 'mainLegend';
}
if (legends[0] && legends[0].firstChild.nodeValue) {
 
sections[seci].text = legends[0].firstChild.nodeValue;
function unhidetzbutton() {
} else {
var tzb = document.getElementById('guesstimezonebutton');
sections[seci].text = '# ' + seci;
if (tzb) {
}
tzb.style.display = 'inline';
sections[seci].secid = children[i].id;
seci++;
if (sections.length != 1) {
children[i].style.display = 'none';
} else {
var selectedid = children[i].id;
}
}
}
}
var toc = document.createElement('ul');
toc.id = 'preftoc';
toc.selectedid = selectedid;
for (i = 0; i < sections.length; i++) {
var li = document.createElement('li');
if (i === 0) {
li.className = 'selected';
}
var a = document.createElement('a');
a.href = '#' + sections[i].secid;
a.onmousedown = a.onclick = uncoversection;
a.appendChild(document.createTextNode(sections[i].text));
a.secid = sections[i].secid;
li.appendChild(a);
toc.appendChild(li);
}
prefform.parentNode.insertBefore(toc, prefform.parentNode.childNodes[0]);
document.getElementById('prefsubmit').id = 'prefcontrol';
}
}


function uncoversection() {
// in [-]HH:MM format...
var oldsecid = this.parentNode.parentNode.selectedid;
// won't yet work with non-even tzs
var newsec = document.getElementById(this.secid);
function fetchTimezone() {
if (oldsecid != this.secid) {
// FIXME: work around Safari bug
var ul = document.getElementById('preftoc');
var localclock = new Date();
document.getElementById(oldsecid).style.display = 'none';
// returns negative offset from GMT in minutes
newsec.style.display = 'block';
var tzRaw = localclock.getTimezoneOffset();
ul.selectedid = this.secid;
var tzHour = Math.floor( Math.abs(tzRaw) / 60);
var lis = ul.getElementsByTagName('li');
var tzMin = Math.abs(tzRaw) % 60;
for (var i = 0; i< lis.length; i++) {
var tzString = ((tzRaw >= 0) ? "-" : "") + ((tzHour < 10) ? "0" : "") + tzHour +
lis[i].className = '';
":" + ((tzMin < 10) ? "0" : "") + tzMin;
return tzString;
}
 
function guessTimezone(box) {
document.getElementsByName("wpHourDiff")[0].value = fetchTimezone();
}
 
function showTocToggle() {
if (document.createTextNode) {
// Uses DOM calls to avoid document.write + XHTML issues
 
var linkHolder = document.getElementById('toctitle');
if (!linkHolder) {
return;
}
}
this.parentNode.className = 'selected';
}
return false;
}


// Timezone stuff
var outerSpan = document.createElement('span');
// tz in format [+-]HHMM
outerSpan.className = 'toctoggle';
function checkTimezone(tz, msg) {
 
var localclock = new Date();
var toggleLink = document.createElement('a');
// returns negative offset from GMT in minutes
toggleLink.id = 'togglelink';
var tzRaw = localclock.getTimezoneOffset();
toggleLink.className = 'internal';
var tzHour = Math.floor( Math.abs(tzRaw) / 60);
toggleLink.href = 'javascript:toggleToc()';
var tzMin = Math.abs(tzRaw) % 60;
toggleLink.appendChild(document.createTextNode(tocHideText));
var tzString = ((tzRaw >= 0) ? "-" : "+") + ((tzHour < 10) ? "0" : "") + tzHour + ((tzMin < 10) ? "0" : "") + tzMin;
 
if (tz != tzString) {
outerSpan.appendChild(document.createTextNode('['));
var junk = msg.split('$1');
outerSpan.appendChild(toggleLink);
document.write(junk[0] + "UTC" + tzString + junk[1]);
outerSpan.appendChild(document.createTextNode(']'));
 
linkHolder.appendChild(document.createTextNode(' '));
linkHolder.appendChild(outerSpan);
 
var cookiePos = document.cookie.indexOf("hidetoc=");
if (cookiePos > -1 && document.cookie.charAt(cookiePos + 8) == 1) {
toggleToc();
}
}
}
}
}


function unhidetzbutton() {
function changeText(el, newText) {
var tzb = document.getElementById('guesstimezonebutton');
// Safari work around
if (tzb) {
if (el.innerText) {
tzb.style.display = 'inline';
el.innerText = newText;
} else if (el.firstChild && el.firstChild.nodeValue) {
el.firstChild.nodeValue = newText;
}
}
}
}


// in [-]HH:MM format...
function toggleToc() {
// won't yet work with non-even tzs
var toc = document.getElementById('toc').getElementsByTagName('ul')[0];
function fetchTimezone() {
var toggleLink = document.getElementById('togglelink');
// FIXME: work around Safari bug
var localclock = new Date();
// returns negative offset from GMT in minutes
var tzRaw = localclock.getTimezoneOffset();
var tzHour = Math.floor( Math.abs(tzRaw) / 60);
var tzMin = Math.abs(tzRaw) % 60;
var tzString = ((tzRaw >= 0) ? "-" : "") + ((tzHour < 10) ? "0" : "") + tzHour +
":" + ((tzMin < 10) ? "0" : "") + tzMin;
return tzString;
}


function guessTimezone(box) {
if (toc && toggleLink && toc.style.display == 'none') {
document.getElementsByName("wpHourDiff")[0].value = fetchTimezone();
changeText(toggleLink, tocHideText);
toc.style.display = 'block';
document.cookie = "hidetoc=0";
} else {
changeText(toggleLink, tocShowText);
toc.style.display = 'none';
document.cookie = "hidetoc=1";
}
}
}


function showTocToggle() {
function escapeQuotes(text) {
if (document.createTextNode) {
var re = new RegExp("'","g");
// Uses DOM calls to avoid document.write + XHTML issues
text = text.replace(re,"\\'");
re = new RegExp("\\n","g");
text = text.replace(re,"\\n");
return escapeQuotesHTML(text);
}


var linkHolder = document.getElementById('toctitle');
function escapeQuotesHTML(text) {
if (!linkHolder) {
var re = new RegExp('&',"g");
return;
text = text.replace(re,"&amp;");
}
re = new RegExp('"',"g");
text = text.replace(re,"&quot;");
re = new RegExp('<',"g");
text = text.replace(re,"&lt;");
re = new RegExp('>',"g");
text = text.replace(re,"&gt;");
return text;
}


var outerSpan = document.createElement('span');
// apply tagOpen/tagClose to selection in textarea,
outerSpan.className = 'toctoggle';
// use sampleText instead of selection if there is none
function insertTags(tagOpen, tagClose, sampleText) {
var txtarea;
if (document.editform) {
txtarea = document.editform.wpTextbox1;
} else {
// some alternate form? take the first one we can find
var areas = document.getElementsByTagName('textarea');
txtarea = areas[0];
}
var selText, isSample = false;


var toggleLink = document.createElement('a');
if (document.selection  && document.selection.createRange) { // IE/Opera
toggleLink.id = 'togglelink';
toggleLink.className = 'internal';
toggleLink.href = 'javascript:toggleToc()';
toggleLink.appendChild(document.createTextNode(tocHideText));


outerSpan.appendChild(document.createTextNode('['));
//save window scroll position
outerSpan.appendChild(toggleLink);
if (document.documentElement && document.documentElement.scrollTop)
outerSpan.appendChild(document.createTextNode(']'));
var winScroll = document.documentElement.scrollTop
 
else if (document.body)
linkHolder.appendChild(document.createTextNode(' '));
var winScroll = document.body.scrollTop;
linkHolder.appendChild(outerSpan);
//get current selection 
 
txtarea.focus();
var cookiePos = document.cookie.indexOf("hidetoc=");
var range = document.selection.createRange();
if (cookiePos > -1 && document.cookie.charAt(cookiePos + 8) == 1) {
selText = range.text;
toggleToc();
//insert tags
}
checkSelectedText();
}
range.text = tagOpen + selText + tagClose;
}
//mark sample text as selected
if (isSample && range.moveStart) {
if (window.opera)
tagClose = tagClose.replace(/\n/g,'');
range.moveStart('character', - tagClose.length - selText.length);  
range.moveEnd('character', - tagClose.length);  
}
range.select();  
//restore window scroll position
if (document.documentElement && document.documentElement.scrollTop)
document.documentElement.scrollTop = winScroll
else if (document.body)
document.body.scrollTop = winScroll;


function changeText(el, newText) {
} else if (txtarea.selectionStart || txtarea.selectionStart == '0') { // Mozilla
// Safari work around
if (el.innerText) {
el.innerText = newText;
} else if (el.firstChild && el.firstChild.nodeValue) {
el.firstChild.nodeValue = newText;
}
}


function toggleToc() {
//save textarea scroll position
var toc = document.getElementById('toc').getElementsByTagName('ul')[0];
var textScroll = txtarea.scrollTop;
var toggleLink = document.getElementById('togglelink');
//get current selection
txtarea.focus();
var startPos = txtarea.selectionStart;
var endPos = txtarea.selectionEnd;
selText = txtarea.value.substring(startPos, endPos);
//insert tags
checkSelectedText();
txtarea.value = txtarea.value.substring(0, startPos)
+ tagOpen + selText + tagClose
+ txtarea.value.substring(endPos, txtarea.value.length);
//set new selection
if (isSample) {
txtarea.selectionStart = startPos + tagOpen.length;
txtarea.selectionEnd = startPos + tagOpen.length + selText.length;
} else {
txtarea.selectionStart = startPos + tagOpen.length + selText.length + tagClose.length;
txtarea.selectionEnd = txtarea.selectionStart;
}
//restore textarea scroll position
txtarea.scrollTop = textScroll;
}


if (toc && toggleLink && toc.style.display == 'none') {
function checkSelectedText(){
changeText(toggleLink, tocHideText);
if (!selText) {
toc.style.display = 'block';
selText = sampleText;
document.cookie = "hidetoc=0";
isSample = true;
} else {
} else if (selText.charAt(selText.length - 1) == ' ') { //exclude ending space char
changeText(toggleLink, tocShowText);
selText = selText.substring(0, selText.length - 1);
toc.style.display = 'none';
tagClose += ' '
document.cookie = "hidetoc=1";
}
}
}
}
}


function escapeQuotes(text) {
var re = new RegExp("'","g");
text = text.replace(re,"\\'");
re = new RegExp("\\n","g");
text = text.replace(re,"\\n");
return escapeQuotesHTML(text);
}


function escapeQuotesHTML(text) {
/**
var re = new RegExp('&',"g");
* Set the accesskey prefix based on browser detection.
text = text.replace(re,"&amp;");
*/
re = new RegExp('"',"g");
var tooltipAccessKeyPrefix = 'alt-';
text = text.replace(re,"&quot;");
if (is_opera) {
re = new RegExp('<',"g");
tooltipAccessKeyPrefix = 'shift-esc-';
text = text.replace(re,"&lt;");
} else if (is_safari
re = new RegExp('>',"g");
  || navigator.userAgent.toLowerCase().indexOf('mac') != -1
text = text.replace(re,"&gt;");
  || navigator.userAgent.toLowerCase().indexOf('konqueror') != -1 ) {
return text;
tooltipAccessKeyPrefix = 'ctrl-';
} else if (is_ff2_x11 || is_ff2_win) {
tooltipAccessKeyPrefix = 'alt-shift-';
}
}
var tooltipAccessKeyRegexp = /\[(ctrl-)?(alt-)?(shift-)?(esc-)?.\]$/;


// apply tagOpen/tagClose to selection in textarea,
/**
// use sampleText instead of selection if there is none
* Add the appropriate prefix to the accesskey shown in the tooltip.
function insertTags(tagOpen, tagClose, sampleText) {
* If the nodeList parameter is given, only those nodes are updated;
var txtarea;
* otherwise, all the nodes that will probably have accesskeys by
if (document.editform) {
* default are updated.
txtarea = document.editform.wpTextbox1;
*
} else {
* @param Array nodeList -- list of elements to update
// some alternate form? take the first one we can find
*/
var areas = document.getElementsByTagName('textarea');
function updateTooltipAccessKeys( nodeList ) {
txtarea = areas[0];
if ( !nodeList ) {
// skins without a "column-one" element don't seem to have links with accesskeys either
var columnOne = document.getElementById("column-one");
if ( columnOne )
updateTooltipAccessKeys( columnOne.getElementsByTagName("a") );
// these are rare enough that no such optimization is needed
updateTooltipAccessKeys( document.getElementsByTagName("input") );
updateTooltipAccessKeys( document.getElementsByTagName("label") );
return;
}
}
var selText, isSample = false;


if (document.selection  && document.selection.createRange) { // IE/Opera
for ( var i = 0; i < nodeList.length; i++ ) {
var element = nodeList[i];
var tip = element.getAttribute("title");
var key = element.getAttribute("accesskey");
if ( key && tooltipAccessKeyRegexp.exec(tip) ) {
tip = tip.replace(tooltipAccessKeyRegexp,
  "["+tooltipAccessKeyPrefix+key+"]");
element.setAttribute("title", tip );
}
}
}


//save window scroll position
/**
if (document.documentElement && document.documentElement.scrollTop)
* Add a link to one of the portlet menus on the page, including:
var winScroll = document.documentElement.scrollTop
*
else if (document.body)
* p-cactions: Content actions (shown as tabs above the main content in Monobook)
var winScroll = document.body.scrollTop;
* p-personal: Personal tools (shown at the top right of the page in Monobook)
//get current selection  
* p-navigation: Navigation
txtarea.focus();
* p-tb: Toolbox
var range = document.selection.createRange();
*
selText = range.text;
* This function exists for the convenience of custom JS authors. All
//insert tags
* but the first three parameters are optional, though providing at
checkSelectedText();
* least an id and a tooltip is recommended.
range.text = tagOpen + selText + tagClose;
  *
//mark sample text as selected
* By default the new link will be added to the end of the list. To
if (isSample && range.moveStart) {
* add the link before a given existing item, pass the DOM node of
if (window.opera)
* that item (easily obtained with document.getElementById()) as the
tagClose = tagClose.replace(/\n/g,'');
* nextnode parameter; to add the link _after_ an existing item, pass
range.moveStart('character', - tagClose.length - selText.length);
* the node's nextSibling instead.
range.moveEnd('character', - tagClose.length);  
*
}
* @param String portlet -- id of the target portlet ("p-cactions", "p-personal", "p-navigation" or "p-tb")
range.select();  
* @param String href -- link URL
//restore window scroll position
* @param String text -- link text (will be automatically lowercased by CSS for p-cactions in Monobook)
if (document.documentElement && document.documentElement.scrollTop)
* @param String id -- id of the new item, should be unique and preferably have the appropriate prefix ("ca-", "pt-", "n-" or "t-")
document.documentElement.scrollTop = winScroll
* @param String tooltip -- text to show when hovering over the link, without accesskey suffix
else if (document.body)
* @param String accesskey -- accesskey to activate this link (one character, try to avoid conflicts)
document.body.scrollTop = winScroll;
* @param Node nextnode -- the DOM node before which the new item should be added, should be another item in the same list
*
* @return Node -- the DOM node of the new item (an LI element) or null
*/
function addPortletLink(portlet, href, text, id, tooltip, accesskey, nextnode) {
var node = document.getElementById(portlet);
if ( !node ) return null;
node = node.getElementsByTagName( "ul" )[0];
if ( !node ) return null;
 
var link = document.createElement( "a" );
link.appendChild( document.createTextNode( text ) );
link.href = href;


} else if (txtarea.selectionStart || txtarea.selectionStart == '0') { // Mozilla
var item = document.createElement( "li" );
item.appendChild( link );
if ( id ) item.id = id;


//save textarea scroll position
if ( accesskey ) {
var textScroll = txtarea.scrollTop;
link.setAttribute( "accesskey", accesskey );
//get current selection
tooltip += " ["+accesskey+"]";
txtarea.focus();
}
var startPos = txtarea.selectionStart;
if ( tooltip ) {
var endPos = txtarea.selectionEnd;
link.setAttribute( "title", tooltip );
selText = txtarea.value.substring(startPos, endPos);
}
//insert tags
if ( accesskey && tooltip ) {
checkSelectedText();
updateTooltipAccessKeys( new Array( link ) );
txtarea.value = txtarea.value.substring(0, startPos)
}
+ tagOpen + selText + tagClose
 
+ txtarea.value.substring(endPos, txtarea.value.length);
if ( nextnode && nextnode.parentNode == node )
//set new selection
node.insertBefore( item, nextnode );
if (isSample) {
else
txtarea.selectionStart = startPos + tagOpen.length;
node.appendChild( item );  // IE compatibility (?)
txtarea.selectionEnd = startPos + tagOpen.length + selText.length;
} else {
txtarea.selectionStart = startPos + tagOpen.length + selText.length + tagClose.length;
txtarea.selectionEnd = txtarea.selectionStart;
}
//restore textarea scroll position
txtarea.scrollTop = textScroll;
}  
 
function checkSelectedText(){
if (!selText) {
selText = sampleText;
isSample = true;
} else if (selText.charAt(selText.length - 1) == ' ') { //exclude ending space char
selText = selText.substring(0, selText.length - 1);
tagClose += ' '
}
}


return item;
}
}




/**
/**
  * Set the accesskey prefix based on browser detection.
  * Set up accesskeys/tooltips from the deprecated ta arrayIf doId
  */
  * is specified, only set up for that idNote that this function is
var tooltipAccessKeyPrefix = 'alt-';
  * deprecated and will not be supported indefinitely -- use
if (is_opera) {
  * updateTooltipAccessKey() instead.
tooltipAccessKeyPrefix = 'shift-esc-';
} else if (is_safari
  || navigator.userAgent.toLowerCase().indexOf('mac') != -1
  || navigator.userAgent.toLowerCase().indexOf('konqueror') != -1 ) {
tooltipAccessKeyPrefix = 'ctrl-';
} else if (is_ff2_x11 || is_ff2_win) {
tooltipAccessKeyPrefix = 'alt-shift-';
}
var tooltipAccessKeyRegexp = /\[(ctrl-)?(alt-)?(shift-)?(esc-)?.\]$/;
 
/**
  * Add the appropriate prefix to the accesskey shown in the tooltip.
  * If the nodeList parameter is given, only those nodes are updated;
  * otherwise, all the nodes that will probably have accesskeys by
  * default are updated.
  *
  *
  * @param Array nodeList -- list of elements to update
  * @param mixed doId string or null
  */
  */
function updateTooltipAccessKeys( nodeList ) {
function akeytt( doId ) {
if ( !nodeList ) {
// A lot of user scripts (and some of the code below) break if
// skins without a "column-one" element don't seem to have links with accesskeys either
// ta isn't defined, so we make sure it is. Explictly using
var columnOne = document.getElementById("column-one");
// window.ta avoids a "ta is not defined" error.
if ( columnOne )
if (!window.ta) window.ta = new Array;
updateTooltipAccessKeys( columnOne.getElementsByTagName("a") );
// these are rare enough that no such optimization is needed
updateTooltipAccessKeys( document.getElementsByTagName("input") );
updateTooltipAccessKeys( document.getElementsByTagName("label") );
return;
}


for ( var i = 0; i < nodeList.length; i++ ) {
// Make a local, possibly restricted, copy to avoid clobbering
var element = nodeList[i];
// the original.
var tip = element.getAttribute("title");
var ta;
var key = element.getAttribute("accesskey");
if ( doId ) {
if ( key && tooltipAccessKeyRegexp.exec(tip) ) {
ta = [doId];
tip = tip.replace(tooltipAccessKeyRegexp,
} else {
  "["+tooltipAccessKeyPrefix+key+"]");
ta = window.ta;
element.setAttribute("title", tip );
}
}
}
}


/**
// Now deal with evil deprecated ta
* Add a link to one of the portlet menus on the page, including:
var watchCheckboxExists = document.getElementById( 'wpWatchthis' ) ? true : false;
*
for (var id in ta) {
* p-cactions: Content actions (shown as tabs above the main content in Monobook)
var n = document.getElementById(id);
* p-personal: Personal tools (shown at the top right of the page in Monobook)
if (n) {
* p-navigation: Navigation
var a = null;
* p-tb: Toolbox
var ak = '';
*
// Are we putting accesskey in it
* This function exists for the convenience of custom JS authors.  All
if (ta[id][0].length > 0) {
* but the first three parameters are optional, though providing at
// Is this object a object? If not assume it's the next child.
* least an id and a tooltip is recommended.
 
*
if (n.nodeName.toLowerCase() == "a") {
* By default the new link will be added to the end of the list. To
a = n;
* add the link before a given existing item, pass the DOM node of
} else {
* that item (easily obtained with document.getElementById()) as the
a = n.childNodes[0];
* nextnode parameter; to add the link _after_ an existing item, pass
}
* the node's nextSibling instead.
// Don't add an accesskey for the watch tab if the watch
*
// checkbox is also available.
* @param String portlet -- id of the target portlet ("p-cactions", "p-personal", "p-navigation" or "p-tb")
if (a && ((id != 'ca-watch' && id != 'ca-unwatch') || !watchCheckboxExists)) {
* @param String href -- link URL
a.accessKey = ta[id][0];
* @param String text -- link text (will be automatically lowercased by CSS for p-cactions in Monobook)
ak = ' ['+tooltipAccessKeyPrefix+ta[id][0]+']';
* @param String id -- id of the new item, should be unique and preferably have the appropriate prefix ("ca-", "pt-", "n-" or "t-")
}
* @param String tooltip -- text to show when hovering over the link, without accesskey suffix
} else {
* @param String accesskey -- accesskey to activate this link (one character, try to avoid conflicts)
// We don't care what type the object is when assigning tooltip
* @param Node nextnode -- the DOM node before which the new item should be added, should be another item in the same list
a = n;
*
ak = '';
* @return Node -- the DOM node of the new item (an LI element) or null
}
*/
function addPortletLink(portlet, href, text, id, tooltip, accesskey, nextnode) {
var node = document.getElementById(portlet);
if ( !node ) return null;
node = node.getElementsByTagName( "ul" )[0];
if ( !node ) return null;


var link = document.createElement( "a" );
if (a) {
link.appendChild( document.createTextNode( text ) );
a.title = ta[id][1]+ak;
link.href = href;
}
}
}
}


var item = document.createElement( "li" );
function setupRightClickEdit() {
item.appendChild( link );
if (document.getElementsByTagName) {
if ( id ) item.id = id;
var spans = document.getElementsByTagName('span');
 
for (var i = 0; i < spans.length; i++) {
if ( accesskey ) {
var el = spans[i];
link.setAttribute( "accesskey", accesskey );
if(el.className == 'editsection') {
tooltip += " ["+accesskey+"]";
addRightClickEditHandler(el);
}
}
if ( tooltip ) {
}
link.setAttribute( "title", tooltip );
}
if ( accesskey && tooltip ) {
updateTooltipAccessKeys( new Array( link ) );
}
}
if ( nextnode && nextnode.parentNode == node )
node.insertBefore( item, nextnode );
else
node.appendChild( item );  // IE compatibility (?)
return item;
}
}


 
function addRightClickEditHandler(el) {
/**
for (var i = 0; i < el.childNodes.length; i++) {
* Set up accesskeys/tooltips from the deprecated ta array. If doId
var link = el.childNodes[i];
* is specified, only set up for that id. Note that this function is
if (link.nodeType == 1 && link.nodeName.toLowerCase() == 'a') {
* deprecated and will not be supported indefinitely -- use
var editHref = link.getAttribute('href');
* updateTooltipAccessKey() instead.
// find the enclosing (parent) header
*
var prev = el.parentNode;
* @param mixed doId string or null
if (prev && prev.nodeType == 1 &&
*/
prev.nodeName.match(/^[Hh][1-6]$/)) {
function akeytt( doId ) {
prev.oncontextmenu = function(e) {
// A lot of user scripts (and some of the code below) break if
if (!e) { e = window.event; }
// ta isn't defined, so we make sure it is. Explictly using
// e is now the event in all browsers
// window.ta avoids a "ta is not defined" error.
var targ;
if (!window.ta) window.ta = new Array;
if (e.target) { targ = e.target; }
 
else if (e.srcElement) { targ = e.srcElement; }
// Make a local, possibly restricted, copy to avoid clobbering
if (targ.nodeType == 3) { // defeat Safari bug
// the original.
targ = targ.parentNode;
var ta;
}
if ( doId ) {
// targ is now the target element
ta = [doId];
 
} else {
// We don't want to deprive the noble reader of a context menu
ta = window.ta;
// for the section edit link, do we?  (Might want to extend this
// to all <a>'s?)
if (targ.nodeName.toLowerCase() != 'a'
|| targ.parentNode.className != 'editsection') {
document.location = editHref;
return false;
}
return true;
};
}
}
}
}
}


// Now deal with evil deprecated ta
var checkboxes;
var watchCheckboxExists = document.getElementById( 'wpWatchthis' ) ? true : false;
var lastCheckbox;
for (var id in ta) {
 
var n = document.getElementById(id);
function setupCheckboxShiftClick() {
if (n) {
checkboxes = [];
var a = null;
lastCheckbox = null;
var ak = '';
var inputs = document.getElementsByTagName('input');
// Are we putting accesskey in it
addCheckboxClickHandlers(inputs);
if (ta[id][0].length > 0) {
}
// Is this object a object? If not assume it's the next child.


if (n.nodeName.toLowerCase() == "a") {
function addCheckboxClickHandlers(inputs, start) {
a = n;
if ( !start) start = 0;
} else {
 
a = n.childNodes[0];
var finish = start + 250;
}
if ( finish > inputs.length )
// Don't add an accesskey for the watch tab if the watch
finish = inputs.length;
// checkbox is also available.
if (a && ((id != 'ca-watch' && id != 'ca-unwatch') || !watchCheckboxExists)) {
a.accessKey = ta[id][0];
ak = ' ['+tooltipAccessKeyPrefix+ta[id][0]+']';
}
} else {
// We don't care what type the object is when assigning tooltip
a = n;
ak = '';
}


if (a) {
for ( var i = start; i < finish; i++ ) {
a.title = ta[id][1]+ak;
var cb = inputs[i];
}
if ( !cb.type || cb.type.toLowerCase() != 'checkbox' )
}
continue;
var end = checkboxes.length;
checkboxes[end] = cb;
cb.index = end;
cb.onclick = checkboxClickHandler;
}
}
}


function setupRightClickEdit() {
if ( finish < inputs.length ) {
if (document.getElementsByTagName) {
setTimeout( function () {
var spans = document.getElementsByTagName('span');
addCheckboxClickHandlers(inputs, finish);
for (var i = 0; i < spans.length; i++) {
}, 200 );
var el = spans[i];
if(el.className == 'editsection') {
addRightClickEditHandler(el);
}
}
}
}
}
}


function addRightClickEditHandler(el) {
function checkboxClickHandler(e) {
for (var i = 0; i < el.childNodes.length; i++) {
if (typeof e == 'undefined') {
var link = el.childNodes[i];
e = window.event;
if (link.nodeType == 1 && link.nodeName.toLowerCase() == 'a') {
}
var editHref = link.getAttribute('href');
if ( !e.shiftKey || lastCheckbox === null ) {
// find the enclosing (parent) header
lastCheckbox = this.index;
var prev = el.parentNode;
return true;
if (prev && prev.nodeType == 1 &&
prev.nodeName.match(/^[Hh][1-6]$/)) {
prev.oncontextmenu = function(e) {
if (!e) { e = window.event; }
// e is now the event in all browsers
var targ;
if (e.target) { targ = e.target; }
else if (e.srcElement) { targ = e.srcElement; }
if (targ.nodeType == 3) { // defeat Safari bug
targ = targ.parentNode;
}
// targ is now the target element
 
// We don't want to deprive the noble reader of a context menu
// for the section edit link, do we?  (Might want to extend this
// to all <a>'s?)
if (targ.nodeName.toLowerCase() != 'a'
|| targ.parentNode.className != 'editsection') {
document.location = editHref;
return false;
}
return true;
};
}
}
}
}
var endState = this.checked;
var start, finish;
if ( this.index < lastCheckbox ) {
start = this.index + 1;
finish = lastCheckbox;
} else {
start = lastCheckbox;
finish = this.index - 1;
}
for (var i = start; i <= finish; ++i ) {
checkboxes[i].checked = endState;
}
lastCheckbox = this.index;
return true;
}
}


var checkboxes;
function toggle_element_activation(ida,idb) {
var lastCheckbox;
if (!document.getElementById) {
return;
}
document.getElementById(ida).disabled=true;
document.getElementById(idb).disabled=false;
}


function setupCheckboxShiftClick() {
function toggle_element_check(ida,idb) {
checkboxes = [];
if (!document.getElementById) {
lastCheckbox = null;
return;
var inputs = document.getElementsByTagName('input');
}
addCheckboxClickHandlers(inputs);
document.getElementById(ida).checked=true;
document.getElementById(idb).checked=false;
}
}


function addCheckboxClickHandlers(inputs, start) {
/**
if ( !start) start = 0;
* Restore the edit box scroll state following a preview operation,
* and set up a form submission handler to remember this state
*/
function scrollEditBox() {
var editBox = document.getElementById( 'wpTextbox1' );
var scrollTop = document.getElementById( 'wpScrolltop' );
var editForm = document.getElementById( 'editform' );
if( editBox && scrollTop ) {
if( scrollTop.value )
editBox.scrollTop = scrollTop.value;
addHandler( editForm, 'submit', function() {
document.getElementById( 'wpScrolltop' ).value = document.getElementById( 'wpTextbox1' ).scrollTop;
} );
}
}
hookEvent( 'load', scrollEditBox );


var finish = start + 250;
var allmessages_nodelist = false;
if ( finish > inputs.length )
var allmessages_modified = false;
finish = inputs.length;
var allmessages_timeout = false;
var allmessages_running = false;


for ( var i = start; i < finish; i++ ) {
function allmessagesmodified() {
var cb = inputs[i];
allmessages_modified = !allmessages_modified;
if ( !cb.type || cb.type.toLowerCase() != 'checkbox' )
allmessagesfilter();
continue;
var end = checkboxes.length;
checkboxes[end] = cb;
cb.index = end;
cb.onclick = checkboxClickHandler;
}
 
if ( finish < inputs.length ) {
setTimeout( function () {
addCheckboxClickHandlers(inputs, finish);
}, 200 );
}
}
}


function checkboxClickHandler(e) {
function allmessagesfilter() {
if (typeof e == 'undefined') {
if ( allmessages_timeout )
e = window.event;
window.clearTimeout( allmessages_timeout );
}
if ( !e.shiftKey || lastCheckbox === null ) {
lastCheckbox = this.index;
return true;
}
var endState = this.checked;
var start, finish;
if ( this.index < lastCheckbox ) {
start = this.index + 1;
finish = lastCheckbox;
} else {
start = lastCheckbox;
finish = this.index - 1;
}
for (var i = start; i <= finish; ++i ) {
checkboxes[i].checked = endState;
}
lastCheckbox = this.index;
return true;
}


function toggle_element_activation(ida,idb) {
if ( !allmessages_running )
if (!document.getElementById) {
allmessages_timeout = window.setTimeout( 'allmessagesfilter_do();', 500 );
return;
}
document.getElementById(ida).disabled=true;
document.getElementById(idb).disabled=false;
}
}


function toggle_element_check(ida,idb) {
function allmessagesfilter_do() {
if (!document.getElementById) {
if ( !allmessages_nodelist )
return;
return;
}
document.getElementById(ida).checked=true;
document.getElementById(idb).checked=false;
}


/**
var text = document.getElementById('allmessagesinput').value;
* Restore the edit box scroll state following a preview operation,
var nodef = allmessages_modified;
* and set up a form submission handler to remember this state
 
*/
allmessages_running = true;
function scrollEditBox() {
 
var editBox = document.getElementById( 'wpTextbox1' );
for ( var name in allmessages_nodelist ) {
var scrollTop = document.getElementById( 'wpScrolltop' );
var nodes = allmessages_nodelist[name];
var editForm = document.getElementById( 'editform' );
var display = ( name.indexOf( text ) == -1 ? 'none' : '' );
if( editBox && scrollTop ) {
 
if( scrollTop.value )
for ( var i = 0; i < nodes.length; i++)
editBox.scrollTop = scrollTop.value;
nodes[i].style.display =
addHandler( editForm, 'submit', function() {
( nodes[i].className == "def" && nodef
document.getElementById( 'wpScrolltop' ).value = document.getElementById( 'wpTextbox1' ).scrollTop;
  ? 'none' : display );
} );
}
}
if ( text != document.getElementById('allmessagesinput').value ||
    nodef != allmessages_modified )
allmessagesfilter_do();  // repeat
allmessages_running = false;
}
}
hookEvent( 'load', scrollEditBox );


var allmessages_nodelist = false;
function allmessagesfilter_init() {
var allmessages_modified = false;
if ( allmessages_nodelist )
var allmessages_timeout = false;
return;
var allmessages_running = false;


function allmessagesmodified() {
var nodelist = new Array();
allmessages_modified = !allmessages_modified;
var templist = new Array();
allmessagesfilter();
}


function allmessagesfilter() {
var table = document.getElementById('allmessagestable');
if ( allmessages_timeout )
if ( !table ) return;
window.clearTimeout( allmessages_timeout );


if ( !allmessages_running )
var rows = document.getElementsByTagName('tr');
allmessages_timeout = window.setTimeout( 'allmessagesfilter_do();', 500 );
for ( var i = 0; i < rows.length; i++ ) {
}
var id = rows[i].getAttribute('id')
if ( id && id.substring(0,16) != 'sp-allmessages-r' ) continue;
templist[ id ] = rows[i];
}


function allmessagesfilter_do() {
var spans = table.getElementsByTagName('span');
if ( !allmessages_nodelist )
for ( var i = 0; i < spans.length; i++ ) {
return;
var id = spans[i].getAttribute('id')
if ( id && id.substring(0,17) != 'sp-allmessages-i-' ) continue;
if ( !spans[i].firstChild || spans[i].firstChild.nodeType != 3 ) continue;


var text = document.getElementById('allmessagesinput').value;
var nodes = new Array();
var nodef = allmessages_modified;
var row1 = templist[ id.replace('i', 'r1') ];
var row2 = templist[ id.replace('i', 'r2') ];


allmessages_running = true;
if ( row1 ) nodes[nodes.length] = row1;
if ( row2 ) nodes[nodes.length] = row2;
nodelist[ spans[i].firstChild.nodeValue ] = nodes;
}


for ( var name in allmessages_nodelist ) {
var k = document.getElementById('allmessagesfilter');
var nodes = allmessages_nodelist[name];
if (k) { k.style.display = ''; }
var display = ( name.indexOf( text ) == -1 ? 'none' : '' );


for ( var i = 0; i < nodes.length; i++)
allmessages_nodelist = nodelist;
nodes[i].style.display =
( nodes[i].className == "def" && nodef
  ? 'none' : display );
}
 
if ( text != document.getElementById('allmessagesinput').value ||
    nodef != allmessages_modified )
allmessagesfilter_do();  // repeat
 
allmessages_running = false;
}
}


function allmessagesfilter_init() {
hookEvent( "load", allmessagesfilter_init );
if ( allmessages_nodelist )
return;


var nodelist = new Array();
/*
var templist = new Array();
Written by Jonathan Snook, http://www.snook.ca/jonathan
 
Add-ons by Robert Nyman, http://www.robertnyman.com
var table = document.getElementById('allmessagestable');
Author says "The credit comment is all it takes, no license. Go crazy with it!:-)"
if ( !table ) return;
From http://www.robertnyman.com/2005/11/07/the-ultimate-getelementsbyclassname/
 
*/
var rows = document.getElementsByTagName('tr');
function getElementsByClassName(oElm, strTagName, oClassNames){
for ( var i = 0; i < rows.length; i++ ) {
var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
var id = rows[i].getAttribute('id')
var arrReturnElements = new Array();
if ( id && id.substring(0,16) != 'sp-allmessages-r' ) continue;
var arrRegExpClassNames = new Array();
templist[ id ] = rows[i];
if(typeof oClassNames == "object"){
for(var i=0; i<oClassNames.length; i++){
arrRegExpClassNames[arrRegExpClassNames.length] =
new RegExp("(^|\\s)" + oClassNames[i].replace(/\-/g, "\\-") + "(\\s|$)");
}
}
else{
arrRegExpClassNames[arrRegExpClassNames.length] =
new RegExp("(^|\\s)" + oClassNames.replace(/\-/g, "\\-") + "(\\s|$)");
}
}
 
var oElement;
var spans = table.getElementsByTagName('span');
var bMatchesAll;
for ( var i = 0; i < spans.length; i++ ) {
for(var j=0; j<arrElements.length; j++){
var id = spans[i].getAttribute('id')
oElement = arrElements[j];
if ( id && id.substring(0,17) != 'sp-allmessages-i-' ) continue;
bMatchesAll = true;
if ( !spans[i].firstChild || spans[i].firstChild.nodeType != 3 ) continue;
for(var k=0; k<arrRegExpClassNames.length; k++){
 
if(!arrRegExpClassNames[k].test(oElement.className)){
var nodes = new Array();
bMatchesAll = false;
var row1 = templist[ id.replace('i', 'r1') ];
break;
var row2 = templist[ id.replace('i', 'r2') ];
}
 
}
if ( row1 ) nodes[nodes.length] = row1;
if(bMatchesAll){
if ( row2 ) nodes[nodes.length] = row2;
arrReturnElements[arrReturnElements.length] = oElement;
nodelist[ spans[i].firstChild.nodeValue ] = nodes;
}
}
return (arrReturnElements)
}
 
function redirectToFragment(fragment) {
var match = navigator.userAgent.match(/AppleWebKit\/(\d+)/);
if (match) {
var webKitVersion = parseInt(match[1]);
if (webKitVersion < 420) {
// Released Safari w/ WebKit 418.9.1 messes up horribly
// Nightlies of 420+ are ok
return;
}
}
if (is_gecko) {
// Mozilla needs to wait until after load, otherwise the window doesn't scroll
addOnloadHook(function () {
if (window.location.hash == "")
window.location.hash = fragment;
});
} else {
if (window.location.hash == "")
window.location.hash = fragment;
}
}
var k = document.getElementById('allmessagesfilter');
if (k) { k.style.display = ''; }
allmessages_nodelist = nodelist;
}
}


hookEvent( "load", allmessagesfilter_init );


/*
/*
Written by Jonathan Snook, http://www.snook.ca/jonathan
* Table sorting script  by Joost de Valk, check it out at http://www.joostdevalk.nl/code/sortable-table/.
Add-ons by Robert Nyman, http://www.robertnyman.com
* Based on a script from http://www.kryogenix.org/code/browser/sorttable/.
Author says "The credit comment is all it takes, no license. Go crazy with it!:-)"
* Distributed under the MIT license: http://www.kryogenix.org/code/browser/licence.html .
From http://www.robertnyman.com/2005/11/07/the-ultimate-getelementsbyclassname/
*
*/
* Copyright (c) 1997-2006 Stuart Langridge, Joost de Valk.
function getElementsByClassName(oElm, strTagName, oClassNames){
*
var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
* @todo don't break on colspans/rowspans (bug 8028)
var arrReturnElements = new Array();
* @todo language-specific digit grouping/decimals (bug 8063)
var arrRegExpClassNames = new Array();
* @todo support all accepted date formats (bug 8226)
if(typeof oClassNames == "object"){
*/
for(var i=0; i<oClassNames.length; i++){
 
arrRegExpClassNames[arrRegExpClassNames.length] =
var ts_image_path = stylepath+"/common/images/";
new RegExp("(^|\\s)" + oClassNames[i].replace(/\-/g, "\\-") + "(\\s|$)");
var ts_image_up = "sort_up.gif";
}
var ts_image_down = "sort_down.gif";
}
var ts_image_none = "sort_none.gif";
else{
var ts_europeandate = wgContentLanguage != "en"; // The non-American-inclined can change to "true"
arrRegExpClassNames[arrRegExpClassNames.length] =
var ts_alternate_row_colors = true;
new RegExp("(^|\\s)" + oClassNames.replace(/\-/g, "\\-") + "(\\s|$)");
var SORT_COLUMN_INDEX;
}
var oElement;
var bMatchesAll;
for(var j=0; j<arrElements.length; j++){
oElement = arrElements[j];
bMatchesAll = true;
for(var k=0; k<arrRegExpClassNames.length; k++){
if(!arrRegExpClassNames[k].test(oElement.className)){
bMatchesAll = false;
break;
}
}
if(bMatchesAll){
arrReturnElements[arrReturnElements.length] = oElement;
}
}
return (arrReturnElements)
}


function redirectToFragment(fragment) {
function sortables_init() {
var match = navigator.userAgent.match(/AppleWebKit\/(\d+)/);
var idnum = 0;
if (match) {
// Find all tables with class sortable and make them sortable
var webKitVersion = parseInt(match[1]);
var tables = getElementsByClassName(document, "table", "sortable");
if (webKitVersion < 420) {
for (var ti = 0; ti < tables.length ; ti++) {
// Released Safari w/ WebKit 418.9.1 messes up horribly
if (!tables[ti].id) {
// Nightlies of 420+ are ok
tables[ti].setAttribute('id','sortable_table_id_'+idnum);
return;
++idnum;
}
}
}
ts_makeSortable(tables[ti]);
if (is_gecko) {
// Mozilla needs to wait until after load, otherwise the window doesn't scroll
addOnloadHook(function () {
if (window.location.hash == "")
window.location.hash = fragment;
});
} else {
if (window.location.hash == "")
window.location.hash = fragment;
}
}
}
}


function ts_makeSortable(table) {
var firstRow;
if (table.rows && table.rows.length > 0) {
if (table.tHead && table.tHead.rows.length > 0) {
firstRow = table.tHead.rows[table.tHead.rows.length-1];
} else {
firstRow = table.rows[0];
}
}
if (!firstRow) return;


/*
// We have a first row: assume it's the header, and make its contents clickable links
* Table sorting script  by Joost de Valk, check it out at http://www.joostdevalk.nl/code/sortable-table/.
for (var i = 0; i < firstRow.cells.length; i++) {
* Based on a script from http://www.kryogenix.org/code/browser/sorttable/.
var cell = firstRow.cells[i];
* Distributed under the MIT license: http://www.kryogenix.org/code/browser/licence.html .
if ((" "+cell.className+" ").indexOf(" unsortable ") == -1) {
*
cell.innerHTML += '&nbsp;&nbsp;<a href="#" class="sortheader" onclick="ts_resortTable(this);return false;"><span class="sortarrow"><img src="'+ ts_image_path + ts_image_none + '" alt="&darr;"/></span></a>';
* Copyright (c) 1997-2006 Stuart Langridge, Joost de Valk.
*
* @todo don't break on colspans/rowspans (bug 8028)
* @todo language-specific digit grouping/decimals (bug 8063)
* @todo support all accepted date formats (bug 8226)
*/
 
var ts_image_path = stylepath+"/common/images/";
var ts_image_up = "sort_up.gif";
var ts_image_down = "sort_down.gif";
var ts_image_none = "sort_none.gif";
var ts_europeandate = wgContentLanguage != "en"; // The non-American-inclined can change to "true"
var ts_alternate_row_colors = true;
var SORT_COLUMN_INDEX;
 
function sortables_init() {
var idnum = 0;
// Find all tables with class sortable and make them sortable
var tables = getElementsByClassName(document, "table", "sortable");
for (var ti = 0; ti < tables.length ; ti++) {
if (!tables[ti].id) {
tables[ti].setAttribute('id','sortable_table_id_'+idnum);
++idnum;
}
}
ts_makeSortable(tables[ti]);
}
if (ts_alternate_row_colors) {
ts_alternate(table);
}
}
}
}


function ts_makeSortable(table) {
function ts_getInnerText(el) {
var firstRow;
if (typeof el == "string") return el;
if (table.rows && table.rows.length > 0) {
if (typeof el == "undefined") { return el };
if (table.tHead && table.tHead.rows.length > 0) {
if (el.textContent) return el.textContent; // not needed but it is faster
firstRow = table.tHead.rows[table.tHead.rows.length-1];
} else {
firstRow = table.rows[0];
}
}
if (!firstRow) return;
 
// We have a first row: assume it's the header, and make its contents clickable links
for (var i = 0; i < firstRow.cells.length; i++) {
var cell = firstRow.cells[i];
if ((" "+cell.className+" ").indexOf(" unsortable ") == -1) {
cell.innerHTML += '&nbsp;&nbsp;<a href="#" class="sortheader" onclick="ts_resortTable(this);return false;"><span class="sortarrow"><img src="'+ ts_image_path + ts_image_none + '" alt="&darr;"/></span></a>';
}
}
if (ts_alternate_row_colors) {
ts_alternate(table);
}
}
 
function ts_getInnerText(el) {
if (typeof el == "string") return el;
if (typeof el == "undefined") { return el };
if (el.textContent) return el.textContent; // not needed but it is faster
if (el.innerText) return el.innerText;    // IE doesn't have textContent
if (el.innerText) return el.innerText;    // IE doesn't have textContent
var str = "";
var str = "";
Line 1,735: Line 1,782:
  * @param id Identifier string
  * @param id Identifier string
  */
  */
function removeSpinner( id ) {
function removeSpinner( id ) {
var spinner = document.getElementById( "mw-spinner-" + id );
var spinner = document.getElementById( "mw-spinner-" + id );
if( spinner ) {
if( spinner ) {
spinner.parentNode.removeChild( spinner );
spinner.parentNode.removeChild( spinner );
}
}
}
 
 
/**
* Add an event handler to an element
*
* @param Element element Element to add handler to
* @param String attach Event to attach to
* @param callable handler Event handler callback
*/
function addHandler( element, attach, handler ) {
if( window.addEventListener ) {
element.addEventListener( attach, handler, false );
} else if( window.attachEvent ) {
element.attachEvent( 'on' + attach, handler );
}
}
 
/**
* Add a click event handler to an element
*
* @param Element element Element to add handler to
* @param callable handler Event handler callback
*/
function addClickHandler( element, handler ) {
addHandler( element, 'click', handler );
}
 
 
function runOnloadHook() {
// don't run anything below this for non-dom browsers
if (doneOnloadHook || !(document.getElementById && document.getElementsByTagName)) {
return;
}
 
// set this before running any hooks, since any errors below
// might cause the function to terminate prematurely
doneOnloadHook = true;
 
histrowinit();
unhidetzbutton();
//
// prefs.js calls addOnloadHook( tabbedprefs ), so the following call is redundant and causes the tabbedprefs toc to display twice.
//
// tabbedprefs();
updateTooltipAccessKeys( null );
akeytt( null );
scrollEditBox();
setupCheckboxShiftClick();
sortables_init();
 
// Run any added-on functions
for (var i = 0; i < onloadFuncts.length; i++) {
onloadFuncts[i]();
}
}
 
// Note: all skins should call runOnloadHook() at the end of html output, so the below should be redundant. It's there just in case.
hookEvent("load", runOnloadHook);
 
 
 
/**
  * Create Google Analytics instance for Citizendium
*/
function loadga() {
var c; (c = document.createElement("script")).src = "https://www.googletagmanager.com/gtag/js?id=G-W7ML9SNPXT";
document.head.appendChild(c);
 
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-W7ML9SNPXT');
}
 
//Call prior function
loadga();
 
 
/**
  * Modify link behavior to open in a new tab when contained in a span.newtab
  */
function checklinks(){
Array.from(document.getElementsByClassName("newtab")).forEach(function(obj){obj.getElementsByTagName("a")[0].target="_blank"});
}
}


function runOnloadHook() {
//Call prior function
// don't run anything below this for non-dom browsers
checklinks();
if (doneOnloadHook || !(document.getElementById && document.getElementsByTagName)) {
return;
}
 
// set this before running any hooks, since any errors below
// might cause the function to terminate prematurely
doneOnloadHook = true;
 
histrowinit();
unhidetzbutton();
tabbedprefs();
updateTooltipAccessKeys( null );
akeytt( null );
scrollEditBox();
setupCheckboxShiftClick();
sortables_init();
 
// Run any added-on functions
for (var i = 0; i < onloadFuncts.length; i++) {
onloadFuncts[i]();
}
}


/**
* Add an event handler to an element
*
* @param Element element Element to add handler to
* @param String attach Event to attach to
* @param callable handler Event handler callback
*/
function addHandler( element, attach, handler ) {
if( window.addEventListener ) {
element.addEventListener( attach, handler, false );
} else if( window.attachEvent ) {
element.attachEvent( 'on' + attach, handler );
}
}


/**
/* </nowiki> */
* Add a click event handler to an element
*
* @param Element element Element to add handler to
* @param callable handler Event handler callback
*/
function addClickHandler( element, handler ) {
addHandler( element, 'click', handler );
}
//note: all skins should call runOnloadHook() at the end of html output,
//     so the below should be redundant. It's there just in case.
hookEvent("load", runOnloadHook);
hookEvent("load", mwSetupToolbar);

Latest revision as of 08:41, 30 January 2023

/* <nowiki> */

 /** Import module *************************************************************
  *
  *  Description: Includes a raw wiki page as javascript or CSS, used for including user made modules.
  *  
  *  Doesn't work in WebKit or IE7...
  */
var loadedScripts = {}; // included-scripts tracker
function importScript(page) {
	var url = wgScript + '?title=' + encodeURIComponent(page.replace(/ /g,'_')).replace(/%2F/ig,'/').replace(/%3A/ig,':') + '&action=raw&ctype=text/javascript';
	
	if (loadedScripts[url]) return null;
	loadedScripts[url] = true;
	
	var s = document.createElement('script');
	s.setAttribute('src',url);
	s.setAttribute('type','text/javascript');
	document.getElementsByTagName('head')[0].appendChild(s);
}

 
 function importStylesheet( page ) {
     var sheet = '@import "'
               + wgScriptPath
               + '/wiki?title='
               + encodeURIComponent( page.replace( ' ', '_' ) )
               + '&action=raw&ctype=text/css";'
     var styleElem = document.createElement( 'style' );
     styleElem.setAttribute( 'type' , 'text/css' );
     styleElem.appendChild( document.createTextNode( sheet ) );
     document.getElementsByTagName( 'head' )[0].appendChild( styleElem );
 }

/* Import more specific scripts if necessary */
//if (wgAction == 'edit' || wgAction == 'submit')
//    importScript("MediaWiki:Common.js/edit.js");
//if (wgPageName == 'Special:Upload')
//    importScript("MediaWiki:Common.js/upload.js");



/** Extra toolbar options ******************************************************
  *
  *  Description: UNDOCUMENTED
  *  Maintainers: 
  */

/* To disable this script, add    mwCustomEditButtons = [];    to [[Special:Mypage/Pinkwich5.js]] */

function imageButons(){
	if (wgAction == 'edit' || wgAction == 'submit') {
		/* Make the Image insertion button use the CZ image template */
		mwEditButtons[5].speedTip = 'Image';
		mwEditButtons[5].tagOpen	= '{{Image|';
		mwEditButtons[5].tagClose = '|right|250px|Image Caption}}';
		
		/* Add extra image buttons */
		if (mwCustomEditButtons) {
			mwCustomEditButtons[mwCustomEditButtons.length] = {
				"imageFile": "http://upload.wikimedia.org/wikipedia/en/c/c8/Button_redirect.png",
				"speedTip": "Redirect",
				"tagOpen": "#REDIRECT [[",
				"tagClose": "]]",
				"sampleText": "Insert text"};
		
			mwCustomEditButtons[mwCustomEditButtons.length] = {
				"imageFile": "http://upload.wikimedia.org/wikipedia/en/c/c9/Button_strike.png",
				"speedTip": "Strike",
				"tagOpen": "<s>",
				"tagClose": "</s>",
				"sampleText": "Strike-through text"};
		
			mwCustomEditButtons[mwCustomEditButtons.length] = {
				"imageFile": "http://upload.wikimedia.org/wikipedia/en/1/13/Button_enter.png",
				"speedTip": "Line break",
				"tagOpen": "<br />",
				"tagClose": "",
				"sampleText": ""};
		
			mwCustomEditButtons[mwCustomEditButtons.length] = {
				"imageFile": "http://upload.wikimedia.org/wikipedia/en/8/80/Button_upper_letter.png",
				"speedTip": "Superscript",
				"tagOpen": "<sup>",
				"tagClose": "</sup>",
				"sampleText": "Superscript text"};
		
			mwCustomEditButtons[mwCustomEditButtons.length] = {
				"imageFile": "http://upload.wikimedia.org/wikipedia/en/7/70/Button_lower_letter.png",
				"speedTip": "Subscript",
				"tagOpen": "<sub>",
				"tagClose": "</sub>",
				"sampleText": "Subscript text"};
		
			mwCustomEditButtons[mwCustomEditButtons.length] = {
				"imageFile": "http://upload.wikimedia.org/wikipedia/en/5/58/Button_small.png",
				"speedTip": "Small",
				"tagOpen": "<small>",
				"tagClose": "</small>",
				"sampleText": "Small Text"};
		
			mwCustomEditButtons[mwCustomEditButtons.length] = {
				"imageFile": "http://upload.wikimedia.org/wikipedia/en/6/60/Button_insert_table.png",
				"speedTip": "Insert a table",
				"tagOpen": '{| class="wikitable"\n|-\n',
				"tagClose": "\n|}",
				"sampleText": "! header 1\n! header 2\n! header 3\n|-\n| row 1, cell 1\n| row 1, cell 2\n| row 1, cell 3\n|-\n| row 2, cell 1\n| row 2, cell 2\n| row 2, cell 3"};
		
			mwCustomEditButtons[mwCustomEditButtons.length] = {
				"imageFile": "http://upload.wikimedia.org/wikipedia/commons/7/79/Button_reflink.png",
				"speedTip": "Insert a reference",
				"tagOpen": "<ref>",
				"tagClose": "</ref>",
				"sampleText": "Insert footnote text here"};
		}
	}
}
addOnloadHook(imageButons);


/** Upload Wizard ***************************************************
 *
 *  Adds many enhancements to the upload form
 *
 *  Maintainer : [[User:Caesar Schinas]]
 */

function uploadForm() {
	if ((wgPageName == 'Special:Upload') && (wgUserLanguage != 'basic')) {
		if ((document.getElementById('wpUploadDescription').value == '') && document.getElementById('preload')) {
			document.getElementById('wpUploadDescription').value = document.getElementById('preload').innerHTML;
			document.getElementById('preload').parentNode.innerHTML = 'Fill in all the details you know:';
		}
		if (wgUserLanguage == 'replace') {
			document.getElementById('wpDestFile').parentNode.parentNode.style.display = 'none';
			document.getElementById('wpUploadDescription').setAttribute('rows','5');
		}
		if ((document.getElementById('wpUploadDescription').value.indexOf('{{Image_Details') != -1) && (wgUserLanguage != 'advanced')) {
			/* get an array of licences */
			var license = document.getElementById('wpLicense');
			var licenses = Array();
			for (var i in license.childNodes) {
				if (license.childNodes[i].nodeName == 'OPTION' && license.childNodes[i].value != '') {
					licenses.push(license.childNodes[i].value);
				}
			}
			/* if there is only one licence available select it and hide the input */
			if (licenses.length == 1) {
				license.value = licenses[0];
				licenseSelectorCheck();
				license.style.display = 'none';
			}
			
			
			/* Create individual fields for the image details */
			
			var labels = {
				'description'	: 'Image description:',
				'author'		: 'Creator name:',
				'copyright'		: 'Copyright holder:',
				'source'		: 'Source:',
				'date-created'	: 'Date created:',
				'pub-country'	: 'Publication country:',
				'notes'			: 'Notes:',
				'versions'		: 'Other versions:'
			};
			var sig = '~~'+'~';
			
			var summary = document.getElementById('wpUploadDescription');
			var table = summary.parentNode.parentNode.parentNode;
			var next = summary.parentNode.parentNode.nextSibling;
			
			var args = Array();
			if (summary.value.indexOf('Details|') != -1)
				args = summary.value.substring(summary.value.indexOf('Details|')+8,summary.value.indexOf('\n')).split('|');
			
			var details = summary.value.substring(summary.value.indexOf('\n|')+2,summary.value.indexOf('\n}}')).split('\n|');
			for (var i in details) {
				details[i] = details[i].split('=');
			}
			for (var i in details) {
				var tr = document.createElement('tr');
				var td1 = document.createElement('td');
				var td2 = document.createElement('td');
				tr.appendChild(td1);
				tr.appendChild(td2);
				td1.setAttribute('class','mw-label');
				td2.setAttribute('class','mw-input');
				td1.style.width = '12em';

				// added by dnessett on 3/12/2010 to increase visible region for Notes
				if ((details[i][0].replace(/^\s+|\s+$/g,'')) == 'notes') {
					var textarea = document.createElement('textarea');
					textarea.setAttribute('wrap','virtual');
					textarea.setAttribute('id',details[i][0].replace(/^\s+|\s+$/g,''));
					textarea.setAttribute('name',details[i][0].replace(/^\s+|\s+$/g,''));
					textarea.setAttribute('value',details[i][1].replace(/^\s+|\s+$/g,''));
					textarea.setAttribute('rows','5');
					td2.appendChild(textarea);
					textarea.style.width = '90%';
				} else {
					var input = document.createElement('input');
					input.setAttribute('type','text');
					input.setAttribute('id',details[i][0].replace(/^\s+|\s+$/g,''));
					input.setAttribute('name',details[i][0].replace(/^\s+|\s+$/g,''));
					input.setAttribute('value',details[i][1].replace(/^\s+|\s+$/g,''));
					td2.appendChild(input);
					input.style.width = '90%';
				}
				
				var label = document.createElement('label');
				label.setAttribute('for',details[i][0].replace(/^\s+|\s+$/g,''));
				label.appendChild(document.createTextNode(labels[details[i][0].replace(/^\s+|\s+$/g,'')]));
				td1.appendChild(label);
				
				table.insertBefore(tr,next);
				
				if ((details[i][0].replace(/^\s+|\s+$/g,'')) == 'author' && (details[i][1].replace(/^\s+|\s+$/g,'') == sig)) tr.style.display = 'none';
			}
			summary.parentNode.parentNode.style.display = 'none';
			
			var septr = document.createElement('tr');
			var septd = document.createElement('td');
			septr.appendChild(septd);
			septd.appendChild(document.createElement('br'));
			table.insertBefore(septr,summary.parentNode.parentNode);
			
			document.getElementById('mw-upload-form').onsubmit = function(){
				var temp = '{{Image_Details';
				for (i in args) {
					temp += '|' + args[i];
				}
				for (i in details) {
					temp += '\n|' + details[i][0] + '= ' + document.getElementById(details[i][0].replace(/^\s+|\s+$/g,'')).value;
				}
				temp += '\n}}';
				summary.value = temp;
				
				if (license.value == '') {
					alert('Please select a licence!');
					return false;
				}
			}
		}
	}
}
addOnloadHook(uploadForm);

function uploadReplaceLink () {
	if (wgNamespaceNumber == 6) {
		var a = document.getElementsByTagName('a');
		for (var i in a) {
			if (a[i].getAttribute('href') && a[i].getAttribute('href').indexOf('wpDestFile') != -1)
				a[i].setAttribute('href', a[i].getAttribute('href') + '&uselang=replace');
		}
	}
}
addOnloadHook(uploadReplaceLink);


/** Credit Line Editor ***************************************************
 *
 *  Creates a simple form for editing credit lines.
 *
 *  Maintainer : [[User:Caesar Schinas]]
 */
function creditEdit() {
  if ((wgPageName.indexOf('/credit') != -1) && (wgAction == 'edit')) {
	var text = document.getElementById('wpTextbox1').value;
	if (text.indexOf('{{creditline') == -1) return false;
	var args = text.substring(text.indexOf('|')+1,text.indexOf('}}')).split('|');
	
	var bodycontent = document.getElementById('bodycontent');
	bodycontent.setAttribute('id','bodycontent-old');
	bodycontent.style.display = 'none';
	
	var div = document.createElement('div');
	bodycontent.parentNode.appendChild(div);
	div.setAttribute('id','bodycontent');
	
	div.innerHTML = "\
<table>\n\
  <tr>\n\
	<th style='text-align:right; padding-right:1em;'>\n\
	  <label for='licence'>Licence Type</label>\n\
	</th>\n\
	<td>\n\
	  <select id='licence' name='licence' style='width:25em;'>\n\
		<option value='C'>C - Copyright, used by permission</option>\n\
		<option value='CC'>CC - Creative Commons</option>\n\
		<option value='GNU'>GNU</option>\n\
		<option value='PD'>PD - Public Domain</option>\n\
		<option value='other' selected='selected'>Other (please only enter letters)</option>\n\
	  </select>\n\
	  <input type='text' id='licence-other' name='imagetype-other' />\n\
	</td>\n\
  </tr>\n\
  <tr>\n\
	<th style='text-align:right; padding-right:1em;'>\n\
	  <label for='imagetype'>Image Type</label>\n\
	</th>\n\
	<td>\n\
	  <select id='imagetype' name='imagetype' style='width:25em;'>\n\
		<option value='Image'>Image</option>\n\
		<option value='Photo'>Photo</option>\n\
		<option value='Diagram'>Diagram</option>\n\
		<option value='Drawing'>Drawing</option>\n\
		<option value='Painting'>Painting</option>\n\
		<option value='Artwork'>Artwork</option>\n\
		<option value='other' selected='selected'>Other</option>\n\
	  </select>\n\
	  <input type='text' id='imagetype-other' name='imagetype-other' />\n\
	</td>\n\
  </tr>\n\
  <tr>\n\
	<th style='text-align:right; padding-right:1em;'>\n\
	  <label for='author'>Author</label>\n\
	</th>\n\
	<td>\n\
	  <input type='text' id='author' name='author' style='width:25em;' />\n\
	</td>\n\
  </tr>\n\
  <tr>\n\
	<th>\n\
	</th>\n\
	<td>\n\
	  <input type='button' id='save' value='Save Credit Line' />\n\
	</td>\n\
  </tr>\n\
</table>\n\
";
	
	// set form field values
	
	if (args[0] && args[0] != 'licence') {
	  document.getElementById('licence-other').value = args[0];
	  for (var i=0; i<4; i++) {
		if (args[0].toUpperCase() == Array('CC','GNU','PD','C')[i]) {
			document.getElementById('licence').value = args[0].toUpperCase();
			document.getElementById('licence-other').style.display = 'none';
		}
	  }
	} else {
	  document.getElementById('licence').value = 'C';
	  document.getElementById('licence-other').style.display = 'none';
	}
	
	if (args[1] && args[1] != 'imagetype') {
	  document.getElementById('imagetype-other').value = args[1];
	  for (var i=0; i<6; i++) {
		if (args[1].toLowerCase() == Array('Image','Photo','Diagram','Drawing','Painting','Artwork')[i].toLowerCase()) {
			document.getElementById('imagetype').value = Array('Image','Photo','Diagram','Drawing','Painting','Artwork')[i];
			document.getElementById('imagetype-other').style.display = 'none';
		}
	  }
	} else {
	  document.getElementById('imagetype').value = 'Image';
	  document.getElementById('imagetype-other').style.display = 'none';
	}
	
	if (args[2] && args[2] != 'author')
	  document.getElementById('author').value = args[2];
	
	
	// onchange handlers for selects
	
	document.getElementById('licence').onchange = function() {
	  if (document.getElementById('licence').value == 'other')
		document.getElementById('licence-other').style.display = 'inline';
	  else
		document.getElementById('licence-other').style.display = 'none';
	}
	
	document.getElementById('imagetype').onchange = function() {
	  if (document.getElementById('imagetype').value == 'other')
		document.getElementById('imagetype-other').style.display = 'inline';
	  else
		document.getElementById('imagetype-other').style.display = 'none';
	}
	
	
	// save the credit line
	
	document.getElementById('save').onclick = function() {
	  var value = '{{creditline';
	  
	  if (document.getElementById('licence').value != 'other')
		value += '|' + document.getElementById('licence').value;
	  else if (document.getElementById('licence-other').value != '')
		value += '|' + document.getElementById('licence-other').value;
	  
	  if (document.getElementById('imagetype').value != 'Image' || document.getElementById('author').value != '') {
		if (document.getElementById('imagetype').value != 'other')
			value += '|' + document.getElementById('imagetype').value;
		else if (document.getElementById('imagetype-other').value != '')
			value += '|' + document.getElementById('imagetype-other').value;
		
		if (document.getElementById('author').value != '')
			value += '|' + document.getElementById('author').value;
	  }
	  
	  value += '}}';
	  
	  document.getElementById('wpTextbox1').value = value;
	  document.getElementById('editform').submit();
	}
  }
}
addOnloadHook(creditEdit);




 /* Test if an element has a certain class **************************************
  *
  * Description: Uses regular expressions and caching for better performance.
  * Maintainers: [[User:Mike Dillon]], [[User:R. Koot]], [[User:SG]]
  */
 
 var hasClass = (function () {
     var reCache = {};
     return function (element, className) {
         return (reCache[className] ? reCache[className] : (reCache[className] = new RegExp("(?:\\s|^)" + className + "(?:\\s|$)"))).test(element.className);
     };
 })();



 

 /** Collapsible tables *********************************************************
  *
  *  Description: Allows tables to be collapsed, showing only the header. See
  *               [[Citizendium:NavFrame]].
  *  Maintainers: [[User:R. Koot]]
  */
 
 var autoCollapse = 2;
 var collapseCaption = "hide";
 var expandCaption = "show";
 
 function collapseTable( tableIndex )
 {
     var Button = document.getElementById( "collapseButton" + tableIndex );
     var Table = document.getElementById( "collapsibleTable" + tableIndex );
 
     if ( !Table || !Button ) {
         return false;
     }
 
     var Rows = Table.getElementsByTagName( "tr" ); 
 
     if ( Button.firstChild.data == collapseCaption ) {
         for ( var i = 1; i < Rows.length; i++ ) {
             Rows[i].style.display = "none";
         }
         Button.firstChild.data = expandCaption;
     } else {
         for ( var i = 1; i < Rows.length; i++ ) {
             Rows[i].style.display = Rows[0].style.display;
         }
         Button.firstChild.data = collapseCaption;
     }
 }
 
 function createCollapseButtons()
 {
     var tableIndex = 0;
     var NavigationBoxes = new Object();
     var Tables = document.getElementsByTagName( "table" );
 
     for ( var i = 0; i < Tables.length; i++ ) {
         if ( hasClass( Tables[i], "collapsible" ) ) {
             NavigationBoxes[ tableIndex ] = Tables[i];
             Tables[i].setAttribute( "id", "collapsibleTable" + tableIndex );
 
             var Button     = document.createElement( "span" );
             var ButtonLink = document.createElement( "a" );
             var ButtonText = document.createTextNode( collapseCaption );
 
             Button.style.styleFloat = "right";
             Button.style.cssFloat = "right";
             Button.style.fontWeight = "normal";
             Button.style.textAlign = "right";
             Button.style.width = "6em";
 
             ButtonLink.setAttribute( "id", "collapseButton" + tableIndex );
             ButtonLink.setAttribute( "href", "javascript:collapseTable(" + tableIndex + ");" );
             ButtonLink.appendChild( ButtonText );
 
             Button.appendChild( document.createTextNode( "[" ) );
             Button.appendChild( ButtonLink );
             Button.appendChild( document.createTextNode( "]" ) );
 
             var Header = Tables[i].getElementsByTagName( "tr" )[0].getElementsByTagName( "th" )[0];
             /* only add button and increment count if there is a header row to work with */
             if (Header) {
                 Header.insertBefore( Button, Header.childNodes[0] );
                 tableIndex++;
             }
         }
     }
 
     for ( var i = 0;  i < tableIndex; i++ ) {
         if ( hasClass( NavigationBoxes[i], "collapsed" ) || ( tableIndex >= autoCollapse && hasClass( NavigationBoxes[i], "autocollapse" ) ) ) {
             collapseTable( i );
         }
     }
 }
 addOnloadHook( createCollapseButtons );


 /** Add dismiss button to watchlist-message *************************************
  *
  *  Description: Hide the watchlist message for one week.
  *  Maintainers: [[User:Ruud Koot|Ruud Koot]]
  */
 
 function addDismissButton() {
    var watchlistMessage = document.getElementById("watchlist-message");
    if ( watchlistMessage == null ) return;
 
    if ( document.cookie.indexOf( "hidewatchlistmessage=yes" ) != -1 ) {
        watchlistMessage.style.display = "none";
    }
 
    var Button     = document.createElement( "span" );
    var ButtonLink = document.createElement( "a" );
    var ButtonText = document.createTextNode( "dismiss" );
 
    ButtonLink.setAttribute( "id", "dismissButton" );
    ButtonLink.setAttribute( "href", "javascript:dismissWatchlistMessage();" );
    ButtonLink.setAttribute( "title", "Hide this message for one week" );
    ButtonLink.appendChild( ButtonText );
 
    Button.appendChild( document.createTextNode( "[" ) );
    Button.appendChild( ButtonLink );
    Button.appendChild( document.createTextNode( "]" ) );
 
    watchlistMessage.appendChild( Button );
 }
 
 function dismissWatchlistMessage() {
     var e = new Date();
     e.setTime( e.getTime() + (7*24*60*60*1000) );
     document.cookie = "hidewatchlistmessage=yes; expires=" + e.toGMTString() + "; path=/";
     var watchlistMessage = document.getElementById("watchlist-message");
     watchlistMessage.style.display = "none";
 }
 
 addOnloadHook( addDismissButton );

 /** Numeric sorting ***************************************************
  *
  *  Description: Fixes a bug (part of [[bugzilla:8115]])
  *  in http://svn.citizendium.org/viewvc/mediawiki/trunk/phase3/skins/common/wikibits.js
  *  regarding [[Help:Sorting|table sorting]]:
  *  it allows sorting of numbers with more than one comma (thousands separator).
  *  Maintainer: [[User:Patrick|Patrick]]
  */
 function ts_parseFloat(num) {
 	if (!num) return 0;
 	num = parseFloat(num.replace(/,/g, ""));
 	return (isNaN(num) ? 0 : num);
 }



// MediaWiki JavaScript support functions

var clientPC = navigator.userAgent.toLowerCase(); // Get client info
var is_gecko = ((clientPC.indexOf('gecko')!=-1) && (clientPC.indexOf('spoofer')==-1)
                && (clientPC.indexOf('khtml') == -1) && (clientPC.indexOf('netscape/7.0')==-1));
var is_safari = ((clientPC.indexOf('applewebkit')!=-1) && (clientPC.indexOf('spoofer')==-1));
var is_khtml = (navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled ));
// For accesskeys
var is_ff2_win = (clientPC.indexOf('firefox/2')!=-1 || clientPC.indexOf('minefield/3')!=-1) && clientPC.indexOf('windows')!=-1;
var is_ff2_x11 = (clientPC.indexOf('firefox/2')!=-1 || clientPC.indexOf('minefield/3')!=-1) && clientPC.indexOf('x11')!=-1;
if (clientPC.indexOf('opera') != -1) {
	var is_opera = true;
	var is_opera_preseven = (window.opera && !document.childNodes);
	var is_opera_seven = (window.opera && document.childNodes);
	var is_opera_95 = (clientPC.search(/opera\/(9.[5-9]|[1-9][0-9])/)!=-1);
}

// Global external objects used by this script.
/*extern ta, stylepath, skin */

// add any onload functions in this hook (please don't hard-code any events in the xhtml source)
var doneOnloadHook;

if (!window.onloadFuncts) {
	var onloadFuncts = [];
}

function addOnloadHook(hookFunct) {
	// Allows add-on scripts to add onload functions
	onloadFuncts[onloadFuncts.length] = hookFunct;
}

function hookEvent(hookName, hookFunct) {
	if (window.addEventListener) {
		window.addEventListener(hookName, hookFunct, false);
	} else if (window.attachEvent) {
		window.attachEvent("on" + hookName, hookFunct);
	}
}

// document.write special stylesheet links
if (typeof stylepath != 'undefined' && typeof skin != 'undefined') {
	if (is_opera_preseven) {
		document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera6Fixes.css">');
	} else if (is_opera_seven && !is_opera_95) {
		document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera7Fixes.css">');
	} else if (is_opera_95) {
		document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera95Fixes.css">');
	} else if (is_khtml) {
		document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/KHTMLFixes.css">');
	}
}

if (wgBreakFrames) {
	// Un-trap us from framesets
	if (window.top != window) {
		window.top.location = window.location;
	}
}

// for enhanced RecentChanges
function toggleVisibility(_levelId, _otherId, _linkId) {
	var thisLevel = document.getElementById(_levelId);
	var otherLevel = document.getElementById(_otherId);
	var linkLevel = document.getElementById(_linkId);
	if (thisLevel.style.display == 'none') {
		thisLevel.style.display = 'block';
		otherLevel.style.display = 'none';
		linkLevel.style.display = 'inline';
	} else {
		thisLevel.style.display = 'none';
		otherLevel.style.display = 'inline';
		linkLevel.style.display = 'none';
	}
}

function historyRadios(parent) {
	var inputs = parent.getElementsByTagName('input');
	var radios = [];
	for (var i = 0; i < inputs.length; i++) {
		if (inputs[i].name == "diff" || inputs[i].name == "oldid") {
			radios[radios.length] = inputs[i];
		}
	}
	return radios;
}

// check selection and tweak visibility/class onclick
function diffcheck() {
	var dli = false; // the li where the diff radio is checked
	var oli = false; // the li where the oldid radio is checked
	var hf = document.getElementById('pagehistory');
	if (!hf) {
		return true;
	}
	var lis = hf.getElementsByTagName('li');
	for (var i=0;i<lis.length;i++) {
		var inputs = historyRadios(lis[i]);
		if (inputs[1] && inputs[0]) {
			if (inputs[1].checked || inputs[0].checked) { // this row has a checked radio button
				if (inputs[1].checked && inputs[0].checked && inputs[0].value == inputs[1].value) {
					return false;
				}
				if (oli) { // it's the second checked radio
					if (inputs[1].checked) {
						oli.className = "selected";
						return false;
					}
				} else if (inputs[0].checked) {
					return false;
				}
				if (inputs[0].checked) {
					dli = lis[i];
				}
				if (!oli) {
					inputs[0].style.visibility = 'hidden';
				}
				if (dli) {
					inputs[1].style.visibility = 'hidden';
				}
				lis[i].className = "selected";
				oli = lis[i];
			}  else { // no radio is checked in this row
				if (!oli) {
					inputs[0].style.visibility = 'hidden';
				} else {
					inputs[0].style.visibility = 'visible';
				}
				if (dli) {
					inputs[1].style.visibility = 'hidden';
				} else {
					inputs[1].style.visibility = 'visible';
				}
				lis[i].className = "";
			}
		}
	}
	return true;
}

// page history stuff
// attach event handlers to the input elements on history page
function histrowinit() {
	var hf = document.getElementById('pagehistory');
	if (!hf) {
		return;
	}
	var lis = hf.getElementsByTagName('li');
	for (var i = 0; i < lis.length; i++) {
		var inputs = historyRadios(lis[i]);
		if (inputs[0] && inputs[1]) {
			inputs[0].onclick = diffcheck;
			inputs[1].onclick = diffcheck;
		}
	}
	diffcheck();
}

// generate toc from prefs form, fold sections
// XXX: needs testing on IE/Mac and safari
// more comments to follow
function tabbedprefs() {
	var prefform = document.getElementById('preferences');
	if (!prefform || !document.createElement) {
		return;
	}
	if (prefform.nodeName.toLowerCase() == 'a') {
		return; // Occasional IE problem
	}
	prefform.className = prefform.className + 'jsprefs';
	var sections = [];
	var children = prefform.childNodes;
	var seci = 0;
	for (var i = 0; i < children.length; i++) {
		if (children[i].nodeName.toLowerCase() == 'fieldset') {
			children[i].id = 'prefsection-' + seci;
			children[i].className = 'prefsection';
			if (is_opera || is_khtml) {
				children[i].className = 'prefsection operaprefsection';
			}
			var legends = children[i].getElementsByTagName('legend');
			sections[seci] = {};
			legends[0].className = 'mainLegend';
			if (legends[0] && legends[0].firstChild.nodeValue) {
				sections[seci].text = legends[0].firstChild.nodeValue;
			} else {
				sections[seci].text = '# ' + seci;
			}
			sections[seci].secid = children[i].id;
			seci++;
			if (sections.length != 1) {
				children[i].style.display = 'none';
			} else {
				var selectedid = children[i].id;
			}
		}
	}
	var toc = document.createElement('ul');
	toc.id = 'preftoc';
	toc.selectedid = selectedid;
	for (i = 0; i < sections.length; i++) {
		var li = document.createElement('li');
		if (i === 0) {
			li.className = 'selected';
		}
		var a = document.createElement('a');
		a.href = '#' + sections[i].secid;
		a.onmousedown = a.onclick = uncoversection;
		a.appendChild(document.createTextNode(sections[i].text));
		a.secid = sections[i].secid;
		li.appendChild(a);
		toc.appendChild(li);
	}
	prefform.parentNode.insertBefore(toc, prefform.parentNode.childNodes[0]);
	document.getElementById('prefsubmit').id = 'prefcontrol';
}

function uncoversection() {
	var oldsecid = this.parentNode.parentNode.selectedid;
	var newsec = document.getElementById(this.secid);
	if (oldsecid != this.secid) {
		var ul = document.getElementById('preftoc');
		document.getElementById(oldsecid).style.display = 'none';
		newsec.style.display = 'block';
		ul.selectedid = this.secid;
		var lis = ul.getElementsByTagName('li');
		for (var i = 0; i< lis.length; i++) {
			lis[i].className = '';
		}
		this.parentNode.className = 'selected';
	}
	return false;
}

// Timezone stuff
// tz in format [+-]HHMM
function checkTimezone(tz, msg) {
	var localclock = new Date();
	// returns negative offset from GMT in minutes
	var tzRaw = localclock.getTimezoneOffset();
	var tzHour = Math.floor( Math.abs(tzRaw) / 60);
	var tzMin = Math.abs(tzRaw) % 60;
	var tzString = ((tzRaw >= 0) ? "-" : "+") + ((tzHour < 10) ? "0" : "") + tzHour + ((tzMin < 10) ? "0" : "") + tzMin;
	if (tz != tzString) {
		var junk = msg.split('$1');
		document.write(junk[0] + "UTC" + tzString + junk[1]);
	}
}

function unhidetzbutton() {
	var tzb = document.getElementById('guesstimezonebutton');
	if (tzb) {
		tzb.style.display = 'inline';
	}
}

// in [-]HH:MM format...
// won't yet work with non-even tzs
function fetchTimezone() {
	// FIXME: work around Safari bug
	var localclock = new Date();
	// returns negative offset from GMT in minutes
	var tzRaw = localclock.getTimezoneOffset();
	var tzHour = Math.floor( Math.abs(tzRaw) / 60);
	var tzMin = Math.abs(tzRaw) % 60;
	var tzString = ((tzRaw >= 0) ? "-" : "") + ((tzHour < 10) ? "0" : "") + tzHour +
		":" + ((tzMin < 10) ? "0" : "") + tzMin;
	return tzString;
}

function guessTimezone(box) {
	document.getElementsByName("wpHourDiff")[0].value = fetchTimezone();
}

function showTocToggle() {
	if (document.createTextNode) {
		// Uses DOM calls to avoid document.write + XHTML issues

		var linkHolder = document.getElementById('toctitle');
		if (!linkHolder) {
			return;
		}

		var outerSpan = document.createElement('span');
		outerSpan.className = 'toctoggle';

		var toggleLink = document.createElement('a');
		toggleLink.id = 'togglelink';
		toggleLink.className = 'internal';
		toggleLink.href = 'javascript:toggleToc()';
		toggleLink.appendChild(document.createTextNode(tocHideText));

		outerSpan.appendChild(document.createTextNode('['));
		outerSpan.appendChild(toggleLink);
		outerSpan.appendChild(document.createTextNode(']'));

		linkHolder.appendChild(document.createTextNode(' '));
		linkHolder.appendChild(outerSpan);

		var cookiePos = document.cookie.indexOf("hidetoc=");
		if (cookiePos > -1 && document.cookie.charAt(cookiePos + 8) == 1) {
			toggleToc();
		}
	}
}

function changeText(el, newText) {
	// Safari work around
	if (el.innerText) {
		el.innerText = newText;
	} else if (el.firstChild && el.firstChild.nodeValue) {
		el.firstChild.nodeValue = newText;
	}
}

function toggleToc() {
	var toc = document.getElementById('toc').getElementsByTagName('ul')[0];
	var toggleLink = document.getElementById('togglelink');

	if (toc && toggleLink && toc.style.display == 'none') {
		changeText(toggleLink, tocHideText);
		toc.style.display = 'block';
		document.cookie = "hidetoc=0";
	} else {
		changeText(toggleLink, tocShowText);
		toc.style.display = 'none';
		document.cookie = "hidetoc=1";
	}
}

function escapeQuotes(text) {
	var re = new RegExp("'","g");
	text = text.replace(re,"\\'");
	re = new RegExp("\\n","g");
	text = text.replace(re,"\\n");
	return escapeQuotesHTML(text);
}

function escapeQuotesHTML(text) {
	var re = new RegExp('&',"g");
	text = text.replace(re,"&amp;");
	re = new RegExp('"',"g");
	text = text.replace(re,"&quot;");
	re = new RegExp('<',"g");
	text = text.replace(re,"&lt;");
	re = new RegExp('>',"g");
	text = text.replace(re,"&gt;");
	return text;
}

// apply tagOpen/tagClose to selection in textarea,
// use sampleText instead of selection if there is none
function insertTags(tagOpen, tagClose, sampleText) {
	var txtarea;
	if (document.editform) {
		txtarea = document.editform.wpTextbox1;
	} else {
		// some alternate form? take the first one we can find
		var areas = document.getElementsByTagName('textarea');
		txtarea = areas[0];
	}
	var selText, isSample = false;

	if (document.selection  && document.selection.createRange) { // IE/Opera

		//save window scroll position
		if (document.documentElement && document.documentElement.scrollTop)
			var winScroll = document.documentElement.scrollTop
		else if (document.body)
			var winScroll = document.body.scrollTop;
		//get current selection  
		txtarea.focus();
		var range = document.selection.createRange();
		selText = range.text;
		//insert tags
		checkSelectedText();
		range.text = tagOpen + selText + tagClose;
		//mark sample text as selected
		if (isSample && range.moveStart) {
			if (window.opera)
				tagClose = tagClose.replace(/\n/g,'');
			range.moveStart('character', - tagClose.length - selText.length); 
			range.moveEnd('character', - tagClose.length); 
		}
		range.select();   
		//restore window scroll position
		if (document.documentElement && document.documentElement.scrollTop)
			document.documentElement.scrollTop = winScroll
		else if (document.body)
			document.body.scrollTop = winScroll;

	} else if (txtarea.selectionStart || txtarea.selectionStart == '0') { // Mozilla

		//save textarea scroll position
		var textScroll = txtarea.scrollTop;
		//get current selection
		txtarea.focus();
		var startPos = txtarea.selectionStart;
		var endPos = txtarea.selectionEnd;
		selText = txtarea.value.substring(startPos, endPos);
		//insert tags
		checkSelectedText();
		txtarea.value = txtarea.value.substring(0, startPos)
			+ tagOpen + selText + tagClose
			+ txtarea.value.substring(endPos, txtarea.value.length);
		//set new selection
		if (isSample) {
			txtarea.selectionStart = startPos + tagOpen.length;
			txtarea.selectionEnd = startPos + tagOpen.length + selText.length;
		} else {
			txtarea.selectionStart = startPos + tagOpen.length + selText.length + tagClose.length;
			txtarea.selectionEnd = txtarea.selectionStart;
		}
		//restore textarea scroll position
		txtarea.scrollTop = textScroll;
	} 

	function checkSelectedText(){
		if (!selText) {
			selText = sampleText;
			isSample = true;
		} else if (selText.charAt(selText.length - 1) == ' ') { //exclude ending space char
			selText = selText.substring(0, selText.length - 1);
			tagClose += ' '
		} 
	}

}


/**
 * Set the accesskey prefix based on browser detection.
 */
var tooltipAccessKeyPrefix = 'alt-';
if (is_opera) {
	tooltipAccessKeyPrefix = 'shift-esc-';
} else if (is_safari
	   || navigator.userAgent.toLowerCase().indexOf('mac') != -1
	   || navigator.userAgent.toLowerCase().indexOf('konqueror') != -1 ) {
	tooltipAccessKeyPrefix = 'ctrl-';
} else if (is_ff2_x11 || is_ff2_win) {
	tooltipAccessKeyPrefix = 'alt-shift-';
}
var tooltipAccessKeyRegexp = /\[(ctrl-)?(alt-)?(shift-)?(esc-)?.\]$/;

/**
 * Add the appropriate prefix to the accesskey shown in the tooltip.
 * If the nodeList parameter is given, only those nodes are updated;
 * otherwise, all the nodes that will probably have accesskeys by
 * default are updated.
 *
 * @param Array nodeList -- list of elements to update
 */
function updateTooltipAccessKeys( nodeList ) {
	if ( !nodeList ) {
		// skins without a "column-one" element don't seem to have links with accesskeys either
		var columnOne = document.getElementById("column-one");
		if ( columnOne )
			updateTooltipAccessKeys( columnOne.getElementsByTagName("a") );
		// these are rare enough that no such optimization is needed
		updateTooltipAccessKeys( document.getElementsByTagName("input") );
		updateTooltipAccessKeys( document.getElementsByTagName("label") );
		return;
	}

	for ( var i = 0; i < nodeList.length; i++ ) {
		var element = nodeList[i];
		var tip = element.getAttribute("title");
		var key = element.getAttribute("accesskey");
		if ( key && tooltipAccessKeyRegexp.exec(tip) ) {
			tip = tip.replace(tooltipAccessKeyRegexp,
					  "["+tooltipAccessKeyPrefix+key+"]");
			element.setAttribute("title", tip );
		}
	}
}

/**
 * Add a link to one of the portlet menus on the page, including:
 *
 * p-cactions: Content actions (shown as tabs above the main content in Monobook)
 * p-personal: Personal tools (shown at the top right of the page in Monobook)
 * p-navigation: Navigation
 * p-tb: Toolbox
 *
 * This function exists for the convenience of custom JS authors.  All
 * but the first three parameters are optional, though providing at
 * least an id and a tooltip is recommended.
 *
 * By default the new link will be added to the end of the list.  To
 * add the link before a given existing item, pass the DOM node of
 * that item (easily obtained with document.getElementById()) as the
 * nextnode parameter; to add the link _after_ an existing item, pass
 * the node's nextSibling instead.
 *
 * @param String portlet -- id of the target portlet ("p-cactions", "p-personal", "p-navigation" or "p-tb")
 * @param String href -- link URL
 * @param String text -- link text (will be automatically lowercased by CSS for p-cactions in Monobook)
 * @param String id -- id of the new item, should be unique and preferably have the appropriate prefix ("ca-", "pt-", "n-" or "t-")
 * @param String tooltip -- text to show when hovering over the link, without accesskey suffix
 * @param String accesskey -- accesskey to activate this link (one character, try to avoid conflicts)
 * @param Node nextnode -- the DOM node before which the new item should be added, should be another item in the same list
 *
 * @return Node -- the DOM node of the new item (an LI element) or null
 */
function addPortletLink(portlet, href, text, id, tooltip, accesskey, nextnode) {
	var node = document.getElementById(portlet);
	if ( !node ) return null;
	node = node.getElementsByTagName( "ul" )[0];
	if ( !node ) return null;

	var link = document.createElement( "a" );
	link.appendChild( document.createTextNode( text ) );
	link.href = href;

	var item = document.createElement( "li" );
	item.appendChild( link );
	if ( id ) item.id = id;

	if ( accesskey ) {
		link.setAttribute( "accesskey", accesskey );
		tooltip += " ["+accesskey+"]";
	}
	if ( tooltip ) {
		link.setAttribute( "title", tooltip );
	}
	if ( accesskey && tooltip ) {
		updateTooltipAccessKeys( new Array( link ) );
	}

	if ( nextnode && nextnode.parentNode == node )
		node.insertBefore( item, nextnode );
	else
		node.appendChild( item );  // IE compatibility (?)

	return item;
}


/**
 * Set up accesskeys/tooltips from the deprecated ta array.  If doId
 * is specified, only set up for that id.  Note that this function is
 * deprecated and will not be supported indefinitely -- use
 * updateTooltipAccessKey() instead.
 *
 * @param mixed doId string or null
 */
function akeytt( doId ) {
	// A lot of user scripts (and some of the code below) break if
	// ta isn't defined, so we make sure it is.  Explictly using
	// window.ta avoids a "ta is not defined" error.
	if (!window.ta) window.ta = new Array;

	// Make a local, possibly restricted, copy to avoid clobbering
	// the original.
	var ta;
	if ( doId ) {
		ta = [doId];
	} else {
		ta = window.ta;
	}

	// Now deal with evil deprecated ta
	var watchCheckboxExists = document.getElementById( 'wpWatchthis' ) ? true : false;
	for (var id in ta) {
		var n = document.getElementById(id);
		if (n) {
			var a = null;
			var ak = '';
			// Are we putting accesskey in it
			if (ta[id][0].length > 0) {
				// Is this object a object? If not assume it's the next child.

				if (n.nodeName.toLowerCase() == "a") {
					a = n;
				} else {
					a = n.childNodes[0];
				}
			 	// Don't add an accesskey for the watch tab if the watch
			 	// checkbox is also available.
				if (a && ((id != 'ca-watch' && id != 'ca-unwatch') || !watchCheckboxExists)) {
					a.accessKey = ta[id][0];
					ak = ' ['+tooltipAccessKeyPrefix+ta[id][0]+']';
				}
			} else {
				// We don't care what type the object is when assigning tooltip
				a = n;
				ak = '';
			}

			if (a) {
				a.title = ta[id][1]+ak;
			}
		}
	}
}

function setupRightClickEdit() {
	if (document.getElementsByTagName) {
		var spans = document.getElementsByTagName('span');
		for (var i = 0; i < spans.length; i++) {
			var el = spans[i];
			if(el.className == 'editsection') {
				addRightClickEditHandler(el);
			}
		}
	}
}

function addRightClickEditHandler(el) {
	for (var i = 0; i < el.childNodes.length; i++) {
		var link = el.childNodes[i];
		if (link.nodeType == 1 && link.nodeName.toLowerCase() == 'a') {
			var editHref = link.getAttribute('href');
			// find the enclosing (parent) header
			var prev = el.parentNode;
			if (prev && prev.nodeType == 1 &&
			prev.nodeName.match(/^[Hh][1-6]$/)) {
				prev.oncontextmenu = function(e) {
					if (!e) { e = window.event; }
					// e is now the event in all browsers
					var targ;
					if (e.target) { targ = e.target; }
					else if (e.srcElement) { targ = e.srcElement; }
					if (targ.nodeType == 3) { // defeat Safari bug
						targ = targ.parentNode;
					}
					// targ is now the target element

					// We don't want to deprive the noble reader of a context menu
					// for the section edit link, do we?  (Might want to extend this
					// to all <a>'s?)
					if (targ.nodeName.toLowerCase() != 'a'
					|| targ.parentNode.className != 'editsection') {
						document.location = editHref;
						return false;
					}
					return true;
				};
			}
		}
	}
}

var checkboxes;
var lastCheckbox;

function setupCheckboxShiftClick() {
	checkboxes = [];
	lastCheckbox = null;
	var inputs = document.getElementsByTagName('input');
	addCheckboxClickHandlers(inputs);
}

function addCheckboxClickHandlers(inputs, start) {
	if ( !start) start = 0;

	var finish = start + 250;
	if ( finish > inputs.length )
		finish = inputs.length;

	for ( var i = start; i < finish; i++ ) {
		var cb = inputs[i];
		if ( !cb.type || cb.type.toLowerCase() != 'checkbox' )
			continue;
		var end = checkboxes.length;
		checkboxes[end] = cb;
		cb.index = end;
		cb.onclick = checkboxClickHandler;
	}

	if ( finish < inputs.length ) {
		setTimeout( function () {
			addCheckboxClickHandlers(inputs, finish);
		}, 200 );
	}
}

function checkboxClickHandler(e) {
	if (typeof e == 'undefined') {
		e = window.event;
	}
	if ( !e.shiftKey || lastCheckbox === null ) {
		lastCheckbox = this.index;
		return true;
	}
	var endState = this.checked;
	var start, finish;
	if ( this.index < lastCheckbox ) {
		start = this.index + 1;
		finish = lastCheckbox;
	} else {
		start = lastCheckbox;
		finish = this.index - 1;
	}
	for (var i = start; i <= finish; ++i ) {
		checkboxes[i].checked = endState;
	}
	lastCheckbox = this.index;
	return true;
}

function toggle_element_activation(ida,idb) {
	if (!document.getElementById) {
		return;
	}
	document.getElementById(ida).disabled=true;
	document.getElementById(idb).disabled=false;
}

function toggle_element_check(ida,idb) {
	if (!document.getElementById) {
		return;
	}
	document.getElementById(ida).checked=true;
	document.getElementById(idb).checked=false;
}

/**
 * Restore the edit box scroll state following a preview operation,
 * and set up a form submission handler to remember this state
 */
function scrollEditBox() {
	var editBox = document.getElementById( 'wpTextbox1' );
	var scrollTop = document.getElementById( 'wpScrolltop' );
	var editForm = document.getElementById( 'editform' );
	if( editBox && scrollTop ) {
		if( scrollTop.value )
			editBox.scrollTop = scrollTop.value;
		addHandler( editForm, 'submit', function() {
			document.getElementById( 'wpScrolltop' ).value = document.getElementById( 'wpTextbox1' ).scrollTop; 
		} );
	}
}
hookEvent( 'load', scrollEditBox );

var allmessages_nodelist = false;
var allmessages_modified = false;
var allmessages_timeout = false;
var allmessages_running = false;

function allmessagesmodified() {
	allmessages_modified = !allmessages_modified;
	allmessagesfilter();
}

function allmessagesfilter() {
	if ( allmessages_timeout )
		window.clearTimeout( allmessages_timeout );

	if ( !allmessages_running )
		allmessages_timeout = window.setTimeout( 'allmessagesfilter_do();', 500 );
}

function allmessagesfilter_do() {
	if ( !allmessages_nodelist )
		return;

	var text = document.getElementById('allmessagesinput').value;
	var nodef = allmessages_modified;

	allmessages_running = true;

	for ( var name in allmessages_nodelist ) {
		var nodes = allmessages_nodelist[name];
		var display = ( name.indexOf( text ) == -1 ? 'none' : '' );

		for ( var i = 0; i < nodes.length; i++)
			nodes[i].style.display =
				( nodes[i].className == "def" && nodef
				  ? 'none' : display );
	}

	if ( text != document.getElementById('allmessagesinput').value ||
	     nodef != allmessages_modified )
		allmessagesfilter_do();  // repeat

	allmessages_running = false;
}

function allmessagesfilter_init() {
	if ( allmessages_nodelist )
		return;

	var nodelist = new Array();
	var templist = new Array();

	var table = document.getElementById('allmessagestable');
	if ( !table ) return;

	var rows = document.getElementsByTagName('tr');
	for ( var i = 0; i < rows.length; i++ ) {
		var id = rows[i].getAttribute('id')
		if ( id && id.substring(0,16) != 'sp-allmessages-r' ) continue;
		templist[ id ] = rows[i];
	}

	var spans = table.getElementsByTagName('span');
	for ( var i = 0; i < spans.length; i++ ) {
		var id = spans[i].getAttribute('id')
		if ( id && id.substring(0,17) != 'sp-allmessages-i-' ) continue;
		if ( !spans[i].firstChild || spans[i].firstChild.nodeType != 3 ) continue;

		var nodes = new Array();
		var row1 = templist[ id.replace('i', 'r1') ];
		var row2 = templist[ id.replace('i', 'r2') ];

		if ( row1 ) nodes[nodes.length] = row1;
		if ( row2 ) nodes[nodes.length] = row2;
		nodelist[ spans[i].firstChild.nodeValue ] = nodes;
	}

	var k = document.getElementById('allmessagesfilter');
	if (k) { k.style.display = ''; }

	allmessages_nodelist = nodelist;
}

hookEvent( "load", allmessagesfilter_init );

/*
	Written by Jonathan Snook, http://www.snook.ca/jonathan
	Add-ons by Robert Nyman, http://www.robertnyman.com
	Author says "The credit comment is all it takes, no license. Go crazy with it!:-)"
	From http://www.robertnyman.com/2005/11/07/the-ultimate-getelementsbyclassname/
*/
function getElementsByClassName(oElm, strTagName, oClassNames){
	var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
	var arrReturnElements = new Array();
	var arrRegExpClassNames = new Array();
	if(typeof oClassNames == "object"){
		for(var i=0; i<oClassNames.length; i++){
			arrRegExpClassNames[arrRegExpClassNames.length] =
				new RegExp("(^|\\s)" + oClassNames[i].replace(/\-/g, "\\-") + "(\\s|$)");
		}
	}
	else{
		arrRegExpClassNames[arrRegExpClassNames.length] =
			new RegExp("(^|\\s)" + oClassNames.replace(/\-/g, "\\-") + "(\\s|$)");
	}
	var oElement;
	var bMatchesAll;
	for(var j=0; j<arrElements.length; j++){
		oElement = arrElements[j];
		bMatchesAll = true;
		for(var k=0; k<arrRegExpClassNames.length; k++){
			if(!arrRegExpClassNames[k].test(oElement.className)){
				bMatchesAll = false;
				break;
			}
		}
		if(bMatchesAll){
			arrReturnElements[arrReturnElements.length] = oElement;
		}
	}
	return (arrReturnElements)
}

function redirectToFragment(fragment) {
	var match = navigator.userAgent.match(/AppleWebKit\/(\d+)/);
	if (match) {
		var webKitVersion = parseInt(match[1]);
		if (webKitVersion < 420) {
			// Released Safari w/ WebKit 418.9.1 messes up horribly
			// Nightlies of 420+ are ok
			return;
		}
	}
	if (is_gecko) {
		// Mozilla needs to wait until after load, otherwise the window doesn't scroll
		addOnloadHook(function () {
			if (window.location.hash == "")
				window.location.hash = fragment;
		});
	} else {
		if (window.location.hash == "")
			window.location.hash = fragment;
	}
}


/*
 * Table sorting script  by Joost de Valk, check it out at http://www.joostdevalk.nl/code/sortable-table/.
 * Based on a script from http://www.kryogenix.org/code/browser/sorttable/.
 * Distributed under the MIT license: http://www.kryogenix.org/code/browser/licence.html .
 *
 * Copyright (c) 1997-2006 Stuart Langridge, Joost de Valk.
 *
 * @todo don't break on colspans/rowspans (bug 8028)
 * @todo language-specific digit grouping/decimals (bug 8063)
 * @todo support all accepted date formats (bug 8226)
 */

var ts_image_path = stylepath+"/common/images/";
var ts_image_up = "sort_up.gif";
var ts_image_down = "sort_down.gif";
var ts_image_none = "sort_none.gif";
var ts_europeandate = wgContentLanguage != "en"; // The non-American-inclined can change to "true"
var ts_alternate_row_colors = true;
var SORT_COLUMN_INDEX;

function sortables_init() {
	var idnum = 0;
	// Find all tables with class sortable and make them sortable
	var tables = getElementsByClassName(document, "table", "sortable");
	for (var ti = 0; ti < tables.length ; ti++) {
		if (!tables[ti].id) {
			tables[ti].setAttribute('id','sortable_table_id_'+idnum);
			++idnum;
		}
		ts_makeSortable(tables[ti]);
	}
}

function ts_makeSortable(table) {
	var firstRow;
	if (table.rows && table.rows.length > 0) {
		if (table.tHead && table.tHead.rows.length > 0) {
			firstRow = table.tHead.rows[table.tHead.rows.length-1];
		} else {
			firstRow = table.rows[0];
		}
	}
	if (!firstRow) return;

	// We have a first row: assume it's the header, and make its contents clickable links
	for (var i = 0; i < firstRow.cells.length; i++) {
		var cell = firstRow.cells[i];
		if ((" "+cell.className+" ").indexOf(" unsortable ") == -1) {
			cell.innerHTML += '&nbsp;&nbsp;<a href="#" class="sortheader" onclick="ts_resortTable(this);return false;"><span class="sortarrow"><img src="'+ ts_image_path + ts_image_none + '" alt="&darr;"/></span></a>';
		}
	}
	if (ts_alternate_row_colors) {
		ts_alternate(table);
	}
}

function ts_getInnerText(el) {
	if (typeof el == "string") return el;
	if (typeof el == "undefined") { return el };
	if (el.textContent) return el.textContent; // not needed but it is faster
	if (el.innerText) return el.innerText;     // IE doesn't have textContent
	var str = "";

	var cs = el.childNodes;
	var l = cs.length;
	for (var i = 0; i < l; i++) {
		switch (cs[i].nodeType) {
			case 1: //ELEMENT_NODE
				str += ts_getInnerText(cs[i]);
				break;
			case 3:	//TEXT_NODE
				str += cs[i].nodeValue;
				break;
		}
	}
	return str;
}

function ts_resortTable(lnk) {
	// get the span
	var span = lnk.getElementsByTagName('span')[0];

	var td = lnk.parentNode;
	var tr = td.parentNode;
	var column = td.cellIndex;

	var table = tr.parentNode;
	while (table && !(table.tagName && table.tagName.toLowerCase() == 'table'))
		table = table.parentNode;
	if (!table) return;

	// Work out a type for the column
	if (table.rows.length <= 1) return;

	// Skip the first row if that's where the headings are
	var rowStart = (table.tHead && table.tHead.rows.length > 0 ? 0 : 1);

	var itm = "";
	for (var i = rowStart; i < table.rows.length; i++) {
		if (table.rows[i].cells.length > column) {
			itm = ts_getInnerText(table.rows[i].cells[column]);
			itm = itm.replace(/^[\s\xa0]+/, "").replace(/[\s\xa0]+$/, "");
			if (itm != "") break;
		}
	}

	sortfn = ts_sort_caseinsensitive;
	if (itm.match(/^\d\d[\/. -][a-zA-Z]{3}[\/. -]\d\d\d\d$/))
		sortfn = ts_sort_date;
	if (itm.match(/^\d\d[\/.-]\d\d[\/.-]\d\d\d\d$/))
		sortfn = ts_sort_date;
	if (itm.match(/^\d\d[\/.-]\d\d[\/.-]\d\d$/))
		sortfn = ts_sort_date;
	if (itm.match(/^[\u00a3$\u20ac]/)) // pound dollar euro
		sortfn = ts_sort_currency;
	if (itm.match(/^[\d.,]+\%?$/))
		sortfn = ts_sort_numeric;

	var reverse = (span.getAttribute("sortdir") == 'down');

	var newRows = new Array();
	for (var j = rowStart; j < table.rows.length; j++) {
		var row = table.rows[j];
		var keyText = ts_getInnerText(row.cells[column]);
		var oldIndex = (reverse ? -j : j);

		newRows[newRows.length] = new Array(row, keyText, oldIndex);
	}

	newRows.sort(sortfn);

	var arrowHTML;
	if (reverse) {
			arrowHTML = '<img src="'+ ts_image_path + ts_image_down + '" alt="&darr;"/>';
			newRows.reverse();
			span.setAttribute('sortdir','up');
	} else {
			arrowHTML = '<img src="'+ ts_image_path + ts_image_up + '" alt="&uarr;"/>';
			span.setAttribute('sortdir','down');
	}

	// We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones
	// don't do sortbottom rows
	for (var i = 0; i < newRows.length; i++) {
		if ((" "+newRows[i][0].className+" ").indexOf(" sortbottom ") == -1)
			table.tBodies[0].appendChild(newRows[i][0]);
	}
	// do sortbottom rows only
	for (var i = 0; i < newRows.length; i++) {
		if ((" "+newRows[i][0].className+" ").indexOf(" sortbottom ") != -1)
			table.tBodies[0].appendChild(newRows[i][0]);
	}

	// Delete any other arrows there may be showing
	var spans = getElementsByClassName(tr, "span", "sortarrow");
	for (var i = 0; i < spans.length; i++) {
		spans[i].innerHTML = '<img src="'+ ts_image_path + ts_image_none + '" alt="&darr;"/>';
	}
	span.innerHTML = arrowHTML;

	ts_alternate(table);		
}

function ts_dateToSortKey(date) {	
	// y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX
	if (date.length == 11) {
		switch (date.substr(3,3).toLowerCase()) {
			case "jan": var month = "01"; break;
			case "feb": var month = "02"; break;
			case "mar": var month = "03"; break;
			case "apr": var month = "04"; break;
			case "may": var month = "05"; break;
			case "jun": var month = "06"; break;
			case "jul": var month = "07"; break;
			case "aug": var month = "08"; break;
			case "sep": var month = "09"; break;
			case "oct": var month = "10"; break;
			case "nov": var month = "11"; break;
			case "dec": var month = "12"; break;
			// default: var month = "00";
		}
		return date.substr(7,4)+month+date.substr(0,2);
	} else if (date.length == 10) {
		if (ts_europeandate == false) {
			return date.substr(6,4)+date.substr(0,2)+date.substr(3,2);
		} else {
			return date.substr(6,4)+date.substr(3,2)+date.substr(0,2);
		}
	} else if (date.length == 8) {
		yr = date.substr(6,2);
		if (parseInt(yr) < 50) { 
			yr = '20'+yr; 
		} else { 
			yr = '19'+yr; 
		}
		if (ts_europeandate == true) {
			return yr+date.substr(3,2)+date.substr(0,2);
		} else {
			return yr+date.substr(0,2)+date.substr(3,2);
		}
	}
	return "00000000";
}

function ts_parseFloat(num) {
	if (!num) return 0;
	num = parseFloat(num.replace(/,/g, ""));
	return (isNaN(num) ? 0 : num);
}

function ts_sort_date(a,b) {
	var aa = ts_dateToSortKey(a[1]);
	var bb = ts_dateToSortKey(b[1]);
	return (aa < bb ? -1 : aa > bb ? 1 : a[2] - b[2]);
}

function ts_sort_currency(a,b) {
	var aa = ts_parseFloat(a[1].replace(/[^0-9.]/g,''));
	var bb = ts_parseFloat(b[1].replace(/[^0-9.]/g,''));
	return (aa != bb ? aa - bb : a[2] - b[2]);
}

function ts_sort_numeric(a,b) {
	var aa = ts_parseFloat(a[1]);
	var bb = ts_parseFloat(b[1]);
	return (aa != bb ? aa - bb : a[2] - b[2]);
}

function ts_sort_caseinsensitive(a,b) {
	var aa = a[1].toLowerCase();
	var bb = b[1].toLowerCase();
	return (aa < bb ? -1 : aa > bb ? 1 : a[2] - b[2]);
}

function ts_sort_default(a,b) {
	return (a[1] < b[1] ? -1 : a[1] > b[1] ? 1 : a[2] - b[2]);
}

function ts_alternate(table) {
	// Take object table and get all it's tbodies.
	var tableBodies = table.getElementsByTagName("tbody");
	// Loop through these tbodies
	for (var i = 0; i < tableBodies.length; i++) {
		// Take the tbody, and get all it's rows
		var tableRows = tableBodies[i].getElementsByTagName("tr");
		// Loop through these rows
		// Start at 1 because we want to leave the heading row untouched
		for (var j = 0; j < tableRows.length; j++) {
			// Check if j is even, and apply classes for both possible results
			var oldClasses = tableRows[j].className.split(" ");
			var newClassName = "";
			for (var k = 0; k < oldClasses.length; k++) {
				if (oldClasses[k] != "" && oldClasses[k] != "even" && oldClasses[k] != "odd")
					newClassName += oldClasses[k] + " ";
			}
			tableRows[j].className = newClassName + (j % 2 == 0 ? "even" : "odd");
		}
	}
}

/*
 * End of table sorting code
 */
 
 
/**
 * Add a cute little box at the top of the screen to inform the user of
 * something, replacing any preexisting message.
 *
 * @param String message HTML to be put inside the right div
 * @param String className   Used in adding a class; should be different for each
 *   call to allow CSS/JS to hide different boxes.  null = no class used.
 * @return Boolean       True on success, false on failure
 */
function jsMsg( message, className ) {
	if ( !document.getElementById ) {
		return false;
	}
	// We special-case skin structures provided by the software.  Skins that
	// choose to abandon or significantly modify our formatting can just define
	// an mw-js-message div to start with.
	var messageDiv = document.getElementById( 'mw-js-message' );
	if ( !messageDiv ) {
		messageDiv = document.createElement( 'div' );
		if ( document.getElementById( 'column-content' )
		&& document.getElementById( 'content' ) ) {
			// MonoBook, presumably
			document.getElementById( 'content' ).insertBefore(
				messageDiv,
				document.getElementById( 'content' ).firstChild
			);
		} else if ( document.getElementById('content')
		&& document.getElementById( 'article' ) ) {
			// Non-Monobook but still recognizable (old-style)
			document.getElementById( 'article').insertBefore(
				messageDiv,
				document.getElementById( 'article' ).firstChild
			);
		} else {
			return false;
		}
	}

	messageDiv.setAttribute( 'id', 'mw-js-message' );
	if( className ) {
		messageDiv.setAttribute( 'class', 'mw-js-message-'+className );
	}
	messageDiv.innerHTML = message;
	return true;
}

/**
 * Inject a cute little progress spinner after the specified element
 *
 * @param element Element to inject after
 * @param id Identifier string (for use with removeSpinner(), below)
 */
function injectSpinner( element, id ) {
	var spinner = document.createElement( "img" );
	spinner.id = "mw-spinner-" + id;
	spinner.src = stylepath + "/common/images/spinner.gif";
	spinner.alt = spinner.title = "...";
	if( element.nextSibling ) {
		element.parentNode.insertBefore( spinner, element.nextSibling );
	} else {
		element.parentNode.appendChild( spinner );
	}
}

/**
 * Remove a progress spinner added with injectSpinner()
 *
 * @param id Identifier string
 */
function removeSpinner( id ) {
	var spinner = document.getElementById( "mw-spinner-" + id );
	if( spinner ) {
		spinner.parentNode.removeChild( spinner );
	}
}


/**
 * Add an event handler to an element
 *
 * @param Element element Element to add handler to
 * @param String attach Event to attach to
 * @param callable handler Event handler callback
 */
function addHandler( element, attach, handler ) {
	if( window.addEventListener ) {
		element.addEventListener( attach, handler, false );
	} else if( window.attachEvent ) {
		element.attachEvent( 'on' + attach, handler );
	}
}

/**
 * Add a click event handler to an element
 *
 * @param Element element Element to add handler to
 * @param callable handler Event handler callback
 */
function addClickHandler( element, handler ) {
	addHandler( element, 'click', handler );
}


function runOnloadHook() {
	// don't run anything below this for non-dom browsers
	if (doneOnloadHook || !(document.getElementById && document.getElementsByTagName)) {
		return;
	}

	// set this before running any hooks, since any errors below
	// might cause the function to terminate prematurely
	doneOnloadHook = true;

	histrowinit();
	unhidetzbutton();
//
//	prefs.js calls addOnloadHook( tabbedprefs ), so the following call is redundant and causes the tabbedprefs toc to display twice.
//
//	tabbedprefs();
	updateTooltipAccessKeys( null );
	akeytt( null );
	scrollEditBox();
	setupCheckboxShiftClick();
	sortables_init();

	// Run any added-on functions
	for (var i = 0; i < onloadFuncts.length; i++) {
		onloadFuncts[i]();
	}
}

// Note: all skins should call runOnloadHook() at the end of html output, so the below should be redundant. It's there just in case.
hookEvent("load", runOnloadHook);



/**
  * Create Google Analytics instance for Citizendium
 */
function loadga() {
	var c; (c = document.createElement("script")).src = "https://www.googletagmanager.com/gtag/js?id=G-W7ML9SNPXT";
	document.head.appendChild(c);

	window.dataLayer = window.dataLayer || [];
	function gtag(){dataLayer.push(arguments);}
	gtag('js', new Date());
	gtag('config', 'G-W7ML9SNPXT');
}

//Call prior function
loadga();


/**
  * Modify link behavior to open in a new tab when contained in a span.newtab
  */
function checklinks(){
	Array.from(document.getElementsByClassName("newtab")).forEach(function(obj){obj.getElementsByTagName("a")[0].target="_blank"});
}

//Call prior function
checklinks();


/* </nowiki> */