مدیاویکی:Gadget-twinklespeedy-2020.js

از ویکی‌واژه

نکته: پس از انتشار ممکن است برای دیدن تغییرات نیاز باشد که حافظهٔ نهانی مرورگر خود را پاک کنید.

  • فایرفاکس / سافاری: کلید Shift را نگه دارید و روی دکمهٔ Reload کلیک کنید، یا کلید‌های Ctrl-F5 یا Ctrl-R را با هم فشار دهید (در رایانه‌های اپل مکینتاش کلید‌های ⌘-R)
  • گوگل کروم: کلیدهای Ctrl+Shift+R را با هم فشار دهید (در رایانه‌های اپل مکینتاش کلید‌های ⌘-Shift-R)
  • اینترنت اکسپلورر/ Edge: کلید Ctrl را نگه‌دارید و روی دکمهٔ Refresh کلیک کنید، یا کلید‌های Ctrl-F5 را با هم فشار دهید
  • اپرا: Ctrl-F5 را بفشارید.
// <nowiki>


(function($) {


/*
 ****************************************
 *** twinklespeedy.js: CSD module
 ****************************************
 * Mode of invocation:     Tab ("CSD")
 * Active on:              Non-special, existing pages
 *
 * NOTE FOR DEVELOPERS:
 *   If adding a new criterion, add it to the appropriate places at the top of
 *   twinkleconfig.js.  Also check out the default values of the CSD preferences
 *   in twinkle.js, and add your new criterion to those if you think it would be
 *   good.
 */

Twinkle.speedy = function twinklespeedy() {
	// Disable on:
	// * special pages
	// * non-existent pages
	if (mw.config.get('wgNamespaceNumber') < 0 || !mw.config.get('wgArticleId')) {
		return;
	}

	Twinkle.addPortletLink(Twinkle.speedy.callback, 'حذف سریع', 'tw-csd', Morebits.userIsSysop ? 'حذف صفحه طبق وو:محس' : 'درخواست حذف صفحه طبق وو:محس'); // localized
};

// This function is run when the CSD tab/header link is clicked
Twinkle.speedy.callback = function twinklespeedyCallback() {
	Twinkle.speedy.initDialog(Morebits.userIsSysop ? Twinkle.speedy.callback.evaluateSysop : Twinkle.speedy.callback.evaluateUser, true);
};

// Used by unlink feature
Twinkle.speedy.dialog = null;
// Used throughout
Twinkle.speedy.hasCSD = !!$('#delete-reason').length;

// The speedy criteria list can be in one of several modes
Twinkle.speedy.mode = {
	sysopSingleSubmit: 1,  // radio buttons, no subgroups, submit when "Submit" button is clicked
	sysopRadioClick: 2,  // radio buttons, no subgroups, submit when a radio button is clicked
	sysopMultipleSubmit: 3, // check boxes, subgroups, "Submit" button already present
	sysopMultipleRadioClick: 4, // check boxes, subgroups, need to add a "Submit" button
	userMultipleSubmit: 5,  // check boxes, subgroups, "Submit" button already pressent
	userMultipleRadioClick: 6,  // check boxes, subgroups, need to add a "Submit" button
	userSingleSubmit: 7,  // radio buttons, subgroups, submit when "Submit" button is clicked
	userSingleRadioClick: 8,  // radio buttons, subgroups, submit when a radio button is clicked

	// are we in "delete page" mode?
	// (sysops can access both "delete page" [sysop] and "tag page only" [user] modes)
	isSysop: function twinklespeedyModeIsSysop(mode) {
		return mode === Twinkle.speedy.mode.sysopSingleSubmit ||
			mode === Twinkle.speedy.mode.sysopMultipleSubmit ||
			mode === Twinkle.speedy.mode.sysopRadioClick ||
			mode === Twinkle.speedy.mode.sysopMultipleRadioClick;
	},
	// do we have a "Submit" button once the form is created?
	hasSubmitButton: function twinklespeedyModeHasSubmitButton(mode) {
		return mode === Twinkle.speedy.mode.sysopSingleSubmit ||
			mode === Twinkle.speedy.mode.sysopMultipleSubmit ||
			mode === Twinkle.speedy.mode.sysopMultipleRadioClick ||
			mode === Twinkle.speedy.mode.userMultipleSubmit ||
			mode === Twinkle.speedy.mode.userMultipleRadioClick ||
			mode === Twinkle.speedy.mode.userSingleSubmit;
	},
	// is db-multiple the outcome here?
	isMultiple: function twinklespeedyModeIsMultiple(mode) {
		return mode === Twinkle.speedy.mode.userMultipleSubmit ||
			mode === Twinkle.speedy.mode.sysopMultipleSubmit ||
			mode === Twinkle.speedy.mode.userMultipleRadioClick ||
			mode === Twinkle.speedy.mode.sysopMultipleRadioClick;
	}
};

// Prepares the speedy deletion dialog and displays it
Twinkle.speedy.initDialog = function twinklespeedyInitDialog(callbackfunc) {
	var dialog;
	Twinkle.speedy.dialog = new Morebits.simpleWindow(Twinkle.getPref('speedyWindowWidth'), Twinkle.getPref('speedyWindowHeight'));
	dialog = Twinkle.speedy.dialog;
	dialog.setTitle('انتخاب معیار حذف سریع'); // localized
	dialog.setScriptName('توینکل'); // localized
	dialog.addFooterLink('سیاست حذف سریع', 'وو:محس'); // localized
	dialog.addFooterLink('راهنمای توینکل', 'en:WP:TW/DOC#speedy'); // localized

	var form = new Morebits.quickForm(callbackfunc, Twinkle.getPref('speedySelectionStyle') === 'radioClick' ? 'change' : null);
	if (Morebits.userIsSysop) {
		form.append({
			type: 'checkbox',
			list: [
				{
					label: 'فقط برچسب بزن، حذف نکن', // localized
					value: 'tag_only',
					name: 'tag_only',
					tooltip: 'اگر فقط قصد دارید به صفحه برچسب بزنید، نه این که آن را حذف سریع کنید، این گزینه را انتخاب کنید.', // localized
					checked: !(Twinkle.speedy.hasCSD || Twinkle.getPref('deleteSysopDefaultToDelete')),
					event: function(event) {
						var cForm = event.target.form;
						var cChecked = event.target.checked;
						// enable talk page checkbox
						if (cForm.talkpage) {
							cForm.talkpage.checked = !cChecked && Twinkle.getPref('deleteTalkPageOnDelete');
						}
						// enable redirects checkbox
						cForm.redirects.checked = !cChecked;
						// enable delete multiple
						cForm.delmultiple.checked = false;
						// enable notify checkbox
						cForm.notify.checked = cChecked;
						// enable deletion notification checkbox
						cForm.warnusertalk.checked = !cChecked && !Twinkle.speedy.hasCSD;
						// enable multiple
						cForm.multiple.checked = false;
						// enable requesting creation protection
						cForm.salting.checked = false;

						Twinkle.speedy.callback.modeChanged(cForm);

						event.stopPropagation();
					}
				}
			]
		});

		var deleteOptions = form.append({
			type: 'div',
			name: 'delete_options'
		});
		deleteOptions.append({
			type: 'header',
			label: 'گزینه‌های حذف' // localized
		});
		if (mw.config.get('wgNamespaceNumber') % 2 === 0 && (mw.config.get('wgNamespaceNumber') !== 2 || (/\//).test(mw.config.get('wgTitle')))) {  // hide option for user pages, to avoid accidentally deleting user talk page
			deleteOptions.append({
				type: 'checkbox',
				list: [
					{
						label: 'صفحه بحث را نیز حذف کن', // localized
						value: 'talkpage',
						name: 'talkpage',
						tooltip: "این گزینه صفحهٔ بحث را هم حذف می‌کند. اگر معیار پ۸ (پروندهٔ موجود در انبار) را انتخاب کنید، این گزینه نادیده گرفته می‌شود و صفحهٔ بحث حذف نمی‌شود.", // localized
						checked: Twinkle.getPref('deleteTalkPageOnDelete'),
						event: function(event) {
							event.stopPropagation();
						}
					}
				]
			});
		}
		deleteOptions.append({
			type: 'checkbox',
			list: [
				{
					label: 'همچنین حذف تغییرمسیرها', // localized
					value: 'redirects',
					name: 'redirects',
					tooltip: 'این گزینه تمام تغییرمسیرهای ورودی به صفحه را نیز حذف می‌کند. از این گزینه برای حذف‌هایی که جهت انتقال یا ادغام صفحه هستند استفاده نکنید.', // localized
					checked: Twinkle.getPref('deleteRedirectsOnDelete'),
					event: function(event) {
						event.stopPropagation();
					}
				}
			]
		});
		deleteOptions.append({
			type: 'checkbox',
			list: [
				{
					label: 'حذف بر اساس چند معیار', // localized
					value: 'delmultiple',
					name: 'delmultiple',
					tooltip: 'اگر این گزینه را انتخاب کنید، می‌توانید بیش از یک معیار را به عنوان دلیل حذف صفحه برگزینید. برای مثال، ترکیب معیار ع۱۱ و م۷ برای حذف مقاله‌ها رایج است.', // localized
					event: function(event) {
						Twinkle.speedy.callback.modeChanged(event.target.form);
						event.stopPropagation();
					}
				}
			]
		});
		deleteOptions.append({
			type: 'checkbox',
			list: [
				{
					label: 'آگاه کردن سازندهٔ صفحه از حذف آن', // localized
					value: 'warnusertalk',
					name: 'warnusertalk',
					tooltip: 'یک الگوی آگاه‌سازی روی صفحهٔ بحث کاربری که صفحه را ایجاد کرده قرار داده می‌شود، به شرط آن که در ترجیحات توینکل، آگاه‌سازی را برای این معیار فعال کرده باشید ' + // localized
						'و این گزینه را هم تیک زده باشید. ممکن است برای سازندهٔ مقاله پیام خوشامدی هم فرستاده شود.', // localized
					checked: !Twinkle.speedy.hasCSD,
					event: function(event) {
						event.stopPropagation();
					}
				}
			]
		});
	}

	var tagOptions = form.append({
		type: 'div',
		name: 'tag_options'
	});

	if (Morebits.userIsSysop) {
		tagOptions.append({
			type: 'header',
			label: 'گزینه‌های مربوط به برچسب‌ها' // localized
		});
	}

	tagOptions.append({
		type: 'checkbox',
		list: [
			{
				label: 'آگاه کردن سازندهٔ صفحه در صورت امکان', // localized
				value: 'notify',
				name: 'notify',
				tooltip: 'یک الگوی آگاه‌سازی روی صفحهٔ بحث کاربری که صفحه را ایجاد کرده قرار می‌گیرد، به شرط آن که در ترجیحات توینکل، آگاه‌سازی را برای این معیار فعال کرده باشید ' + // localized
						'و این گزینه را هم تیک بزنید. ممکن است برای سازندهٔ صفحه پیام خوشامدی هم فرستاده شود.', // localized
				checked: !Morebits.userIsSysop || !(Twinkle.speedy.hasCSD || Twinkle.getPref('deleteSysopDefaultToDelete')),
				event: function(event) {
					event.stopPropagation();
				}
			}
		]
	});
	tagOptions.append({
		type: 'checkbox',
		list: [
			{
				label: 'برچسب برای محافظت در برابر ایجاد', // localized
				value: 'salting',
				name: 'salting',
				tooltip: 'اگر این گزینه را انتخاب کنید، کنار برچسب حذف سریع یک برچسب {{نمک}} هم قرار می‌دهد تا از مدیران درخواست کند که صفحه پس از حذف، در برابر ایجاد هم محافظت شود. فقط در صورتی این گزینه را استفاده کنید که صفحه بارها ایجاد شده باشد.', // localized
				event: function(event) {
					event.stopPropagation();
				}
			}
		]
	});
	tagOptions.append({
		type: 'checkbox',
		list: [
			{
				label: 'برچسب با چند دلیل', // localized
				value: 'multiple',
				name: 'multiple',
				tooltip: 'اگر این گزینه را انتخاب کنید، می‌توانید بیش از یک معیار را به عنوان دلیل حذف صفحه برگزینید. برای مثال، ترکیب معیار ع۱۱ و م۷ برای حذف مقاله‌ها رایج است.', // localized
				event: function(event) {
					Twinkle.speedy.callback.modeChanged(event.target.form);
					event.stopPropagation();
				}
			}
		]
	});

	form.append({
		type: 'div',
		name: 'work_area',
		label: 'فعال کردن پودمان حذف سریع ناموفق بود. لطفاً دوباره تلاش کنید یا در [[ویکی‌واژه:فنی]] گزارش کنید.' // localized
	});

	if (Twinkle.getPref('speedySelectionStyle') !== 'radioClick') {
		form.append({ type: 'submit', className: 'tw-speedy-submit' }); // Renamed in modeChanged
	}

	var result = form.render();
	dialog.setContent(result);
	dialog.display();

	Twinkle.speedy.callback.modeChanged(result);
};

Twinkle.speedy.callback.getMode = function twinklespeedyCallbackGetMode(form) {
	var mode = Twinkle.speedy.mode.userSingleSubmit;
	if (form.tag_only && !form.tag_only.checked) {
		if (form.delmultiple.checked) {
			mode = Twinkle.speedy.mode.sysopMultipleSubmit;
		} else {
			mode = Twinkle.speedy.mode.sysopSingleSubmit;
		}
	} else {
		if (form.multiple.checked) {
			mode = Twinkle.speedy.mode.userMultipleSubmit;
		} else {
			mode = Twinkle.speedy.mode.userSingleSubmit;
		}
	}
	if (Twinkle.getPref('speedySelectionStyle') === 'radioClick') {
		mode++;
	}

	return mode;
};

Twinkle.speedy.callback.modeChanged = function twinklespeedyCallbackModeChanged(form) {
	var namespace = mw.config.get('wgNamespaceNumber');

	// first figure out what mode we're in
	var mode = Twinkle.speedy.callback.getMode(form);
	var isSysopMode = Twinkle.speedy.mode.isSysop(mode);

	if (isSysopMode) {
		$('[name=delete_options]').show();
		$('[name=tag_options]').hide();
		$('button.tw-speedy-submit').text('حذف صفحه'); // localized
	} else {
		$('[name=delete_options]').hide();
		$('[name=tag_options]').show();
		$('button.tw-speedy-submit').text('برچسب زدن به صفحه'); // localized
	}

	var work_area = new Morebits.quickForm.element({
		type: 'div',
		name: 'work_area'
	});

	if (mode === Twinkle.speedy.mode.userMultipleRadioClick || mode === Twinkle.speedy.mode.sysopMultipleRadioClick) {
		var evaluateType = isSysopMode ? 'evaluateSysop' : 'evaluateUser';

		work_area.append({
			type: 'div',
			label: 'هنگامی که کارتان تمام شد، کلیک کنید:' // localized
		});
		work_area.append({
			type: 'button',
			name: 'submit-multiple',
			label: isSysopMode ? 'حذف صفحه' : 'برچسب زدن به صفحه', // localized
			event: function(event) {
				Twinkle.speedy.callback[evaluateType](event);
				event.stopPropagation();
			}
		});
	}

	var radioOrCheckbox = Twinkle.speedy.mode.isMultiple(mode) ? 'checkbox' : 'radio';

	if (isSysopMode && !Twinkle.speedy.mode.isMultiple(mode)) {
		work_area.append({ type: 'header', label: 'دلیل دیگر' }); // localized
		work_area.append({ type: radioOrCheckbox, name: 'csd', list: Twinkle.speedy.generateCsdList(Twinkle.speedy.customRationale, mode) });
	}

	if (namespace % 2 === 1 && namespace !== 3) {
		// show db-talk on talk pages, but not user talk pages
		work_area.append({ type: 'header', label: 'صفحه‌های بحث' }); // localized
		work_area.append({ type: radioOrCheckbox, name: 'csd', list: Twinkle.speedy.generateCsdList(Twinkle.speedy.talkList, mode) });
	}

	if (!mw.config.get('wgIsRedirect')) {
		switch (namespace) {
			case 0:  // article
			case 1:  // talk
				work_area.append({ type: 'header', label: 'مقاله‌ها' }); // localized
				work_area.append({ type: radioOrCheckbox, name: 'csd', list: Twinkle.speedy.generateCsdList(Twinkle.speedy.articleList, mode) });
				break;

			case 2:  // user
			case 3:  // user talk
				work_area.append({ type: 'header', label: 'صفحه‌های کاربری' }); // localized
				work_area.append({ type: radioOrCheckbox, name: 'csd', list: Twinkle.speedy.generateCsdList(Twinkle.speedy.userList, mode) });
				break;

			case 6:  // file
			case 7:  // file talk
				work_area.append({ type: 'header', label: 'پرونده‌ها' }); // localized
				work_area.append({ type: radioOrCheckbox, name: 'csd', list: Twinkle.speedy.generateCsdList(Twinkle.speedy.fileList, mode) });
				if (!isSysopMode) {
					work_area.append({ type: 'div', label: 'افزودن برچسب برای معیارهای پ۴ (بدون مجوز)، پ۵ (پروندهٔ غیر آزاد استفاده نشده)، پ۶ (فاقد دلیل برای استفادهٔ منصفانه) و پ۱۱ (بدون مدرک برای مجوز) با استفاده از زبانهٔ «تصاویر» در توینکل ممکن است.' }); // localized
				}
				break;

			case 10:  // template
			case 11:  // template talk
				work_area.append({ type: 'header', label: 'الگوها' }); // localized
				work_area.append({ type: radioOrCheckbox, name: 'csd', list: Twinkle.speedy.generateCsdList(Twinkle.speedy.templateList, mode) });
				break;

			case 14:  // category
			case 15:  // category talk
				work_area.append({ type: 'header', label: 'رده‌ها' }); // localized
				work_area.append({ type: radioOrCheckbox, name: 'csd', list: Twinkle.speedy.generateCsdList(Twinkle.speedy.categoryList, mode) });
				break;

			case 100:  // portal
			case 101:  // portal talk
				work_area.append({ type: 'header', label: 'درگاه‌ها' }); // localized
				work_area.append({ type: radioOrCheckbox, name: 'csd', list: Twinkle.speedy.generateCsdList(Twinkle.speedy.portalList, mode) });
				break;

			default:
				break;
		}
	} else {
		if (namespace === 2 || namespace === 3) {
			work_area.append({ type: 'header', label: 'صفحه‌های کاربری' }); // localized
			work_area.append({ type: radioOrCheckbox, name: 'csd', list: Twinkle.speedy.generateCsdList(Twinkle.speedy.userList, mode) });
		}
		work_area.append({ type: 'header', label: 'تغییرمسیرها' }); // localized
		work_area.append({ type: radioOrCheckbox, name: 'csd', list: Twinkle.speedy.generateCsdList(Twinkle.speedy.redirectList, mode) });
	}

	var generalCriteria = Twinkle.speedy.generalList;

	// custom rationale lives under general criteria when tagging
	if (!isSysopMode) {
		generalCriteria = Twinkle.speedy.customRationale.concat(generalCriteria);
	}
	work_area.append({ type: 'header', label: 'دلایل عمومی' }); // localized
	work_area.append({ type: radioOrCheckbox, name: 'csd', list: Twinkle.speedy.generateCsdList(generalCriteria, mode) });

	var old_area = Morebits.quickForm.getElements(form, 'work_area')[0];
	form.replaceChild(work_area.render(), old_area);

	// if sysop, check if CSD is already on the page and fill in custom rationale
	if (isSysopMode && Twinkle.speedy.hasCSD) {
		var customOption = $('input[name=csd][value=reason]')[0];
		if (customOption) {
			if (Twinkle.getPref('speedySelectionStyle') !== 'radioClick') {
				// force listeners to re-init
				customOption.click();
				customOption.parentNode.appendChild(customOption.subgroup);
			}
			customOption.subgroup.querySelector('input').value = decodeURIComponent($('#delete-reason').text()).replace(/\+/g, ' ');
		}
	}
};

Twinkle.speedy.generateCsdList = function twinklespeedyGenerateCsdList(list, mode) {
	// mode switches
	var isSysopMode = Twinkle.speedy.mode.isSysop(mode);
	var multiple = Twinkle.speedy.mode.isMultiple(mode);
	var hasSubmitButton = Twinkle.speedy.mode.hasSubmitButton(mode);
	var pageNamespace = mw.config.get('wgNamespaceNumber');

	var openSubgroupHandler = function(e) {
		$(e.target.form).find('input').prop('disabled', true);
		$(e.target.form).children().css('color', 'gray');
		$(e.target).parent().css('color', 'black').find('input').prop('disabled', false);
		$(e.target).parent().find('input:text')[0].focus();
		e.stopPropagation();
	};
	var submitSubgroupHandler = function(e) {
		var evaluateType = Twinkle.speedy.mode.isSysop(mode) ? 'evaluateSysop' : 'evaluateUser';
		Twinkle.speedy.callback[evaluateType](e);
		e.stopPropagation();
	};

	return $.map(list, function(critElement) {
		var criterion = $.extend({}, critElement);

		if (multiple) {
			if (criterion.hideWhenMultiple) {
				return null;
			}
			if (criterion.hideSubgroupWhenMultiple) {
				criterion.subgroup = null;
			}
		} else {
			if (criterion.hideWhenSingle) {
				return null;
			}
			if (criterion.hideSubgroupWhenSingle) {
				criterion.subgroup = null;
			}
		}

		if (isSysopMode) {
			if (criterion.hideWhenSysop) {
				return null;
			}
			if (criterion.hideSubgroupWhenSysop) {
				criterion.subgroup = null;
			}
		} else {
			if (criterion.hideWhenUser) {
				return null;
			}
			if (criterion.hideSubgroupWhenUser) {
				criterion.subgroup = null;
			}
		}

		if (mw.config.get('wgIsRedirect') && criterion.hideWhenRedirect) {
			return null;
		}

		if (criterion.showInNamespaces && criterion.showInNamespaces.indexOf(pageNamespace) < 0) {
			return null;
		}
		if (criterion.hideInNamespaces && criterion.hideInNamespaces.indexOf(pageNamespace) > -1) {
			return null;
		}

		if (criterion.subgroup && !hasSubmitButton) {
			if (Array.isArray(criterion.subgroup)) {
				criterion.subgroup = criterion.subgroup.concat({
					type: 'button',
					name: 'submit',
					label: isSysopMode ? 'حذف صفحه' : 'برچسب زدن به صفحه', // localized
					event: submitSubgroupHandler
				});
			} else {
				criterion.subgroup = [
					criterion.subgroup,
					{
						type: 'button',
						name: 'submit',  // ends up being called "csd.submit" so this is OK
						label: isSysopMode ? 'حذف صفحه' : 'برچسب زدن به صفحه', // localized
						event: submitSubgroupHandler
					}
				];
			}
			// FIXME: does this do anything?
			criterion.event = openSubgroupHandler;
		}

		return criterion;
	});
};

Twinkle.speedy.customRationale = [
	{
		label: 'دلیل دیگر' + (Morebits.userIsSysop ? ' (دلیل شخصی‌سازی‌شده برای حذف)' : ' با استفاده از الگوی {{حذف سریع}}'), // localized
		value: 'reason',
		tooltip: 'دست کم یکی از معیارهای حذف سریع باید برای صفحه مصداق داشته باشد، و شما این را باید در دلیلی که می‌نویسید ذکر کنید. این گزینه برای آن نیست که وقتی دلیل حذف را بین گزینه‌های دیگر نیافتید از آن استفاده کنید.', // localized
		subgroup: {
			name: 'reason_1',
			type: 'input',
			label: 'دلیل: ', // localized
			size: 60
		},
		hideWhenMultiple: true
	}
];

Twinkle.speedy.talkList = [
	{
		label: 'ع۸: صفحهٔ بحث یتیم', // localized
		value: 'talk',
		tooltip: 'این معیار شامل صفحه‌های بحثی که برای پروژه مفید باشند نمی‌شود.؛ به‌خصوص صفحه‌های بحث کاربر، بایگانی‌های صفحه‌های بحث، و صفحهٔ بحث پرونده‌هایی که در ویکی‌انبار موجود هستند.' // localized
	}
];

Twinkle.speedy.fileList = [
	{
		label: 'پ۱: پرونده تکراری', // localized
		value: 'redundantimage',
		tooltip: 'هر پرونده‌ای که تکراری باشد، قالبش با نسخهٔ دیگر یکی باشد و کیفیتش از آن کمتر باشد این شامل پرونده‌هایی که نسخهٔ دیگری از آن‌ها در ویکی‌انبار است و این به دلیل نوع اجازه‌نامهٔ تصویر است، نمی‌شود. این قبیل تصاویر باید با برچسب {{جا:موجود در انبار}} علامت‌گذاری شوند.', // localized
		subgroup: {
			name: 'redundantimage_filename',
			type: 'input',
			label: 'نام پرونده‌ای که این پرونده تکرارش کرده‌است: ', // localized
			tooltip: 'پیشوند «پرونده:» را می‌توانید ننویسید.' // localized
		}
	},
	{
		label: 'پ۲: تصاویر خراب یا خالی', // localized
		value: 'noimage',
		tooltip: 'پیش از حذف چنین تصاویری مطمئن شوید که مدیاویکی قادر به خواندن تصویر و نمایش یک نسخهٔ کوچک‌تر از آن تصویر نیست. این معیار شامل پرونده‌های خالی (بدون محتوا) و نیز می‌شود' // localized
	},
	{
		label: 'پ۲: صفحهٔ توضیحات نالازم برای پرونده‌ای که در ویکی‌انبار است', // localized
		value: 'fpcfail',
		tooltip: 'تصویری که در ویکی‌انبار است اما صفحه‌ای در ویکی‌پدیا دارد که حاوی اطلاعات و برچسب‌هایی است که دیگر لازم نیستند.', // localized
		hideWhenMultiple: true
	},
	{
		label: 'پ۳: اجازه‌نامهٔ نامناسب', // localized
		value: 'noncom',
		tooltip: 'پرونده‌ای که با مجوز «فقط استفادهٔ غیرتجاری»، «اثر اشتقاقی ممنوع»، یا «استفاده فقط با اخذ مجوز» منتشر شده‌است. این شامل تصاویری که مجوز «کرییتیو کامانز برای استفادهٔ غیرتجاری» دارند نیز می‌شود' // localized
	},
	{
		label: 'پ۴: فاقد اطلاعات لازم در مورد اجازه‌نامه', // localized
		value: 'unksource',
		tooltip: 'پرونده‌هایی که در ردهٔ «تصویرهای با منبع نامعلوم» یا «تصاویر با وضعیت حق تکثیر نامعلوم» یا نظایر آن قرار دارند: این پرونده‌ها حاوی الگویی هستند که آن‌ها را در چنین رده‌ای قرار می‌دهد و اگر هفت روز چنین شرایطی را داشته باشند )صرف نظر از این که کی بارگذاری شده‌اند) می‌توانند حذف شوند. توجه کنید که گاهی کاربران منبع اثر را در خلاصه ویرایش می‌نویسند پس حتماً تاریخچه را از این نظر بررسی کنید', // localized
		hideWhenUser: true
	},
	{
		label: 'پ۵:  پرونده‌های  غیرآزاد استفاده‌نشده', // localized
		value: 'f5',
		tooltip: 'پرونده‌هایی که مجوز آزاد ندارند و در مالکیت عمومی نیستند و در هیچ مقاله‌ای استفاده نشده‌اند (یا تنها کاربردهایشان در مقاله‌هایی بوده که حذف شده‌اند)، و بعید است که در مقاله‌ای دیگر استفاده شوند. استثناهای معقول عبارتند از پرونده‌هایی که برای یک مقاله که به زودی ساخته می‌شود بارگذاری شده‌اند. برای تصاویر غیرآزاد استفاده نشدهٔ دیگر، از برچسب «استفاده منصفانهٔ یتیم» در زبانهٔ «تصاویر» توینکل استفاده کنید', // localized
		hideWhenUser: true
	},
	{
		label: 'پ۶: فقدان توضیح در مورد استفادهٔ منصفانه', // localized
		value: 'norat',
		tooltip: 'می‌توان هر پرونده فاقد دلیل برای استفادهٔ منصفانه را هفت روز پس از بارگذاری آن حذف کرد. پرونده‌های بارگذاری شده پیش از ۴/۵/۲۰۰۶ نباید حذف سریع شوند. در عوض باید کاربر بارگذار را از لزوم ارائه دلیل برای استفادهٔ منصفانه آگاه کنید. می‌توان پرونده‌های بارگذاری شده پس از تاریخ یادشده را با دلیل «استفاده منصفانه» برچسب‌گذاری کرد.', // localized
		hideWhenUser: true
	},
	{
		label: 'پ۷: ادعای نادرست در مورد استفادهٔ منصفانه', // localized
		value: 'badfairuse',  // same as below
		tooltip: 'این برچسب تنها برای پرونده‌هایی با برچسب استفاده منصفانه‌ای که آشکارا نامعتبر است، مثلاً یک برچسب {{نگاره نماد}} بر روی عکس یک شگون‌نما. در مواردی که نیازمند یک دورهٔ انتظار هستند (تصاویر قابل جایگزینی یا استدلال مورد اختلاف)، از گزینه‌های موجود در زبانهٔ حذف سریع پروندهٔ توینکل استفاده کنید.', // localized
		subgroup: {
			name: 'badfairuse_rationale',
			type: 'input',
			label: 'توضیح اختیاری: ', // localized
			size: 60
		}
	},
	{
		label: 'پ۷: استفادهٔ منصفانه از رسانه‌ای از یک آژانس تصویر تجاری که با موضوع مورد تفسیر، منبع مرتبط نیست', // localized
		value: 'badfairuse',  // same as above
		tooltip: 'تصاویر یا رسانه‌های غیر آزاد از یک منبع تجاری (مثلاً آسوشید پرس یا گتی ایمجز)، در جایی که خود پرونده موضوع مورد تفسیر منبع نیست، به‌عنوان ادعای نامعتبر استفادهٔ منصفانه در نظر گرفته می‌شوند و معیارهای سخت‌گیرانهٔ وو:ملاک منصفانه را احراز نخواهند کرد.', // localized
		subgroup: {
			name: 'badfairuse_rationale',
			type: 'input',
			label: 'توضیح اختیاری: ', // localized
			size: 60
		},
		hideWhenMultiple: true
	},
	{
		label: 'پ۸: تصویرهایی که همانند آن‌ها در ویکی‌انبار موجود است', // localized
		value: 'commons',
		tooltip: 'مواردی که دارای شرایط زیر باشند، شامل این معیار می‌شوند: ۱: فرمت هر دو تصویر با هم یکسان است. ۲: مجوز پرونده(ها) به‌طور منطقی مورد تردید است و مجوز بدون تردید در ویکی‌انبار مورد تأیید قرار گرفته‌است. ۳: تمامی اطلاعات موجود در صفحهٔ توضیحات پرونده در صفحهٔ توضیحات پرونده در ویکی‌انبار نیز موجود است. این شامل تاریخچهٔ کامل بارگذاری به‌همراه پبوند به صفحهٔ کاربری محلی بارگذار می‌شود. ۴: پرونده حفاظت نشده است و صفحهٔ توضیحات پرونده دربردارندهٔ درخواست عدم انتقال به ویکی‌انبار نیست. ۵: اگر پرونده با نامی در ویکی‌انبار موجود است که با نام آن در ویکی محلی متفاوت است، هدف تمامی ارجاعات محلی به پرونده باید به عنوان مورد استفاده در انبار تغییر یابند. ۶: برای پرونده‌های {{بارگذاری شده از انبار}}: این پرونده‌ها باید به محض این که از صفحهٔ اصلی برداشته‌شدند، حذف سریع شوند', // localized
		subgroup: {
			name: 'commons_filename',
			type: 'input',
			label: 'نام پرونده در انبار: ', // localized
			value: Morebits.pageNameNorm,
			tooltip: 'اگر نام تصویر در انبار با نامش در این‌جا یکسان است، می‌توانید خالی بگذارید. نیازی به درج پیشوند «پرونده:» نیست.' // localized
		},
		hideWhenMultiple: true
	},
	{
		label: 'پ۹: نقض آشکار حق تکثیر', // localized
		value: 'imgcopyvio',
		tooltip: 'پرونده از یک وبگاه یا منبع دیگر کپی شده است که فاقد مجوز سازگار با ویکی‌پدیا است و بارگذار نه مدعی استفادهٔ منصفانه است، و نه ادعای باورپذیری مبنی بر داشتن اجازهٔ استفادهٔ آزاد از پرونده را دارد. منابعی که فاقد مجوز سازگار با ویکی‌پدیا هستند شامل بایگانی‌های عکس‌های آرشیوی مانند گتی ایمجز یا کوربیس می‌شوند. مواردی که شامل نقض غیر آشکار حق تکثیر باشند، باید برای نظرخواهی به ویکی‌واژه:نظرخواهی برای حذف بروند.', // localized
		subgroup: [
			{
				name: 'imgcopyvio_url',
				type: 'input',
				label: 'پیوند به نشانی نقض حق تکثیر، شامل پیشوند "http://".  اگر نقض حق تکثیر از یک منبع غیر اینترنتی رخ داده‌است و قادر به ارائهٔ نشانی نیستید، باید از جعبهٔ استدلال حذف استفاده کنید. ', // localized
				size: 60
			},
			{
				name: 'imgcopyvio_rationale',
				type: 'input',
				label: 'استدلال حذف برای نقض حق تکثیر غیر اینترنتی: ', // localized
				size: 60
			}
		]
	},
	{
		label: 'پ۱۰: پرونده‌های غیررسانه‌ای یا بی‌استفاده', // localized
		value: 'badfiletype',
		tooltip: 'پرونده‌های بارگذاری شده، تصویر، صوت یا ویدئو نیستند (به‌عنوان مثال، پرونده‌هایی با پسوند .doc، .pdf، یا .xls) و نه تنها در هیچ مقاله‌ای استفاده نشده‌اند، بلکه هیچ کاربرد دانشنامه‌ای دیگری نیز برای آن‌ها مورد انتظار نیست' // localized
	},
	{
		label: 'پ۱۱: بدون مدرک در مورد مجوز', // localized
		value: 'nopermission',
		tooltip: 'اگر یک بارگذار مجوزی را مشخص کرده و از یک شخص ثالث، بدون ارائهٔ مدرکی مبنی بر موافقت آن شخص ثالث به‌عنوان منبع/دارنده حق تکثیر نام برده است، آن آیتم باید هفت روز پس از ارسال آگاه‌سازی به بارگذار حذف شود.', // localized
		hideWhenUser: true
	},
	{
		label: 'ع۸: صفحه بحث پرونده بدون صفحه پرونده متناظر', // localized
		value: 'imagepage',
		tooltip: 'این معیار تنها در مواردی استفاده می‌شود که پرونده به هیچ عنوان موجود نباشد. برای پرونده‌های خراب و صفحه‌های توضیحات محلی برای پرونده‌های موجود در انبار، باید از پ۲ استفاده کرد؛ برای تغییرمسیرهای نامحتمل باید از ت۳ استفاده کرد؛ و برای تغییرمسیرهای شکسته از انبار باید از ت۴ استفاده کرد.' // localized
	}
];

Twinkle.speedy.articleList = [
	{
		label: 'م۱: بدون بافت مشخص', // localized
		value: 'nocontext',
		tooltip: 'منظور مقالاتی است که نمی‌توان موضوع مقاله را دریافت. مثال: او صاحب یک شرکت بزرگ است و خیلی کارش درست است. این معیار تنها باید برای مقاله‌های بسیار کوتاه استفاده شود. نداشتن بافت مشخص را نباید با بدون محتوا بودن (م۳) اشتباه گرفت.' // localized
	},
	{
		label: 'م۲: مقالات غیرفارسی که در پروژه‌های دیگر ویکی‌مدیا وجود دارند', // localized
		value: 'foreign',
		tooltip: 'اگر مقالهٔ مورد نظر در پروژه‌های دیگر موجود نیست، باید از الگوی {{اصلاح ترجمه}} استفاده کرد. تمام مقاله‌های غرفارسی که مشمول این معیار نمی‌شوند (و مشمول هیچ یک از معیارهای دیگر حذف سریع نیز نیستند) باید برای بازبینی و ترجمهٔ احتمالی در صفحه‌های نیازمند ترجمه (صنت) فهرست شوند', // localized
		subgroup: {
			name: 'foreign_source',
			type: 'input',
			label: 'پیوند میان‌ویکی به مقاله در زبان دیگر: ', // localized
			tooltip: 'For example, fr:Bonjour'
		}
	},
	{
		label: 'م۳: بدون محتوا', // localized
		value: 'nocontent',
		tooltip: 'مقاله‌هایی که تنها شامل مجموعه‌ای از پیوندها (از جمله پیوند به بیرون، برچسب رده و جستارهای وابسته)، بازنویسی عنوان مقاله و تلاش برای برقراری ارتباط با فرد یا گروه مربوط به نام مقاله باشد. این موارد شامل صفحه‌های ابهام‌زدایی نمی‌شود.' // localized
	},
	{
		label: 'م۵: انتقال به ویکی دیگر', // localized
		value: 'transwiki',
		tooltip: 'هر مقاله‌ای که به نظرخواهی برای حذف رفته، نتیجهٔ نظرخواهی انتقال به ویکی‌دیگر بوده، انتقال به ویکی دیگر به‌درستی انجام شده و اطلاعات نگارنده نیز ثبت شده‌است. در مقابل، هر مقاله‌ای که تنها شامل یک معنای لغت‌نامه‌وار بوده، انتقال به ویکی دیگر به‌درستی انجام شده و اطلاعات نگارنده نیز ثبت شده‌است.', // localized
		subgroup: {
			name: 'transwiki_location',
			type: 'input',
			label: 'پیوند به ویکی دیگری که باید به آن منتقل شود: ', // localized
			tooltip: 'For example, https://en.wiktionary.org/wiki/twinkle or [[wikt:twinkle]]'
		}
	},
	{
		label: 'م۷: موضوع غیر قابل توجه (اشخاص، جانوران، سازمان‌ها و وبگاه‌ها و رخدادها)', // localized
		value: 'a7',
		tooltip: 'مقاله‌ای دربارهٔ اشخاص حقیقی، دسته‌ای از افراد، گروه، باشگاه، شرکت، محتوای وب، حیوان تک، سفر یا حزب که به‌طور مشخص دلیل اهمیت موضوع را نشان نمی‌دهد. در صورت بحث‌برانگیز بودن، یا در صورتی که در یک نظرخواهی قبلاً  اجماع بر ماندن مقاله بوده‌است، مقاله باید در عوض به نظرخواهی برای حذف برود.', // localized
		hideWhenSingle: true
	},
	{
		label: 'م۷: موضوع غیر قابل توجه (اشخاص)', // localized
		value: 'person',
		tooltip: 'مقاله‌ای دربارهٔ یک شخص حقیق که به‌طور مشخص دلیل اهمیت موضوع را نشان نمی‌دهد. در صورت بحث‌برانگیز بودن، یا در صورتی که در یک نظرخواهی قبلاً  اجماع بر ماندن مقاله بوده‌است، مقاله باید در عوض به نظرخواهی برای حذف برود', // localized
		hideWhenMultiple: true
	},
	{
		label: 'م۷: موضوع غیر قابل توجه (گروه موسیقی)', // localized
		value: 'band',
		tooltip: 'مقاله‌ای دربارهٔ یک گروه موسیقی، خواننده یا موسیقی‌دان که به‌طور مشخص دلیل اهمیت موضوع را نشان نمی‌دهد.', // localized
		hideWhenMultiple: true
	},
	{
		label: 'م۷: موضوع غیر قابل توجه (باشگاه، گروه)', // localized
		value: 'club',
		tooltip: 'مقاله‌ای دربارهٔ یک باشگاه، اجتماع یا گروع که به‌طور مشخص دلیل اهمیت موضوع را نشان نمی‌دهد.', // localized
		hideWhenMultiple: true
	},
	{
		label: 'م۷: موضوع غیر قابل توجه (شرکت یا سازمان)', // localized
		value: 'corp',
		tooltip: 'مقاله‌ای دربارهٔ یک شرکت یا سازمان که به‌طور مشخص دلیل اهمیت موضوع را نشان نمی‌دهد.', // localized
		hideWhenMultiple: true
	},
	{
		label: 'م۷: موضوع غیر قابل توجه (وبسایت یا محتوای وب)', // localized
		value: 'web',
		tooltip: 'مقاله‌ای دربارهٔ یک وبگاه، وب‌نوشت انجمن آنلاین، پادکست یا محتوای وب مشابه که به‌طور مشخص دلیل اهمیت موضوع را نشان نمی‌دهد.', // localized
		hideWhenMultiple: true
	},
	{
		label: 'م۷: موضوع غیر قابل توجه (تک حیوان)', // localized
		value: 'animal',
		tooltip: 'مقاله‌ای دربارهٔ یک حیوان تک (مقلاً یک حیوان خانگی) که به‌طور مشخص دلیل اهمیت موضوع را نشان نمی‌دهد.', // localized
		hideWhenMultiple: true
	},
	{
		label: 'م۷: موضوع غیر قابل توجه (رویداد سازماندهی شده)', // localized
		value: 'event',
		tooltip: 'مقاله‌ای دربارهٔ یک رویداد سازماندهی شده (تور، مأموریت، همایش، مهمانی و غیره) که به‌طور مشخص دلیل اهمیت موضوع را نشان نمی‌دهد.', // localized
		hideWhenMultiple: true
	},
	{
		label: 'م۹: موضوع غیرقابل توجه (موسیقی ضبط‌شده)', // localized
		value: 'a9',
		tooltip: 'مقاله‌ای دربارهٔ یک موسیقی ضبط شده که به‌طور مشخص دلیل اهمیت موضوع را نشان نمی‌دهد و مقالهٔ خالق اثر نیز هرگز موجود نبوده یا حذف شده‌' // localized
	},
	{
		label: 'م۱۰: مقالهٔ تکراری (مقالهٔ تازه‌ساز که محتوای یکسانی با مقالهٔ قدیمی‌تر دارد)', // localized
		value: 'a10',
		tooltip: 'مقاله‌ای که اخیراً ایجاد شده و تاریخچه کوتاهی دارد و یکی از محتوای موجود در دانشنامه را دوباره تکرار کرده و اطلاعات آن را گسترش یا بهبود نداده، و عنوان آن تغییر مسیر محتمل نیست. این شامل صفحات تفکیک‌شده یا هرگونه مقاله‌ای که حاصل گسترش یا بازآرایی یک مقالهٔ قدیمی‌تر است، نمی‌شود..', // localized
		subgroup: {
			name: 'a10_article',
			type: 'input',
			label: 'نام مقالهٔ تکرار شده: ' // localized
		}
	},
	{
		label: 'م۱۱: مشخصاً ساختهٔ ذهن نویسنده است و هیچ ادعایی در مورد مهم بودنش وجود ندارد', // localized
		value: 'madeup',
		tooltip: 'مقاله‌ای که به سادگی نشان می‌دهد که موضوع آن، توسط سازندهٔ مقاله یا کسی که او را شخصاً می‌شناسد، اختراع یا ابداع یا کشف شده و به صورت معتبر نشان نمی‌دهد که چرا موضوع آن مهم یا قابل توجه است.' // localized
	}
];

Twinkle.speedy.categoryList = [
	{
		label: 'ر۱: ردهٔ خالی', // localized
		value: 'catempty',
		tooltip: 'رده‌هایی که برای چهار روز متوالی هیچ زیررده‌ای نداشته باشند و هیچ مقاله‌ای هم در آن رده‌ها قرار نگیرد. این قاعده شمال رده‌های ابهام‌زدایی و بعضی استثناهای دیگر نمی‌شود. اگر رده به تازگی ایجاد نشده باشد، امکان دارد قبلاً شامل مقالاتی بوده باشد، و بررسی‌های بیشتری لازم خواهد بود.' // localized
	},
	{
		label: 'ع۸: رده‌های مربوط به الگوی حذف شده یا تغییرمسیر یافته', // localized
		value: 'templatecat',
		tooltip: 'This is for situations where a category is effectively empty, because the template(s) that formerly placed pages in that category are now deleted. This excludes categories that are still in use.'
	},
	{
		label: 'ع۸: تغییرمسیر به هدف ناموجود', // localized
		value: 'redirnone',
		tooltip: 'This excludes any page that is useful to the project, and in particular: deletion discussions that are not logged elsewhere, user and user talk pages, talk page archives, plausible redirects that can be changed to valid targets, and file pages or talk pages for files that exist on Wikimedia Commons.',
		hideWhenMultiple: true
	}
];

Twinkle.speedy.userList = [
	{
		label: 'ک۱: درخواست کاربر', // localized
		value: 'userreq',
		tooltip: 'Personal subpages, upon request by their user. In some rare cases there may be administrative need to retain the page. Also, sometimes, main user pages may be deleted as well. See Wikipedia:User page for full instructions and guidelines',
		subgroup: mw.config.get('wgNamespaceNumber') === 3 && mw.config.get('wgTitle').indexOf('/') === -1 ? {
			name: 'userreq_rationale',
			type: 'input',
			label: 'A mandatory rationale to explain why this user talk page should be deleted: ',
			tooltip: 'User talk pages are deleted only in highly exceptional circumstances. See WP:DELTALK.',
			size: 60
		} : null,
		hideSubgroupWhenMultiple: true
	},
	{
		label: 'ک۲: کاربر ناموجود', // localized
		value: 'nouser',
		tooltip: 'User pages of users that do not exist (Check Special:Listusers)'
	},
	{
		label: 'ک۳: نگارخانه غیر آزاد', // localized
		value: 'gallery',
		tooltip: 'Galleries in the userspace which consist mostly of "fair use" or non-free files. Wikipedia\'s non-free content policy forbids users from displaying non-free files, even ones they have uploaded themselves, in userspace. It is acceptable to have free files, GFDL-files, Creative Commons and similar licenses along with public domain material, but not "fair use" files',
		hideWhenRedirect: true
	},
	{
		label: 'U5: Blatant WP:NOTWEBHOST violations',
		value: 'notwebhost',
		tooltip: 'Pages in userspace consisting of writings, information, discussions, and/or activities not closely related to Wikipedia\'s goals, where the owner has made few or no edits outside of userspace, with the exception of plausible drafts and pages adhering to WP:UPYES.',
		hideWhenRedirect: true
	},
	{
		label: 'ک۱۱: صفحهٔ کاربری تبلیغاتی با نام کاربری تبلیغاتی', // localized
		value: 'spamuser',
		tooltip: 'A promotional user page, with a username that promotes or implies affiliation with the thing being promoted. Note that simply having a page on a company or product in one\'s userspace does not qualify it for deletion. If a user page is spammy but the username is not, then consider tagging with regular G11 instead.',
		hideWhenMultiple: true,
		hideWhenRedirect: true
	},
	{
		label: 'G13: AfC draft submission or a blank draft, stale by over 6 months',
		value: 'afc',
		tooltip: 'Any rejected or unsubmitted AfC draft submission or a blank draft, that has not been edited in over 6 months (excluding bot edits).',
		hideWhenMultiple: true,
		hideWhenRedirect: true
	}
];

Twinkle.speedy.templateList = [
	{
		label: 'ال۲. نمایش نادرست ویکی‌واژه:سیاست‌ها و رهنمودها', // localized
		value: 'policy',
		tooltip: 'This includes "speedy deletion" templates for issues that are not speedy deletion criteria and disclaimer templates intended to be used in articles',
		subgroup: {
			name: 'policy_rationale',
			type: 'input',
			label: 'توضیح اختیاری: ', // localized
			size: 60
		},
		hideSubgroupWhenSysop: true
	},
	{
		label: 'ال۳. الگوهای تکراری و دارای کدنویسی سخت', // localized
		value: 'duplicatetemplate',
		tooltip: 'Templates that are either substantial duplications of another template or hardcoded instances of another template where the same functionality could be provided by that other template',
		subgroup: {
			name: 'duplicatetemplate_2',
			type: 'input',
			label: 'Template this is redundant to: ',
			tooltip: 'The "Template:" prefix is not needed.'
		},
		hideWhenMultiple: true
	}
];

Twinkle.speedy.portalList = [
	{
		label: 'P1: Portal that would be subject to speedy deletion if it were an article',
		value: 'p1',
		tooltip: 'You must specify a single article criterion that applies in this case (A1, A3, A7, or A10).',
		subgroup: {
			name: 'p1_criterion',
			type: 'input',
			label: 'Article criterion that would apply: '
		}
	},
	{
		label: 'P2: Underpopulated portal (fewer than three non-stub articles)',
		value: 'emptyportal',
		tooltip: 'Any Portal based on a topic for which there is not a non-stub header article, and at least three non-stub articles detailing subject matter that would be appropriate to discuss under the title of that Portal'
	}
];

Twinkle.speedy.generalList = [
	{
		label: 'ع۱: عبارت‌های نامفهوم', // localized
		value: 'nonsense',
		tooltip: 'This does not include poor writing, partisan screeds, obscene remarks, vandalism, fictional material, material not in English, poorly translated material, implausible theories, or hoaxes. In short, if you can understand it, G1 does not apply.',
		hideInNamespaces: [ 2 ] // Not applicable in userspace
	},
	{
		label: 'ع۲: صفحه‌های آزمایشی', // localized
		value: 'test',
		tooltip: 'A page created to test editing or other Wikipedia functions. Pages in the User namespace are not included, nor are valid but unused or duplicate templates (although criterion T3 may apply).',
		hideInNamespaces: [ 2 ] // Not applicable in userspace
	},
	{
		label: 'ع۳: خرابکاری محض', // localized
		value: 'vandalism',
		tooltip: 'Plain pure vandalism (including redirects left behind from pagemove vandalism)'
	},
	{
		label: 'ع۳: کلک‌زنی آشکار', // localized
		value: 'hoax',
		tooltip: 'Blatant and obvious hoax, to the point of vandalism',
		hideWhenMultiple: true
	},
	{
		label: 'ع۴: ساخت دوبارهٔ صفحه‌ای که بر پایهٔ نظرخواهیِ حذف حذف شده‌است', // localized
		value: 'repost',
		tooltip: 'A copy, by any title, of a page that was deleted via an XfD process or Deletion review, provided that the copy is substantially identical to the deleted version. This clause does not apply to content that has been "userfied", to content undeleted as a result of Deletion review, or if the prior deletions were proposed or speedy deletions, although in this last case, other speedy deletion criteria may still apply',
		subgroup: {
			name: 'repost_xfd',
			type: 'input',
			label: 'صفحه نظرخواهی حذف: ', // localized
			tooltip: 'حتما باید با «ویکی‌واژه:» آغاز شود', // localized
			size: 60
		}
	},
	{
		label: 'ع۵: ساختهٔ کاربران تحریم‌شده یا بسته‌شده', // localized
		value: 'banned',
		tooltip: 'Pages created by banned or blocked users in violation of their ban or block, and which have no substantial edits by others',
		subgroup: {
			name: 'banned_user',
			type: 'input',
			label: 'نام کاربری شخص طرد شده: ', // localized
			tooltip: 'نباید با «کاربر:» آغاز شود' // localized
		}
	},
	{
		label: 'ع۶: انتقال', // localized
		value: 'move',
		tooltip: 'ممکن کردن انتقال از طریق حذف', // localized
		subgroup: [
			{
				name: 'move_page',
				type: 'input',
				label: 'Page to be moved here: '
			},
			{
				name: 'move_reason',
				type: 'input',
				label: 'Reason: ',
				size: 60
			}
		],
		hideWhenMultiple: true
	},
	{
		label: 'ع۶: نظرخواهی برای حذف', // localized
		value: 'xfd',
		tooltip: 'نظرخواهی برای حذف با «حذف شود» جمع‌بندی شده ولی صفحه حذف نشده‌است', // localized
		subgroup: {
			name: 'xfd_fullvotepage',
			type: 'input',
			label: 'Page where the deletion discussion was held: ',
			tooltip: 'Must start with "Wikipedia:"',
			size: 40
		},
		hideWhenMultiple: true
	},
	{
		label: 'ع۶: انتقال از طریق کپی پیست', // localized
		value: 'copypaste',
		tooltip: 'This only applies for a copy-and-paste page move of another page that needs to be temporarily deleted to make room for a clean page move.',
		subgroup: {
			name: 'copypaste_sourcepage',
			type: 'input',
			label: 'Original page that was copy-pasted here: '
		},
		hideWhenMultiple: true
	},
	{
		label: 'ع۶: حذف‌های فنی', // localized
		value: 'g6',
		tooltip: 'Other routine maintenance tasks',
		subgroup: {
			name: 'g6_rationale',
			type: 'input',
			label: 'دلیل: ', // localized
			size: 60
		}
	},
	{
		label: 'ع۷: درخواست از طرف نویسنده', // localized
		value: 'author',
		tooltip: 'Any page for which deletion is requested by the original author in good faith, provided the page\'s only substantial content was added by its author. If the author blanks the page, this can also be taken as a deletion request.',
		subgroup: {
			name: 'author_rationale',
			type: 'input',
			label: 'Optional explanation: ',
			tooltip: 'Perhaps linking to where the author requested this deletion.',
			size: 60
		},
		hideSubgroupWhenSysop: true
	},
	{
		label: 'ع۸: صفحه‌های وابسته به صفحه‌ای حذف‌شده یا ناموجود', // localized
		value: 'g8',
		tooltip: 'such as talk pages with no corresponding subject page; subpages with no parent page; file pages without a corresponding file; redirects to non-existent targets; or categories populated by deleted or retargeted templates. This excludes any page that is useful to the project, and in particular: deletion discussions that are not logged elsewhere, user and user talk pages, talk page archives, plausible redirects that can be changed to valid targets, and file pages or talk pages for files that exist on Wikimedia Commons.',
		subgroup: {
			name: 'g8_rationale',
			type: 'input',
			label: 'Optional explanation: ',
			size: 60
		},
		hideSubgroupWhenSysop: true
	},
	{
		label: 'ع۸: زیرصفحه‌های فاقد صفحهٔ مادر', // localized
		value: 'subpage',
		tooltip: 'This excludes any page that is useful to the project, and in particular: deletion discussions that are not logged elsewhere, user and user talk pages, talk page archives, plausible redirects that can be changed to valid targets, and file pages or talk pages for files that exist on Wikimedia Commons.',
		hideWhenMultiple: true,
		hideInNamespaces: [ 0, 6, 8 ]  // hide in main, file, and mediawiki-spaces
	},
	{
		label: 'ع۱۰: صفحه‌های حمله', // localized
		value: 'attack',
		tooltip: 'Pages that serve no purpose but to disparage or threaten their subject or some other entity (e.g., "John Q. Doe is an imbecile"). This includes a biography of a living person that is negative in tone and unsourced, where there is no NPOV version in the history to revert to. Administrators deleting such pages should not quote the content of the page in the deletion summary!'
	},
	{
		label: 'ع۱۰: زندگی‌نامه افراد زندهٔ کاملاً منفی و بدون منبع', // localized
		value: 'negublp',
		tooltip: 'A biography of a living person that is entirely negative in tone and unsourced, where there is no neutral version in the history to revert to.',
		hideWhenMultiple: true
	},
	{
		label: 'ع۱۱: تبلیغات واضح', // localized
		value: 'spam',
		tooltip: 'Pages which exclusively promote a company, product, group, service, or person and which would need to be fundamentally rewritten in order to become encyclopedic. Note that an article about a company or a product which describes its subject from a neutral point of view does not qualify for this criterion; an article that is blatant advertising should have inappropriate content as well'
	},
	{
		label: 'ع۱۲: نقض آشکار حق تکثیر', // localized
		value: 'copyvio',
		tooltip: 'Either: (1) Material was copied from another website that does not have a license compatible with Wikipedia, or is photography from a stock photo seller (such as Getty Images or Corbis) or other commercial content provider; (2) There is no non-infringing content in the page history worth saving; or (3) The infringement was introduced at once by a single person rather than created organically on wiki and then copied by another website such as one of the many Wikipedia mirrors',
		subgroup: [
			{
				name: 'copyvio_url',
				type: 'input',
				label: 'URL (if available): ',
				tooltip: 'If the material was copied from an online source, put the URL here, including the "http://" or "https://" protocol.',
				size: 60
			},
			{
				name: 'copyvio_url2',
				type: 'input',
				label: 'Additional URL: ',
				tooltip: 'Optional. Should begin with "http://" or "https://"',
				size: 60
			},
			{
				name: 'copyvio_url3',
				type: 'input',
				label: 'Additional URL: ',
				tooltip: 'Optional. Should begin with "http://" or "https://"',
				size: 60
			}
		]
	},
	{
		label: 'ع۱۳: پیش‌نویس رهاشده', // localized
		value: 'afc',
		tooltip: 'Any rejected or unsubmitted AfC submission in userspace or any non-redirect page in draft namespace, that has not been edited for more than 6 months. Blank drafts in either namespace are also included.',
		hideWhenRedirect: true,
		showInNamespaces: [2, 118]  // user, draft namespaces only
	},
	{
		label: 'ع۱۴: صفحهٔ ابهام‌زدایی نالازم', // localized
		value: 'disambig',
		tooltip: 'This only applies for orphaned disambiguation pages which either: (1) disambiguate only one existing Wikipedia page and whose title ends in "(disambiguation)" (i.e., there is a primary topic); or (2) disambiguate no (zero) existing Wikipedia pages, regardless of its title.  It also applies to orphan "Foo (disambiguation)" redirects that target pages that are not disambiguation or similar disambiguation-like pages (such as set index articles or lists)'
	}
];

Twinkle.speedy.redirectList = [
	{
		label: 'ت۲: تغییرمسیر به فضای نام دیگر', // localized
		value: 'rediruser',
		tooltip: 'This does not include the pseudo-namespace shortcuts. If this was the result of a page move, consider waiting a day or two before deleting the redirect',
		showInNamespaces: [ 0 ]
	},
	{
		label: 'ت۳: غلط‌های املایی نامحتمل', // localized
		value: 'redirtypo',
		tooltip: 'However, redirects from common misspellings or misnomers are generally useful, as are redirects in other languages'
	},
	{
		label: 'R4: File namespace redirect with a name that matches a Commons page',
		value: 'redircom',
		tooltip: 'The redirect should have no incoming links (unless the links are cleary intended for the file or redirect at Commons).',
		showInNamespaces: [ 6 ]
	},
	{
		label: 'G6: Redirect to malplaced disambiguation page',
		value: 'movedab',
		tooltip: 'This only applies for redirects to disambiguation pages ending in (disambiguation) where a primary topic does not exist.',
		hideWhenMultiple: true
	},
	{
		label: 'ع۸: تغییرمسیر به هدف ناموجود', // localized
		value: 'redirnone',
		tooltip: 'This excludes any page that is useful to the project, and in particular: deletion discussions that are not logged elsewhere, user and user talk pages, talk page archives, plausible redirects that can be changed to valid targets, and file pages or talk pages for files that exist on Wikimedia Commons.',
		hideWhenMultiple: true
	}
];

Twinkle.speedy.normalizeHash = {
	'reason': 'حذف سریع', // localized
	'nonsense': 'ع۱', // localized
	'test': 'ع۲', // localized
	'vandalism': 'ع۳', // localized
	'hoax': 'ع۳', // localized
	'repost': 'ع۴', // localized
	'banned': 'ع۵', //localized
	'move': 'ع۶', // localiezd
	'xfd': 'ع۶', // localiezd
	'movedab': 'ع۶', // localized
	'copypaste': 'ع۶', // localized
	'g6': 'ع۶', // localized
	'author': 'ع۷', // localized
	'g8': 'ع۸', // localized
	'talk': 'ع۸', // localized
	'subpage': 'ع۸', // localized
	'redirnone': 'ع۸', // localized
	'templatecat': 'ع۸', // localized
	'imagepage': 'ع۸', // localized
	'attack': 'ع۱۰', // localized
	'negublp': 'ع۱۰', // localized
	'spam': 'ع۱۱', // localized
	'spamuser': 'ع۱۱', // localized
	'copyvio': 'ع۱۲', // localized
	'afc': 'ع۱۳', // localized
	'disambig': 'ع۱۴', // localized
	'nocontext': 'م۱', // localized
	'foreign': 'م۲', // localized
	'nocontent': 'م۳', // localized
	'transwiki': 'م۵', // localized
	'a7': 'م۷', // localized
	'person': 'م۷', // localized
	'corp': 'م۷', // localized
	'web': 'م۷', // localized
	'band': 'م۷', // localized
	'club': 'م۷', // localized
	'animal': 'م۷', // localized
	'event': 'م۷', // localized
	'a9': 'م۹', // localized
	'a10': 'م۱۰', // localized
	'madeup': 'م۱۱', // localized
	'rediruser': 'ت۲', // localized
	'redirtypo': 'ت۳', // localized
	'redircom': 'ت۴', // localized
	'redundantimage': 'پ۱', // localized
	'noimage': 'پ۲', // localized
	'fpcfail': 'پ۲', // localized
	'noncom': 'پ۳', // localized
	'unksource': 'پ۴', // localized
	'unfree': 'پ۵', // localized
	'f5': 'پ۵', // localized
	'norat': 'پ۶', // localized
	'badfairuse': 'پ۷', // localized
	'commons': 'پ۸', // localized
	'imgcopyvio': 'پ۹', // localized
	'badfiletype': 'پ۱۰', // localized
	'nopermission': 'پ۱۱', // localized
	'catempty': 'ر۱', // localized
	'userreq': 'ک۱', // localized
	'nouser': 'ک۲', // localized
	'gallery': 'ک۳', // localized
	'notwebhost': 'ک۵', // localized
	'policy': 'ال۲', // localized
	'duplicatetemplate': 'ال۳', // localized
	'p1': 'د۱', // localized
	'emptyportal': 'د۲' // localized
};

Twinkle.speedy.callbacks = {
	getTemplateCodeAndParams: function(params) {
		var code, parameters, i;
		if (params.normalizeds.length > 1) {
			code = '{{db-multiple';
			params.utparams = {};
			$.each(params.normalizeds, function(index, norm) {
				code += '|' + norm.toUpperCase();
				parameters = params.templateParams[index] || [];
				for (var i in parameters) {
					if (typeof parameters[i] === 'string' && !parseInt(i, 10)) {  // skip numeric parameters - {{db-multiple}} doesn't understand them
						code += '|' + i + '=' + parameters[i];
					}
				}
				$.extend(params.utparams, Twinkle.speedy.getUserTalkParameters(norm, parameters));
			});
			code += '}}';
		} else {
			parameters = params.templateParams[0] || [];
			code = '{{db-' + params.values[0];
			for (i in parameters) {
				if (typeof parameters[i] === 'string') {
					code += '|' + i + '=' + parameters[i];
				}
			}
			if (params.usertalk) {
				code += '|help=off';
			}
			code += '}}';
			params.utparams = Twinkle.speedy.getUserTalkParameters(params.normalizeds[0], parameters);
		}

		return [code, params.utparams];
	},

	parseWikitext: function(wikitext, callback) {
		var query = {
			action: 'parse',
			prop: 'text',
			pst: 'true',
			text: wikitext,
			contentmodel: 'wikitext',
			title: mw.config.get('wgPageName')
		};

		var statusIndicator = new Morebits.status('ایجاد خلاصهٔ حذف'); // localized
		var api = new Morebits.wiki.api('Parsing deletion template', query, function(apiObj) {
			var reason = decodeURIComponent($(apiObj.getXML().querySelector('text').childNodes[0].nodeValue).find('#delete-reason').text()).replace(/\+/g, ' ');
			if (!reason) {
				statusIndicator.warn('امکان ایجاد خلاصه از الگوی حذف وجود ندارد'); // localized
			} else {
				statusIndicator.info('کامل'); // localized
			}
			callback(reason);
		}, statusIndicator);
		api.post();
	},

	noteToCreator: function(pageobj) {
		var params = pageobj.getCallbackParameters();
		var initialContrib = pageobj.getCreator();

		// disallow notifying yourself
		if (initialContrib === mw.config.get('wgUserName')) {
			Morebits.status.warn('شما (' + initialContrib + ') این صفحه را ایجاد کرده‌اید؛ توقف آگاه‌سازی کاربر'); // localized
			initialContrib = null;

		// don't notify users when their user talk page is nominated/deleted
		} else if (initialContrib === mw.config.get('wgTitle') && mw.config.get('wgNamespaceNumber') === 3) {
			Morebits.status.warn('Notifying initial contributor: this user created their own user talk page; skipping notification');
			initialContrib = null;

		// quick hack to prevent excessive unwanted notifications, per request. Should actually be configurable on recipient page...
		} else if ((initialContrib === 'Cyberbot I' || initialContrib === 'SoxBot') && params.normalizeds[0] === 'f2') {
			Morebits.status.warn('Notifying initial contributor: page created procedurally by bot; skipping notification');
			initialContrib = null;

		// Check for already existing tags
		} else if (Twinkle.speedy.hasCSD && params.warnUser && !confirm('The page is has a deletion-related tag, and thus the creator has likely been notified.  Do you want to notify them for this deletion as well?')) {
			Morebits.status.info('Notifying initial contributor', 'canceled by user; skipping notification.');
			initialContrib = null;
		}

		if (initialContrib) {
			var usertalkpage = new Morebits.wiki.page('User talk:' + initialContrib, 'Notifying initial contributor (' + initialContrib + ')'),
				notifytext, i, editsummary;

			// special cases: "db" and "db-multiple"
			if (params.normalizeds.length > 1) {
				notifytext = '\n{{subst:db-' + (params.warnUser ? 'deleted' : 'notice') + '-multiple|1=' + Morebits.pageNameNorm;
				var count = 2;
				$.each(params.normalizeds, function(index, norm) {
					notifytext += '|' + count++ + '=' + norm.toUpperCase();
				});
			} else if (params.normalizeds[0] === 'db') {
				notifytext = '\n{{subst:db-reason-' + (params.warnUser ? 'deleted' : 'notice') + '|1=' + Morebits.pageNameNorm;
			} else {
				notifytext = '\n{{subst:db-csd-' + (params.warnUser ? 'deleted' : 'notice') + '-custom|1=';
				if (params.values[0] === 'copypaste') {
					notifytext += params.templateParams[0].sourcepage;
				} else {
					notifytext += Morebits.pageNameNorm;
				}
				notifytext += '|2=' + params.values[0];
			}

			for (i in params.utparams) {
				if (typeof params.utparams[i] === 'string') {
					notifytext += '|' + i + '=' + params.utparams[i];
				}
			}
			notifytext += (params.welcomeuser ? '' : '|nowelcome=yes') + '}} ~~~~';

			editsummary = 'آگاه‌سازی: ' + (params.warnUser ? '' : 'نامزدی ') + 'حذف سریع'; // localized
			if (params.normalizeds.indexOf('g10') === -1) {  // no article name in summary for G10 taggings
				editsummary += ' [[:' + Morebits.pageNameNorm + ']].';
			} else {
				editsummary += ' صفحهٔ حمله.'; // localized
			}

			usertalkpage.setAppendText(notifytext);
			usertalkpage.setEditSummary(editsummary + Twinkle.getPref('summaryAd'));
			usertalkpage.setCreateOption('recreate');
			usertalkpage.setFollowRedirect(true);
			usertalkpage.append(function onNotifySuccess() {
				// add this nomination to the user's userspace log, if the user has enabled it
				if (params.lognomination) {
					Twinkle.speedy.callbacks.user.addToLog(params, initialContrib);
				}
			}, function onNotifyError() {
				// if user could not be notified, log nomination without mentioning that notification was sent
				if (params.lognomination) {
					Twinkle.speedy.callbacks.user.addToLog(params, null);
				}
			});
		} else if (params.lognomination) {
			// log nomination even if the user notification wasn't sent
			Twinkle.speedy.callbacks.user.addToLog(params, null);
		}
	},

	sysop: {
		main: function(params) {
			var reason;
			if (!params.normalizeds.length && params.normalizeds[0] === 'db') {
				reason = prompt('Enter the deletion summary to use, which will be entered into the deletion log:', '');
				Twinkle.speedy.callbacks.sysop.deletePage(reason, params);
			} else {
				var code = Twinkle.speedy.callbacks.getTemplateCodeAndParams(params)[0];
				Twinkle.speedy.callbacks.parseWikitext(code, function(reason) {
					if (params.promptForSummary) {
						reason = prompt('Enter the deletion summary to use, or press OK to accept the automatically generated one.', reason);
					}
					Twinkle.speedy.callbacks.sysop.deletePage(reason, params);
				});
			}
		},
		deletePage: function(reason, params) {
			var thispage = new Morebits.wiki.page(mw.config.get('wgPageName'), 'حذف صفحه'); // localized

			if (reason === null) {
				return Morebits.status.error('درخواست دلیل', 'لغو توسط کاربر'); // localized
			} else if (!reason || !reason.replace(/^\s*/, '').replace(/\s*$/, '')) {
				return Morebits.status.error('درخواست دلیل', "you didn't give one.  I don't know... what with admins and their apathetic antics... I give up...");
			}

			var deleteMain = function(callback) {
				thispage.setEditSummary(reason + Twinkle.getPref('deletionSummaryAd'));
				thispage.deletePage(function() {
					thispage.getStatusElement().info('انجام شد'); // localized
					typeof callback === 'function' && callback();
					Twinkle.speedy.callbacks.sysop.deleteTalk(params);
				});
			};

			// look up initial contributor. If prompting user for deletion reason, just display a link.
			// Otherwise open the talk page directly
			if (params.warnUser) {
				thispage.setCallbackParameters(params);
				thispage.lookupCreation(function(pageobj) {
					deleteMain(function() {
						Twinkle.speedy.callbacks.noteToCreator(pageobj);
					});
				});
			} else {
				deleteMain();
			}
		},
		deleteTalk: function(params) {
			// delete talk page
			if (params.deleteTalkPage &&
					params.normalized !== 'f8' &&
					document.getElementById('ca-talk').className !== 'new') {
				var talkpage = new Morebits.wiki.page(mw.config.get('wgFormattedNamespaces')[mw.config.get('wgNamespaceNumber') + 1] + ':' + mw.config.get('wgTitle'), 'حذف صفحهٔ بحث'); // localized
				talkpage.setEditSummary('[[WP:CSD#G8|G8]]: Talk page of deleted page "' + Morebits.pageNameNorm + '"' + Twinkle.getPref('deletionSummaryAd'));
				talkpage.deletePage();
				// this is ugly, but because of the architecture of wiki.api, it is needed
				// (otherwise success/failure messages for the previous action would be suppressed)
				window.setTimeout(function() {
					Twinkle.speedy.callbacks.sysop.deleteRedirects(params);
				}, 1800);
			} else {
				Twinkle.speedy.callbacks.sysop.deleteRedirects(params);
			}
		},
		deleteRedirects: function(params) {
			// delete redirects
			if (params.deleteRedirects) {
				var query = {
					'action': 'query',
					'titles': mw.config.get('wgPageName'),
					'prop': 'redirects',
					'rdlimit': 'max' // 500 is max for normal users, 5000 for bots and sysops
				};
				var wikipedia_api = new Morebits.wiki.api('getting list of redirects...', query, Twinkle.speedy.callbacks.sysop.deleteRedirectsMain,
					new Morebits.status('در حال حذف تغییرمسیرها')); // localized
				wikipedia_api.params = params;
				wikipedia_api.post();
			}

			// promote Unlink tool
			var $link, $bigtext;
			if (mw.config.get('wgNamespaceNumber') === 6 && params.normalized !== 'f8') {
				$link = $('<a/>', {
					'href': '#',
					'text': 'click here to go to the Unlink tool',
					'css': { 'fontSize': '130%', 'fontWeight': 'bold' },
					'click': function() {
						Morebits.wiki.actionCompleted.redirect = null;
						Twinkle.speedy.dialog.close();
						Twinkle.unlink.callback('Removing usages of and/or links to deleted file ' + Morebits.pageNameNorm);
					}
				});
				$bigtext = $('<span/>', {
					'text': 'To orphan backlinks and remove instances of file usage',
					'css': { 'fontSize': '130%', 'fontWeight': 'bold' }
				});
				Morebits.status.info($bigtext[0], $link[0]);
			} else if (params.normalized !== 'f8') {
				$link = $('<a/>', {
					'href': '#',
					'text': 'click here to go to the Unlink tool',
					'css': { 'fontSize': '130%', 'fontWeight': 'bold' },
					'click': function() {
						Morebits.wiki.actionCompleted.redirect = null;
						Twinkle.speedy.dialog.close();
						Twinkle.unlink.callback('Removing links to deleted page ' + Morebits.pageNameNorm);
					}
				});
				$bigtext = $('<span/>', {
					'text': 'To orphan backlinks',
					'css': { 'fontSize': '130%', 'fontWeight': 'bold' }
				});
				Morebits.status.info($bigtext[0], $link[0]);
			}
		},
		deleteRedirectsMain: function(apiobj) {
			var xmlDoc = apiobj.getXML();
			var $snapshot = $(xmlDoc).find('redirects rd');
			var total = $snapshot.length;
			var statusIndicator = apiobj.statelem;

			if (!total) {
				statusIndicator.status('هیچ تغییرمسیری پیدا نشد'); // localized
				return;
			}

			statusIndicator.status('0%');

			var current = 0;
			var onsuccess = function(apiobjInner) {
				var now = parseInt(100 * ++current / total, 10) + '%';
				statusIndicator.update(now);
				apiobjInner.statelem.unlink();
				if (current >= total) {
					statusIndicator.info(now + ' (کامل شد)'); // localized
					Morebits.wiki.removeCheckpoint();
				}
			};

			Morebits.wiki.addCheckpoint();

			$snapshot.each(function(key, value) {
				var title = $(value).attr('title');
				var page = new Morebits.wiki.page(title, 'در حال حذف تغییرمسیر "' + title + '"'); // localized
				page.setEditSummary('[[WP:CSD#G8|G8]]: Redirect to deleted page "' + Morebits.pageNameNorm + '"' + Twinkle.getPref('deletionSummaryAd'));
				page.deletePage(onsuccess);
			});
		}
	},

	user: {
		main: function(pageobj) {
			var statelem = pageobj.getStatusElement();

			// defaults to /doc for lua modules, which may not exist
			if (!pageobj.exists() && mw.config.get('wgPageContentModel') !== 'Scribunto') {
				statelem.error("It seems that the page doesn't exist; perhaps it has already been deleted");
				return;
			}

			var text = pageobj.getPageText();
			var params = pageobj.getCallbackParameters();

			statelem.status('در حال بررسی برچسب‌های روی صفحه...'); // localized

			// check for existing deletion tags
			var tag = /(?:\{\{\s*(db|delete|db-.*?|speedy deletion-.*?)(?:\s*\||\s*\}\}))/.exec(text);
			// This won't make use of the db-multiple template but it probably should
			if (tag && !confirm('The page already has the CSD-related template {{' + tag[1] + '}} on it.  Do you want to add another CSD template?')) {
				return;
			}

			var xfd = /\{\{((?:article for deletion|proposed deletion|prod blp|template for discussion)\/dated|[cfm]fd\b)/i.exec(text) || /#invoke:(RfD)/.exec(text);
			if (xfd && !confirm('The deletion-related template {{' + xfd[1] + '}} was found on the page. Do you still want to add a CSD template?')) {
				return;
			}

			// given the params, builds the template and also adds the user talk page parameters to the params that were passed in
			// returns => [<string> wikitext, <object> utparams]
			var buildData = Twinkle.speedy.callbacks.getTemplateCodeAndParams(params),
				code = buildData[0];
			params.utparams = buildData[1];

			// curate/patrol the page
			if (Twinkle.getPref('markSpeedyPagesAsPatrolled')) {
				pageobj.triage();
			}

			// Wrap SD template in noinclude tags if we are in template space.
			// Won't work with userboxes in userspace, or any other transcluded page outside template space
			if (mw.config.get('wgNamespaceNumber') === 10) {  // Template:
				code = '<noinclude>' + code + '</noinclude>';
			}

			// Remove tags that become superfluous with this action
			text = text.replace(/\{\{\s*([Uu]serspace draft)\s*(\|(?:\{\{[^{}]*\}\}|[^{}])*)?\}\}\s*/g, '');
			if (mw.config.get('wgNamespaceNumber') === 6) {
				// remove "move to Commons" tag - deletion-tagged files cannot be moved to Commons
				text = text.replace(/\{\{(mtc|(copy |move )?to ?commons|move to wikimedia commons|copy to wikimedia commons)[^}]*\}\}/gi, '');
			}

			if (params.requestsalt) {
				if (params.normalizeds.indexOf('g10') === -1) {
					code = code + '\n{{نمک}}'; // localized
				} else {
					code = '{{نمک}}\n' + code; // localized
				}
			}

			// Generate edit summary for edit
			var editsummary;
			if (params.normalizeds.length > 1) {
				editsummary = 'ثبت درخواست حذف سریع ('; // localized
				$.each(params.normalizeds, function(index, norm) {
					editsummary += '[[ویکی‌واژه:محس#' + norm.toUpperCase() + '|محس ' + norm.toUpperCase() + ']], '; // localized
				});
				editsummary = editsummary.substr(0, editsummary.length - 2); // remove trailing comma
				editsummary += ').';
			} else if (params.normalizeds[0] === 'db') {
				editsummary = 'ثبت درخواست [[ویکی‌واژه:محس|حذف سریع]] با معیار «' + params.templateParams[0]['1'] + '».'; // localized
			} else {
				editsummary = 'ثبت درخواست حذف سریع ([[ویکی‌واژه:محس#' + params.normalizeds[0].toUpperCase() + '|محس ' + params.normalizeds[0].toUpperCase() + ']]).'; // localized
			}

			// Set the correct value for |ts= parameter in {{db-g13}}
			if (params.normalizeds.indexOf('g13') !== -1) {
				code = code.replace('$TIMESTAMP', pageobj.getLastEditTime());
			}

			pageobj.setPageText(code + (params.normalizeds.indexOf('g10') !== -1 ? '' : '\n' + text)); // cause attack pages to be blanked
			pageobj.setEditSummary(editsummary + Twinkle.getPref('summaryAd'));
			pageobj.setWatchlist(params.watch);
			if (params.scribunto) {
				pageobj.setCreateOption('recreate'); // Module /doc might not exist
				if (params.watch) {
					// Watch module in addition to /doc subpage
					var watch_query = {
						action: 'watch',
						titles: mw.config.get('wgPageName'),
						token: mw.user.tokens.get('watchToken')
					};
					new Morebits.wiki.api('Adding Module to watchlist', watch_query).post();
				}
			}
			pageobj.save(Twinkle.speedy.callbacks.user.tagComplete);
		},

		tagComplete: function(pageobj) {
			var params = pageobj.getCallbackParameters();

			// Notification to first contributor, will also log nomination to the user's userspace log
			if (params.usertalk) {
				var thispage = new Morebits.wiki.page(Morebits.pageNameNorm);
				thispage.setCallbackParameters(params);
				thispage.lookupCreation(Twinkle.speedy.callbacks.noteToCreator);
			// or, if not notifying, add this nomination to the user's userspace log without the initial contributor's name
			} else if (params.lognomination) {
				Twinkle.speedy.callbacks.user.addToLog(params, null);
			}
		},

		// note: this code is also invoked from twinkleimage
		// the params used are:
		//   for CSD: params.values, params.normalizeds  (note: normalizeds is an array)
		//   for DI: params.fromDI = true, params.templatename, params.normalized  (note: normalized is a string)
		addToLog: function(params, initialContrib) {
			var usl = new Morebits.userspaceLogger(Twinkle.getPref('speedyLogPageName'));
			usl.initialText =
				"This is a log of all [[WP:CSD|speedy deletion]] nominations made by this user using [[WP:TW|Twinkle]]'s CSD module.\n\n" +
				'If you no longer wish to keep this log, you can turn it off using the [[Wikipedia:Twinkle/Preferences|preferences panel]], and ' +
				'nominate this page for speedy deletion under [[WP:CSD#U1|CSD U1]].' +
				(Morebits.userIsSysop ? '\n\nThis log does not track outright speedy deletions made using Twinkle.' : '');

			var formatParamLog = function(normalize, csdparam, input) {
				if ((normalize === 'G4' && csdparam === 'xfd') ||
					(normalize === 'G6' && csdparam === 'page') ||
					(normalize === 'G6' && csdparam === 'fullvotepage') ||
					(normalize === 'G6' && csdparam === 'sourcepage') ||
					(normalize === 'A2' && csdparam === 'source') ||
					(normalize === 'A10' && csdparam === 'article') ||
					(normalize === 'F1' && csdparam === 'filename') ||
					(normalize === 'F5' && csdparam === 'replacement')) {
					input = '[[:' + input + ']]';
				} else if (normalize === 'G5' && csdparam === 'user') {
					input = '[[:User:' + input + ']]';
				} else if (normalize === 'G12' && csdparam.lastIndexOf('url', 0) === 0 && input.lastIndexOf('http', 0) === 0) {
					input = '[' + input + ' ' + input + ']';
				} else if (normalize === 'T3' && csdparam === 'template') {
					input = '[[:Template:' + input + ']]';
				} else if (normalize === 'F8' && csdparam === 'filename') {
					input = '[[commons:' + input + ']]';
				} else if (normalize === 'P1' && csdparam === 'criterion') {
					input = '[[WP:CSD#' + input + ']]';
				}
				return ' {' + normalize + ' ' + csdparam + ': ' + input + '}';
			};

			var extraInfo = '';

			// If a logged file is deleted but exists on commons, the wikilink will be blue, so provide a link to the log
			var fileLogLink = mw.config.get('wgNamespaceNumber') === 6 ? ' ([{{fullurl:Special:Log|page=' + mw.util.wikiUrlencode(mw.config.get('wgPageName')) + '}} log])' : '';

			var editsummary = 'Logging speedy deletion nomination';
			var appendText = '# [[:' + Morebits.pageNameNorm;

			if (params.fromDI) {
				appendText += ']]' + fileLogLink + ': DI [[WP:CSD#' + params.normalized.toUpperCase() + '|CSD ' + params.normalized.toUpperCase() + ']] ({{tl|di-' + params.templatename + '}})';
				// The params data structure when coming from DI is quite different,
				// so this hardcodes the only interesting items worth logging
				['reason', 'replacement', 'source'].forEach(function(item) {
					if (params[item]) {
						extraInfo += formatParamLog(params.normalized.toUpperCase(), item, params[item]);
						return false;
					}
				});
				editsummary += ' [[:' + Morebits.pageNameNorm + ']].'; // localized
			} else {
				if (params.normalizeds.indexOf('g10') === -1) {  // no article name in log for G10 taggings
					appendText += ']]' + fileLogLink + ': ';
					editsummary += ' [[:' + Morebits.pageNameNorm + ']].'; // localized
				} else {
					appendText += '|این]] صفحهٔ حمله' + fileLogLink + ': '; // localized
					editsummary += ' یک صفحهٔ حمله.'; // localized
				}
				if (params.normalizeds.length > 1) {
					appendText += 'چند معیار ('; // localized
					$.each(params.normalizeds, function(index, norm) {
						appendText += '[[WP:CSD#' + norm.toUpperCase() + '|' + norm.toUpperCase() + ']], ';
					});
					appendText = appendText.substr(0, appendText.length - 2);  // remove trailing comma
					appendText += ')';
				} else if (params.normalizeds[0] === 'db') {
					appendText += '{{tl|db-reason}}';
				} else {
					appendText += '[[WP:CSD#' + params.normalizeds[0].toUpperCase() + '|CSD ' + params.normalizeds[0].toUpperCase() + ']] ({{tl|db-' + params.values[0] + '}})';
				}

				// If params is "empty" it will still be full of empty arrays, but ask anyway
				if (params.templateParams) {
					// Treat custom rationale individually
					if (params.normalizeds[0] && params.normalizeds[0] === 'db') {
						extraInfo += formatParamLog('Custom', 'rationale', params.templateParams[0]['1']);
					} else {
						params.templateParams.forEach(function(item, index) {
							var keys = Object.keys(item);
							if (keys[0] !== undefined && keys[0].length > 0) {
								// Second loop required since some items (G12, F9) may have multiple keys
								keys.forEach(function(key, keyIndex) {
									if (keys[keyIndex] === 'blanked' || keys[keyIndex] === 'ts') {
										return true; // Not worth logging
									}
									extraInfo += formatParamLog(params.normalizeds[index].toUpperCase(), keys[keyIndex], item[key]);
								});
							}
						});
					}
				}
			}

			if (params.requestsalt) {
				appendText += '; حفاظت در برابر ایجاد درخواست شده‌است ([[ویکی‌واژه:نمک|نمک‌خورده]])'; // localized
			}
			if (extraInfo) {
				appendText += '؛ اطلاعات اضافی:' + extraInfo; // localized
			}
			if (initialContrib) {
				appendText += '؛ {{user|1=' + initialContrib + '}} آگاه شد'; // localized
			}
			appendText += ' ~~~~~\n';

			usl.log(appendText, editsummary + Twinkle.getPref('summaryAd'));

		}
	}
};

// validate subgroups in the form passed into the speedy deletion tag
Twinkle.speedy.getParameters = function twinklespeedyGetParameters(form, values) {
	var parameters = [];

	$.each(values, function(index, value) {
		var currentParams = [];
		switch (value) {
			case 'reason':
				if (form['csd.reason_1']) {
					var dbrationale = form['csd.reason_1'].value;
					if (!dbrationale || !dbrationale.trim()) {
						alert('دلیل دلخواه: لطفاً دلیلی ارائه کنید.'); // localized
						parameters = null;
						return false;
					}
					currentParams['1'] = dbrationale;
				}
				break;

			case 'userreq':  // U1
				if (form['csd.userreq_rationale']) {
					var u1rationale = form['csd.userreq_rationale'].value;
					if (mw.config.get('wgNamespaceNumber') === 3 && !(/\//).test(mw.config.get('wgTitle')) &&
							(!u1rationale || !u1rationale.trim())) {
						alert('CSD U1:  Please specify a rationale when nominating user talk pages.');
						parameters = null;
						return false;
					}
					currentParams.rationale = u1rationale;
				}
				break;

			case 'repost':  // G4
				if (form['csd.repost_xfd']) {
					var deldisc = form['csd.repost_xfd'].value;
					if (deldisc) {
						if (!/^(?:وپ|ویکی‌پدیا):/i.test(deldisc)) { // localized
							alert('محس ع۴: صفحه نظرخواهی حذف باید با "ویکی‌واژه:" آغاز شود.'); // localized
							parameters = null;
							return false;
						}
						currentParams.xfd = deldisc;
					}
				}
				break;

			case 'banned':  // G5
				if (form['csd.banned_user'] && form['csd.banned_user'].value) {
					currentParams.user = form['csd.banned_user'].value.replace(/^\s*کاربر:/i, ''); // localized
				}
				break;

			case 'move':  // G6
				if (form['csd.move_page'] && form['csd.move_reason']) {
					var movepage = form['csd.move_page'].value,
						movereason = form['csd.move_reason'].value;
					if (!movepage || !movepage.trim()) {
						alert('محس ع۶ (انتقال):  لطفاً نام صفحه‌ای که باید به اینجا انتقال یابد مشخص کنید.'); // localized
						parameters = null;
						return false;
					}
					if (!movereason || !movereason.trim()) {
						alert('محس ع۶ (انتقال): لطفاً دلیل انتقال را مشخص کنید.'); // localized
						parameters = null;
						return false;
					}
					currentParams.page = movepage;
					currentParams.reason = movereason;
				}
				break;

			case 'xfd':  // G6
				if (form['csd.xfd_fullvotepage']) {
					var xfd = form['csd.xfd_fullvotepage'].value;
					if (xfd) {
						if (!/^(?:wp|wikipedia):/i.test(xfd)) {
							alert('CSD G6 (XFD):  The deletion discussion page name, if provided, must start with "Wikipedia:".');
							parameters = null;
							return false;
						}
						currentParams.fullvotepage = xfd;
					}
				}
				break;

			case 'copypaste':  // G6
				if (form['csd.copypaste_sourcepage']) {
					var copypaste = form['csd.copypaste_sourcepage'].value;
					if (!copypaste || !copypaste.trim()) {
						alert('محس ع۶ (کپی‌پیست): لطفاً نام صفحهٔ مبدأ را مشخص کنید.'); // localized
						parameters = null;
						return false;
					}
					currentParams.sourcepage = copypaste;
				}
				break;

			case 'g6':  // G6
				if (form['csd.g6_rationale'] && form['csd.g6_rationale'].value) {
					currentParams.rationale = form['csd.g6_rationale'].value;
				}
				break;

			case 'author':  // G7
				if (form['csd.author_rationale'] && form['csd.author_rationale'].value) {
					currentParams.rationale = form['csd.author_rationale'].value;
				}
				break;

			case 'g8':  // G8
				if (form['csd.g8_rationale'] && form['csd.g8_rationale'].value) {
					currentParams.rationale = form['csd.g8_rationale'].value;
				}
				break;

			case 'attack':  // G10
				currentParams.blanked = 'yes';
				// it is actually blanked elsewhere in code, but setting the flag here
				break;

			case 'copyvio':  // G12
				if (form['csd.copyvio_url'] && form['csd.copyvio_url'].value) {
					currentParams.url = form['csd.copyvio_url'].value;
				}
				if (form['csd.copyvio_url2'] && form['csd.copyvio_url2'].value) {
					currentParams.url2 = form['csd.copyvio_url2'].value;
				}
				if (form['csd.copyvio_url3'] && form['csd.copyvio_url3'].value) {
					currentParams.url3 = form['csd.copyvio_url3'].value;
				}
				break;

			case 'afc':  // G13
				currentParams.ts = '$TIMESTAMP'; // to be replaced by the last revision timestamp when page is saved
				break;

			case 'redundantimage':  // F1
				if (form['csd.redundantimage_filename']) {
					var redimage = form['csd.redundantimage_filename'].value;
					if (!redimage || !redimage.trim()) {
						alert('CSD F1:  Please specify the filename of the other file.');
						parameters = null;
						return false;
					}
					currentParams.filename = /^\s*(Image|File):/i.test(redimage) ? redimage : 'File:' + redimage;
				}
				break;

			case 'badfairuse':  // F7
				if (form['csd.badfairuse_rationale'] && form['csd.badfairuse_rationale'].value) {
					currentParams.rationale = form['csd.badfairuse_rationale'].value;
				}
				break;

			case 'commons':  // F8
				if (form['csd.commons_filename']) {
					var filename = form['csd.commons_filename'].value;
					if (filename && filename.trim() && filename !== Morebits.pageNameNorm) {
						currentParams.filename = /^\s*(Image|File):/i.test(filename) ? filename : 'File:' + filename;
					}
				}
				break;

			case 'imgcopyvio':  // F9
				if (form['csd.imgcopyvio_url'] && form['csd.imgcopyvio_rationale']) {
					var f9url = form['csd.imgcopyvio_url'].value;
					var f9rationale = form['csd.imgcopyvio_rationale'].value;
					if ((!f9url || !f9url.trim()) && (!f9rationale || !f9rationale.trim())) {
						alert('CSD F9: You must enter a url or reason (or both) when nominating a file under F9.');
						parameters = null;
						return false;
					}
					if (form['csd.imgcopyvio_url'].value) {
						currentParams.url = f9url;
					}
					if (form['csd.imgcopyvio_rationale'].value) {
						currentParams.rationale = f9rationale;
					}
				}
				break;

			case 'foreign':  // A2
				if (form['csd.foreign_source']) {
					var foreignlink = form['csd.foreign_source'].value;
					if (!foreignlink || !foreignlink.trim()) {
						alert('CSD A2:  Please specify an interwiki link to the article of which this is a copy.');
						parameters = null;
						return false;
					}
					currentParams.source = foreignlink;
				}
				break;

			case 'transwiki':  // A5
				if (form['csd.transwiki_location'] && form['csd.transwiki_location'].value) {
					currentParams.location = form['csd.transwiki_location'].value;
				}
				break;

			case 'a10':  // A10
				if (form['csd.a10_article']) {
					var duptitle = form['csd.a10_article'].value;
					if (!duptitle || !duptitle.trim()) {
						alert('محس م۱۰: لطفاً نام مقالهٔ تکرار شده را مشخص کنید.'); // localized
						parameters = null;
						return false;
					}
					currentParams.article = duptitle;
				}
				break;

			case 'policy':  // T2
				if (form['csd.policy_rationale'] && form['csd.policy_rationale'].value) {
					currentParams.rationale = form['csd.policy_rationale'].value;
				}
				break;

			case 'duplicatetemplate':  // T3
				if (form['csd.duplicatetemplate_2']) {
					var t3template = form['csd.duplicatetemplate_2'].value;
					if (!t3template || !t3template.trim()) {
						alert('محس ال۳: لطفاً نام الگوی تکرار شده را مشخص کنید.'); // localized
						parameters = null;
						return false;
					}
					currentParams.ts = '~~~~~';
					currentParams.template = t3template.replace(/^\s*Template:/i, '');
				}
				break;

			case 'p1':  // P1
				if (form['csd.p1_criterion']) {
					var criterion = form['csd.p1_criterion'].value;
					if (!criterion || !criterion.trim()) {
						alert('CSD P1:  Please specify a single criterion.');
						parameters = null;
						return false;
					}
					currentParams.criterion = criterion;
				}
				break;

			default:
				break;
		}
		parameters.push(currentParams);
	});
	return parameters;
};

// Function for processing talk page notification template parameters
// key1/value1: for {{db-criterion-[notice|deleted]}} (via {{db-csd-[notice|deleted]-custom}})
// utparams.param: for {{db-[notice|deleted]-multiple}}
Twinkle.speedy.getUserTalkParameters = function twinklespeedyGetUserTalkParameters(normalized, parameters) {
	var utparams = [];

	// Special cases
	if (normalized === 'db') {
		utparams['2'] = parameters['1'];
	} else if (normalized === 'g6') {
		utparams.key1 = 'to';
		utparams.value1 = Morebits.pageNameNorm;
	} else if (normalized === 'g12') {
		['url', 'url2', 'url3'].forEach(function(item, idx) {
			if (parameters[item]) {
				idx++;
				utparams['key' + idx] = item;
				utparams['value' + idx] = utparams[item] = parameters[item];
			}
		});
	} else {
		// Handle the rest
		var param;
		switch (normalized) {
			case 'g4':
				param = 'xfd';
				break;
			case 'a2':
				param = 'source';
				break;
			case 'a5':
				param = 'location';
				break;
			case 'a10':
				param = 'article';
				break;
			case 'f9':
				param = 'url';
				break;
			case 'p1':
				param = 'criterion';
				break;
			default:
				break;
		}
		// No harm in providing a usertalk template with the others' parameters
		if (param && parameters[param]) {
			utparams.key1 = param;
			utparams.value1 = utparams[param] = parameters[param];
		}
	}
	return utparams;
};


Twinkle.speedy.resolveCsdValues = function twinklespeedyResolveCsdValues(e) {
	var values = (e.target.form ? e.target.form : e.target).getChecked('csd');
	if (values.length === 0) {
		alert('Please select a criterion!');
		return null;
	}
	return values;
};

Twinkle.speedy.callback.evaluateSysop = function twinklespeedyCallbackEvaluateSysop(e) {
	var form = e.target.form ? e.target.form : e.target;

	if (e.target.type === 'checkbox' || e.target.type === 'text' ||
			e.target.type === 'select') {
		return;
	}

	var tag_only = form.tag_only;
	if (tag_only && tag_only.checked) {
		Twinkle.speedy.callback.evaluateUser(e);
		return;
	}

	var values = Twinkle.speedy.resolveCsdValues(e);
	if (!values) {
		return;
	}
	var templateParams = Twinkle.speedy.getParameters(form, values);
	if (!templateParams) {
		return;
	}

	var normalizeds = values.map(function(value) {
		return Twinkle.speedy.normalizeHash[value];
	});

	// analyse each criterion to determine whether to watch the page, prompt for summary, or notify the creator
	var watchPage, promptForSummary;
	normalizeds.forEach(function(norm) {
		if (Twinkle.getPref('watchSpeedyPages').indexOf(norm) !== -1) {
			watchPage = true;
		}
		if (Twinkle.getPref('promptForSpeedyDeletionSummary').indexOf(norm) !== -1) {
			promptForSummary = true;
		}
	});

	var warnusertalk = false;
	if (form.warnusertalk.checked) {
		$.each(normalizeds, function(index, norm) {
			if (Twinkle.getPref('warnUserOnSpeedyDelete').indexOf(norm) !== -1) {
				if (norm === 'g6' && values[index] !== 'copypaste') {
					return true;
				}
				warnusertalk = true;
				return false;  // break
			}
		});
	}

	var welcomeuser = false;
	if (warnusertalk) {
		$.each(normalizeds, function(index, norm) {
			if (Twinkle.getPref('welcomeUserOnSpeedyDeletionNotification').indexOf(norm) !== -1) {
				welcomeuser = true;
				return false;  // break
			}
		});
	}

	var params = {
		values: values,
		normalizeds: normalizeds,
		watch: watchPage,
		deleteTalkPage: form.talkpage && form.talkpage.checked,
		deleteRedirects: form.redirects.checked,
		warnUser: warnusertalk,
		welcomeuser: welcomeuser,
		promptForSummary: promptForSummary,
		templateParams: templateParams
	};

	Morebits.simpleWindow.setButtonsEnabled(false);
	Morebits.status.init(form);

	Twinkle.speedy.callbacks.sysop.main(params);
};

Twinkle.speedy.callback.evaluateUser = function twinklespeedyCallbackEvaluateUser(e) {
	var form = e.target.form ? e.target.form : e.target;

	if (e.target.type === 'checkbox' || e.target.type === 'text' ||
			e.target.type === 'select') {
		return;
	}

	var values = Twinkle.speedy.resolveCsdValues(e);
	if (!values) {
		return;
	}
	var templateParams = Twinkle.speedy.getParameters(form, values);
	if (!templateParams) {
		return;
	}

	// var multiple = form.multiple.checked;
	var normalizeds = [];
	$.each(values, function(index, value) {
		var norm = Twinkle.speedy.normalizeHash[value];

		normalizeds.push(norm);
	});

	// analyse each criterion to determine whether to watch the page/notify the creator
	var watchPage = false;
	$.each(normalizeds, function(index, norm) {
		if (Twinkle.getPref('watchSpeedyPages').indexOf(norm) !== -1) {
			watchPage = true;
			return false;  // break
		}
	});

	var notifyuser = false;
	if (form.notify.checked) {
		$.each(normalizeds, function(index, norm) {
			if (Twinkle.getPref('notifyUserOnSpeedyDeletionNomination').indexOf(norm) !== -1) {
				if (norm === 'g6' && values[index] !== 'copypaste') {
					return true;
				}
				notifyuser = true;
				return false;  // break
			}
		});
	}

	var welcomeuser = false;
	if (notifyuser) {
		$.each(normalizeds, function(index, norm) {
			if (Twinkle.getPref('welcomeUserOnSpeedyDeletionNotification').indexOf(norm) !== -1) {
				welcomeuser = true;
				return false;  // break
			}
		});
	}

	var csdlog = false;
	if (Twinkle.getPref('logSpeedyNominations')) {
		$.each(normalizeds, function(index, norm) {
			if (Twinkle.getPref('noLogOnSpeedyNomination').indexOf(norm) === -1) {
				csdlog = true;
				return false;  // break
			}
		});
	}

	var params = {
		values: values,
		normalizeds: normalizeds,
		watch: watchPage,
		usertalk: notifyuser,
		welcomeuser: welcomeuser,
		lognomination: csdlog,
		requestsalt: form.salting.checked,
		templateParams: templateParams
	};

	Morebits.simpleWindow.setButtonsEnabled(false);
	Morebits.status.init(form);

	Morebits.wiki.actionCompleted.redirect = mw.config.get('wgPageName');
	Morebits.wiki.actionCompleted.notice = 'Tagging complete';

	// Modules can't be tagged, follow standard at TfD and place on /doc subpage
	params.scribunto = mw.config.get('wgPageContentModel') === 'Scribunto';
	var wikipedia_page = params.scribunto ? new Morebits.wiki.page(mw.config.get('wgPageName') + '/doc', 'Tagging module documentation page') : new Morebits.wiki.page(mw.config.get('wgPageName'), 'Tagging page');
	wikipedia_page.setCallbackParameters(params);
	wikipedia_page.load(Twinkle.speedy.callbacks.user.main);
};
})(jQuery);


// </nowiki>