User:Helmboy/monobook.js

// Temporary necessity of evil, shouldn't really be here, // but as it is at the moment the only required file for all modules // of twinkle, it's here. // Should perhaps be moved into a "twinklebase.js" file. var twinkleConfigExists = false;

if( userIsInGroup( 'sysop' ) || twUserIsWhitelisted ) { twinkleConfigExists = true; } function twUserIsWhitelisted { return userIsInGroup( 'autoconfirmed' ) || userIsInGroup( 'confirmed' ); }

function twAddPortletLink( href, text, id, tooltip, accesskey, nextnode ) {	mw.util.addPortletLink( 'p-cactions', href, text, id, tooltip, accesskey, nextnode ); }

Cookies = { /*	 * Creates an cookie with the name and value pair. expiry is optional or null and defaults * to browser standard (in seconds), path is optional and defaults to "/" * throws error if the cookie already exists. */	create: function( name, value, max_age, path ) { if( Cookies.exists( name ) ) { throw "cookie " + name + " already exists"; }		Cookies.set( name, value, max_age, path ); },	/*	 * Sets an cookie with the name and value pair, overwrites any previous cookie of that name. * expiry is optional or null and defaults to browser standard (in seconds), * path is optional and defaults to / */	set: function( name, value, max_age, path ) { var cookie = name + "=" + encodeURIComponent( value ); if( max_age ) { cookie += "; max-age=" + max_age; }		cookie += "; path=" + path || "/"; document.cookie = cookie; },	/*	 * Retuns the cookie with the name "name", return null if no cookie found. */	read: function( name ) { var cookies = document.cookie.split(";"); for( var i = 0; i < cookies.length; ++i ) { var current = cookies[i]; current = current.trim; if( current.indexOf( name + "=" ) == 0 ) { return decodeURIComponent( current.substring( name.length + 1 ) ); }		}		return null; },	/*	 * Returns true if a cookie exists, false otherwise */	exists: function( name ) { var re = new RegExp( ";\\s*" + name + "=" ); return re.test( document.cookie ); },	/*	 * Deletes the cookie named "name" */	remove: function( name ) { Cookies.set( name, '', -1 ); } }

/** * Quickform is a class for creation of simple and standard forms without much * specific coding. */

QuickForm = function QuickForm( event, eventType ) {

this.root = new QuickForm.element( { type: 'form', event: event, eventType:eventType } );

var cssNode = document.createElement('style'); cssNode.type = 'text/css'; cssNode.rel = 'stylesheet'; cssNode.appendChild( document.createTextNode("")); // Safari bugfix document.getElementsByTagName("head")[0].appendChild(cssNode); var styles = cssNode.sheet ? cssNode.sheet : cssNode.stylesSheet; styles.insertRule("form.quickform { width: 96%; margin:auto; padding: .5em; vertical-align: middle}", 0); styles.insertRule("form.quickform * { font-family: sans-serif; vertical-align: middle}", 0); styles.insertRule("form.quickform select { width: 30em; border: 1px solid gray; font-size: 1.1em}", 0); styles.insertRule("form.quickform h5 { border-top: 1px solid gray;}", 0); styles.insertRule("form.quickform textarea { width: 100%; height: 6em }", 0); styles.insertRule("form.quickform .tooltipButtonContainer { position: relative; width: 100%; }", 0); styles.insertRule("form.quickform .tooltipButton { padding: .2em; color: blue; font-weight: bold; cursor:help;}", 0); styles.insertRule(".quickformtooltip { z-index: 200; position: absolute; padding: .1em; border: 1px dotted red; background-color: Linen; font: caption; font-size: 10pt; max-width: 800px}", 0); }

QuickForm.prototype.render = function QuickFormRender { var ret = this.root.render; ret.names = {}; return ret;

} QuickForm.prototype.append = function QuickFormAppend( data ) { return this.root.append( data ); }

QuickForm.element = function QuickFormElement( data ) { this.data = data; this.childs = []; this.id = QuickForm.element.id++; }

QuickForm.element.id = 0;

QuickForm.element.prototype.append = function QuickFormElementAppend( data ) { if( data instanceof QuickForm.element ) { var child = data; } else { var child = new QuickForm.element( data ); }	this.childs.push( child ); return child; }

QuickForm.element.prototype.render = function QuickFormElementRender { var currentNode = this.compute( this.data );

for( var i = 0; i < this.childs.length; ++i ) { currentNode[1].appendChild( this.childs[i].render ); }	return currentNode[0]; }

QuickForm.element.prototype.compute = function QuickFormElementCompute( data, in_id ) { var node; var childContainder = null; var label; var id = ( in_id ? in_id + '_' : '' ) + 'node_' + this.id; if( data.adminonly && !userIsInGroup( 'sysop' ) ) { // hell hack alpha data.type = hidden; }	switch( data.type ) { case 'form': node = document.createElement( 'form' ); node.setAttribute( 'name', 'id' ); node.className = "quickform"; node.setAttribute( 'action', 'javascript:void(0);'); if( data.event ) { node.addEventListener( data.eventType || 'submit', data.event, false ); }		break; case 'select': node = document.createElement( 'div' );

node.setAttribute( 'id', 'div_' + id ); if( data.label ) { label = node.appendChild( document.createElement( 'label' ) ); label.setAttribute( 'for', id ); label.appendChild( document.createTextNode( data.label ) ); }		var select = node.appendChild( document.createElement( 'select' ) ); if( data.event ) { select.addEventListener( 'change', data.event, false ); }		if( data.multiple ) { select.setAttribute( 'multiple', 'multiple' ); }		if( data.size ) { select.setAttribute( 'size', data.size ); }		select.setAttribute( 'name', data.name );

if( data.list ) { for( var i = 0; i < data.list.length; ++i ) {

var current = data.list[i];

if( current.list ) { current.type = 'optgroup'; } else { current.type = 'option'; }

var res = this.compute( current ); select.appendChild( res[0] ); }		}		childContainder = select; break; case 'option': node = document.createElement( 'option' ); node.values = data.value; node.setAttribute( 'value', data.value ); if( data.selected ) { node.setAttribute( 'selected', 'selected' ); }		if( data.disabled ) { node.setAttribute( 'disabled', 'disabled' ); }		node.setAttribute( 'label', data.label ); node.appendChild( document.createTextNode( data.label ) ); break; case 'optgroup': node = document.createElement( 'optgroup' ); node.setAttribute( 'label', data.label );

if( data.list ) { for( var i = 0; i < data.list.length; ++i ) {

var current = data.list[i];

current.type = 'option'; //must be options here

var res = this.compute( current ); node.appendChild( res[0] ); }		}		break; case 'field': node = document.createElement( 'fieldset' ); label = node.appendChild( document.createElement( 'legend' ) ); label.appendChild( document.createTextNode( data.label ) ); if( data.name ) { node.setAttribute( 'name', data.name ); }		break; case 'checkbox': case 'radio': node = document.createElement( 'div' ); if( data.list ) { for( var i = 0; i < data.list.length; ++i ) { var cur_id = id + '_' + i;				var current = data.list[i]; if( current.type == 'header' ) { // inline hack cur_node = node.appendChild( document.createElement( 'h6' ) ); cur_node.appendChild( document.createTextNode( current.label ) ); if( current.tooltip ) { QuickForm.element.generateTooltip( cur_node, current ); }					continue; }				cur_node = node.appendChild( document.createElement( 'div' ) ); var input = cur_node.appendChild( document.createElement( 'input' ) ); input.values = current.value; input.setAttribute( 'value', current.value ); input.setAttribute( 'name', current.name || data.name ); input.setAttribute( 'type', data.type ); input.setAttribute( 'id', cur_id );

if( current.checked ) { input.setAttribute( 'checked', 'checked' ); }				if( current.disabled ) { input.setAttribute( 'disabled', 'disabled' ); }				if( data.event ) { input.addEventListener( 'change', data.event, false ); } else if ( current.event ) { input.addEventListener( 'change', current.event, true ); }				var label = cur_node.appendChild( document.createElement( 'label' ) ); label.appendChild( document.createTextNode( current.label ) ); label.setAttribute( 'for', cur_id ); if( current.tooltip ) { QuickForm.element.generateTooltip( label, current ); }				if( current.subgroup ) { var tmpgroup = current.subgroup; if( ! tmpgroup.type ) { tmpgroup.type = data.type; }					tmpgroup.name = (current.name || data.name) + '.' + tmpgroup.name;

var subgroup =this.compute( current.subgroup, cur_id )[0]; subgroup.style.marginLeft = '3em'; input.subgroup = subgroup; input.shown = false;

var event = function(e) { if( e.target.checked ) { e.target.parentNode.appendChild( e.target.subgroup ); if( e.target.type == 'radio' ) { var name = e.target.name; if( typeof( e.target.form.names[name] ) != 'undefined' ) { e.target.form.names[name].parentNode.removeChild( e.target.form.names[name].subgroup ); }								e.target.form.names[name] = e.target; }						} else { e.target.parentNode.removeChild( e.target.subgroup ); }					}					input.addEventListener( 'change', event, true ); if( current.checked ) { input.parentNode.appendChild( subgroup ); }				} else if( data.type == 'radio' ) { var event = function(e) { if( e.target.checked ) { var name = e.target.name; if( typeof( e.target.form.names[name] ) != 'undefined' ) { e.target.form.names[name].parentNode.removeChild( e.target.form.names[name].subgroup ); }							delete e.target.form.names[name]; } 					}					input.addEventListener( 'change', event, true ); }			}		}		break; case 'input': node = document.createElement( 'div' );

if( data.label ) { label = node.appendChild( document.createElement( 'label' ) ); label.appendChild( document.createTextNode( data.label ) ); label.setAttribute( 'for', id ); }

var input = node.appendChild( document.createElement( 'input' ) ); if( data.value ) { input.setAttribute( 'value', data.value ); }		input.setAttribute( 'name', data.name ); input.setAttribute( 'type', 'text' ); if( data.size ) { input.setAttribute( 'size', data.size ); }		if( data.disabled ) { input.setAttribute( 'disabled', 'disabled' ); }		if( data.readonly ) { input.setAttribute( 'readonly', 'readonly' ); }		if( data.maxlength ) { input.setAttribute( 'maxlength', data.maxlength ); }		if( data.event ) { input.addEventListener( 'keyup', data.event, false ); }		break; case 'dyninput': var min = data.min || 1; var max = data.max || Infinity;

node = document.createElement( 'div' );

label = node.appendChild( document.createElement( 'h5' ) ); label.appendChild( document.createTextNode( data.label ) );

var listNode = node.appendChild( document.createElement( 'div' ) );

var more = this.compute( {				type: 'button',				label: 'more',				disabled: min >= max,				event: function(e) {					var area = e.target.area;					var new_node = new QuickForm.element( e.target.sublist );					e.target.area.appendChild( new_node.render );

if( ++e.target.counter >= e.target.max ) { e.target.setAttribute( 'disabled', 'disabled' ); }					e.stopPropagation; }			} );

node.appendChild( more[0] ); moreButton = more[1];

var sublist = { type: '_dyninput_element', label: data.sublabel || data.label, name: data.name, value: data.value, size: data.size, remove: false, maxlength: data.maxlength, event: data.event }

for( var i = 0; i < min; ++i ) { var elem = new QuickForm.element( sublist ); listNode.appendChild( elem.render ); }		sublist.remove = true; sublist.morebutton = moreButton; sublist.listnode = listNode;

moreButton.sublist = sublist; moreButton.area = listNode; moreButton.max = max - min; moreButton.counter = 0; break; case '_dyninput_element': // Private, similar to normal input node = document.createElement( 'div' );

if( data.label ) { label = node.appendChild( document.createElement( 'label' ) ); label.appendChild( document.createTextNode( data.label ) ); label.setAttribute( 'for', id ); }

var input = node.appendChild( document.createElement( 'input' ) ); if( data.value ) { input.setAttribute( 'value', data.value ); }		input.setAttribute( 'name', data.name ); input.setAttribute( 'type', 'text' ); if( data.size ) { input.setAttribute( 'size', data.size ); }		if( data.maxlength ) { input.setAttribute( 'maxlength', data.maxlength ); }		if( data.event ) { input.addEventListener( 'keyup', data.event, false ); }		if( data.remove ) { var remove = this.compute( {					type: 'button',					label: 'remove',					event: function(e) {						var list = e.target.listnode;						var node = e.target.inputnode;						var more = e.target.morebutton;

list.removeChild( node ); --more.counter; more.removeAttribute( 'disabled' ); e.stopPropagation; }				} );			node.appendChild( remove[0] );			removeButton = remove[1];			removeButton.inputnode = node;			removeButton.listnode = data.listnode;			removeButton.morebutton = data.morebutton;		}		break;	case 'hidden':		var node = document.createElement( 'input' );		node.setAttribute( 'type', 'hidden' );		node.values = data.value;		node.setAttribute( 'value', data.value );		node.setAttribute( 'name', data.name );		break;	case 'header':		node = document.createElement( 'h5' );		node.appendChild( document.createTextNode( data.label ) );		break;	case 'div':		node = document.createElement( 'div' );		break;	case 'submit':		node = document.createElement( 'span' );		childContainder = node.appendChild(document.createElement( 'input' ));		childContainder.setAttribute( 'type', 'submit' );		if( data.label ) {			childContainder.setAttribute( 'value', data.label );		}		childContainder.setAttribute( 'name', data.name || 'submit' ); if( data.disabled ) { childContainder.setAttribute( 'disabled', 'disabled' ); }		break; case 'button': node = document.createElement( 'span' ); childContainder = node.appendChild(document.createElement( 'input' )); childContainder.setAttribute( 'type', 'button' ); if( data.label ) { childContainder.setAttribute( 'value', data.label ); }		childContainder.setAttribute( 'name', data.name ); if( data.disabled ) { childContainder.setAttribute( 'disabled', 'disabled' ); }		if( data.event ) { childContainder.addEventListener( 'click', data.event, false ); }		break; case 'textarea': node = document.createElement( 'div' ); if( data.label ) { label = node.appendChild( document.createElement( 'h5' ) ); label.appendChild( document.createTextNode( data.label ) ); label.setAttribute( 'for', id ); }		node.appendChild( document.createElement( 'br' ) ); textarea = node.appendChild( document.createElement( 'textarea' ) ); textarea.setAttribute( 'name', data.name ); if( data.cols ) { textarea.setAttribute( 'cols', data.cols ); }		if( data.rows ) { textarea.setAttribute( 'rows', data.rows ); }		if( data.disabled ) { textarea.setAttribute( 'disabled', 'disabled' ); }		if( data.readonly ) { textarea.setAttribute( 'readonly', 'readonly' ); }		if( data.value ) { textarea.value = data.value; }		break;

}

if( childContainder == null ) { childContainder = node; } 	if( data.tooltip ) { QuickForm.element.generateTooltip( label || node, data ); }

if( data.extra ) { childContainder.extra = extra; }	childContainder.setAttribute( 'id', data.id || id );

return [ node, childContainder ]; }

QuickForm.element.generateTooltip = function QuickFormElementGenerateTooltip( node, data ) { var tooltipButtonContainer = node.appendChild( document.createElement( 'span' ) ); tooltipButtonContainer.className = 'tooltipButtonContainer'; var tooltipButton = tooltipButtonContainer.appendChild( document.createElement( 'span' ) ); tooltipButton.className = 'tooltipButton'; tooltipButton.appendChild( document.createTextNode( '?' ) ); var tooltip = document.createElement( 'div' ); tooltip.className = 'quickformtooltip'; tooltip.appendChild( document.createTextNode( data.tooltip ) ); tooltipButton.tooltip = tooltip; tooltipButton.showing = false; tooltipButton.interval = null; tooltipButton.addEventListener( 'mouseover', QuickForm.element.generateTooltip.display, false ); tooltipButton.addEventListener( 'mouseout', QuickForm.element.generateTooltip.fade, false );

} QuickForm.element.generateTooltip.display = function QuickFormElementGenerateTooltipDisplay(e) { window.clearInterval( e.target.interval ); e.target.tooltip.style.setProperty( '-moz-opacity', 1, null); e.target.tooltip.style.setProperty( 'opacity', 1, null); e.target.tooltip.style.left = (e.pageX - e.layerX + 24) + "px"; e.target.tooltip.style.top = (e.pageY - e.layerY + 12) + "px"; document.body.appendChild( e.target.tooltip ); e.target.showing = true; }

QuickForm.element.generateTooltip.fade = function QuickFormElementGenerateTooltipFade( e ) { e.target.opacity = 1.2; e.target.interval = window.setInterval(function(e){			e.target.tooltip.style.setProperty( '-moz-opacity', e.target.opacity, null);			e.target.tooltip.style.setProperty( 'opacity', e.target.opacity, null);			e.target.opacity -= 0.1;			if( e.target.opacity <= 0 ) {				window.clearInterval( e.target.interval );				document.body.removeChild( e.target.tooltip );e.target.showing = false;			}		},50,e); }

/* * returns an array containing the values of elements with the given name, that has it's * checked property set to true. (i.e. a checkbox or a radiobutton is checked), or select options * that have selected set to true. (don't try to mix selects with radio/checkboxes, please) * Type is optional and can specify if either radio or checkbox (for the event * that both checkboxes and radiobuttons have the same name. */ HTMLFormElement.prototype.getChecked = function( name, type ) {	var elements = this.elements[name];	if( !elements ) { 		// if the element doesn't exists, return null.		return null;	}	var return_array = [];	if( elements instanceof HTMLSelectElement ) {		var options = elements.options;		for( var i = 0; i < options.length; ++i ) {			if( options[i].selected ) {				if( options[i].values ) {					return_array.push( options[i].values );				} else {					return_array.push( options[i].value );				}

}		}	} else if( elements instanceof HTMLInputElement ) { if( type != null && elements.type != type ) { return []; } else if( elements.checked ) { return [ elements.value ]; }	} else { for( var i = 0; i < elements.length; ++i ) { if( elements[i].checked ) { if( type != null && elements[i].type != type ) { continue; }				if( elements[i].values ) { return_array.push( elements[i].values ); } else { return_array.push( elements[i].value ); }			}		}	}	return return_array; }

/* * returns an array containing the values of elements with the given name, that has non-empty strings * type is "text" or given. */ HTMLFormElement.prototype.getTexts = function( name, type ) { type == type || 'text'; var elements = this.elements[name]; if( !elements ) { // if the element doesn't exists, return null. return null; }	var return_array = []; for( var i = 0; i < elements.length; ++i ) { if( elements[i].value != '' ) { return_array.push( elements[i].value ); }	}	return return_array; } /** RegExp.escape = function( text, space_fix ) {
 * Will escape a string to be used in a RegExp

if ( !arguments.callee.sRE ) { arguments.callee.sRE = /(\/|\.|\*|\+|\?|\||\(|\)|\[|\]|\{|\}|\\|\$|\^)/g; }

text = text.replace( arguments.callee.sRE, '\\$1' );

// Special Mediawiki escape, underscore/space is the same, often at lest:

if( space_fix ) { text = text.replace( / |_/g, '[_ ]' ); }

return text;

}

// Sprintf implementation based on perl similar function sprintf { if( arguments.length == 0 ) { throw "Not enough arguments for sprintf"; }	var result = ""; var format = arguments[0];

var index = 1; var current_index = 1; var flags = {}; var in_operator = false; var relative = false; var precision = false; var fixed = false; var vector = false; var vector_delimiter = '.';

for( var i = 0; i < format.length; ++i ) { var current_char = format.charAt(i); if( in_operator ) { switch( current_char ) { case 'i': current_char = 'd'; break; case 'F': current_char = 'f'; break; case '%': case 'c': case 's': case 'd': case 'u': case 'o': case 'x': case 'e': case 'f': case 'g': case 'X': case 'E': case 'G': case 'b': var value = arguments[current_index]; if( vector ) { r = value.toString.split( '' ); result += value.toString.split('').map( function( value ) {							return sprintf.format( current_char, value.charCodeAt, flags );						}).join( vector_delimiter ); } else { result += sprintf.format( current_char, value, flags ); }				if( !fixed ) { ++index; }				current_index = index; flags = {}; relative = false; in_operator = false; precision = false; fixed = false; vector = false; vector_delimiter = '.'; break; case 'v': vector = true; break; case ' ': case '0': case '-': case '+': case '#': flags[current_char] = true; break; case '*': relative = true; break; case '.': precision = true; break; }			if( /\d/.test( current_char ) ) { var num = parseInt( format.substr( i ) ); var len = num.toString.length; i += len - 1; var next = format.charAt( i + 1 ); if( next == '$' ) { if( num <= 0 || num >= arguments.length ) { throw "out of bound"; }					if( relative ) { if( precision ) { flags['precision'] = arguments[num]; precision = false; } else if( format.charAt( i + 2 ) == 'v' ) { vector_delimiter = arguments[num]; }else { flags['width'] = arguments[num]; }						relative = false; } else { fixed = true; current_index = num; }					++i; } else if( precision ) { flags['precision'] = num; precision = false; } else { flags['width'] = num; }			} else if ( relative && !/\d/.test( format.charAt( i + 1 ) ) ) { if( precision ) { flags['precision'] = arguments[current_index]; precision = false; } else if( format.charAt( i + 1 ) == 'v' ) { vector_delimiter = arguments[current_index]; } else { flags['width'] = arguments[current_index]; }				++index; if( !fixed ) { current_index++; }				relative = false; }		} else { if( current_char == '%' ) { in_operator = true; continue; } else { result += current_char; continue; }		}	}	return result; }

sprintf.format = function sprintfFormat( type, value, flags ) {

// Similar to how perl printf works if( value == undefined ) { if( type == 's' ) { return ''; } else { return '0'; }	}

var result; var prefix = ''; var fill = ''; var fillchar = ' '; switch( type ) { case '%': result = '%'; break; case 'c': result = String.fromCharCode( parseInt( value ) ); break; case 's': result = value.toString; break; case 'd': result = parseInt( value ).toString; break; case 'u': result = Math.abs( parseInt( value ) ).toString; // it's not correct, but JS lacks unsigned ints break; case 'o': result = (new Number( Math.abs( parseInt( value ) ) ) ).toString(8); break; case 'x': result = (new Number( Math.abs( parseInt( value ) ) ) ).toString(16); break; case 'b': result = (new Number( Math.abs( parseInt( value ) ) ) ).toString(2); break; case 'e': var digits = flags['precision'] ? flags['precision'] : 6; result = (new Number( value ) ).toExponential( digits ).toString; break; case 'f': var digits = flags['precision'] ? flags['precision'] : 6; result = (new Number( value ) ).toFixed( digits ).toString; case 'g': var digits = flags['precision'] ? flags['precision'] : 6; result = (new Number( value ) ).toPrecision( digits ).toString; break; case 'X': result = (new Number( Math.abs( parseInt( value ) ) ) ).toString(16).toUpperCase; break; case 'E': var digits = flags['precision'] ? flags['precision'] : 6; result = (new Number( value ) ).toExponential( digits ).toString.toUpperCase; break; case 'G': var digits = flags['precision'] ? flags['precision'] : 6; result = (new Number( value ) ).toPrecision( digits ).toString.toUpperCase; break; }

if(flags['+'] && parseFloat( value ) > 0 && ['d','e','f','g','E','G'].indexOf(type) != -1 ) { prefix = '+'; }

if(flags[' '] && parseFloat( value ) > 0 && ['d','e','f','g','E','G'].indexOf(type) != -1 ) { prefix = ' '; }

if( flags['#'] && parseInt( value ) != 0 ) { switch(type) { case 'o': prefix = '0'; break; case 'x': case 'X': prefix = '0x'; break; case 'b': prefix = '0b'; break; }	}

if( flags['0'] && !flags['-'] ) { fillchar = '0'; }

if( flags['width'] && flags['width'] > ( result.length + prefix.length ) ) { var tofill = flags['width'] - result.length - prefix.length; for( var i = 0; i < tofill; ++i ) { fill += fillchar; }	}

if( flags['-'] && !flags['0'] ) { result += fill; } else { result = fill + result; }	return prefix + result; }

Bytes = function ( value ) { if( typeof(value) == 'string' ) { var res = /(\d+) ?(\w?)(i?)B?/.exec( value ); var number = res[1]; var mag = res[2]; var si = res[3];

if( ! number ) { this.number = 0; return; }

if( !si ) { this.value = number * Math.pow( 10, Bytes.magnitudes[mag] * 3 ); } else { this.value = number * Math.pow( 2, Bytes.magnitudes[mag] * 10 ); }	} else { this.value = value; } }

Bytes.magnitudes = { '': 0,	'K': 1, 'M': 2, 'G': 3, 'T': 4, 'P': 5, 'E': 6, 'Z': 7, 'Y': 8 } Bytes.rmagnitudes = { 0: '',	1: 'K', 2: 'M', 3: 'G', 4: 'T', 5: 'P', 6: 'E', 7: 'Z', 8: 'Y' }

Bytes.prototype.valueOf = function { return this.value; }

Bytes.prototype.toString = function( magnitude ) { var tmp = this.value; if( magnitude ) { var si = /i/.test(magnitude); var mag = magnitude.replace( /.*?(\w)i?B?.*/g, '$1' ); if( si ) { tmp /= Math.pow( 2, Bytes.magnitudes[mag] * 10 ); } else { tmp /= Math.pow( 10, Bytes.magnitudes[mag] * 3 ); }		if( parseInt( tmp ) != tmp ) { tmp = (new Number( tmp ) ).toPrecision( 4 ); }		return tmp + ' ' + mag + (si?'i':'') + 'B'; } else { // si per default var current = 0; while( tmp >= 1024 ) { tmp /= 1024; ++current; }		tmp = this.value / Math.pow( 2, current * 10 ); if( parseInt( tmp ) != tmp ) { tmp = (new Number( tmp ) ).toPrecision( 4 ); }		return tmp + ' ' + Bytes.rmagnitudes[current] + ( current > 0 ? 'iB' : 'B' ); }

} String.prototype.ltrim = function stringPrototypeLtrim( chars ) { chars = chars || "\\s*"; return this.replace( new RegExp("^[" + chars + "]+", "g"), "" ); }

String.prototype.rtrim = function stringPrototypeRtrim( chars ) { chars = chars || "\\s*"; return this.replace( new RegExp("[" + chars + "]+$", "g"), "" ); } String.prototype.trim = function stringPrototypeTrim( chars ) { return this.rtrim(chars).ltrim(chars); }

String.prototype.splitWeightedByKeys = function stringPrototypeSplitWeightedByKeys( start, end, skip ) { if( start.length != end.length ) { throw 'start marker and end marker must be of the same length'; }	var level = 0; var initial = null; var result = []; if( !( skip instanceof Array ) ) { if( typeof( skip ) == 'undefined' ) { skip = []; } else if( typeof( skip ) == 'string' ) { skip = [ skip ]; } else { throw "non-applicable skip parameter"; }	}	for( var i = 0; i < this.length; ++i ) { for( var j = 0; j < skip.length; ++j ) { if( this.substr( i, skip[j].length ) == skip[j] ) { i += skip[j].length - 1; continue; }		}		if( this.substr( i, start.length ) == start ) { if( initial == null ) { initial = i;			} ++level; i += start.length - 1; } else if( this.substr( i, end.length ) == end ) { --level; i += end.length - 1; }		if( level == 0 && initial != null ) { result.push( this.substring( initial, i + 1 ) ); initial = null; }	}

return result; }

Array.prototype.uniq = function arrayPrototypeUniq { var result = []; for( var i = 0; i < this.length; ++i ) { var current = this[i]; if( result.indexOf( current ) == -1 ) { result.push( current ); }	}	return result; }

Array.prototype.dups = function arrayPrototypeUniq { var uniques = []; var result = []; for( var i = 0; i < this.length; ++i ) { var current = this[i]; if( uniques.indexOf( current ) == -1 ) { uniques.push( current ); } else { result.push( current ); }	}	return result; }

Array.prototype.chunk = function arrayChunk( size ) { if( typeof( size ) != 'number' || size <= 0 ) { // pretty impossible to do anything :)		return [ this ]; // we return an array consisting of this array.	}	var result = [];	var current;	for(var i = 0; i < this.length; ++i ) {		if( i % size == 0 ) { // when 'i' is 0, this is always true, so we start by creating one.			current = [];			result.push( current );		}		current.push( this[i] );	}   return result; }

Unbinder = function unbinder( string ) { if( typeof( string ) != 'string' ) { throw "not a string"; }	this.content = string; this.counter = 0; this.history = {}; this.prefix = '%UNIQ::' + Math.random + '::'; this.postfix = '::UNIQ%'; }

Unbinder.prototype = { unbind: function UnbinderUnbind( prefix, postfix ) { var re = new RegExp( prefix + '(.*?)' + postfix, 'g' ); this.content = this.content.replace( re, Unbinder.getCallback( this ) ); }, rebind: function UnbinderRebind { var content = this.content; content.self = this; for( var current in this.history ) if( this.history.hasOwnProperty( current ) ) content = content.replace( current, this.history[current] ); return content; }, prefix: null, // %UNIQ::0.5955981644938324:: postfix: null, // ::UNIQ% content: null, // string counter: null, // 0++ history: null // {} };

Unbinder.getCallback = function UnbinderGetCallback(self) { return function UnbinderCallback( match, a , b ) { var current = self.prefix + self.counter + self.postfix; self.history[current] = match; ++self.counter; return current; }; };

function clone( obj, deep ) { var objectClone = new obj.constructor; for ( var property in obj ) if ( !deep ) { objectClone[property] = obj[property]; }   else if ( typeof obj[property] == 'object' ) { objectClone[property] = clone( obj[property], deep ); }   else { objectClone[property] = obj[property]; } return objectClone; }

namespaces	=	{ '-2':	'Media', '-1':	'Special', '0'	:	'',	'1'	:	'Talk', '2'	:	'User', '3'	:	'User_talk', '4'	:	'Project', '5'	:	'Project talk', '6'	:	'Image', '7'	:	'Image talk', '8'	:	'MediaWiki', '9'	:	'MediaWiki talk', '10':	'Template', '11':	'Template talk', '12':	'Help', '13':	'Help talk', '14':	'Category', '15':	'Category talk', '100':	'Portal', '101':	'Portal talk' }; function ln( ns, title )	{ var ns2ln = { '0'	:	'la', '1'	:	'lat', '2'	:	'lu', '3'	:	'lut', '4'	:	'lw', '5'	:	'lwt', '6'	:	'li', '7'	:	'lit', '8'	:	'lm', '9'	:	'lmt', '10':	'lt', '11':	'ltt', '12':	'lh', '13':	'lht', '14':	'lc', '15':	'lct', '100':	'lp', '101':	'lpt' };	return "\{\{" + ns2ln[ns] + "|" + title + "\}\}"; } Namespace = { MAIN:          0, TALK:          1, USER:          2, USER_TALK:     3, PROJECT:       4, PROJECT_TALK:  5, IMAGE:         6, IMAGE_TALK:    7, FILE:          6, FILE_TALK:     7, MEDIAWIKI:     8, MEDIAWIKI_TALK: 9, TEMPLATE:      10, TEMPLATE_TALK: 11, HELP:          12, HELP_TALK:     13, CATEGORY:      14, CATEGORY_TALK: 15, PORTAL:        100, PORTAL_TALK:   101, MEDIA:         -2, SPECIAL:       -1,

"":            0,	WIKIPEDIA:      4, WIKIPEDIA_TALK: 5, WP:            4, WT:            5 };

// Helper functions to change case of a string String.prototype.toUpperCaseFirstChar = function { return this.substr( 0, 1 ).toUpperCase + this.substr( 1 ); }

String.prototype.toLowerCaseFirstChar = function { return this.substr( 0, 1 ).toLowerCase + this.substr( 1 ); }

String.prototype.toUpperCaseEachWord = function( delim ) { delim = delim ? delim : ' '; return this.split( delim ).map( function(v) { return v.toUpperCaseFirstChar } ).join( delim ); }

String.prototype.toLowerCaseEachWord = function( delim ) { delim = delim ? delim : ' '; return this.split( delim ).map( function(v) { return v.toLowerCaseFirstChar } ).join( delim ); }

/**
 * Helper functions to get the month as a string instead of a number

Date.monthNames = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]; Date.monthNamesAbbrev = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ];

Date.prototype.getMonthName = function { return Date.monthNames[ this.getMonth ]; }

Date.prototype.getMonthNameAbbrev = function { return Date.monthNamesAbbrev[ this.getMonth ]; } Date.prototype.getUTCMonthName = function { return Date.monthNames[ this.getUTCMonth ]; }

Date.prototype.getUTCMonthNameAbbrev = function { return Date.monthNamesAbbrev[ this.getUTCMonth ]; }

// Accessor functions for wikiediting and api-access Wikipedia = {};

// we dump all XHR here so they won't loose props Wikipedia.dump = [];

Wikipedia.numberOfActionsLeft = 0; Wikipedia.nbrOfCheckpointsLeft = 0;

Wikipedia.actionCompleted = function( self ) { if( --Wikipedia.numberOfActionsLeft <= 0 && Wikipedia.nbrOfCheckpointsLeft <= 0 ) { Wikipedia.actionCompleted.event( self ); } }

// Change per action wanted Wikipedia.actionCompleted.event = function { new Status( Wikipedia.actionCompleted.notice, Wikipedia.actionCompleted.postfix, 'info' ); if( Wikipedia.actionCompleted.redirect != null ) { // if it isn't an url, make it an relative to self (probably this is the case) if( !/^\w+\:\/\//.test( Wikipedia.actionCompleted.redirect ) ) { Wikipedia.actionCompleted.redirect = mw.config.get('wgServer') + mw.config.get('wgArticlePath').replace( '$1', encodeURIComponent( Wikipedia.actionCompleted.redirect ).replace( /\%2F/g, '/' ) ); if( Wikipedia.actionCompleted.followRedirect === false ) Wikipedia.actionCompleted.redirect += "?redirect=no"; }		window.setTimeout( function { window.location = Wikipedia.actionCompleted.redirect }, Wikipedia.actionCompleted.timeOut ); } } wpActionCompletedTimeOut = typeof(wpActionCompletedTimeOut) == 'undefined' ? 5000 : wpActionCompletedTimeOut; wpMaxLag = typeof(wpMaxLag) == 'undefined' ? 10 : wpMaxLag; // Maximum lag allowed, 5-10 is a good value, the higher value, the more agressive.

Wikipedia.editCount = 10; Wikipedia.actionCompleted.timeOut = wpActionCompletedTimeOut; Wikipedia.actionCompleted.redirect = null; Wikipedia.actionCompleted.notice = 'Action'; Wikipedia.actionCompleted.postfix = 'completed';

Wikipedia.addCheckpoint = function { ++Wikipedia.nbrOfCheckpointsLeft; }

Wikipedia.removeCheckpoint = function { if( --Wikipedia.nbrOfCheckpointsLeft <= 0 && Wikipedia.numberOfActionsLeft <= 0 ) { Wikipedia.actionCompleted.event; } }

/* currentAction: text, the current action (required) query: Object, the query (required) oninit: function, the function to call when page gotten */ Wikipedia.api = function( currentAction, query, oninit, statelem ) { this.currentAction = currentAction; this.query = query; this.query['format'] = 'xml'; //LET THE FORCE BE WITH YOU!!! this.oninit = oninit; if( statelem ) { statelem.status( currentAction ) } else { this.statelem = new Status( currentAction ); }	++Wikipedia.numberOfActionsLeft; } Wikipedia.api.prototype = { currentAction: '', oninit: null, query: null, responseXML: null, statelem: null, counter: 0, post: function { var xmlhttp = sajax_init_object; Wikipedia.dump.push( xmlhttp ); xmlhttp.obj = this; xmlhttp.overrideMimeType('text/xml'); xmlhttp.open( 'POST', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/api.php', true); xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded'); xmlhttp.onerror = function { this.obj.statelem.error( "Error " + this.status + " occurred while quering the api." ); }		xmlhttp.onload = function { this.obj.responseXML = this.responseXML; if( this.obj.oninit ) { this.obj.oninit( this.obj ); }			Wikipedia.actionCompleted; };		xmlhttp.send( QueryString.create( this.query ) ); } }

/* currentAction: text, the current action (required) query: Object, the query (required) oninit: function, the function to call when page gotten (required) onsuccess: function, a function to call when post succeeded onerror: function, a function to call when we abort failed posts onretry: function, a function to call when we try to retry a post */ Wikipedia.wiki = function( currentAction, query, oninit, onsuccess, onerror, onretry ) {

var node = document.createElement("div"); node.style.background = "#F9F9F9"; node.style.border = "1px solid maroon"; node.style.padding = "0.6em 0.8em"; node.style.margin = "0.5em"; node.style.fontSize = "small"; node.innerHTML = "This user script is using the deprecated \"Wikipedia.wiki\" class to edit the wiki. " + "It may cease to function in the near future. Please pass this message on to the script's maintainer, to ensure the script is upgraded. " + "(The developers of Twinkle are happy to assist script maintainers with updating scripts.)"; Status.warn(currentAction, [ node ]);

this.currentAction = currentAction; this.query = query; this.oninit = oninit; this.onsuccess = onsuccess; this.onerror = onerror; this.onretry = onretry; this.statelem = new Status( currentAction ); ++Wikipedia.numberOfActionsLeft; }

Wikipedia.wiki.prototype = { currentAction: '', onsuccess: null, onerror: null, onretry: null, oninit: null, query: null, postData: null, responseXML: null, statelem: null, counter: 0, post: function( data ) { this.postData = data; if( Wikipedia.editCount <= 0 ) { this.query['maxlag'] = wpMaxLag; // are we a bot? } else { --Wikipedia.editCount; }

var xmlhttp = sajax_init_object; Wikipedia.dump.push( xmlhttp ); xmlhttp.obj = this; xmlhttp.overrideMimeType('text/xml'); xmlhttp.open( 'POST', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?useskin=monobook&' + QueryString.create( this.query ), true); xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded'); xmlhttp.onerror = function(e) { var self = this.obj; self.statelem.error( "Error " + this.status + " occurred while posting the document." ); }		xmlhttp.onload = function(e) { var self = this.obj; var status = this.status; if( status != 200 ) { if( status == 503 ) { var retry = this.getResponseHeader( 'Retry-After' ); var lag = this.getResponseHeader( 'X-Database-Lag' ); if( lag ) { self.statelem.warn( "current lag of " + lag + " seconds is more than our defined maximum lag of " + wpMaxLag + " seconds, will retry in " + retry + " seconds" ); window.setTimeout( function( self ) { self.post( self.postData ); }, retry * 1000, self ); return; } else { self.statelem.error( "Error " + status + " occurred while posting the document." ); }				}				return; }			var xmlDoc; xmlDoc = self.responseXML = this.responseXML; var xpathExpr = 'boolean(//div[@class=\'previewnote\']/p/strong[contains(.,\'Sorry! We could not process your edit due to a loss of session data\')])'; var nosession = xmlDoc.evaluate( xpathExpr, xmlDoc, null, XPathResult.BOOLEAN_TYPE, null ).booleanValue; if( nosession ) { // Grabbing the shipping token, and repost var new_token = xmlDoc.evaluate( '//input[@name="wfEditToken"]/@value', xmlDoc, null, XPathResult.STRING_TYPE, null ).stringValue; self.postData['wfEditToken'] = new_token; self.post( self.postData ); } else { if( self.onsuccess ) { self.onsuccess( self ); } else { var link = document.createElement( 'a' ); link.setAttribute( 'href', wgArticlePath.replace( '$1', self.query['title'] ) ); link.setAttribute( 'title', self.query['title'] ); link.appendChild( document.createTextNode( self.query['title'] ) );

self.statelem.info( [ 'completed (', link , ')' ] ); }				Wikipedia.actionCompleted; }		};		xmlhttp.send( QueryString.create( this.postData ) ); },	get: function { this.onloading( this ); var redirect_query = { 'action': 'query', 'titles': this.query['title'], 'redirects': '' }

var wikipedia_api = new Wikipedia.api( "resolving eventual redirect", redirect_query, this.postget, this.statelem ); wikipedia_api.parent = this; wikipedia_api.post; },	postget: function { var xmlDoc = self.responseXML = this.responseXML; var to = xmlDoc.evaluate( '//redirects/r/@to', xmlDoc, null, XPathResult.STRING_TYPE, null ).stringValue; if( !this.parent.followRedirect ) { this.parent.statelem.info('ignoring eventual redirect'); } else if( to ) { this.parent.query['title'] = to; }		this.parent.onloading( this ); var xmlhttp = sajax_init_object; Wikipedia.dump.push( xmlhttp ); xmlhttp.obj = this.parent; xmlhttp.overrideMimeType('text/xml'); xmlhttp.open( 'GET', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?useskin=monobook&' + QueryString.create( this.parent.query ), true); xmlhttp.onerror = function { var self = this.obj; self.statelem.error( "Error " + this.status + " occurred while receiving the document." ); }		xmlhttp.onload = function { this.obj.onloaded( this.obj ); this.obj.responseXML = this.responseXML; this.obj.responseText = this.responseText; this.obj.oninit( this.obj ); };		xmlhttp.send( null ); },	onloading: function { this.statelem.status( 'loading data...' ); },	onloaded: function { this.statelem.status( 'data loaded...' ); } }

Number.prototype.zeroFill = function( length ) { var str = this.toFixed; if( !length ) { return str; } while( str.length < length ) { str = '0' + str; } return str; }

Mediawiki = {};

Mediawiki.Template = { parse: function( text, start ) { var count = -1; var level = -1; var equals = -1; var current = ''; var result = { name: '', parameters: {} };

for( var i = start; i < text.length; ++i ) { var test3 = text.substr( i, 3 ); if( test3 == '\{\{\{' ) { current += '\{\{\{'; i += 2; ++level; continue; }			if( test3 == '\}\}\}' ) { current += '\}\}\}'; i += 2; --level; continue; }			var test2 = text.substr( i, 2 ); if( test2 == '\{\{' || test2 == '\[\[' ) { current += test2; ++i; ++level; continue; }			if( test2 == '\]\]' ) { current += test2; ++i; --level; continue; }			if( test2 == '\}\}' ) { current += test2; ++i; --level;

if( level <= 0 ) { if( count == -1 ) { result.name = current.substring(2).trim; ++count; } else { if( equals != -1 ) { var key = current.substring( 0, equals ).trim; var value = current.substring( equals ).trim; result.parameters[key] = value; equals = -1; } else { result.parameters[count] = current; ++count; }					}					break; }				continue; }

if( text.charAt(i) == '|' && level <= 0 ) { if( count == -1 ) { result.name = current.substring(2).trim; ++count; } else { if( equals != -1 ) { var key = current.substring( 0, equals ).trim; var value = current.substring( equals + 1 ).trim; result.parameters[key] = value; equals = -1; } else { result.parameters[count] = current; ++count; }				}				current = ''; } else if( equals == -1 && text.charAt(i) == '=' && level <= 0 ) { equals = current.length; current += text.charAt(i); } else { current += text.charAt(i); }		}

return result; } }

Mediawiki.Page = function mediawikiPage( text ) { this.text = text; }

Mediawiki.Page.prototype = { text: '', removeLink: function( link_target ) { var first_char = link_target.substr( 0, 1 ); var link_re_string = "[" + first_char.toUpperCase + first_char.toLowerCase + ']' + RegExp.escape( link_target.substr( 1 ), true ); var link_simple_re = new RegExp( "\\[\\[(" + link_re_string + ")\\|?\\]\\]", 'g' ); var link_named_re = new RegExp( "\\[\\[" + link_re_string + "\\|(.+?)\\]\\]", 'g' ); if( link_simple_re.test(this.text) ) { this.text = this.text.replace( link_simple_re, "$1" ); } else { this.text = this.text.replace( link_named_re, "$1" ); }	},	commentOutImage: function( image, reason ) { var unbinder = new Unbinder( this.text ); unbinder.unbind( '' );

reason = reason ? ' ' + reason + ': ' : ''; var first_char = image.substr( 0, 1 ); var image_re_string = "[" + first_char.toUpperCase + first_char.toLowerCase + ']' + RegExp.escape( image.substr( 1 ), true );

/*		 * Check for normal image links, i.e. 		 * Will eat the whole link */		var links_re = new RegExp( "\\[\\[(?:[Ii]mage|[Ff]ile):\\s*" + image_re_string ); var allLinks = unbinder.content.splitWeightedByKeys( ,  ).uniq; for( var i = 0; i < allLinks.length; ++i ) { if( links_re.test( allLinks[i] ) ) { var replacement = ''; unbinder.content = unbinder.content.replace( allLinks[i], replacement, 'g' ); }		}		// unbind the newly created comments unbinder.unbind( '' ); /*		 * Check for gallery images, i.e. instances that must start on a new line, eventually preceded with some space, and must include Image: prefix * Will eat the whole line. */		var gallery_image_re = new RegExp( "(^\\s*(?:[Ii]mage|[Ff]ile):\\s*" + image_re_string + ".*?$)", 'mg' ); unbinder.content.replace( gallery_image_re, "" );

// unbind the newly created comments unbinder.unbind( '' ); /*		 * Check free image usages, for example as template arguments, might have the Image: prefix excluded, but must be preceeded by an | * Will only eat the image name and the preceeding bar and an eventual named parameter */		var free_image_re = new RegExp( "(\\|\\s*(?:[\\w\\s]+\\=)?\\s*(?:(?:[Ii]mage|[Ff]ile):\\s*)?" + image_re_string + ")", 'mg' ); unbinder.content.replace( free_image_re, "" );

// Rebind the content now, we are done! this.text = unbinder.rebind; },	addToImageComment: function( image, data ) { var first_char = image.substr( 0, 1 ); var image_re_string = "(?:[Ii]mage|[Ff]ile):\\s*[" + first_char.toUpperCase + first_char.toLowerCase + ']' + RegExp.escape( image.substr( 1 ), true ); var links_re = new RegExp( "\\[\\[" + image_re_string ); var allLinks = this.text.splitWeightedByKeys( ,  ).uniq; for( var i = 0; i < allLinks.length; ++i ) { if( links_re.test( allLinks[i] ) ) { var replacement = allLinks[i]; // just put it at the end? replacement = replacement.replace( /\]\]$/, '|' + data + ']]' ); this.text = this.text.replace( allLinks[i], replacement, 'g' ); }		}		var gallery_re = new RegExp( "^(\\s*" + image_re_string + '.*?)\\|?(.*?)$', 'mg' ); var replacement = "$1|$2 " + data; this.text = this.text.replace( gallery_re, replacement ); },	removeTemplate: function( template ) { var first_char = template.substr( 0, 1 ); var template_re_string = "(?:[Tt]emplate:)?\\s*[" + first_char.toUpperCase + first_char.toLowerCase + ']' + RegExp.escape( template.substr( 1 ), true ); var links_re = new RegExp( "\\\{\\\{" + template_re_string ); var allTemplates = this.text.splitWeightedByKeys( '{\{', '}}', [ '' ] ).uniq; for( var i = 0; i < allTemplates.length; ++i ) { if( links_re.test( allTemplates[i] ) ) { this.text = this.text.replace( allTemplates[i], '', 'g' ); }		}

},	getText: function { return this.text; } }

// Simple helper functions to see what groups a user might belong

function userIsInGroup( group ) {

return ( wgUserGroups != null && wgUserGroups.indexOf( group ) != -1 ) || ( wgUserGroups == null && group == 'anon' ); }

function userIsAnon { return wgUserGroups == null; }

// AOL Proxy IP Addresses (2007-02-03) var AOLNetworks = [ '64.12.96.0/19',	'149.174.160.0/20',	'152.163.240.0/21',	'152.163.248.0/22',	'152.163.252.0/23',	'152.163.96.0/22',	'152.163.100.0/23',	'195.93.32.0/22',	'195.93.48.0/22',	'195.93.64.0/19',	'195.93.96.0/19',	'195.93.16.0/20',	'198.81.0.0/22',	'198.81.16.0/20',	'198.81.8.0/23',	'202.67.64.128/25',	'205.188.192.0/20',	'205.188.208.0/23',	'205.188.112.0/20',	'205.188.146.144/30',	'207.200.112.0/21', ];

// AOL Client IP Addresses (2007-02-03) var AOLClients = [ '172.128.0.0/10',	'172.192.0.0/12',	'172.208.0.0/14',	'202.67.66.0/23',	'172.200.0.0/15',	'172.202.0.0/15',	'172.212.0.0/14',	'172.216.0.0/16',	'202.67.68.0/22',	'202.67.72.0/21',	'202.67.80.0/20',	'202.67.96.0/19', ];

/**
 * ipadress is in the format 1.2.3.4 and network is in the format 1.2.3.4/5

function isInNetwork( ipaddress, network ) { var iparr = ipaddress.split('.'); var ip = (parseInt(iparr[0]) << 24) + (parseInt(iparr[1]) << 16) + (parseInt(iparr[2]) << 8) + (parseInt(iparr[3]));

var netmask = 0xffffffff << network.split('/')[1];

var netarr = network.split('/')[0].split('.'); var net = (parseInt(netarr[0]) << 24) + (parseInt(netarr[1]) << 16) + (parseInt(netarr[2]) << 8) + (parseInt(netarr[3]));

return (ip & netmask) == net; }

/* Returns true if given string contains a valid IP-address, that is, from 0.0.0.0 to 255.255.255.255*/ function isIPAddress( string ){ var res = /(\d{1,4})\.(\d{1,3})\.(\d{1,3})\.(\d{1,4})/.exec( string ); return res != null && res.slice( 1, 5 ).every( function( e ) { return e < 256; } ); }

/** function QueryString(qString) { this.string = qString; this.params = {};
 * Maps the querystring to an object
 * Functions:
 * QueryString.exists(key)
 * returns true if the particular key is set
 * QueryString.get(key)
 * returns the value associated to the key
 * QueryString.equals(key, value)
 * returns true if the value associated with given key equals given value
 * QueryString.toString
 * returns the query string as a string
 * QueryString.create( hash )
 * creates an querystring and encodes strings via encodeURIComponent and joins arrays with |
 * In static context, the value of location.search.substring(1), else the value given to the constructor is going to be used. The mapped hash is saved in the object.
 * Example:
 * var value = QueryString.get('key');
 * var obj = new QueryString('foo=bar&baz=quux');
 * value = obj.get('foo');
 * Example:
 * var value = QueryString.get('key');
 * var obj = new QueryString('foo=bar&baz=quux');
 * value = obj.get('foo');
 * value = obj.get('foo');

if( qString.length == 0 ) { return; }

qString.replace(/\+/, ' '); var args = qString.split('&');

for( var i = 0; i < args.length; ++i ) { var pair = args[i].split( '=' ); var key = decodeURIComponent( pair[0] ), value = key;

if( pair.length == 2 ) { value = decodeURIComponent( pair[1] ); }

this.params[key] = value; } }

QueryString.static = null;

QueryString.staticInit = function { if( QueryString.static == null ) { QueryString.static = new QueryString(location.search.substring(1)); } }

QueryString.get = function(key) { QueryString.staticInit; return QueryString.static.get(key); };

QueryString.prototype.get = function(key) { return this.params[key] ? this.params[key] : null; };

QueryString.exists = function(key) { QueryString.staticInit; return QueryString.static.exists(key); }

QueryString.prototype.exists = function(key) { return this.params[key] ? true : false; }

QueryString.equals = function(key, value) { QueryString.staticInit; return QueryString.static.equals(key, value); }

QueryString.prototype.equals = function(key, value) { return this.params[key] == value ? true : false; }

QueryString.toString = function { QueryString.staticInit; return QueryString.static.toString; }

QueryString.prototype.toString = function { return this.string ? this.string : null; }

QueryString.create = function( arr ) { var resarr = Array; var editToken; // KLUGE: this should always be the last item in the query string (bug TW-B-0013) for( var i in arr ) { if( typeof arr[i] == 'undefined' ) { continue; }		var res; if( arr[i] instanceof Array ){ var v = Array; for(var j = 0; j < arr[i].length; ++j ) { v[j] = encodeURIComponent( arr[i][j] ); }			res = v.join('|'); } else { res = encodeURIComponent( arr[i] ); }               if( i == 'wpEditToken' ) { editToken = res; } else { resarr.push( encodeURIComponent( i ) + '=' + res ); }	}	if( typeof editToken != 'undefined' ) { resarr.push( 'wpEditToken=' + editToken ); }	return resarr.join('&'); } QueryString.prototype.create = QueryString.create;

/**
 * Simple exception handling

Exception = function( message ) { this.message = message || ''; this.name = "Exception"; }

Exception.prototype.what = function { return this.message; }

function Status( text, stat, type ) { this.text = this.codify(text); this.stat = this.codify(stat); this.type = type || 'status'; this.generate; if( stat ) { this.render; } } Status.init = function( root ) { if( !( root instanceof Element ) ) { throw new Exception( 'object not an instance of Element' ); }	while( root.hasChildNodes ) { root.removeChild( root.firstChild ); }	Status.root = root;

var cssNode = document.createElement('style'); cssNode.type = 'text/css'; cssNode.rel = 'stylesheet'; cssNode.appendChild( document.createTextNode("")); // Safari bugfix document.getElementsByTagName("head")[0].appendChild(cssNode); var styles = cssNode.sheet ? cssNode.sheet : cssNode.stylesSheet; styles.insertRule(".tw_status_status { color: SteelBlue; }", 0); styles.insertRule(".tw_status_info { color: ForestGreen; }", 0); styles.insertRule(".tw_status_warn { color: OrangeRed; }", 0); styles.insertRule(".tw_status_error { color: OrangeRed; font-weight: 900; }", 0); } Status.root = null;

Status.prototype = { stat: null, text: null, type: 'status', target: null, node: null, linked: false, link: function { if( ! this.linked && Status.root ) { Status.root.appendChild( this.node ); this.linked = true; }	},	unlink: function { if( this.linked ) { Status.root.removeChild( this.node ); this.linked = false; }	},	codify: function( obj ) { if ( ! ( obj instanceof Array ) ) { obj = [ obj ]; }		var result; result = document.createDocumentFragment; for( var i = 0; i < obj.length; ++i ) { if( typeof obj[i] == 'string' ) { result.appendChild( document.createTextNode( obj[i] ) ); } else if( obj[i] instanceof Element ) { result.appendChild( obj[i] ); } // Else cosmic radiation made something shit }		return result;

},	update: function( status, type ) { this.stat = this.codify( status ); if( type ) { this.type = type; }		this.render; },	generate: function { this.node = document.createElement( 'div' ); this.node.appendChild( document.createElement('span') ).appendChild( this.text ); this.node.appendChild( document.createElement('span') ).appendChild( document.createTextNode( ': ' ) ); this.target = this.node.appendChild( document.createElement( 'span' ) ); this.target.appendChild( document.createTextNode( '' ) ); // dummy node },	render: function { this.node.className = 'tw_status_' + this.type; while( this.target.hasChildNodes ) { this.target.removeChild( this.target.firstChild ); }		this.target.appendChild( this.stat ); this.link; },	status: function( status ) { this.update( status, 'status'); },	info: function( status ) { this.update( status, 'info'); },	warn: function( status ) { this.update( status, 'warn'); },	error: function( status ) { this.update( status, 'error'); } }

Status.status = function( text, status ) { return new Status( text, status, 'status' ); } Status.info = function( text, status ) { return new Status( text, status, 'info' ); } Status.warn = function( text, status ) { return new Status( text, status, 'error' ); } Status.error = function( text, status ) { return new Status( text, status, 'error' ); }

// Simple helper function to create a simple node function htmlNode( type, content, color ) { var node = document.createElement( type ); if( color ) { node.style.color = color; }	node.appendChild( document.createTextNode( content ) ); return node; }

// A simple dragable window

function SimpleWindow( width, height ) { var stylesheet = document.createElement('style'); stylesheet.type = 'text/css'; stylesheet.rel = 'stylesheet'; stylesheet.appendChild( document.createTextNode("") ); // Safari bugfix document.getElementsByTagName("head")[0].appendChild(stylesheet); var styles = stylesheet.sheet ? stylesheet.sheet : stylesheet.styleSheet; styles.insertRule(		".simplewindow { "+			"font: x-small sans-serif;"+			"position: fixed; "+			"background-color: AliceBlue; "+			"border: 2px ridge Black; "+			"z-index: 100; "+			"}",		0	);

styles.insertRule(		".simplewindow .content { "+			"position: absolute; "+			"top: 20px; "+			"bottom: 0; "+			"overflow: auto; "+			"width: 100%; "+			"}",		0	);

styles.insertRule(		".simplewindow .resizebuttonhorizontal { "+			"position: absolute; "+			"background-color: MediumPurple; "+			"opacity: 0.5; "+			"right: -2px; "+			"bottom: -2px; "+			"width: 20px; "+			"height: 4px; "+			"cursor: se-resize; "+			"}",		0	); styles.insertRule(		".simplewindow .resizebuttonvertical { "+			"position: absolute; "+			"opacity: 0.5; "+			"background-color: MediumPurple; "+			"right: -2px; "+			"bottom: -2px; "+			"width: 4px; "+			"height: 20px; "+			"cursor: se-resize; "+			"}",		0	);

styles.insertRule( 		".simplewindow .closebutton {"+			"position: absolute; "+			"font: 100 0.8em sans-serif; "+			"top: 1px; "+			"left: 1px; "+			"height: 100%; "+			"cursor: pointer; "+			"}",		0	);

styles.insertRule(		".simplewindow .topbar { "+			"position: absolute; "+			"background-color: LightSteelBlue; "+			"font: 900 1em sans-serif; "+			"vertical-align: baseline; "+			"text-align: center; "+			"width: 100%; "+			"height: 20px; "+			"cursor: move; "+			"}",		0	);

this.width = width; this.height = height;

var frame = document.createElement( 'div' ); var content = document.createElement( 'div' ); var topbar = document.createElement( 'div' ); var title = document.createElement( 'span' ); var closeButton = document.createElement( 'span' ); var resizeButton2 = document.createElement( 'div' ); var resizeButton1 = document.createElement( 'div' );

this.frame = frame; this.title = title; this.content = content;

frame.className = 'simplewindow'; content.className = 'content'; topbar.className = 'topbar'; resizeButton1.className = 'resizebuttonvertical'; resizeButton2.className = 'resizebuttonhorizontal'; closeButton.className = 'closebutton'; title.className = 'title';

topbar.appendChild( closeButton ); topbar.appendChild( title ); frame.appendChild( topbar ); frame.appendChild( content ); frame.appendChild( resizeButton1 ); frame.appendChild( resizeButton2 );

frame.style.width = Math.min(parseInt(window.innerWidth), parseInt(width)) + 'px'; frame.style.height = Math.min(parseInt(window.innerHeight), parseInt(height)) + 'px'; frame.style.top = Math.max(0, parseInt( window.innerHeight - this.height )/2 ) + 'px' ; frame.style.left = Math.max(0, parseInt( window.innerWidth - this.width )/2 ) + 'px'; var img = document.createElement( 'img' ); img.src = "http://upload.wikimedia.org/wikipedia/commons/thumb/6/65/Crystal_button_cancel.svg/18px-Crystal_button_cancel.svg.png"; closeButton.appendChild( img );

var self = this;

// Specific events frame.addEventListener( 'mousedown', function(event) { self.focus(event); }, false ); closeButton.addEventListener( 'click', function(event) {self.close(event); }, false ); topbar.addEventListener( 'mousedown', function(event) {self.initMove(event); }, false ); resizeButton1.addEventListener( 'mousedown', function(event) {self.initResize(event); }, false ); resizeButton2.addEventListener( 'mousedown', function(event) {self.initResize(event); }, false );

// Generic events window.addEventListener( 'mouseover', function(event) {self.handleEvent(event); }, false ); window.addEventListener( 'mousemove', function(event) {self.handleEvent(event); }, false ); window.addEventListener( 'mouseup', function(event) {self.handleEvent(event); }, false ); this.currentState = this.initialState; }

SimpleWindow.prototype = { focusLayer: 100, width: 800, height: 600, initialState: "Inactive", currentState: null, // current state of finite state machine (one of 'actionTransitionFunctions' properties) focus: function(event) { this.frame.style.zIndex = ++this.focusLayer; },	close: function(event) { event.preventDefault; document.body.removeChild( this.frame ); },	initMove: function(event) { event.preventDefault; this.initialX = parseInt( event.clientX - this.frame.offsetLeft ); this.initialY = parseInt( event.clientY - this.frame.offsetTop ); this.frame.style.opacity = '0.5'; this.currentState = 'Move'; },	initResize: function(event) { event.preventDefault; this.frame.style.opacity = '0.5'; this.currentState = 'Resize'; },	handleEvent: function(event) { event.preventDefault; var actionTransitionFunction = this.actionTransitionFunctions[this.currentState][event.type]; if( !actionTransitionFunction ) { actionTransitionFunction = this.unexpectedEvent; }		var nextState = actionTransitionFunction.call(this, event); if( !nextState ){ nextState = this.currentState; }       if( !this.actionTransitionFunctions[nextState] ){ nextState = this.undefinedState(event, nextState); }       this.currentState = nextState; event.stopPropagation; },   unexpectedEvent: function(event) { throw ("Handled unexpected event '" + event.type + "' in state '" + this.currentState); return this.initialState; },     undefinedState: function(event, state) { throw ("Transitioned to undefined state '" + state + "' from state '" + this.currentState + "' due to event '" + event.type); return this.initialState; }, 	actionTransitionFunctions: { Inactive: { mouseover: function(event) { return this.currentState; },           mousemove: function(event) { return this.currentState; },           mouseup: function(event) { return this.currentState; }       },         Move: { mouseover: function(event) { this.moveWindow( event.clientX, event.clientY ); return this.currentState; },           mousemove: function(event) { return this.doActionTransition("Move", "mouseover", event); },           mouseup: function(event) { this.frame.style.opacity = '1'; return 'Inactive'; }       }, 		Resize: { mouseover: function(event) { this.resizeWindow( event.clientX, event.clientY ); return this.currentState; },			mousemove: function(event) { return this.doActionTransition("Resize", "mouseover", event); },			mouseup: function(event) { this.frame.style.opacity = '1'; return 'Inactive'; }		}	},	doActionTransition: function(anotherState, anotherEventType, event) { return this.actionTransitionFunctions[anotherState][anotherEventType].call(this,event); },	display: function { document.body.appendChild( this.frame ); },	setTitle: function( title ) { this.title.textContent = title; },	setWidth: function( width ) { this.frame.style.width = width; },	setHeight: function( height ) { this.frame.style.height = height; },	setContent: function( content ) { this.purgeContent; this.addContent( content ); },	addContent: function( content ) { this.content.appendChild( content ); },	purgeContent: function( content ) { while( this.content.hasChildNodes ) { this.content.removeChild( this.content.firstChild ); }	},	moveWindow: function( x, y ) { this.frame.style.left = x - this.initialX + 'px'; this.frame.style.top = y - this.initialY + 'px'; },	resizeWindow: function( x, y ) { this.frame.style.height = Math.max( parseInt( y - this.frame.offsetTop ), 200 ) + 'px'; this.frame.style.width = Math.max( parseInt( x - this.frame.offsetLeft ), 200 ) + 'px'; } }

// NOTE! // Twinkle blacklist was removed per http://en.wikipedia.org/wiki/WP:Administrators%27_noticeboard/Archive221#New_Twinkle_blacklist_proposal // This script is outdated anyway -- current Gadget version of Twinkle lives elsewhere, and has no blacklist either. Amalthea, 21 June 2011. var twinkleBlacklistedUsers = [];

// to check of morebits had loaded morebits_js_loaded = true;

// When Twinkle modules are imported, we can't be sure that this base module // has been loaded yet. For that reason, modules using them need // to initialize themselves using //  window.TwinkleInit = (window.TwinkleInit || []).concat( someInitializationFunction ); // for maximal robustness. Looks weird, works well. addOnloadHook(function {	var funcs = window.TwinkleInit;	window.TwinkleInit = { concat : function(func){ func; return window.TwinkleInit;} }; //redefine the concat method used to enqueue initializers: From now on, they just execute immediately.	if (funcs) for (var i=0; i<funcs.length; i++) funcs[i]; });

//

// If FurMeConfig does not exist. if( typeof( FurMeConfig ) == 'undefined' ) FurMeConfig = {};

if ( typeof(FurMeConfig.watchMyEdits) == 'undefined' ) FurMeConfig.watchMyEdits = false;

if( typeof( FurMeConfig.openArticleMode ) == 'undefined' ) FurMeConfig.openArticleMode = 'none';

if( typeof( FurMeConfig.openAllArticles ) == 'undefined' ) FurMeConfig.openAllArticles = false;

if( typeof( FurMeConfig.windowHeight ) == 'undefined' ) FurMeConfig.windowHeight = '680';

if( typeof( FurMeConfig.cleanAmazonURLs ) == 'undefined' ) FurMeConfig.cleanAmazonURLs = true; if( typeof( FurMeConfig.linkFreeLogo ) == 'undefined' ) FurMeConfig.linkFreeLogo = false;

if( typeof( FurMeConfig.linkImageTags ) == 'undefined' ) FurMeConfig.linkImageTags = true;

var seedValues = new Array; seedValues['name'] = ''; seedValues['artist'] = ''; seedValues['label'] = ''; seedValues['infobox'] = false; seedValues['title'] = ''; seedValues['url'] = ''; seedValues['resolution'] = ''; seedValues['author'] = ''; seedValues['publisher'] = ''; seedValues['year'] = ''; seedValues['coverArtist'] = ''; seedValues['distributor'] = ''; seedValues['infoboxAlbum'] = false; seedValues['infoboxSingle'] = false;

// For compatibility with wikEd if (typeof(window.wikEdProgramVersion) != 'undefined' && readCookie('wikEdDisabled') != '1' && wgAction == "edit") {	var wikEdSetupHook = wikEdSetupHook || []; wikEdSetupHook.push(furme); } else {	addOnloadHook(furme); }

function furme { if( wgNamespaceNumber == 0 || wgNamespaceNumber == 2 ) {		try { var furmeRunning = decodeURIComponent(/[&?]furme=([^&]*)/.exec(window.location.search)[1]); } catch (err) {} if (furmeRunning == 'true') furme.imageRemover; }	if( wgNamespaceNumber == 6 ) { editLinkFreeLogo = "javascript:window.location = '"+ wgScript + '?title=' + encodeURIComponent(mw.config.get('wgPageName')) + '&action=edit&furme=true&freelogo=true' + "'"; switch (FurMeConfig.furmeLocation) {			case 'toolbox': portletLinkLocation = 'p-tb'; furmeTitleText = 'Apply FUR'; freeLogoTitleText = 'Free logo'; imageTagsTitleText = 'Tags'; break; case 'personal': portletLinkLocation = 'p-personal'; furmeTitleText = 'apply FUR'; freeLogoTitleText = 'free logo'; imageTagsTitleText = 'tags'; break; case 'filetoc': var filetoc = document.getElementById('filetoc'); if (filetoc != null) {					var li = document.createElement('li'); li.innerHTML = 'Apply FUR'; filetoc.appendChild(li);

if (FurMeConfig.linkFreeLogo) {						var li = document.createElement('li'); li.innerHTML = 'Free logo'; filetoc.appendChild(li); }					if (FurMeConfig.linkImageTags) {						var li = document.createElement('li'); li.innerHTML = 'Tags'; filetoc.appendChild(li); }				}				break; case 'tab': default: portletLinkLocation = 'p-cactions'; furmeTitleText = 'fur'; freeLogoTitleText = 'free logo'; imageTagsTitleText = 'tags'; break; }		// Add the links to the html page if( typeof( portletLinkLocation ) != 'undefined' ) {			mw.util.addPortletLink( portletLinkLocation, "javascript:furme.seedValues", furmeTitleText, "furme-fur", "Apply fair-use rationale to image", ""); if (FurMeConfig.linkFreeLogo) mw.util.addPortletLink( portletLinkLocation, editLinkFreeLogo, freeLogoTitleText, "furme-freelogo", "Change licensing information to free logo", ""); if (FurMeConfig.linkImageTags) mw.util.addPortletLink( portletLinkLocation, "javascript:furme.imagetags", imageTagsTitleText, "furme-imagetags", "Edit/Add image tags", ""); }	}	// Add the FUR template if( wgNamespaceNumber == 6 && wgAction == "edit" && /[&?]furme=/.test(window.location.search) ) { // Check if we are doing free logo changes if (/[&?]freelogo=/.test(window.location.search) || /[&?]furmeImageTags=/.test(window.location.search)) {			furmeEditText(''); }		else {			 			var type = decodeURIComponent(/[&?]type=([^&]*)/.exec(window.location.search)[1]); // Open the template page to get copy of template syntax var url = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/api.php?action=query&prop=revisions&titles=User:AWeenieMan/furme/Template:' + type + '&rvprop=content&format=xml' var http = new XMLHttpRequest; // create the HTTP Object http.open("GET", url, true); http.onreadystatechange = function { if( http.readyState == 4 ) { xmlDocument = http.responseXML; template = xmlDocument.getElementsByTagName('rev')[0].childNodes[0].nodeValue; template = template.replace(/(\s*)<[\/]?nowiki>(\s*)/ig, ''); furmeEditText(template + "\n"); }			};			http.send(null); }	} }

function furmeEditText(template) { var editform = document.editform; if (!editform) return; var textbox = editform.wpTextbox1; if (!textbox) return; if (/[&?]freelogo=/.test(window.location.search) == false && /[&?]furmeImageTags=/.test(window.location.search) == false) {		var purpose = decodeURIComponent(/[&?]purpose=([^&]*)/.exec(window.location.search)[1]); var portion = decodeURIComponent(/[&?]portion=([^&]*)/.exec(window.location.search)[1]); var resolution = decodeURIComponent(/[&?]resolution=([^&]*)/.exec(window.location.search)[1]); var replaceability = decodeURIComponent(/[&?]replaceability=([^&]*)/.exec(window.location.search)[1]); var description = decodeURIComponent(/[&?]description=([^&]*)/.exec(window.location.search)[1]); var article = decodeURIComponent(/[&?]article=([^&]*)/.exec(window.location.search)[1]); var owner = decodeURIComponent(/[&?]owner=([^&]*)/.exec(window.location.search)[1]); var website = decodeURIComponent(/[&?]website=([^&]*)/.exec(window.location.search)[1]); var use = decodeURIComponent(/[&?]use=([^&]*)/.exec(window.location.search)[1]); var type = decodeURIComponent(/[&?]type=([^&]*)/.exec(window.location.search)[1]); var artist = decodeURIComponent(/[&?]artist=([^&]*)/.exec(window.location.search)[1]); var album = decodeURIComponent(/[&?]album=([^&]*)/.exec(window.location.search)[1]); var label = decodeURIComponent(/[&?]label=([^&]*)/.exec(window.location.search)[1]); var year = decodeURIComponent(/[&?]year=([^&]*)/.exec(window.location.search)[1]); var author = decodeURIComponent(/[&?]author=([^&]*)/.exec(window.location.search)[1]); var publisher = decodeURIComponent(/[&?]publisher=([^&]*)/.exec(window.location.search)[1]); var title = decodeURIComponent(/[&?]bookTitle=([^&]*)/.exec(window.location.search)[1]); var coverArtist = decodeURIComponent(/[&?]coverArtist=([^&]*)/.exec(window.location.search)[1]); var useType = decodeURIComponent(/[&?]useType=([^&]*)/.exec(window.location.search)[1]); var distributor = decodeURIComponent(/[&?]distributor=([^&]*)/.exec(window.location.search)[1]); var rename = decodeURIComponent(/[&?]rename=([^&]*)/.exec(window.location.search)[1]); var reduce = decodeURIComponent(/[&?]reduce=([^&]*)/.exec(window.location.search)[1]); var scanned = decodeURIComponent(/[&?]scan=([^&]*)/.exec(window.location.search)[1]); if (purpose != 'undefined') template = template.replace(/(\s*)Purpose(\s*)=(\s*)/, "$1Purpose$2= " + purpose.trim + "\n"); if (portion != 'undefined') template = template.replace(/(\s*)Portion(\s*)=(\s*)/, "$1Portion$2= " + portion.trim + "\n"); if (resolution != 'undefined') template = template.replace(/(\s*)Low_resolution(\s*)=(\s*)/, "$1Low_resolution$2= " + resolution.trim + "\n"); if (replaceability != 'undefined') template = template.replace(/(\s*)Replaceability(\s*)=(\s*)/, "$1Replaceability$2= " + replaceability.trim + "\n"); if (description != 'undefined') template = template.replace(/(\s*)Description(\s*)=(\s*)/, "$1Description$2= " + description.trim + "\n"); if (article != 'undefined') template = template.replace(/(\s*)Article(\s*)=(\s*)/, "$1Article$2= " + article.trim + "\n"); if (owner != 'undefined') template = template.replace(/(\s*)Owner(\s*)=(\s*)/, "$1Owner$2= " + owner.trim + "\n"); if (website != 'undefined') template = template.replace(/(\s*)Website(\s*)=(\s*)/, "$1Website$2= " + website.trim + "\n"); if (website != 'undefined' && (type == 'Non-free use rationale' || type == 'Historic fur')) template = template.replace(/(\s*)Source(\s*)=(\s*)/, "$1Source$2= " + website.trim + "\n"); if (use != 'undefined') template = template.replace(/(\s*)Use(\s*)=(\s*)/, "$1Use$2= " + use.trim + "\n"); if (artist != 'undefined') template = template.replace(/(\s*)Artist(\s*)=(\s*)/, "$1Artist$2= " + artist.trim + "\n"); if (label != 'undefined') template = template.replace(/(\s*)Label(\s*)=(\s*)/, "$1Label$2= " + label.trim + "\n"); if (album != 'undefined') template = template.replace(/(\s*)Name(\s*)=(\s*)/, "$1Name$2= " + album.trim + "\n"); if (useType != 'undefined' && (type == 'Album cover fur' || type == 'Film cover fur')) template = template.replace(/(\s*)Type(\s*)=(\s*)/, "$1Type$2= " + useType.trim + "\n"); if (year != 'undefined') template = template.replace(/(\s*)Year(\s*)=(\s*)/, "$1Year$2= " + year.trim + "\n"); if (author != 'undefined') template = template.replace(/(\s*)Author(\s*)=(\s*)/, "$1Author$2= " + author.trim + "\n"); if (title != 'undefined') template = template.replace(/(\s*)Title(\s*)=(\s*)/, "$1Title$2= " + title.trim + "\n"); if (coverArtist != 'undefined') template = template.replace(/(\s*)Cover_artist(\s*)=(\s*)/, "$1Cover_artist$2= " + coverArtist.trim + "\n"); if (distributor != 'undefined') template = template.replace(/(\s*)Distributor(\s*)=(\s*)/, "$1Distributor$2= " + distributor.trim + "\n"); if (publisher != 'undefined') template = template.replace(/(\s*)Publisher(\s*)=(\s*)/, "$1Publisher$2= " + publisher.trim + "\n"); if (scanned == 'Yes') template = template.replace(/(\s*)Source(\s*)=(\s*)/, "$1Source$2= Scanned by uploader.\n"); }	textboxText = textbox.value; /*		FIND THE SUMMARY TEXT, MAKE SURE TO BE BELOW IT (PLACE SUMMARY TEXT IF NOT THERE) */	regExFindSummary = /==\s*[Ss]ummary\s*==\s*/; findSummary = textboxText.search(regExFindSummary); if (findSummary == -1) { textboxText = "== Summary ==\n" + textboxText; }	textboxText = textboxText.replace(regExFindSummary, "== Summary ==\n" + template); /*		GET RID OF DISPUTED TEMPLATES (WHERE THE PROBLEM SHOULD NOW BE CORRECTED) */	regExFindNoSource = /\{\{(Di-no source|No source|Unspecified|Unknownsource|Fairuseunknownsource|Fuus|Nosource|No source since|No source notified|No info|Nosources|Di-no-source)(.*)\}\}\n*/i; regExFindDisputed = /\{\{(Di-disputed fair use rationale|Di-disputed rationale|Improve rationale|Di-missing article links)(.*)\}\}\n*/i; regExFindNoRationale = /\{\{(Di-no fair use rationale|No rationale|Fairuse rationale needed|Fu-ra-ne|Norat|Norationale|Di-no rationale)(.*)\}\}\n*/i; regExFindMissingArticleLinks = /\s*\{\{(Di-missing article links)[^\}]+?\}\}\s*/i; textboxText = textboxText.replace(regExFindNoSource, ''); textboxText = textboxText.replace(regExFindDisputed, ''); textboxText = textboxText.replace(regExFindNoRationale, ''); textboxText = textboxText.replace(regExFindMissingArticleLinks, ''); /*		GET RID OF DISPUTED IMAGE CATEGORIES (PRESENT ONLY SOMETIMES) */	regExFindDisputedCategory = /(\\,)*\[\[Category:Disputed non-free images(.*)]](\n)*/i; textboxText = textboxText.replace(regExFindDisputedCategory, ''); /*		ADD IN == LICENSING == TAG IF NOT THERE */	regExFindLicensing = /\s*==\s*[Ll]icensing[:]*\s*==\s*/; textboxText = textboxText.replace(regExFindLicensing, "\n\n== Licensing ==\n"); findLicensing = textboxText.search(regExFindLicensing); if (findLicensing == -1) { regExFindLicense = /\n*\{\{\s*([Tt]emplate:)*([Nn]on-free|[Pp][Dd]|[Cc]C|[Gg]FDL|[Gg]PL)([^\}]*)\}\}\s*/g; textboxText = textboxText.replace(regExFindLicense, "\n\n== Licensing ==\n"); }	/*		FREE LOGO SPECIFIC CHANGES */	if (/[&?]freelogo=/.test(window.location.search)) {		// Remove all non-free licenses regExFindLicense = /\n*\{\{Non-free(.*)\}\}\s*/i; textboxText = textboxText.replace(regExFindLicense, ''); // Add free license textboxText = textboxText.replace(regExFindLicensing, "\n\n== Licensing ==\n\n"); // Remove any fair use headings regExFindFUHeading = /(\s*)==\s*Fair use[^]+?==\s*/ig; textboxText = textboxText.replace(regExFindFUHeading, "$1"); // Remove any fair use rationale regExFindRationale = /\{\{(logo fur|Non-free use rationale|Fair use rationale|Non-free fair use rationale|Rationale|Non-free media rationale|Non-free image data|Non-free image rationale)[^]+?\}\}\s*/igm; textboxText = textboxText.replace(regExFindRationale, ''); }	/*		IMAGE TAGS-TAB SPECIFIC CHANGES */	else if (/[&?]furmeImageTags=/.test(window.location.search)) {		// Add new license tag if (/[&?]imageLicense=/.test(window.location.search)) {			var imageLicense = decodeURIComponent(/[&?]imageLicense=([^&]*)/.exec(window.location.search)[1]); if ( imageLicense != '' ) {				// Temporarily rename tags beginning with "Non-free" that should not be removed var tagsNoReplace = 'Non-free use rationale|Non-free image data|Non-free image rationale|Non-free media rationale|Non-free reduced|Non-free fair use rationale'; regExFindTagsNoReplace = '/\{\{\s*([Tt]emplate:)*(' + tagsNoReplace + ')/gi'; textboxText = textboxText.replace(eval(regExFindTagsNoReplace), '{{%%$2%%'); // Remove all licenses regExFindLicense = /\n*\{\{\s*([Tt]emplate:)*([Nn]on-free|[Pp][Dd]|[Cc]C|[Gg]FDL|[Gg]PL)[^\}]*\}\}\s*/g; textboxText = textboxText.replace(regExFindLicense, ''); // Rename tags back regExFindTagsNoReplace = '/\{\{%%(' + tagsNoReplace + ')%%/gi'; textboxText = textboxText.replace(eval(regExFindTagsNoReplace), "{{$1"); textboxText = textboxText.replace(regExFindLicensing, "\n\n== Licensing ==\n{{" + imageLicense + "}}\n"); editSummary = 'changing license to ' + imageLicense; }		}		// Add in maintenance tags if (/[&?]imageTags=/.test(window.location.search)) {			var imageTags = decodeURIComponent(/[&?]imageTags=([^&]*)/.exec(window.location.search)[1]); if ( imageTags != '' ) {				// Add tag if (/\{\{Information\}\}/.test(imageTags)) {					imageTags = imageTags.replace(/\{\{Information\}\}\n/, ''); informationTemplate = '\n'; textboxText = textboxText.replace(regExFindSummary, "== Summary ==\n" + informationTemplate); if (typeof(editSummary) != 'undefined') editSummary += '; '; else editSummary = ''; editSummary += 'adding '; }				// Ask for new name on Commons if (/\{\{subst:ncd\}\}/.test(imageTags)) {					var img = prompt( 'enter the image name on Commons (if different than local name), excluding the Image: prefix' ); if (img != null && img != '') imageTags = imageTags.replace(/\{\{subst:ncd\}\}/,  + img + ); }				textboxText = imageTags + textboxText; if (typeof(editSummary) != 'undefined') editSummary += '; '; else editSummary = ''; editSummary += 'adding ' + imageTags.replace('\n', ', ').rtrim(', '); }		}		// Remove any fair use rationale if (/[&?]removefur=/.test(window.location.search)) {			// Remove any fair use headings regExFindFUHeading = /(\s*)==\s*Fair use[^]+?==\s*/ig; textboxText = textboxText.replace(regExFindFUHeading, "$1"); regExFindRationale = /\{\{(.*fur|Non-free use rationale|Fair use rationale|Non-free fair use rationale|Rationale|Non-free media rationale|Non-free image data|Non-free image rationale)[^]+?\}\}\s*/igm; textboxText = textboxText.replace(regExFindRationale, ''); }	}	/*		ADD IMAGE FOR RENAMING TAG */	if (typeof(rename) != 'undefined') {		if (rename != 'undefined') {			var dot = wgTitle.lastIndexOf('.'); var extension = wgTitle.substr(dot, wgTitle.length); if (FurMeConfig.renameMethod == 'bot') {				regExFindWikiLinks = /\[\[|\]\]/gi; regExFindWikiLinks2 = /^.*\|/gi; if (type == 'Album cover fur') {					if (useType != 'undefined') renameTag = ''; else renameTag = ''; }				else if (type == 'Book cover fur') {					renameTag = ''; }				else if (type == 'Film cover fur') {					renameTag = ''; }				else if (type == 'Logo fur') {					renameTag = ''; }			}			else renameTag = ''; textboxText = textboxText.replace(regExFindSummary, renameTag + "\n== Summary ==\n"); }	}	/*		ADD NON-FREE REDUCE TAG */	if (typeof(reduce) != 'undefined') {		if (reduce != 'undefined') {			reduceTag = ''; textboxText = textboxText.replace(regExFindSummary, reduceTag + "\n== Summary ==\n"); }	}	textbox.value = textboxText; // copy wpTextbox1 textarea back to wikEd frame if (typeof(wikEdUseWikEd) != 'undefined') { if (wikEdUseWikEd == true) { WikEdUpdateFrame; }	}

if (FurMeConfig.watchMyEdits) editform.wpWatchthis.checked = true; if (editform.wpSummary) { if (/[&?]freelogo=/.test(window.location.search)) editform.wpSummary.value = "changing license to PD-textlogo using FurMe"; else if (/[&?]furmeImageTags=/.test(window.location.search)) editform.wpSummary.value = editSummary + " using FurMe"; else editform.wpSummary.value = "adding FUR using FurMe"; }	switch(FurMeConfig.actionOnSubmit) {		case 'none': break; case 'save': if (editform.wpSave) { editform.wpSave.click; }			break; case 'preview': if (editform.wpPreview) { editform.wpPreview.click; }			break; case 'diff': default: if (editform.wpDiff) { editform.wpDiff.click; }			break; } }

furme.seedValues = function furmeSeedValues(titleSeed) { var urlSeedTemp = ''; /*		SEE IF THERE IS ONLY ONE ARTICLE TO WHICH THE IMAGE LINKS */	if (titleSeed == 'undefined' || null == titleSeed) {		var linkList = document.getElementById('linkstoimage'); while (linkList && (!linkList.tagName || linkList.tagName.toLowerCase != "ul")) linkList = linkList.nextSibling; if (typeof linkList != 'undefined' && null != linkList) { var pageLinks = linkList.getElementsByTagName("a"); if (pageLinks.length == 1) seedValues['title'] = pageLinks[0].getAttribute("title"); }	}	else {		seedValues['title'] = titleSeed; }	/* 		SEE IF THERE IS ONLY ONE EXTERNAL URL (ASSUMED TO BE SOURCE) */	extUrlCount = 0; regExFindHyperlink = /(javascript|wikimedia|wikipedia)/; var linkList = document.getElementById('bodyContent').getElementsByTagName("a"); if (document.getElementById('imageLicense')) var licenseLinkList = document.getElementById('imageLicense').getElementsByTagName("a"); if (typeof linkList != 'undefined' && null != linkList) { for( var i = 0; i < linkList.length; ++i ) { // Loop through ignore list var ignoreLink = false; if (typeof licenseLinkList != 'undefined' && null != licenseLinkList) { for( var j = 0; j < licenseLinkList.length; ++j ) { if (linkList[i].href == licenseLinkList[j].href) ignoreLink = true; }			}			if( regExFindHyperlink.test(linkList[i].href) == false 				&& linkList[i].href.length > 0 				&& !ignoreLink) { // Ignore internal links and license links if (linkList[i].href != urlSeedTemp) { urlSeedTemp = linkList[i].href; extUrlCount++; }			}		}	}	if (extUrlCount == 1) { seedValues['url'] = urlSeedTemp; }	// Attempt to find incomplete url else if (extUrlCount == 0) {		regExFindURL = /[\s\W]www\.([^<>\s]+?)\.(com|gov|edu|cc|org|net|uk|eu|ca|cn|tv|fm|pl|nz)[^\s"<>]*(?=\b[\s\W])/ig;		var pageText = document.getElementById('bodyContent').innerHTML;		findURL = pageText.match(regExFindURL);		if (findURL != null) {			seedValues['url'] = 'http://' + findURL[0].trimPunctuation.trim.toLowerCase;		}		else		{			//regExFindURL = /[\s\W]([^<>\s"]+?)\.(com|gov|edu|cc|org|net|uk|eu|ca|cn|tv|fm|pl|nz)[^\s"<>]*(?=\b[\s<\.\?\/])/ig;			regExFindURL = /[\s\W]([^<>\s"]+?)\.(com|gov|edu|cc|org|net|uk|eu|ca|cn|tv|fm|pl|nz)[^\s"<>]*(?=\b[\s\W])/ig;			findURL = pageText.match(regExFindURL);			if (typeof findURL != 'undefined' && null != findURL) {				for( var i = 0; i < findURL.length; ++i ) {					if (findURL[i].search('http://') == -1 && findURL[i].search(/\/w\/index\.php\?title=/) == -1 && seedValues['url'] == '')					{						// Ignore this common one in EXIF data						if (findURL[i].trimPunctuation.trim.toLowerCase != 'paint.net') seedValues['url'] = 'http://www.' + findURL[i].trimPunctuation.trim.toLowerCase; }				}			}

}	}	/*		CLEAN AMAZON URLS */	if (FurMeConfig.cleanAmazonURLs == true) { if (seedValues['url'].search(/amazon\./) != -1) { seedValues['url'] = seedValues['url'].cleanAmazonURL; }	}	/* 		SEE IF THE IMAGE IS <301PX WIDE/TALL (FAIR USE STANDARD) */	if (document.getElementById('file').getElementsByTagName("img")[0].width < 301 ||		document.getElementById('file').getElementsByTagName("img")[0].height < 301) { seedValues['resolution'] = 'Yes' }	/*		FILL IN PARAMETERS FROM INFOBOX ON ARTICLE */	if (seedValues['title'].length > 0) {		var url = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/api.php?action=query&prop=revisions&titles=' + encodeURIComponent(seedValues['title']) + '&rvprop=content&format=xml' var http = new XMLHttpRequest; // create the HTTP Object http.open("GET", url, false); http.send(null); if (http.status == 200) {			try {				xmlDocument = http.responseXML; articleText = xmlDocument.getElementsByTagName('rev')[0].childNodes[0].nodeValue; try { seedValues['artist'] = articleText.match(/Artist\s*=\s*(.*)\s*\|/i)[1].rtrimPipe; seedValues['artist'] = seedValues['artist'].replace(/\[*(Various Artists|Various|Multiple|Multiple Artists|N\/A)\]*/i, ''); } catch(err) {} try { seedValues['author'] = articleText.match(/Author\s*=\s*(.*)\s*\|/i)[1].rtrimPipe } catch(err) {} try { seedValues['coverArtist'] = articleText.match(/Cover_artist\s*=\s*(.*)\s*\|/i)[1].rtrimPipe } catch(err) {} try { seedValues['name'] = articleText.match(/Name\s*=\s*(.*)\s*\|/i)[1].rtrimPipe ; seedValues['name'] = seedValues['name'].replace(/( ||)/i, ' '); } catch(err) {} try { seedValues['publisher'] = articleText.match(/Publisher\s*=\s*(.*)\s*\|/i)[1].rtrimPipe } catch(err) {} try { seedValues['year'] = articleText.match(/Release_date\s*=\s*(.*)\s*\|/i)[1]; seedValues['year'] = seedValues['year'].match(/([1-9][0-9]{3})/ig); } 				catch(err) {} try {					seedValues['label'] = articleText.match(/Label\s*=\s*(.*)\s*\|/i)[1].rtrimPipe; seedValues['label'] = seedValues['label'].replace(/\s*<(small)>(.*?)<\/\1>/ig, ''); seedValues['label'] = seedValues['label'].replace(/\s*/ig, ' / '); seedValues['label'] = seedValues['label'].replace(/\s*(\(US\)|\(UK\)|\(U\.S\.\)|\(U\.K\.\))\s*/ig, ''); seedValues['label'] = seedValues['label'].replace(/\s*\{\{flag.*}}\s*/ig, ''); seedValues['label'] = seedValues['label'].replace(/\s*\|\s*Producer\s*=\s*.*/ig, ''); }				catch(err) {} try { seedValues['distributor'] = articleText.match(/Distributor\s*=\s*(.*)\s*\|/i)[1].rtrimPipe } catch(err) {} try { var infoboxType = articleText.match(/\{\{Infobox\s?([^\s\|]+)/i)[1].toLowerCase } catch(err) {} if (infoboxType == '' || infoboxType == 'undefined' || null == infoboxType) try { var infoboxType = articleText.match(/\{\{([^\s]+)\s?Infobox\s*/i)[1].toLowerCase } catch(err) {} if (infoboxType == 'album' || infoboxType == 'albums') seedValues['infoboxAlbum'] = true; else if (infoboxType == 'single' || infoboxType == 'singles') seedValues['infoboxSingle'] = true; // Check if image is used in infobox infoboxImages = articleText.match(/(Cover|logo|logofile|station_logo|company_logo|image|image_name)\s*=\s*(.*)\s*[\|\}]/gi); if (infoboxImages != null) {					for (var i = 0; i < infoboxImages.length; i++) {						infoboxImages[i] = decodeURIComponent(infoboxImages[i]); if (infoboxImages[i].toLowerCase.replace(/_/gi, ' ').search(wgTitle.replace(/(\(|\)|\^|\$|\.|\{|\?|\*|\+|\|)/gi, "\\$1").toLowerCase) != -1) seedValues['infobox'] = true; }				}			}			catch(err) {} }	}	/*		OPTIONALLY, IF NOT IN INFOBOX, OPEN THE ARTICLE IN A NEW WINDOW/TAB/ETC. OR, OPEN ALL ARTICLES */	if (!seedValues['infobox'] && (seedValues['title'].length > 0 || FurMeConfig.openAllArticles) ) {		var maxArticlesToOpen = 10; if (FurMeConfig.openAllArticles == false) maxArticlesToOpen = 1; if (typeof pageLinks != 'undefined' && null != pageLinks) { for (var i = 0; i < Math.min(maxArticlesToOpen, pageLinks.length); i++) {				var url = mw.config.get('wgServer') + mw.config.get('wgArticlePath').replace(/\$1/, pageLinks[i].getAttribute('title')) + '?furme=true&image=' + wgPageName.stripslashes; switch( FurMeConfig.openArticleMode ) {					case 'tab': window.open( url, '_tab' + i ); break; case 'browser': window.open( url, 'furmearticlewindow' + i ); break; case 'blank': window.open( url, '_blank', 'location=no,toolbar=no,status=no,directories=no,scrollbars=yes,width=1200,height=800' ); break; case 'window': window.open( url, 'furmearticlewindow', 'location=no,toolbar=no,status=no,directories=no,scrollbars=yes,width=1200,height=800' ); break; case 'none': default: break; }			}		}	}	furme.callback; }

furme.imagetags = function furmeImageTags { var Window = new SimpleWindow( 600, FurMeConfig.windowHeight ); Window.setTitle( "Edit/Add image tags" ); var form = new QuickForm( furme.imagetags.evaluate ); var cssNode = document.createElement('style'); cssNode.type = 'text/css'; cssNode.rel = 'stylesheet'; cssNode.appendChild( document.createTextNode("")); // Safari bugfix document.getElementsByTagName("head")[0].appendChild(cssNode); var styles = cssNode.sheet ? cssNode.sheet : cssNode.stylesSheet; styles.insertRule("form.quickform fieldset div#furme-two-cols-cleanup { -moz-column-count: 2; }", 0); styles.insertRule("form.quickform fieldset div#furme-two-cols-commons { -moz-column-count: 2; }", 0); styles.insertRule("form.quickform fieldset div#furme-two-cols-favorites { -moz-column-count: 2; }", 0); styles.insertRule("form.quickform fieldset div#furme-two-cols-general { -moz-column-count: 2; }", 0); styles.insertRule("form.quickform fieldset div#furme-two-cols-restriction { -moz-column-count: 2; }", 0); styles.insertRule("form.quickform fieldset div#furme-two-cols-replacement { -moz-column-count: 2; }", 0); var licenseMenu = form.append( {			type: 'select',			name: 'imageLicense',			label: 'Change image license to ',		} ); // ADD FAVORITE LICENSE TAGS TO DROP-DOWN if( typeof( FurMeConfig.tagsImageLicenseFavorites ) != 'undefined' ) {		licenseMenu.append( { type:'option', label: , value:  } ); for ( var i = 0; i < FurMeConfig.tagsImageLicenseFavorites.length; i++) { 			licenseMenu.append( { type:'option', label: FurMeConfig.tagsImageLicenseFavorites[i], value: FurMeConfig.tagsImageLicenseFavorites[i] } ); }	}

licenseMenu.append( { type:'option', label: , value:  } ); licenseMenu.append( { type:'option', label: '__FREE LICENSES__', value: '' } ); licenseMenu.append( { type:'option', label: 'Attribution', value: 'Attribution' } ); licenseMenu.append( { type:'option', label: 'Cc-by', value: 'Cc-by' } ); licenseMenu.append( { type:'option', label: 'Cc-by-2.0', value: 'Cc-by-2.0' } ); licenseMenu.append( { type:'option', label: 'Cc-by-3.0', value: 'Cc-by-3.0' } ); licenseMenu.append( { type:'option', label: 'Cc-by-sa', value: 'Cc-by-sa' } ); licenseMenu.append( { type:'option', label: 'Cc-by-sa-2.0', value: 'Cc-by-sa-2.0' } ); licenseMenu.append( { type:'option', label: 'Cc-by-sa-3.0', value: 'Cc-by-sa-3.0' } ); licenseMenu.append( { type:'option', label: 'Cc-sa', value: 'Cc-sa' } ); licenseMenu.append( { type:'option', label: 'Free screenshot', value: 'Free screenshot' } ); licenseMenu.append( { type:'option', label: 'GFDL-self', value: 'GFDL-self' } ); licenseMenu.append( { type:'option', label: 'GFDL-presumed', value: 'GFDL-presumed' } ); licenseMenu.append( { type:'option', label: 'GPL', value: 'GPL' } ); licenseMenu.append( { type:'option', label: 'Money-US', value: 'Money-US' } ); licenseMenu.append( { type:'option', label: 'PD-art', value: 'PD-art' } ); licenseMenu.append( { type:'option', label: 'PD-art-life-70', value: 'PD-art-life-70' } ); licenseMenu.append( { type:'option', label: 'PD-art-US', value: 'PD-art-US' } ); licenseMenu.append( { type:'option', label: 'PD-Australia', value: 'PD-Australia' } ); licenseMenu.append( { type:'option', label: 'PD-author', value: 'PD-author' } ); licenseMenu.append( { type:'option', label: 'PD-because', value: 'PD-because' } ); licenseMenu.append( { type:'option', label: 'PD-BritishGov', value: 'PD-BritishGov' } ); licenseMenu.append( { type:'option', label: 'PD-Canada', value: 'PD-Canada' } ); licenseMenu.append( { type:'option', label: 'PD-font', value: 'PD-font' } ); licenseMenu.append( { type:'option', label: 'PD-ineligible', value: 'PD-ineligible' } ); licenseMenu.append( { type:'option', label: 'PD-Italy', value: 'PD-Italy' } ); licenseMenu.append( { type:'option', label: 'PD-link', value: 'PD-link' } ); licenseMenu.append( { type:'option', label: 'PD-old', value: 'PD-old' } ); licenseMenu.append( { type:'option', label: 'PD-old-50', value: 'PD-old-50' } ); licenseMenu.append( { type:'option', label: 'PD-old-100', value: 'PD-old-100' } ); licenseMenu.append( { type:'option', label: 'PD-release', value: 'PD-release' } ); licenseMenu.append( { type:'option', label: 'PD-Russia-2008', value: 'PD-Russia-2008' } ); licenseMenu.append( { type:'option', label: 'PD-shape', value: 'PD-shape' } ); licenseMenu.append( { type:'option', label: 'PD-self', value: 'PD-self' } ); licenseMenu.append( { type:'option', label: 'PD-text', value: 'PD-text' } ); licenseMenu.append( { type:'option', label: 'PD-US', value: 'PD-US' } ); licenseMenu.append( { type:'option', label: 'PD-US-1923-abroad', value: 'PD-US-1923-abroad' } ); licenseMenu.append( { type:'option', label: 'PD-US-patent', value: 'PD-US-patent' } ); licenseMenu.append( { type:'option', label: 'PD-USGov', value: 'PD-USGov' } ); licenseMenu.append( { type:'option', label: 'PD-USGov-CIA', value: 'PD-USGov-CIA' } ); licenseMenu.append( { type:'option', label: 'PD-USGov-Congress', value: 'PD-USGov-Congress' } ); licenseMenu.append( { type:'option', label: 'PD-USGov-Congress-Bio', value: 'PD-USGov-Congress-Bio' } ); licenseMenu.append( { type:'option', label: 'PD-USGov-DOC-Census', value: 'PD-USGov-DOC-Census' } ); licenseMenu.append( { type:'option', label: 'PD-USGov-DOC-NOAA', value: 'PD-USGov-DOC-NOAA' } ); licenseMenu.append( { type:'option', label: 'PD-USGov-DOJ', value: 'PD-USGov-DOJ' } ); licenseMenu.append( { type:'option', label: 'PD-USGov-Interior-NPS', value: 'PD-USGov-Interior-NPS' } ); licenseMenu.append( { type:'option', label: 'PD-USGov-Interior-USGS', value: 'PD-USGov-Interior-USGS' } ); licenseMenu.append( { type:'option', label: 'PD-USGov-Military', value: 'PD-USGov-Military' } ); licenseMenu.append( { type:'option', label: 'PD-USGov-Military-Air Force', value: 'PD-USGov-Military-Air Force' } ); licenseMenu.append( { type:'option', label: 'PD-USGov-Military-Army', value: 'PD-USGov-Military-Army' } ); licenseMenu.append( { type:'option', label: 'PD-USGov-Military-Marines', value: 'PD-USGov-Military-Marines' } ); licenseMenu.append( { type:'option', label: 'PD-USGov-Military-Navy', value: 'PD-USGov-Military-Navy' } ); licenseMenu.append( { type:'option', label: 'PD-USGov-NASA', value: 'PD-USGov-NASA' } ); licenseMenu.append( { type:'option', label: 'PD-USGov-USDA',value: 'PD-USGov-USDA' } ); licenseMenu.append( { type:'option', label: 'PD-USGov-USDA-FS', value: 'PD-USGov-USDA-FS' } ); licenseMenu.append( { type:'option', label: 'PD-user', value: 'PD-user' } ); licenseMenu.append( { type:'option', label: 'Wikipedia-screenshot', value: 'Wikipedia-screenshot' } ); licenseMenu.append( { type:'option', label: '__NON-FREE LICENSES__', value: '' } ); licenseMenu.append( { type:'option', label: 'Non-free 2D art', value: 'Non-free 2D art' } ); licenseMenu.append( { type:'option', label: 'Non-free 3D art', value: 'Non-free 3D art' } ); licenseMenu.append( { type:'option', label: 'Non-free album cover', value: 'Non-free album cover' } ); licenseMenu.append( { type:'option', label: 'Non-free audio sample', value: 'Non-free audio sample' } ); licenseMenu.append( { type:'option', label: 'Non-free AUSPIC', value: 'Non-free AUSPIC' } ); licenseMenu.append( { type:'option', label: 'Non-free Australian DoD', value: 'Non-free Australian DoD' } ); licenseMenu.append( { type:'option', label: 'Non-free Baseball HoF', value: 'Non-free Baseball HoF' } ); licenseMenu.append( { type:'option', label: 'Non-free board game cover', value: 'Non-free board game cover' } ); licenseMenu.append( { type:'option', label: 'Non-free book cover', value: 'Non-free book cover' } ); licenseMenu.append( { type:'option', label: 'Non-free British Columbia traffic sign', value: 'Non-free British Columbia traffic sign' } ); licenseMenu.append( { type:'option', label: 'Non-free character', value: 'Non-free character' } ); licenseMenu.append( { type:'option', label: 'Non-free cereal box cover', value: 'Non-free cereal box cover' } ); licenseMenu.append( { type:'option', label: 'Non-free Cartoon Network image', value: 'Non-free Cartoon Network image' } ); licenseMenu.append( { type:'option', label: 'Non-free comic', value: 'Non-free comic' } ); licenseMenu.append( { type:'option', label: 'Non-free computer icon', value: 'Non-free computer icon' } ); licenseMenu.append( { type:'option', label: 'Non-free Crown copyright', value: 'Non-free Crown copyright' } ); licenseMenu.append( { type:'option', label: 'Non-free currency', value: 'Non-free currency' } ); licenseMenu.append( { type:'option', label: 'Non-free currency-EU banknote', value: 'Non-free currency-EU banknote' } ); licenseMenu.append( { type:'option', label: 'Non-free currency-EU coin common', value: 'Non-free currency-EU coin common' } ); licenseMenu.append( { type:'option', label: 'Non-free currency-EU coin national', value: 'Non-free currency-EU coin national' } ); licenseMenu.append( { type:'option', label: 'Non-free currency-New Zealand', value: 'Non-free currency-New Zealand' } ); licenseMenu.append( { type:'option', label: 'Non-free currency-Switzerland', value: 'Non-free currency-Switzerland' } ); licenseMenu.append( { type:'option', label: 'Non-free currency-UK', value: 'Non-free currency-UK' } ); licenseMenu.append( { type:'option', label: 'Non-free Denver Public Library image', value: 'Non-free Denver Public Library image' } ); licenseMenu.append( { type:'option', label: 'Non-free ESA media', value: 'Non-free ESA media' } ); licenseMenu.append( { type:'option', label: 'Non-free fair use in', value: 'Non-free fair use in' } ); licenseMenu.append( { type:'option', label: 'Non-free film screenshot', value: 'Non-free film screenshot' } ); licenseMenu.append( { type:'option', label: 'Non-free flag', value: 'Non-free flag' } ); licenseMenu.append( { type:'option', label: 'Non-free game cover', value: 'Non-free game cover' } ); licenseMenu.append( { type:'option', label: 'Non-free game screenshot', value: 'Non-free game screenshot' } ); licenseMenu.append( { type:'option', label: 'Non-free historic image', value: 'Non-free historic image' } ); licenseMenu.append( { type:'option', label: 'Non-free logo', value: 'Non-free logo' } ); licenseMenu.append( { type:'option', label: 'Non-free magazine cover', value: 'Non-free magazine cover' } ); licenseMenu.append( { type:'option', label: 'Non-free Mozilla logo', value: 'Non-free Mozilla logo' } ); licenseMenu.append( { type:'option', label: 'Non-free music video screenshot', value: 'Non-free music video screenshot' } ); licenseMenu.append( { type:'option', label: 'Non-free NASA logo', value: 'Non-free NASA logo' } ); licenseMenu.append( { type:'option', label: 'Non-free newspaper image', value: 'Non-free newspaper image' } ); licenseMenu.append( { type:'option', label: 'Non-free parody', value: 'Non-free parody' } ); licenseMenu.append( { type:'option', label: 'Non-free Otto Perry image', value: 'Non-free Otto Perry image' } ); licenseMenu.append( { type:'option', label: 'Non-free poster', value: 'Non-free poster' } ); licenseMenu.append( { type:'option', label: 'Non-free product cover', value: 'Non-free product cover' } ); licenseMenu.append( { type:'option', label: 'Non-free promotional', value: 'Non-free promotional' } ); licenseMenu.append( { type:'option', label: 'Non-free recording medium', value: 'Non-free recording medium' } ); licenseMenu.append( { type:'option', label: 'Non-free Robert Richardson image', value: 'Non-free Robert Richardson image' } ); licenseMenu.append( { type:'option', label: 'Non-free Scout logo', value: 'Non-free Scout logo' } ); licenseMenu.append( { type:'option', label: 'Non-free sheet music', value: 'Non-free sheet music' } ); licenseMenu.append( { type:'option', label: 'Non-free software cover', value: 'Non-free software cover' } ); licenseMenu.append( { type:'option', label: 'Non-free software screenshot', value: 'Non-free software screenshot' } ); licenseMenu.append( { type:'option', label: 'Non-free speech', value: 'Non-free speech' } ); licenseMenu.append( { type:'option', label: 'Non-free stamp', value: 'Non-free stamp' } ); licenseMenu.append( { type:'option', label: 'Non-free standard test image', value: 'Non-free standard test image' } ); licenseMenu.append( { type:'option', label: 'Non-free symbol', value: 'Non-free symbol' } ); licenseMenu.append( { type:'option', label: 'Non-free television screenshot', value: 'Non-free television screenshot' } ); licenseMenu.append( { type:'option', label: 'Non-free unsure', value: 'Non-free unsure' } ); licenseMenu.append( { type:'option', label: 'Non-free USGov-IEEPA sanctions', value: 'Non-free USGov-IEEPA sanctions' } ); licenseMenu.append( { type:'option', label: 'Non-free USGov-USPS stamp', value: 'Non-free USGov-USPS stamp' } ); licenseMenu.append( { type:'option', label: 'Non-free video cover', value: 'Non-free video cover' } ); licenseMenu.append( { type:'option', label: 'Non-free video screenshot', value: 'Non-free video screenshot' } ); licenseMenu.append( { type:'option', label: 'Non-free vodcast screenshot', value: 'Non-free vodcast screenshot' } ); licenseMenu.append( { type:'option', label: 'Non-free web screenshot', value: 'Non-free web screenshot' } ); licenseMenu.append( { type:'option', label: 'Non-free Wikimedia logo', value: 'Non-free Wikimedia logo' } ); licenseMenu.append( { type:'option', label: 'Non-free with NC', value: 'Non-free with NC' } ); licenseMenu.append( { type:'option', label: 'Non-free with ND', value: 'Non-free with ND' } ); licenseMenu.append( { type:'option', label: 'Non-free with permission', value: 'Non-free with permission' } ); licenseMenu.append( { type:'option', label: 'Non-free WWE photo', value: 'Non-free WWE photo' } ); form.append( { type:'submit', label: 'Submit' } ); // ADD FAVORITE LICENSE TAGS TO DROP-DOWN if( typeof( FurMeConfig.tagsImageTagFavorites ) != 'undefined' ) {		var fieldSet = form.append( {			type: 'field',			label: 'Favorites'			} ); fieldsetDiv = fieldSet.append( {				type: 'div', 				id: 'furme-two-cols-favorites'			} ); for ( var i = 0; i < FurMeConfig.tagsImageTagFavorites.length; i++) { 			fieldsetDiv.append( { type:'checkbox', name:'imageTags', list: [ {label: FurMeConfig.tagsImageTagFavorites[i], value: FurMeConfig.tagsImageTagFavorites[i] } ] } ); }	}	var fieldSet = form.append( {			type: 'field',			label: 'General'			} ); fieldsetDiv = fieldSet.append( {			type: 'div', 			id: 'furme-two-cols-general'		} ); fieldsetDiv.append( {			type: 'checkbox',			name: 'imageTags',			list: [				{ label: , value:  }			]		} ); var fieldSet = form.append( {			type: 'field',			label: 'Cleanup'			} ); fieldsetDiv = fieldSet.append( {			type: 'div', 			id: 'furme-two-cols-cleanup'		} ); fieldsetDiv.append( {			type: 'checkbox',			name: 'imageTags',			list: [				{ label: , value:  },				{ label: , value:  },				{ label: , value:  },				{ label: , value:  },				{ label: , value:  },				{ label: , value:  },				{ label: , value:  },				{ label: , value:  },				{ label: , value:  },				{ label: , value:  },				{ label: , value:  },				{ label: , value:  },				{ label: , value:  }, 				{ label: , value:  },				{ label: , value:  },				{ label: , value:  },				{ label: , value:  },				{ label: , value:  },				{ label: , value:  },				{ label: , value:  }			]		} ); var fieldSet = form.append( {			type: 'field',			label: 'Commons'			} ); fieldsetDiv = fieldSet.append( {			type: 'div', 			id: 'furme-two-cols-commons'		} ); fieldsetDiv.append( {			type: 'checkbox',			name: 'imageTags',			list: [                               { label: , value:  },				{ label: , value:  },				{ label: , value:  },				{ label: , value:  }, 				{ label: , value:  }			]		} ); var fieldSet = form.append( {			type: 'field',			label: 'Restrictions'			} ); fieldsetDiv = fieldSet.append( {			type: 'div', 			id: 'furme-two-cols-restriction'		} ); fieldsetDiv.append( {			type: 'checkbox',			name: 'imageTags',			list: [				{ label: , value:  },				{ label: , value:  },				{ label: , value:  },				{ label: , value:  }

]		} );	var fieldSet = form.append( { type: 'field', label: 'Replacement Available' } );	fieldsetDiv = fieldSet.append( { type: 'div', id: 'furme-two-cols-replacement' } ); 	fieldsetDiv.append( { type: 'checkbox', name: 'imageTags', list: [ { label: , value:  }, { label: , value:  } ]		} );	var result = form.render;	Window.setContent( result );	Window.display; }

furme.imagetags.evaluate = function furmeImageTagsEvaluate(event) { var imageTags = ''; var imageLicense = ''; if ( /[&?]furme-scroller=([^&]*)/.exec(window.location.search) ) { var scrollerStarted = /[&?]furme-scroller=([^&]*)/.exec(window.location.search)[1]; }	if( event.target.imageLicense ) { imageLicense = event.target.imageLicense.options[event.target.imageLicense.selectedIndex].value }	if (typeof event.target.imageTags != 'undefined' && null != event.target.imageTags) { for (var i = 0; i < event.target.imageTags.length; i++) {			if (event.target.imageTags[i].checked) imageTags += encodeURIComponent(event.target.imageTags[i].value + '\n'); }	}

window.location = wgScript + '?title=' + encodeURIComponent(mw.config.get('wgPageName')) + '&action=edit&furme=true&furmeImageTags=true&furme-scroller=' + scrollerStarted + '&imageLicense=' + imageLicense + '&imageTags=' + imageTags; }

furme.callback = function furmeCallback { var defaultGeneric = true; var defaultAlbumCover = false; var defaultBook = false; var defaultLogo = false; var defaultFilm = false; var defaultIndex = 0; var Window = new SimpleWindow( 600, FurMeConfig.windowHeight ); Window.setTitle( "Apply fair-use rationale to image" ); var form = new QuickForm( furme.callback.evaluate ); if ( /[&?]furme-scroller=([^&]*)/.exec(window.location.search) ) var scrollerStarted = decodeURIComponent(/[&?]furme-scroller=([^&]*)/.exec(window.location.search)[1]); else var scrollerStarted = 'false'; /*		WHAT SHOULD THE DEFAULT FUR OPTION BE	*/ if (document.getElementById('catlinks')) var linkList = document.getElementById('catlinks').getElementsByTagName("a"); if (linkList != 'undefined' && null != linkList) {		for( var i = 0; i < linkList.length; ++i ) { switch (linkList[i].title) {				case 'Category:Album covers': defaultAlbumCover = true; defaultGeneric = false; defaultIndex = 2; break; case 'Category:All non-free Logos': defaultLogo = true; defaultGeneric = false; defaultIndex = 1; break; case 'Category:Book covers': defaultBook = true; defaultGeneric = false; defaultIndex = 3; break; case 'Category:DVD covers': defaultFilm = true; defaultGeneric = false; defaultIndex = 4; break; default: break; }		}	}	if ( scrollerStarted == 'true' ) {		form.append( {			type: 'button',			name: 'furme-scroller-button',			label: 'FurMe Scroller: Skip Image',			event: furme.callback.next		} ); form.append( {			type: 'button',			name: 'furme-scroller-cancel',			label: 'FurMe Scroller: Stop!',			event: furme.callback.stopScrolling		} ); }	var field = form.append( {			type: 'field',			label: 'Type of fair-use rationale wanted'		} ); field.append( {			type: 'radio',			name: 'type',			event: furme.callback.choice,			list: [				{					label: 'Non-free use',					value: 'Non-free use rationale',					checked: defaultGeneric,					tooltip: 'Image or media being used with a non-free license under WP:FURG'				},				{					label: 'Logo',					value: 'Logo fur',					checked: defaultLogo,					tooltip: 'Image or media is a logo used to help the reader identify the organization'				},				{					label: 'Album Cover',					value: 'Album cover fur',					checked: defaultAlbumCover,					tooltip: 'Image or media is a cover of an album'				},				{					label: 'Book Cover',					value: 'Book cover fur',					checked: defaultBook,					tooltip: 'Image or media is a front cover of a book'				},				{					label: 'Film Cover',					value: 'Film cover fur',					checked: defaultFilm,					tooltip: 'Image or media is a cover of a film'				},				{					label: 'Historic Photo', value: 'Historic fur', tooltip: 'Image or media is a historically significant photograph' }			]		} );	form.append( { type: 'div', label: 'Work area', name: 'work_area' } );	var result = form.render;	Window.setContent( result );	Window.display;	// We must init the	var evt = document.createEvent( "Event" );	evt.initEvent( 'change', true, true );	result.type[defaultIndex].dispatchEvent( evt );	furme.callback.choice(evt); }

furme.callback.next = function furmeCallbackNext(event) { window.location = wgArticlePath.replace(/\$1/, wgPageName); }

furme.callback.stopScrolling = function furmeCallbackStopScrolling(event) { document.cookie = 'FurMeScroller-Counter=;path=/;expires=-1'; document.cookie = 'FurMeScroller-Images=;path=/;expires=-1'; window.location = wgArticlePath.replace(/\$1/, wgPageName); }

furme.callback.choice = function furmeCallbackChoose(event) { var value = event.target.value; var root = event.target.form; var work_area = new QuickForm.element( { 			type: 'div',			name: 'work_area'		} ); switch( value ) { case 'Non-free use rationale': work_area.append( {				type: 'input',				name: 'article',				label: 'Article: ',				value: seedValues['title']			} ); work_area.append( {				type: 'input',				name: 'website',				label: 'Source: ',				value: seedValues['url']			} ); work_area.append( {				type: 'input',				name: 'portion',				label: 'Portion: ',				tooltip: "How much copyrighted material is used? The amount used must not make the work as a whole less valuable to the copyright holder."			} ); work_area.append( {				type: 'input',				name: 'resolution',				label: 'Low Resolution: ',				value: seedValues['resolution'],				tooltip: "Images must generally be of low resolution. The rule of thumb for raster images is no more than 300 pixels in width or height, which ensures that the image's resolution is less than 0.1 megapixels. If you are using an image of higher resolution, please explain why. If the image is 0.1 megapixels or less, just put \"Yes\"."			} ); work_area.append( {				type: 'textarea',				name: 'purpose',				label: 'Purpose: ',				tooltip: "How does the media contribute significantly to the article(s) in which it is used? The use of the media must not interfere with the media's original purpose."			} ); work_area.append( {				type: 'textarea',				name: 'description',				label: 'Description: '			} ); work_area.append( {				type: 'textarea',				name: 'replaceability',				label: 'Replaceability: ',				tooltip: 'Explain why no free equivalent could reasonably be obtained or created to replace this media.'			} ); work_area.append( {				type: 'checkbox',				name: 'reduce',				list: [					{						label: 'Tag image for size reduction',						value: 'Yes'					}				]			} ); break; case 'Logo fur': work_area.append( {				type: 'input',				name: 'article',				label: 'Article: ',				value: seedValues['title']			} ); work_area.append( {				type: 'input',				name: 'website',				label: 'Website: ',				value: seedValues['url']			} ); work_area.append( {				type: 'input',				name: 'owner',				label: 'Owner: '			} ); var field = work_area.append( {			type: 'field',			label: 'Image use'			} );

field.append( {				type: 'radio',				name: 'useInArticle',				list: [					{						label: 'Infobox (' + seedValues['infobox'] + ')',						value: 'Infobox',						checked: seedValues['infobox'],						tooltip: 'The logo is used in a company infobox for logos that represent the company'					},					{						label: 'Org',						value: 'Org',						tooltip: 'The logo is used to identify an organization in an article or section about the organization'					},					{						label: 'Brand',						value: 'Brand',						tooltip: 'Image is used to identify a brand in an article or section about the brand'					},					{						label: 'Product',						value: 'Product',						tooltip: 'Image is used to identify a product or service in an article or section about that product or service'					},					{						label: 'Public facility',						value: 'Public facility',						tooltip: 'The logo used to identify a road, airport, station, route, city, neighborhood, government service, etc' },					{						label: 'Other', value: 'Other', tooltip: 'Some other use. Describe in "Purpose"' }				]

} );		work_area.append( { type: 'checkbox', name: 'rename', list: [ {						label: 'Tag image for renaming', value: 'Yes' }				]			} );		work_area.append( { type: 'checkbox', name: 'reduce', list: [ {						label: 'Tag image for size reduction', value: 'Yes' }				]			} );		break;	case 'Album cover fur':		work_area.append( { type: 'input', name: 'article', label: 'Article: ', value: seedValues['title'] } );		work_area.append( { type: 'input', name: 'website', label: 'Website: ', value: seedValues['url'] } );		work_area.append( { type: 'input', name: 'artist', label: 'Artist: ', value: seedValues['artist'] } );		work_area.append( { type: 'input', name: 'album', label: 'Album: ', value: seedValues['name'] } );		work_area.append( { type: 'input', name: 'label', label: 'Label: ', value: seedValues['label'] } );

work_area.append( {				type: 'input',				name: 'owner',				label: 'Owner: '			} ); var fieldType = work_area.append( {			type: 'field',			label: 'Type'			} ); fieldType.append( {				type: 'radio',				name: 'useType',				list: [					{						label: 'Album',						value: 'album',						checked: seedValues['infoboxAlbum']					},					{						label: 'Single',						value: 'single',						checked: seedValues['infoboxSingle']					}				]

} );		var field = work_area.append( { type: 'field', label: 'Image use' } );

field.append( {				type: 'radio',				name: 'useInArticle',				list: [					{						label: 'Infobox (' + seedValues['infobox'] + ')',						value: 'Infobox',						checked: seedValues['infobox'],						tooltip: 'The image is used in an infobox for the article about the album / work'					},					{						label: 'Header',						value: 'Header',						tooltip: 'The image is used at the top of article about the album / work'					},					{						label: 'Section',						value: 'Section',						tooltip: 'Image is used in a section devoted to the album / work'					},					{						label: 'Artist',						value: 'Artist',						tooltip: 'Image is used in an article about the artist (be careful here)'					},					{						label: 'Other',						value: 'Other',						tooltip: 'Some other use. Describe in "Purpose"'					}				]

} );		work_area.append( { type: 'checkbox', name: 'scanned', list: [ {						label: 'Scanned by uploader', value: 'Yes' }				]			} );		work_area.append( { type: 'checkbox', name: 'rename', list: [ {						label: 'Tag image for renaming', value: 'Yes' }				]			} );		work_area.append( { type: 'checkbox', name: 'reduce', list: [ {						label: 'Tag image for size reduction', value: 'Yes' }				]			} );		break;	case 'Book cover fur':		work_area.append( { type: 'input', name: 'article', label: 'Article: ', value: seedValues['title'] } );		work_area.append( { type: 'input', name: 'title', label: 'Title: ', value: seedValues['name'] } );		work_area.append( { type: 'input', name: 'author', label: 'Author: ', value: seedValues['author'] } );		work_area.append( { type: 'input', name: 'publisher', label: 'Publisher: ', value: seedValues['publisher'] } );		work_area.append( { type: 'input', name: 'website', label: 'Website: ', value: seedValues['url'] } );		work_area.append( { type: 'input', name: 'owner', label: 'Owner: ' } );		work_area.append( { type: 'input', name: 'coverArtist', label: 'Cover Artist: ', value: seedValues['coverArtist'] } );		work_area.append( { type: 'input', name: 'year', label: 'Year: ', value: seedValues['year'] } );		var field = work_area.append( { type: 'field', label: 'Image use' } );

field.append( {				type: 'radio',				name: 'useInArticle',				list: [					{						label: 'Infobox (' + seedValues['infobox'] + ')',						value: 'Infobox',						checked: seedValues['infobox'],						tooltip: 'The image is used in an infobox for the article about the book'					},					{						label: 'Header',						value: 'Header',						tooltip: 'The image is used at the top of article about the book'					},					{						label: 'Section',						value: 'Section',						tooltip: 'Image is used in a section devoted to the book'					},					{						label: 'Author',						value: 'Author',						tooltip: 'Image is used in an article about the author (be careful here)'					},					{						label: 'Other',						value: 'Other',						tooltip: 'Some other use. Describe in "Purpose"'					}				]

} );		work_area.append( { type: 'checkbox', name: 'scanned', list: [ {						label: 'Scanned by uploader', value: 'Yes' }				]			} );		work_area.append( { type: 'checkbox', name: 'rename', list: [ {						label: 'Tag image for renaming', value: 'Yes' }				]			} );		work_area.append( { type: 'checkbox', name: 'reduce', list: [ {						label: 'Tag image for size reduction', value: 'Yes' }				]			} );		break;	case 'Film cover fur':		work_area.append( { type: 'input', name: 'article', label: 'Article: ', value: seedValues['title'] } );		work_area.append( { type: 'input', name: 'website', label: 'Website: ', value: seedValues['url'] } );		work_area.append( { type: 'input', name: 'album', // share the same parameter as album cover label: 'Film: ', value: seedValues['name'] } );		work_area.append( { type: 'input', name: 'distributor', label: 'Distributor: ', value: seedValues['distributor'] } );

work_area.append( {				type: 'input',				name: 'owner',				label: 'Owner: '			} ); var fieldType = work_area.append( {			type: 'field',			label: 'Type'			} ); fieldType.append( {				type: 'radio',				name: 'useType',				list: [					{						label: 'DVD',						value: 'DVD'					},					{						label: 'VHS',						value: 'video cassette'					}				]

} );		var field = work_area.append( { type: 'field', label: 'Image use' } );

field.append( {				type: 'radio',				name: 'useInArticle',				list: [					{						label: 'Infobox (' + seedValues['infobox'] + ')',						value: 'Infobox',						checked: seedValues['infobox'],						tooltip: 'The image is used in an infobox for the article about the film / work'					},					{						label: 'Header',						value: 'Header',						tooltip: 'The image is used at the top of article about the film / work'					},					{						label: 'Section',						value: 'Section',						tooltip: 'Image is used in a section devoted to the film / work'					},					{						label: 'Other',						value: 'Other',						tooltip: 'Some other use. Describe in "Purpose"'					}				]

} );		work_area.append( { type: 'checkbox', name: 'scanned', list: [ {						label: 'Scanned by uploader', value: 'Yes' }				]			} );		work_area.append( { type: 'checkbox', name: 'rename', list: [ {						label: 'Tag image for renaming', value: 'Yes' }				]			} );		work_area.append( { type: 'checkbox', name: 'reduce', list: [ {						label: 'Tag image for size reduction', value: 'Yes' }				]			} );		break;	case 'Historic fur':		work_area.append( { type: 'input', name: 'article', label: 'Article: ', value: seedValues['title'] } );		work_area.append( { type: 'input', name: 'website', label: 'Source: ', value: seedValues['url'] } );		}

work_area.append( { type:'submit' } ); work_area = work_area.render; root.replaceChild( work_area, root.lastChild ); var refreshImageContainer = document.getElementsByName('article')[0].parentNode.appendChild( document.createElement( 'span' ) ); var refreshImage = refreshImageContainer.appendChild( document.createElement( 'img' ) ); refreshImage.setAttribute('src', 'http://upload.wikimedia.org/wikipedia/commons/6/6e/Reload_page.png'); refreshImage.setAttribute('onclick', 'furme.refreshValues'); refreshImage.setAttribute('title', 'Refresh values'); refreshImage.style.width = '18px'; refreshImage.style.cursor = 'pointer';

}

furme.refreshValues = function furmeRefreshValues { var newArticle = document.getElementsByName('article')[0].value document.body.removeChild( document.getElementsByName('id')[0].parentNode.parentNode ); furme.seedValues(newArticle); } furme.callback.evaluate = function furmeCallbackEvaluate(event) { var types = event.target.type; for( var i = 0; i < types.length; ++i ) { if( types[i].checked ) { var type = types[i].value; break; }	}	if ( /[&?]furme-scroller=([^&]*)/.exec(window.location.search) ) { var scrollerStarted = /[&?]furme-scroller=([^&]*)/.exec(window.location.search)[1]; }	if( event.target.portion ) { var portion = encodeURIComponent(event.target.portion.value); }	if( event.target.description ) { var description = encodeURIComponent(event.target.description.value); }	if( event.target.resolution ) { var resolution = encodeURIComponent(event.target.resolution.value); }	if( event.target.purpose ) { var purpose = encodeURIComponent(event.target.purpose.value); }	if( event.target.replaceability ) { var replaceability = encodeURIComponent(event.target.replaceability.value); }	if( event.target.article ) { var article = encodeURIComponent(event.target.article.value); }	if( event.target.website ) { var website = encodeURIComponent(event.target.website.value); }	if( event.target.owner ) { var owner = encodeURIComponent(event.target.owner.value); }	if( event.target.artist ) { var artist = encodeURIComponent(event.target.artist.value); }	if( event.target.album ) { var album = encodeURIComponent(event.target.album.value); }	if( event.target.label ) { var label = encodeURIComponent(event.target.label.value); }	if( event.target.author ) { var author = encodeURIComponent(event.target.author.value); }	if( event.target.publisher ) { var publisher = encodeURIComponent(event.target.publisher.value); }	if( event.target.year ) { var year = encodeURIComponent(event.target.year.value); }	if( event.target.title ) { var title = encodeURIComponent(event.target.title.value); }	if( event.target.distributor ) { var distributor = encodeURIComponent(event.target.distributor.value); }	if( event.target.coverArtist ) { var coverArtist = encodeURIComponent(event.target.coverArtist.value); }	if (typeof event.target.useType != 'undefined' && null != event.target.useType) { for (var i=0; i < event.target.useType.length; i++) { if (event.target.useType[i].checked) { var useType = encodeURIComponent(event.target.useType[i].value); }		}	}	if (typeof event.target.useInArticle != 'undefined' && null != event.target.useInArticle) { for (var i=0; i < event.target.useInArticle.length; i++) { if (event.target.useInArticle[i].checked) { var useInArticle = encodeURIComponent(event.target.useInArticle[i].value); }		}	}	if (typeof event.target.scanned != 'undefined' && null != event.target.scanned) { if (event.target.scanned.checked) var scanned = encodeURIComponent(event.target.scanned.value); }	if (typeof event.target.rename != 'undefined' && null != event.target.rename) { if (event.target.rename.checked) var rename = encodeURIComponent(event.target.rename.value); }	if (typeof event.target.reduce != 'undefined' && null != event.target.reduce) { if (event.target.reduce.checked) var reduce = encodeURIComponent(event.target.reduce.value); }

window.location = wgScript + '?title=' + encodeURIComponent(mw.config.get('wgPageName')) + '&action=edit&furme=true&furme-scroller=' + scrollerStarted + '&type=' + type + '&article=' + article + '&website=' + website + '&portion=' + portion + '&resolution=' + resolution + '&purpose=' + purpose + '&description=' + description + '&replaceability=' + replaceability + '&use=' + useInArticle + '&useType=' + useType + '&owner=' + owner + '&artist=' + artist + '&album=' + album + '&label=' + label + '&rename=' + rename + '&scan=' + scanned + '&author=' + author + '&publisher=' + publisher + '&year=' + year + '&bookTitle=' + title + '&coverArtist=' + coverArtist + '&distributor=' + distributor + '&reduce=' + reduce;

}

furme.imageRemover = function furmeImageRemover {	try { var image = decodeURIComponent(/[&?]image=([^&]*)/.exec(window.location.search)[1]); } catch (err) {} if (typeof(image) != 'undefined') {		if ((wgNamespaceNumber == 0 || wgNamespaceNumber == 2) && wgAction == 'view') {			var imageList = document.getElementById('bodyContent').getElementsByTagName('img'); if (typeof imageList != 'undefined' && null != imageList) { for( var i = 0; i < imageList.length; ++i ) { if (imageList[i].parentNode.className == 'image' && decodeURIComponent(imageList[i].parentNode.href) == mw.config.get('wgServer') + mw.config.get('wgArticlePath').replace(/\$1/, image)) { var imageContainer = imageList[i].parentNode.parentNode.appendChild( document.createElement( 'div' ) ); var removalLink = imageContainer.appendChild( document.createElement( 'a' ) ) removalLink.innerHTML = '<< Remove unacceptably used image >>'; removalLink.href = wgScript + '?title=' + wgPageName + '&action=edit&furme=true&image=' + encodeURIComponent(image); removalLink.focus; imageList[i].parentNode.parentNode.style.border = '1px solid #6E1616'; imageList[i].parentNode.parentNode.style.backgroundColor = 'pink'; }				}			}		}		else if ((wgNamespaceNumber == 0 || wgNamespaceNumber == 2) && wgAction == 'edit') { 			var editform = document.editform; if (!editform) return; var textbox = editform.wpTextbox1; if (!textbox) return; textboxText = textbox.value; switch (FurMeConfig.imageRemovalMethod) {				case 'pixel': regExFindImage = '/(' + image.replace(/Image:/, '') + ')/ig'; // underscores textboxText = textboxText.replace(eval(regExFindImage), 'Pixel.gif'); if (image.search(/_/ig) != -1) // spaces {						regExFindImage = '/(' + image.replace(/Image:/, '').replace(/_/ig, ' ') + ')/ig'; textboxText = textboxText.replace(eval(regExFindImage), 'Pixel.gif'); }					break; case 'nonfreeimageremoved': regExFindImage = '/(' + image.replace(/Image:/, '') + ')/ig'; // underscores textboxText = textboxText.replace(eval(regExFindImage), 'NonFreeImageRemoved.svg'); if (image.search(/_/ig) != -1) // spaces {						regExFindImage = '/(' + image.replace(/Image:/, '').replace(/_/ig, ' ') + ')/ig'; textboxText = textboxText.replace(eval(regExFindImage), 'NonFreeImageRemoved.svg'); }					break; case 'comment': default: regExFindImage = '/(\\[\\[.*' + image + '.*\\]\\])\\s*/ig'; // underscores regexFindImageGallery = '/^\\s*(' + image + '.*)\\n/igm'; // underscores regexFindImageInfobox = '/([= ])(' + image.replace(/Image:/, '') + '.*)\\n/ig'; // underscores textboxText = textboxText.replace(eval(regExFindImage), ''); textboxText = textboxText.replace(eval(regexFindImageGallery), '\n'); textboxText = textboxText.replace(eval(regexFindImageInfobox), '$1\n'); if (image.search(/_/ig) != -1) // spaces {						regExFindImage = '/(\\[\\[.*' + image.replace(/_/ig, ' ') + '.*\\]\\])\\s*/ig'; regexFindImageGallery = '/^\\s*(' + image.replace(/_/ig, ' ') + '.*)\\n/igm'; regexFindImageInfobox = '/([= ])(' + image.replace(/Image:/, '').replace(/_/ig, ' ') + '.*)\\n/ig'; textboxText = textboxText.replace(eval(regExFindImage), ''); textboxText = textboxText.replace(eval(regexFindImageGallery), '\n'); textboxText = textboxText.replace(eval(regexFindImageInfobox), '$1\n'); }					break; }			textbox.value = textboxText; if (FurMeConfig.watchMyEdits) editform.wpWatchthis.checked = true; if (editform.wpSummary) editform.wpSummary.value = "Non-free image removed per WP:NFC using FurMe"; switch(FurMeConfig.actionOnSubmit) {				case 'none': break; case 'save': if (editform.wpSave) { editform.wpSave.click; }					break; case 'preview': if (editform.wpPreview) { editform.wpPreview.click; }					break; case 'diff': default: if (editform.wpDiff) { editform.wpDiff.click; }					break; }

}	} }

String.prototype.trimPunctuation = function { return this.replace(/^\W+/g,""); }

String.prototype.rtrimPipe = function { return this.replace(/\|\s*$/g,""); }

String.prototype.stripslashes = function { temp = this.replace(/\\'/g,'\''); temp = temp.replace(/\\"/g,'"'); temp = temp.replace(/\\\\/g,'\\'); temp = temp.replace(/\\0/g,'\0'); return temp; }

String.prototype.cleanAmazonURL = function { temp = this.replace(/\/[^\/]+?=[^]+?$/g, ''); temp = temp.replace(/gp\/product/g, 'o/ASIN'); return temp; }

function readCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for(var i=0;i < ca.length;i++) { var c = ca[i]; while (c.charAt(0)==' ') c = c.substring(1,c.length); if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); }	return null; }

//