ഉപയോക്താവ്:മാതൃകാ ഉപയോക്താവ്/twinklearv.js

വിക്കിപീഡിയ, ഒരു സ്വതന്ത്ര വിജ്ഞാനകോശം.

ശ്രദ്ധിക്കുക: സേവ് ചെയ്തശേഷം മാറ്റങ്ങൾ കാണാനായി താങ്കൾക്ക് ബ്രൗസറിന്റെ കാഷെ ഒഴിവാക്കേണ്ടി വന്നേക്കാം.

  • ഫയർഫോക്സ് / സഫാരി: Reload ബട്ടൺ അമർത്തുമ്പോൾ Shift കീ അമർത്തി പിടിക്കുകയോ, Ctrl-F5 അല്ലെങ്കിൽ Ctrl-R (മാക്കിന്റോഷിൽ ⌘-R ) എന്ന് ഒരുമിച്ച് അമർത്തുകയോ ചെയ്യുക
  • ഗൂഗിൾ ക്രോം: Ctrl-Shift-R (മാക്കിന്റോഷിൽ ⌘-Shift-R ) അമർത്തുക
  • ഇന്റർനെറ്റ് എക്സ്പ്ലോറർ: Refresh ബട്ടൺ അമർത്തുമ്പോൾ Ctrl കീ അമർത്തിപിടിക്കുക. അല്ലെങ്കിൽ Ctrl-F5 അമർത്തുക
  • ഓപ്പറ: Menu → Settings എടുക്കുക (മാക്കിൽ Opera → Preferences) എന്നിട്ട് Privacy & security → Clear browsing data → Cached images and files ചെയ്യുക.
// If TwinkleConfig aint exist.
if( typeof( TwinkleConfig ) == 'undefined' ) {
	TwinkleConfig = {};
}

/**
 TwinkleConfig.summaryAd (string)
 If ad should be added or not to summary, default [[WP:TWINKLE|TWINKLE]]
 */
if( typeof( TwinkleConfig.summaryAd ) == 'undefined' ) {
	TwinkleConfig.summaryAd = " using [[WP:TW|TW]]";
}

/**
 TwinkleConfig.markAIVReportAsMinor (boolean)
 Defines if a reports to AIV should be marked as minor, if false, default is applied as per preference.
 */
if( typeof( TwinkleConfig.markAIVReportAsMinor ) == 'undefined' ) {
	TwinkleConfig.markAIVReportAsMinor = true;
}

/**
 TwinkleConfig.markUAAReportAsMinor (boolean)
 Defines if a reports to UAA should be marked as minor, if false, default is applied as per preference.
 */
if( typeof( TwinkleConfig.markUAAReportAsMinor ) == 'undefined' ) {
	TwinkleConfig.markUAAReportAsMinor = true;
}

/**
 TwinkleConfig.markSockReportAsMinor (boolean)
 Defines if a reports to SPI should be marked as minor, if false, default is applied as per preference.
 */
if( typeof( TwinkleConfig.markSockReportAsMinor ) == 'undefined' ) {
	TwinkleConfig.markSockReportAsMinor = true;
}

function num2order( num ) {
	switch( num ) {
	case 1: return '';
	case 2: return '2nd';
	case 3: return '3rd';
	default: return num + 'th';
	}
}

$( twinklearv );

function twinklearv(){
	var username;


	if ( wgNamespaceNumber == 3 || wgNamespaceNumber == 2 || ( wgNamespaceNumber == -1 && wgTitle == "Contributions" )){

		// If we are on the contributions page, need to parse some then
		if( wgNamespaceNumber == -1 && wgTitle == "Contributions" ) {
			username = decodeURIComponent(document.evaluate( 'substring-after(//div[@id="contentSub"]//a[@title="Special:Log"][last()]/@href, "user=")', document, null, XPathResult.STRING_TYPE, null).stringValue.replace( /\+/g, "%20"));
		} else {
			username = wgTitle.split( '/' )[0]; // only first part before any slashes
		}

		if( !username ) {
			// Something is fishy, there was no user? lets about everything
			throw "given username was " + username + " and thus makes no sense.";
		}

		var name = isIPAddress( username ) ? 'Report IP' : 'Report';
		var title =  isIPAddress( username ) ? 'Report IP to Administators' : 'Report user to Administrators';
		if (twinkleConfigExists)
		{
			mw.util.addPortletLink( 'p-cactions', "javascript:twinklearv.callback(\"" + username.replace( /\"/g, "\\\"") + "\")", "ARV", "tw-arv", name, title );
		}
		else
		{
			mw.util.addPortletLink('p-cactions', 'javascript:alert("Your account is too new to use Twinkle.");', 'ARV', 'tw-arv', name, title);
		}
	}
}

twinklearv.callback = function twinklearvCallback( uid ) {
	if( uid == wgUserName ){
		alert( 'You don\'t want to report yourself, do you?' );
		return;
	}

	var Window = new SimpleWindow( 600, 500 );
	Window.setTitle( "Advance Reporting and Vetting" ); //Backronym

	var form = new QuickForm( twinklearv.callback.evaluate );
	var categories = form.append( {
			type: 'select',
			name: 'category',
			label: 'Select report type: ',
			event: twinklearv.callback.change_category
		} );
	categories.append( {
			type: 'option',
			label: 'Vandalism',
			value: 'aiv'
		} );
	categories.append( {
			type: 'option',
			label: 'Username',
			value: 'username'
		} );
	categories.append( {
			type: 'option',
			label: 'Sockpuppeteer',
			value: 'sock'
		} );

	form.append( {
			type: 'field',
			label:'Work area',
			name: 'work_area'
		} );
	form.append( {
			type: 'hidden',
			name: 'uid',
			value: uid
		} );
	
	var result = form.render();
	Window.setContent( result );
	Window.display();

	// We must init the
	var evt = document.createEvent( "Event" );
	evt.initEvent( 'change', true, true );
	result.category.dispatchEvent( evt );

}

twinklearv.callback.change_category = function twinklearvCallbackChangeCategory(e) {
	var value = e.target.value;
	var root = e.target.form;
	var old_area;
	for( var i = 0; i < root.childNodes.length; ++i ) {
		var node = root.childNodes[i];
		if( 
			node instanceof Element &&
			node.getAttribute( 'name' ) == 'work_area' 
		) {
			old_area = node;
			break;
		}
	}
	var work_area = null;

	switch( value ) {
	default:
	case 'aiv':
		work_area = new QuickForm.element( { 
				type: 'field',
				label: 'Report user for vandalism',
				name: 'work_area'
			} );
		work_area.append( {
				type: 'input',
				name: 'page',
				label: 'Primary linked page: ',
				tooltip: 'Leave blank to not link to the page in the report',
				value: QueryString.exists( 'vanarticle' ) ? QueryString.get( 'vanarticle' ) : '',
				event: function(e) {
					var value = e.target.value;
					var root = e.target.form;
					if( value == '' ) {
						root.badid.disabled = root.goodid.disabled = true;
					} else {
						root.badid.disabled = false;
						root.goodid.disabled = root.badid.value == '';
					}
				}
			} );
		work_area.append( {
				type: 'input',
				name: 'badid',
				label: 'Revision ID for target page when vandalised: ',
				tooltip: 'Leave blank for no diff link',
				value: QueryString.exists( 'vanarticlerevid' ) ? QueryString.get( 'vanarticlerevid' ) : '',
				disabled: !QueryString.exists( 'vanarticle' ),
				event: function(e) {
					var value = e.target.value;
					var root = e.target.form;
					root.goodid.disabled = value == '';
				}
			} );
		work_area.append( {
				type: 'input',
				name: 'goodid',
				label: 'Last good revision ID before vandalism of target page: ',
				tooltip: 'Leave blank for diff link to previous revision',
				value: QueryString.exists( 'vanarticlegoodrevid' ) ? QueryString.get( 'vanarticlegoodrevid' ) : '',
				disabled: !QueryString.exists( 'vanarticle' ) || QueryString.exists( 'vanarticlerevid' )
			} );
		work_area.append( {
				type: 'checkbox',
				name: 'arvtype',
				list: [
					{ 
						label: 'Vandalism after final (level 4 or 4im) warning given',
						value: 'final'
					},
					{ 
						label: 'Vandalism after recent (within 1 day) release of block',
						value: 'postblock'
					},
					{ 
						label: 'Evidently a vandalism-only account',
						value: 'vandalonly',
						disabled: isIPAddress( root.uid.value )
					},
					{ 
						label: 'Account is evidently a spambot or a compromised account',
						value: 'spambot'
					},
					{ 
						label: 'Account is a promotion-only account',
						value: 'promoonly'
					}
				]
			} );
		work_area.append( {
				type: 'textarea',
				name: 'reason',
				label: 'Comment: '
			} );
		work_area.append( { type:'submit' } );
		work_area = work_area.render();
		old_area.parentNode.replaceChild( work_area, old_area );
		break;
	case 'username':
		work_area = new QuickForm.element( { 
				type: 'field',
				label: 'Report username violation',
				name: 'work_area'
			} );
		work_area.append ( { 
				type:'header', 
				label:'Type(s) of inappropriate username',
				tooltip: 'Wikipedia does not allow usernames that are misleading, promotional, offensive or disruptive. Domain names and e-mail addresses are likewise prohibited. These criteria apply to both usernames and signatures. Usernames that are inappropriate in another language, or that represent an inappropriate name with misspellings and substitutions, or do so indirectly or by implication, are still considered inappropriate.'
			} );
		work_area.append( {
				type: 'checkbox',
				name: 'arvtype',
				list: [
					{
						label: 'Misleading username',
						value: 'misleading',
						tooltip: 'Misleading usernames imply relevant, misleading things about the contributor. For example, misleading points of fact, an impression of undue authority, or the suggestion that the account is operated by a group, project or collective rather than one individual.'
					},
					{ 
						label: 'Promotional username',
						value: 'promotional',
						tooltip: 'Promotional usernames are advertisements for a company or group.'
					},
					{ 
						label: 'Offensive username',
						value: 'offensive',
						tooltip: 'Offensive usernames make harmonious editing difficult or impossible.'
					},
					{ 
						label: 'Disruptive username',
						value: 'disruptive',
						tooltip: 'Disruptive usernames include outright trolling or personal attacks, or otherwise show a clear intent to disrupt Wikipedia.'
					}
				]
			} );
		work_area.append( {
				type: 'textarea',
				name: 'reason',
				label: 'Comment:'
			} );
		work_area.append( { type:'submit' } );
		work_area = work_area.render();
		old_area.parentNode.replaceChild( work_area, old_area );
		break;

	case 'sock':
		work_area = new QuickForm.element( { 
				type: 'field',
				label: 'Report suspected sockpuppeteer',
				name: 'work_area'
			} );
		work_area.append(
			{
				type: 'dyninput',
				name: 'sockpuppet',
				label: 'Sockpuppets',
				sublabel: 'Sock: ',
				tooltip: 'The username of the sockpuppet without the User:-prefix',
				min: 2
			}
		);
		work_area.append( {
				type: 'textarea',
				label: 'Evidence:',
				name: 'evidence',
				tooltip: 'Enter your evidence. It should make clear that each of these users is likely to be abusing multiple accounts. Usually this means diffs, page histories or other information that justifies why the users are a) the same and b) disruptive. This should purely be evidence and information needed to judge the matter. Avoid all other discussion that is not evidence of sockpuppetry or other multiple account abuse.'
			} );
		work_area.append( {
				type: 'checkbox',
				list: [ {
					label: 'Request CheckUser evidence',
					name: 'checkuser',
					tooltip: 'CheckUser is a tool used to obtain technical evidence related to a sock-puppetry allegation. It will not be used without good cause, which you must clearly demonstrate. Make sure your evidence explains why CheckUser is appropriate.',
					subgroup: {
						label: 'Select situation:',
						name: 'checkusercode',
						type: 'select',
						list: [
							{
								label: 'Evasion of bans or other remedies issued by the arbitration committee (closed cases only)',
								value: 'A'
							},
							{
								label: 'Ongoing, serious pattern vandalism involving dozens of incidents',
								value: 'B'
							},
							{
								label: 'Vote fraud for a closed vote where the possible sockpuppet votes affect the outcome',
								value: 'C'
							},
							{
								label: '3RR violation using socks',
								value: 'D'
							},
							{
								label: 'Evasion of community-based bans or blocks',
								value: 'E'
							},
							{
								label: 'Request doesn\'t fit any of the criteria but you believe a check is warranted anyway',
								value: 'F'
							}
						]
					}
				} ]
			} );
		work_area.append( { type:'submit' } );
		work_area = work_area.render();
		old_area.parentNode.replaceChild( work_area, old_area );
		break;
	}
}

twinklearv.callbacks = {
	aiv: function( self ) {
		uid = self.params.uid;
		reason = self.params.reason;
		var form = self.responseXML.getElementById('editform');

		if( !form ) {
			self.statelem.error( 'Failed to retrieve edit form.' );
			return;
		}
		var text = form.wpTextbox1.value;

		var re = new RegExp( "\\{\\{\\s*(?:(?:[Ii][Pp])?[Vv]andal|[Uu]serlinks)\\s*\\|\\s*(?:1=)?\\s*" + RegExp.escape( uid, true ) + "\\s*\\}\\}" );

		var myArr;
		if( ( myArr = re.exec( text ) ) ) {
			self.statelem.info( 'Report already present, will not add a new one' );
			return;
		}
		self.statelem.status( 'Adding new report...' );
		var postData = {
			'wpMinoredit': ( form.wpMinoredit.checked || TwinkleConfig.markAIVReportAsMinor ) ? '' : undefined, 
			'wpWatchthis': form.wpWatchthis.checked ? '' : undefined,
			'wpStarttime': form.wpStarttime.value,
			'wpEdittime': form.wpEdittime.value,
			'wpAutoSummary': form.wpAutoSummary.value,
			'wpEditToken': form.wpEditToken.value,
			'wpSection': form.wpSection.value,
			'wpSummary': 'Reporting [[Special:Contributions/' + uid + '|' + uid + ']].'+ TwinkleConfig.summaryAd,
			'wpTextbox1': text + '*\{\{' + ( isIPAddress( uid ) ? 'IPvandal' : 'vandal' ) + '|' + (/\=/.test( uid ) ? '1=' : '' ) + uid + '\}\} - ' + reason + ' ~~' + '~~'
		};

		self.post( postData );
	},
	username: function( self ) {
		uid = self.params.uid;
		reason = self.params.reason;
		var form = self.responseXML.getElementById('editform');

		if( !form ) {
			self.statelem.error( 'Failed to retrieve edit form.' );
			return;
		}
		var text = form.wpTextbox1.value;

		if (new RegExp( "\\{\\{\\s*user-uaa\\s*\\|\\s*(1\\s*=\\s*)?" + RegExp.escape(uid, true) + "\\s*(\\||\\})" ).test(text)) {
			self.statelem.error( 'User is already listed.' );
			return;
		}

		self.statelem.status( 'Adding new report...' );
		var postData = {
			'wpMinoredit': ( form.wpMinoredit.checked || TwinkleConfig.markUAAReportAsMinor ) ? '' : undefined, 
			'wpWatchthis': form.wpWatchthis.checked ? '' : undefined,
			'wpStarttime': form.wpStarttime.value,
			'wpEdittime': form.wpEdittime.value,
			'wpAutoSummary': form.wpAutoSummary.value,
			'wpEditToken': form.wpEditToken.value,
			'wpSection': form.wpSection.value,
			'wpSummary': 'Reporting [[Special:Contributions/' + uid + '|' + uid + ']].'+ TwinkleConfig.summaryAd,
			'wpTextbox1': text.replace( /-->/, "-->\n" + reason.replace( '\$', "$$$$" ) )
		};
		self.post( postData );
	},
	sock: {
		main: function( self ) { 
			var form = self.responseXML.getElementById('editform');
			var text = form.wpTextbox1.value;
			var open = false;

			if( text.match( /(^\s*$|^\s*\{\{spiarchive notice\|.+?\}\}\s*$|\{\{spiclose\|archive\}\}(?![\s\S]*?report date))/i ) ) {
				self.statelem.info( 'Open discussion not found, creating new discussion' );
			} else {
				self.statelem.info( 'Open discussion found' );
				if( !confirm( "Would you like to continue?\n(Twinkle will add your non-redundant information to the open discussion)" ) ) {
					self.statelem.info( 'Open discussion found, aborted per user request' );
					return;
				}
				open = true;
				self.statelem.info( 'Open discussion found, adding additional information' );
			}

			if( !open ) {
				var query = {
					'title': 'User talk:' + self.params.uid,
					'action': 'submit'
				};

				var wikipedia_wiki = new Wikipedia.wiki( 'Notifying suspected sockpuppeteer', query, twinklearv.callbacks.sock.notifySock );
				wikipedia_wiki.params = self.params;
				wikipedia_wiki.get();

				var query = {
					'title': 'User:' + self.params.uid,
					'action': 'submit'
				};

				var wikipedia_wiki = new Wikipedia.wiki( 'Tag suspected sockpuppeteer', query, twinklearv.callbacks.sock.tagSockpuppeteer );
				wikipedia_wiki.params = self.params;
				wikipedia_wiki.get();
			}

			var statusIndicator1 = new Status('Tagging suspected sockpuppets', '0%');
			var statusIndicator2 = new Status('Notifying suspected sockpuppets', '0%');

			var total = self.params.sockpuppets.length * 2;

			var onsuccess = function( self ) {
				var obj = self.params.obj;
				var total = self.params.total;
				var now = parseInt( 100 * ++(self.params.current)/total ) + '%';
				obj.update( now );
				self.statelem.unlink();
				if( self.params.current >= total ) {
					obj.info( now + ' (completed)' );
					Wikipedia.removeCheckpoint();
				}
			}
			var onloaded = onsuccess;

			var onloading = function( self ) {}

			Wikipedia.addCheckpoint();

			var params1 = clone( self.params );
			params1.total = total;
			params1.obj = statusIndicator1;
			params1.current =   0;

			var params2 = clone( self.params );
			params2.total = total;
			params2.obj = statusIndicator2;
			params2.current =   0;

			var socks = self.params.sockpuppets;
			for( var i = 0; i < socks.length; ++i ) {
				var query = {
					'title': 'User:' + socks[i],
					'action': 'submit'
				};
				var wikipedia_wiki = new Wikipedia.wiki( "Tagging of " +  socks[i], query, twinklearv.callbacks.sock.tagSockpuppet );
				wikipedia_wiki.params = params1;
				wikipedia_wiki.onloaded = onloaded;
				wikipedia_wiki.onsuccess = onsuccess;
				wikipedia_wiki.get();
				var query = {
					'title': 'User talk:' + socks[i],
					'action': 'submit'
				};
				var wikipedia_wiki = new Wikipedia.wiki( "Notification for " +  socks[i], query, twinklearv.callbacks.sock.notifySock );
				wikipedia_wiki.params = params2;
				wikipedia_wiki.onloaded = onloaded;
				wikipedia_wiki.onsuccess = onsuccess;
				wikipedia_wiki.get();
			}

			if( open ) {
				for( var i = self.params.sockpuppets.length - 1; i >= 0; i-- ) {
					var re = new RegExp( "\\{\\{(checkuser|checkip)\\| *(1=)?" + RegExp.escape( self.params.sockpuppets[i], true ) + " *\\}\\}(?![\\s\\S]*?\\{\\{spiclose\\|archive\\}\\})", "i" );
					if( re.exec( text ) ) {
						self.params.sockpuppets.splice( i, 1 );
						i--;
					}
				}

				if( self.params.sockpuppets.length > 0 ) {
					if( text.match( /(\s*?;[ \t]*evidence submitted by)(?![\s\S]*?\{\{spiclose\|archive\}\})/i ) ) {
						Status.info( 'Info', 'Reporting suspected sockpuppets not yet listed in open discussion' );
						text = text.replace( /(\s*?;[ \t]*evidence submitted by)(?![\s\S]*?\{\{spiclose\|archive\}\})/i,
								'\n' + self.params.sockpuppets.map( function(v) { return '* \{\{' + ( isIPAddress( v ) ? 'checkip' : 'checkuser' ) + '|1=' + v + '\}\}' } ).join( '\n' ) + '$1' );
					} else {
						Status.info( 'Error', 'Unable to find appropriate location to insert new sockpuppets');
					}
				} else {
					Status.info( 'Info', 'All suspected sockpuppets found in open discussion, skipping' );
				}

				if( !self.params.evidence.match( /^\s*$/ ) ) {
					if( text.match( /(\s*?;[ \t]*comments by accused parties)(?![\s\S]*?\{\{spiclose\|archive\}\})/i ) ) {
						Status.info( 'Info', 'Adding new evidence section to open discussion' );
						text = text.replace( /(\s*?;[ \t]*comments by accused parties)(?![\s\S]*?\{\{spiclose\|archive\}\})/i, 
								'\n\n\n;Evidence submitted by \~\~\~\n' + self.params.evidence + " \~\~\~\~$1" );
					} else if( text.match( /(\s*?;[ \t]*comments by other users)(?![\s\S]*?\{\{spiclose\|archive\}\})/i ) ) {
						Status.info( 'Info', 'Adding new evidence section to open discussion' );
						text = text.replace( /(\s*?;[ \t]*comments by other users)(?![\s\S]*?\{\{spiclose\|archive\}\})/i, 
								'\n\n\n;Evidence submitted by \~\~\~\n' + self.params.evidence + " \~\~\~\~$1" );
					} else {
						Status.info( 'Error', 'Unable to find appropriate location to insert new evidence');
					}
				} else {
					Status.info( 'Info', 'No new evidence provided, skipping' );
				}

				if( self.params.checkuser ) {
					var newSection = false;
					if( !text.match( /;[ \t]*checkuser requests(?![\s\S]*?\{\{spiclose\|archive\}\})/i ) ) {
						text = text.replace( /(\s*?;[ \t]*clerk, patrolling admin and checkuser comments)(?![\s\S]*?\{\{spiclose\|archive\}\})/i, '\n\n\n;CheckUser requests$1');
						newSection = true;
					}

					var re = new RegExp( "\\{\\{rfcu\\| *(" + self.params.checkusercode + " *\\| *No2ndletter|" + self.params.checkusercode + " *\\| *[A-F]{1}|[A-F]{1} *\\| *" + self.params.checkusercode + ") *\\| *\\w*? *\\}\\}(?![\\s\\S]*?\\{\\{spiclose\\|archive\\}\\})", "i" );
					if( !re.exec( text ) ) {
						if( text.match( /(\s*?;[ \t]*clerk, patrolling admin and checkuser comments)(?![\s\S]*?\{\{spiclose\|archive\}\})/i ) ) {
						Status.info( 'Info', 'Adding CheckUser request to open discussion' );
						text = text.replace( /(\s*?;[ \t]*clerk, patrolling admin and checkuser comments)(?![\s\S]*?\{\{spiclose\|archive\}\})/i, 
								( newSection ? '' : '\n' ) + '\n\{\{RFCU|' + self.params.checkusercode + '|No2ndletter|New\}\} &nbsp;&nbsp; <small>Requested by \~\~\~\~</small>\n$1' );
						} else {
							Status.info( 'Error', 'Unable to find appropriate location to insert new CheckUser request');
						}
					} else {
						Status.info( 'Info', 'Identical CheckUser request found in open discussion, skipping' );
					}
				}
			} else {
				text += 
					"\{\{subst:Wikipedia:Sockpuppet investigations/SPI/Blank report template header\}\}\n\n" +
					";Suspected sockpuppets\n" +
					self.params.sockpuppets.map( function(v) { return "* \{\{" + ( isIPAddress( v ) ? "checkip" : "checkuser" ) + "|1=" + v + "\}\}" } ).join( "\n" ) +
					"\n\n\n;Evidence submitted by \~\~\~\n" +
					self.params.evidence + " \~\~\~\~\n\n\n" +
					";Comments by accused parties  &nbsp;&nbsp; <small><span style=\"font-weight:normal\">\'\'See \[\[Wikipedia:Sockpuppet investigations/SPI/Guidance#Defending yourself against claims|Defending yourself against claims\]\].\'\'</span></small>\n\n\n" +
					";Comments by other users\n\n\n";
				
				if( self.params.checkuser ) {
					text += ";CheckUser requests\n" +
						"\{\{RFCU|" + self.params.checkusercode + "|No2ndletter|New\}\} &nbsp;&nbsp; <small>Requested by \~\~\~\~</small>\n\n\n";
				}
				
				text += ";Clerk, patrolling admin and checkuser comments\n\n\n" +
					";Conclusions\n\n\n" +
					"----\n";
			}

			var postData = {
				'wpMinoredit': form.wpMinoredit.checked ? '' : undefined,
				'wpWatchthis': form.wpWatchthis.checked ? '' : undefined,
				'wpStarttime': form.wpStarttime.value,
				'wpEdittime': form.wpEdittime.value,
				'wpAutoSummary': form.wpAutoSummary.value,
				'wpEditToken': form.wpEditToken.value,
				'wpSection': form.wpSection.value,
				'wpSummary': ( open ? 'Extending' : 'Creating new' ) + ' discussion for [[Special:Contributions/' + self.params.uid + '|' + self.params.uid + ']].'+ TwinkleConfig.summaryAd,
				'wpTextbox1': text
			};
			self.post( postData );
		},
		tagSockpuppeteer: function( self ) {
			var form = self.responseXML.getElementById('editform');
			var text = form.wpTextbox1.value;
			if( /\{\{sockpuppeteer.*?\}\}/.exec( text ) ) { // already marked as a sock, just ignore then
				self.onsuccess( self );
				Wikipedia.actionCompleted();
				return;
			}
			var postData = {
				'wpMinoredit': form.wpMinoredit.checked ? '' : undefined,
				'wpWatchthis': form.wpWatchthis.checked ? '' : undefined,
				'wpStarttime': form.wpStarttime.value,
				'wpEdittime': form.wpEdittime.value,
				'wpAutoSummary': form.wpAutoSummary.value,
				'wpEditToken': form.wpEditToken.value,
				'wpSection': form.wpSection.value,
				'wpSummary': "Adding suspected sockpuppeteer tag." + TwinkleConfig.summaryAd,
				'wpTextbox1': "\{\{sockpuppeteer\}\}\n" + text
			};

			self.post( postData );
		},
		tagSockpuppet: function( self ) {
			var form = self.responseXML.getElementById('editform');
			var text = form.wpTextbox1.value;
			if( /\{\{sockpuppet.*?\}\}/.exec( text ) ) { // already marked as a sock, just ignore then
				self.onsuccess( self );
				Wikipedia.actionCompleted();
				return;
			}
			var postData = {
				'wpMinoredit': form.wpMinoredit.checked ? '' : undefined,
				'wpWatchthis': form.wpWatchthis.checked ? '' : undefined,
				'wpStarttime': form.wpStarttime.value,
				'wpEdittime': form.wpEdittime.value,
				'wpAutoSummary': form.wpAutoSummary.value,
				'wpEditToken': form.wpEditToken.value,
				'wpSection': form.wpSection.value,
				'wpSummary': "Adding suspected sockpuppet tag for suspected sockpuppeteer [[User:" +  self.params.uid + ']].' + TwinkleConfig.summaryAd,
				'wpTextbox1': "\{\{sockpuppet|1=" + self.params.uid + "\}\}\n" + text
			};

			self.post( postData );
		},
		notifySock: function( self ) {
			var form = self.responseXML.getElementById('editform');
			text = form.wpTextbox1.value;
			var postData = {
				'wpMinoredit': form.wpMinoredit.checked ? '' : undefined,
				'wpWatchthis': form.wpWatchthis.checked ? '' : undefined,
				'wpStarttime': form.wpStarttime.value,
				'wpEdittime': form.wpEdittime.value,
				'wpAutoSummary': form.wpAutoSummary.value,
				'wpEditToken': form.wpEditToken.value,
				'wpSection': form.wpSection.value,
				'wpSummary': "Notifying about suspicion of sockpuppeteering." + TwinkleConfig.summaryAd,
				'wpTextbox1': text + "\n\{\{subst:socksuspectnotice|1=" + self.params.uid + "\}\} \~\~\~\~"
			};

			self.post( postData );
		}
	}
}

twinklearv.callback.evaluate = function(e) {
	var form = e.target;
	var reason = "";
	if( form.reason ) {
		comment = form.reason.value;
	}
	var uid = form.uid.value;
	switch( form.category.value ) {
	default:
	case 'aiv':
		var types = form.getChecked( 'arvtype' );
		if( types.length == 0 && comment == '' ) {
			alert( 'You must specify some reason' );
			return;
		}

		types = types.map( function(v) {
				switch(v) {
				case 'final':
					return 'vandalism after final warning';
					break;
				case 'postblock':
					return 'vandalism after recent release of block';
					break;
				case 'spambot':
					return 'account is evidently a spambot or a compromised account';
					break;
				case 'vandalonly':
					return 'actions evidently indicate a vandalism-only account';
					break;
				case 'promoonly':
					return 'account is being used only for promotional purposes';
					break;
				}
			} ).join( ', ' );


		if( form.page.value != '' ) {
			reason += 'On [[' + form.page.value.replace( /^(Image|Category):/i, ':$1:' ) + ']]';

			if( form.badid.value != '' ) {
				var query = {
					'title': form.page.value,
					'diff': form.badid.value,
					'oldid': form.goodid.value
				};
				reason += ' ([' +  mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + QueryString.create( query ) + ' diff])';
			}
			reason += ';';
		}

		if( types ) {
			reason += " " + types;
		}
		if (comment != '' ) {
			reason += ". " + comment + '.';
		}
		Status.init( form );

		var query = {
			'title': 'Wikipedia:Administrator intervention against vandalism',
			'action': 'submit',
			'section': 1
		};
		wikipedia_wiki = new Wikipedia.wiki( 'Processing AIV request', query, twinklearv.callbacks.aiv );
		wikipedia_wiki.params = { reason:reason, uid:uid };
		wikipedia_wiki.get();
		break;
	case 'username':
		var types = form.getChecked( 'arvtype' );
		if( types.length == 0 ) {
			alert( 'You must specify at least one breached violation' );
			return;
		}
		types = types.map( function( v ) { return v.toLowerCaseFirstChar(); } );

		if( types.length <= 2 ) {
			types = types.join( ' and ' );
		} else {
			types = [ types.slice( 0, -1 ).join( ', ' ), types.slice( -1 ) ].join( ' and ' );
		}
		var article = 'a';
		if( /[aeiouwyh]/.test( types[0] ) ) { // non 100% correct, but whatever inlcuding 'h' for Cockney
			article = 'an';
		}
		reason = "*\{\{user-uaa|1=" + uid + "\}\} &mdash; Violation of username policy because it's " + article + " " + types + " username; ";
		if (comment != '' ) {
			reason += "''" + comment.toUpperCaseFirstChar() + "''. ";
		}
		reason += "\~\~\~\~";
		Status.init( form );

		var query = {
			'title': 'Wikipedia:Usernames for administrator attention',
			'action': 'submit',
			'section': 1
		};

		wikipedia_wiki = new Wikipedia.wiki( 'Processing UAA request', query, twinklearv.callbacks.username );
		wikipedia_wiki.params = { reason:reason, uid:uid };
		wikipedia_wiki.get();
		break;
	case 'sock':
		var sockpuppets = form.getTexts( 'sockpuppet' );
		var evidence = form.evidence.value.rtrim();
		var checkuser = form.checkuser.checked;
		var checkusercode = form.getChecked( 'checkuser.checkusercode' );
		Status.init( form );

		var query = {
			'title': 'Wikipedia:Sockpuppet investigations/' +  uid,
			'action': 'submit'
		};

		var wikipedia_wiki = new Wikipedia.wiki( 'Retrieving discussion page', query, twinklearv.callbacks.sock.main );
		wikipedia_wiki.params = { uid:uid, sockpuppets:sockpuppets, evidence:evidence, checkuser:checkuser, checkusercode:checkusercode?checkusercode[0]:null };
		wikipedia_wiki.get();
	}
}