میڈیاویکی:Gadget-twinkleprotect-2022.js

تفصیل کے لیے کھولیں کے بٹن پر کلک کریں یاددہانی: محفوظ کرنے کے بعد تازہ ترین تبدیلیوں کو دیکھنے کے لیے آپ کو اپنے براؤزر کا کیش صاف کرنا ہوگا۔

  • فائرفاکس/ سفاری: جب Reload پر کلک کریں تو Shift دبا کر رکھیں، یا Ctrl-F5 یا Ctrl-R دبائیں (Mac پر R- )
  • گوگل کروم: Ctrl-Shift-R دبائیں (Mac پر Shift-R-⌘)
  • انٹرنیٹ ایکسپلورر: جب Refresh پر کلک کریں تو Ctrl یا Ctrl-F5 دبائیں
  • اوپیرا: Tools → Preferences میں جائیں اور کیش صاف کریں

// <nowiki>


(function($) {


/*
 ****************************************
 *** twinkleprotect.js: Protect/RPP module
 ****************************************
 * Mode of invocation:     Tab ("PP"/"RPP")
 * Active on:              Non-special, non-MediaWiki pages
 */

// Note: a lot of code in this module is re-used/called by batchprotect.

var localizedTypeNames = {
		edit: 'ترمیم',
		move: 'منتقلی',
		create: 'تخلیق',
		stabilize: 'پایدار',
		cascading: 'آبشاری'
	},
	localizedLevelNames = {
		autoconfirmed: 'خود توثیق شدہ صارفین',
		extendedconfirmed: 'توسیعی توثیق شدہ صارفین',
		sysop: 'منتظمین'
	};

Twinkle.protect = function twinkleprotect() {
	if (mw.config.get('wgNamespaceNumber') < 0 || mw.config.get('wgNamespaceNumber') === 8) {
		return;
	}

	Twinkle.addPortletLink(Twinkle.protect.callback, (Morebits.userIsSysop || Morebits.userIsEliminator) ? 'محفوظ' : 'محفوظ کرنے کی درخواست', 'tw-rpp',
		(Morebits.userIsSysop || Morebits.userIsEliminator) ? 'صفحہ کو محفوظ کریں' : 'صفحہ کو محفوظ کرنے کی درخواست دیں');
};

Twinkle.protect.callback = function twinkleprotectCallback() {
	var Window = new Morebits.simpleWindow(620, 530);
	Window.setTitle((Morebits.userIsSysop || Morebits.userIsEliminator) ? 'محفوظ کریں، درخواست دیں یا ٹیگ چسپاں کریں' : 'محفوظ کرنے کی درخواست یا اس کا ٹیگ چسپاں کریں');
	Window.setScriptName('پلک');
	Window.addFooterLink('سانچہ جات حفاظت', 'سانچہ:سانچہ جات محفوظ شدگی');
	Window.addFooterLink('محفوظ شدگی کی حکمت عملی', 'وپ:محفوظ');
	Window.addFooterLink('رہنمائے پلک', ':en:WP:TW/DOC#protect');
	Window.addFooterLink('آپ کے تاثرات', 'تبادلۂ خیال ویکیپیڈیا:پلک');

	var form = new Morebits.quickForm(Twinkle.protect.callback.evaluate);
	var actionfield = form.append({
		type: 'field',
		label: 'اقدام کی نوعیت'
	});
	if (Morebits.userIsSysop || Morebits.userIsEliminator) {
		actionfield.append({
			type: 'radio',
			name: 'actiontype',
			event: Twinkle.protect.callback.changeAction,
			list: [
				{
					label: 'صفحہ کو محفوظ کریں',
					value: 'protect',
					tooltip: 'صفحہ کو محفوظ کریں',
					checked: true
				}
			]
		});
	}
	actionfield.append({
		type: 'radio',
		name: 'actiontype',
		event: Twinkle.protect.callback.changeAction,
		list: [
			{
				label: 'صفحہ کو محفوظ کرنے کی درخواست دیں',
				value: 'request',
				tooltip: 'اگر آپ خود ' + ((Morebits.userIsSysop || Morebits.userIsEliminator) ? 'محفوظ کرنے کی بجائے ' : '') + 'وپ:دحص  پر محفوظ کرنے کی درخواست دینا چاہیں۔',
				checked: (!Morebits.userIsSysop && !Morebits.userIsEliminator)
			},
			{
				label: 'صفحہ میں محفوظ کا سانچہ چسپاں کریں',
				value: 'tag',
				tooltip: ((Morebits.userIsSysop || Morebits.userIsEliminator) ? 'اگر صفحہ محفوظ ہو لیکن کوئی سانچہ چسپاں نہ کیا گیا ہو، یا ' : '') + 'اگر محفوظ کرنے والے منتظم نے صفحہ محفوظ کرنے کے بعد اس میں مناسب سانچہ لگانا بھول گیا ہو تو کوئی موزوں سانچہ چسپاں کریں',
				disabled: mw.config.get('wgArticleId') === 0 || mw.config.get('wgPageContentModel') === 'Scribunto'
			}
		]
	});

	form.append({ type: 'field', label: 'ترتیب', name: 'field_preset' });
	form.append({ type: 'field', label: '1', name: 'field1' });
	form.append({ type: 'field', label: '2', name: 'field2' });

	form.append({ type: 'submit' });

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

	// We must init the controls
	var evt = document.createEvent('Event');
	evt.initEvent('change', true, true);
	result.actiontype[0].dispatchEvent(evt);

	// get current protection level asynchronously
	Twinkle.protect.fetchProtectionLevel();
};


// A list of bots who may be the protecting sysop, for whom we shouldn't
// remind the user contact before requesting unprotection (evaluate)
Twinkle.protect.trustedBots = ['Shuaib-bot', 'ZumrahBot', 'UrduBot'];

// Customizable namespace and FlaggedRevs settings
// In theory it'd be nice to have restrictionlevels defined here,
// but those are only available via a siteinfo query

// mw.loader.getState('ext.flaggedRevs.review') returns null if the
// FlaggedRevs extension is not registered.  Previously, this was done with
// wgFlaggedRevsParams, but after 1.34-wmf4 it is no longer exported if empty
// (https://gerrit.wikimedia.org/r/c/mediawiki/extensions/FlaggedRevs/+/508427)
var hasFlaggedRevs = mw.loader.getState('ext.flaggedRevs.review') &&
// FlaggedRevs only valid in some namespaces, hardcoded until [[phab:T218479]]
(mw.config.get('wgNamespaceNumber') === 0 || mw.config.get('wgNamespaceNumber') === 4);
// Limit template editor; a Twinkle restriction, not a site setting
var isTemplate = mw.config.get('wgNamespaceNumber') === 10 || mw.config.get('wgNamespaceNumber') === 828;


// Contains the current protection level in an object
// Once filled, it will look something like:
// { edit: { level: "sysop", expiry: <some date>, cascade: true }, ... }
Twinkle.protect.currentProtectionLevels = {};

// returns a jQuery Deferred object, usage:
//   Twinkle.protect.fetchProtectingAdmin(apiObject, pageName, protect/stable).done(function(admin_username) { ...code... });
Twinkle.protect.fetchProtectingAdmin = function twinkleprotectFetchProtectingAdmin(api, pageName, protType, logIds) {
	logIds = logIds || [];

	return api.get({
		format: 'json',
		action: 'query',
		list: 'logevents',
		letitle: pageName,
		letype: protType
	}).then(function(data) {
		// don't check log entries that have already been checked (e.g. don't go into an infinite loop!)
		var event = data.query ? $.grep(data.query.logevents, function(le) {
			return $.inArray(le.logid, logIds);
		})[0] : null;
		if (!event) {
			// fail gracefully
			return null;
		} else if (event.action === 'move_prot' || event.action === 'move_stable') {
			return twinkleprotectFetchProtectingAdmin(api, protType === 'protect' ? event.params.oldtitle_title : event.params.oldtitle, protType, logIds.concat(event.logid));
		}
		return event.user;
	});
};

Twinkle.protect.fetchProtectionLevel = function twinkleprotectFetchProtectionLevel() {

	var api = new mw.Api();
	var protectDeferred = api.get({
		format: 'json',
		indexpageids: true,
		action: 'query',
		list: 'logevents',
		letype: 'protect',
		letitle: mw.config.get('wgPageName'),
		prop: hasFlaggedRevs ? 'info|flagged' : 'info',
		inprop: 'protection|watched',
		titles: mw.config.get('wgPageName')
	});
	var stableDeferred = api.get({
		format: 'json',
		action: 'query',
		list: 'logevents',
		letype: 'stable',
		letitle: mw.config.get('wgPageName')
	});

	var earlyDecision = [protectDeferred];
	if (hasFlaggedRevs) {
		earlyDecision.push(stableDeferred);
	}

	$.when.apply($, earlyDecision).done(function(protectData, stableData) {
		// $.when.apply is supposed to take an unknown number of promises
		// via an array, which it does, but the type of data returned varies.
		// If there are two or more deferreds, it returns an array (of objects),
		// but if there's just one deferred, it retuns a simple object.
		// This is annoying.
		protectData = $(protectData).toArray();

		var pageid = protectData[0].query.pageids[0];
		var page = protectData[0].query.pages[pageid];
		var current = {}, adminEditDeferred;

		// Save requested page's watched status for later in case needed when filing request
		Twinkle.protect.watched = page.watchlistexpiry || page.watched === '';

		$.each(page.protection, function(index, protection) {
			// Don't overwrite actual page protection with cascading protection
			if (!protection.source) {
				current[protection.type] = {
					level: protection.level,
					expiry: protection.expiry,
					cascade: protection.cascade === ''
				};
				// logs report last admin who made changes to either edit/move/create protection, regardless if they only modified one of them
				if (!adminEditDeferred) {
					adminEditDeferred = Twinkle.protect.fetchProtectingAdmin(api, mw.config.get('wgPageName'), 'protect');
				}
			} else {
				// Account for the page being covered by cascading protection
				current.cascading = {
					expiry: protection.expiry,
					source: protection.source,
					level: protection.level // should always be sysop, unused
				};
			}
		});

		if (page.flagged) {
			current.stabilize = {
				level: page.flagged.protection_level,
				expiry: page.flagged.protection_expiry
			};
			adminEditDeferred = Twinkle.protect.fetchProtectingAdmin(api, mw.config.get('wgPageName'), 'stable');
		}

		// show the protection level and log info
		Twinkle.protect.hasProtectLog = !!protectData[0].query.logevents.length;
		Twinkle.protect.protectLog = Twinkle.protect.hasProtectLog && protectData[0].query.logevents;
		Twinkle.protect.hasStableLog = hasFlaggedRevs ? !!stableData[0].query.logevents.length : false;
		Twinkle.protect.stableLog = Twinkle.protect.hasStableLog && stableData[0].query.logevents;
		Twinkle.protect.currentProtectionLevels = current;

		if (adminEditDeferred) {
			adminEditDeferred.done(function(admin) {
				if (admin) {
					$.each(['edit', 'move', 'create', 'stabilize', 'cascading'], function(i, type) {
						if (Twinkle.protect.currentProtectionLevels[type]) {
							Twinkle.protect.currentProtectionLevels[type].admin = admin;
						}
					});
				}
				Twinkle.protect.callback.showLogAndCurrentProtectInfo();
			});
		} else {
			Twinkle.protect.callback.showLogAndCurrentProtectInfo();
		}
	});
};

Twinkle.protect.callback.showLogAndCurrentProtectInfo = function twinkleprotectCallbackShowLogAndCurrentProtectInfo() {
	var currentlyProtected = !$.isEmptyObject(Twinkle.protect.currentProtectionLevels);

	if (Twinkle.protect.hasProtectLog || Twinkle.protect.hasStableLog) {
		var $linkMarkup = $('<span>');

		if (Twinkle.protect.hasProtectLog) {
			$linkMarkup.append(
				$('<a target="_blank" href="' + mw.util.getUrl('خاص:نوشتہ', {action: 'view', page: mw.config.get('wgPageName'), type: 'protect'}) + '">نوشتۂ حفاظت</a>'));
			if (!currentlyProtected || (!Twinkle.protect.currentProtectionLevels.edit && !Twinkle.protect.currentProtectionLevels.move)) {
				var lastProtectAction = Twinkle.protect.protectLog[0];
				if (lastProtectAction.action === 'unprotect') {
					$linkMarkup.append(' (تاریخ ' + new Morebits.date(lastProtectAction.timestamp).calendar('utc') + ') کو صفحہ محفوظ کیا گیا');
				} else { // protect or modify
					$linkMarkup.append(' (مورخہ ' + new Morebits.date(lastProtectAction.params.details[0].expiry).calendar('utc') + ') کو حفاظت ختم ہو جائے گی');
				}
			}
			$linkMarkup.append(Twinkle.protect.hasStableLog ? $('<span> &bull; </span>') : null);
		}

		if (Twinkle.protect.hasStableLog) {
			$linkMarkup.append($('<a target="_blank" href="' + mw.util.getUrl('خاص:نوشتہ', {action: 'view', page: mw.config.get('wgPageName'), type: 'stable'}) + '">معلق تبدیلیوں کا نوشتہ</a>)'));
			if (!currentlyProtected || !Twinkle.protect.currentProtectionLevels.stabilize) {
				var lastStabilizeAction = Twinkle.protect.stableLog[0];
				if (lastStabilizeAction.action === 'reset') {
					$linkMarkup.append(' (بازنشانی‌شده در ' + new Morebits.date(lastStabilizeAction.timestamp).calendar('utc') + ')');
				} else { // config or modify
					$linkMarkup.append(' (منقضی‌شده در ' + new Morebits.date(lastStabilizeAction.params.expiry).calendar('utc') + ')');
				}
			}
		}

		Morebits.status.init($('div[name="hasprotectlog"] span')[0]);
		Morebits.status.warn(
			currentlyProtected ? 'سابقہ حفاظتیں' : 'یہ صفحہ کبھی محفوظ رہ چکا ہے',
			$linkMarkup[0]
		);
	}

	Morebits.status.init($('div[name="currentprot"] span')[0]);
	var protectionNode = [], statusLevel = 'info';

	if (currentlyProtected) {
		$.each(Twinkle.protect.currentProtectionLevels, function(type, settings) {
			var label = type === 'stabilize' ? 'معلق تبدیلیاں' : localizedTypeNames[type];

			if (type === 'cascading') { // Covered by another page
				label = 'آبشاری حفاظت ';
				protectionNode.push($('<b>' + label + '</b>')[0]);
				if (settings.source) { // Should by definition exist
					var sourceLink = '<a target="_blank" href="' + mw.util.getUrl(settings.source) + '">' + settings.source + '</a>';
					protectionNode.push($('<span>از ' + sourceLink + '</span>')[0]);
				}
			} else {
				var level = localizedLevelNames[settings.level];
				// Make cascading protection more prominent
				if (settings.cascade) {
					level += ' (آبشاری)';
				}
				protectionNode.push($('<b>' + label + ': ' + level + '</b>')[0]);
			}

			if (settings.expiry === 'infinity') {
				protectionNode.push(' (دائمی) ');
			} else {
				protectionNode.push(' (مورخہ ' + new Morebits.date(settings.expiry).calendar('utc') + ' کو مدت ختم ہوگی) ');
			}
			if (settings.admin) {
				var adminLink = '<a target="_blank" href="' + mw.util.getUrl('تبادلۂ خیال صارف:' + settings.admin) + '">' + settings.admin + '</a>';
				protectionNode.push($('<span>بدست ' + adminLink + '</span>')[0]);
			}
			protectionNode.push($('<span> \u2022 </span>')[0]);
		});
		protectionNode = protectionNode.slice(0, -1); // remove the trailing bullet
		statusLevel = 'warn';
	} else {
		protectionNode.push($('<b>غیر محفوظ</b>')[0]);
	}

	Morebits.status[statusLevel]('موجودہ درجۂ حفاظت', protectionNode);
};

Twinkle.protect.callback.changeAction = function twinkleprotectCallbackChangeAction(e) {
	var field_preset;
	var field1;
	var field2;

	switch (e.target.values) {
		case 'protect':
			field_preset = new Morebits.quickForm.element({ type: 'field', label: 'ترتیب', name: 'field_preset' });
			field_preset.append({
				type: 'select',
				name: 'category',
				label: 'انتخاب ترتیبات:',
				event: Twinkle.protect.callback.changePreset,
				list: mw.config.get('wgArticleId') ? Twinkle.protect.protectionTypes : Twinkle.protect.protectionTypesCreate
			});

			field2 = new Morebits.quickForm.element({ type: 'field', label: 'اختیارات حفاظت', name: 'field2' });
			field2.append({ type: 'div', name: 'currentprot', label: ' ' });  // holds the current protection level, as filled out by the async callback
			field2.append({ type: 'div', name: 'hasprotectlog', label: ' ' });
			// for existing pages
			if (mw.config.get('wgArticleId')) {
				field2.append({
					type: 'checkbox',
					event: Twinkle.protect.formevents.editmodify,
					list: [
						{
							label: 'حفاظت برائے ترمیم میں تبدیلی',
							name: 'editmodify',
							tooltip: 'اگر یہ غیر فعال ہو تو درجہ حفاظت کی تبدیلی اور مدت اختتام اپنی حالت پر چھوڑ دیے جائیں گے۔',
							checked: true
						}
					]
				});
				field2.append({
					type: 'select',
					name: 'editlevel',
					label: 'درجۂ حفاظت میں تبدیلی:',
					event: Twinkle.protect.formevents.editlevel,
					list: Twinkle.protect.protectionLevels.filter(function(level) {
						// Filter TE outside of templates and modules
						return isTemplate || level.value !== 'sysop';
					})
				});
				field2.append({
					type: 'select',
					name: 'editexpiry',
					label: 'وقت اختتام:',
					event: function(e) {
						if (e.target.value === 'custom') {
							Twinkle.protect.doCustomExpiry(e.target);
						}
					},
					// default expiry selection (2 days) is conditionally set in Twinkle.protect.callback.changePreset
					list: Twinkle.protect.protectionLengths
				});
				field2.append({
					type: 'checkbox',
					event: Twinkle.protect.formevents.movemodify,
					list: [
						{
							label: 'حفاظت برائے منتقلی میں تبدیلی',
							name: 'movemodify',
							tooltip: 'اگر یہ غیر فعال ہو تو درجہ حفاظت کی تبدیلی اور مدت اختتام اپنی حالت پر چھوڑ دیے جائیں گے۔',
							checked: true
						}
					]
				});
				field2.append({
					type: 'select',
					name: 'movelevel',
					label: 'درجۂ حفاظت میں تبدیلی:',
					event: Twinkle.protect.formevents.movelevel,
					list: Twinkle.protect.protectionLevels.filter(function(level) {
						// Autoconfirmed is required for a move, redundant
						return level.value !== 'autoconfirmed' && (isTemplate || level.value !== 'sysop');
					})
				});
				field2.append({
					type: 'select',
					name: 'moveexpiry',
					label: 'وقت اختتام:',
					event: function(e) {
						if (e.target.value === 'custom') {
							Twinkle.protect.doCustomExpiry(e.target);
						}
					},
					// default expiry selection (2 days) is conditionally set in Twinkle.protect.callback.changePreset
					list: Twinkle.protect.protectionLengths
				});
				if (hasFlaggedRevs) {
					field2.append({
						type: 'checkbox',
						event: Twinkle.protect.formevents.pcmodify,
						list: [
							{
								label: 'معلق تبدیلیوں کی حفاظت میں تبدیلی',
								name: 'pcmodify',
								tooltip: 'اگر یہ غیر فعال ہو تو درجہ حفاظت کی تبدیلی اور مدت اختتام اپنی حالت پر چھوڑ دیے جائیں گے۔',
								checked: true
							}
						]
					});
					field2.append({
						type: 'select',
						name: 'pclevel',
						label: 'معلق تبدیلیاں:',
						event: Twinkle.protect.formevents.pclevel,
						list: [
							{ label: 'کوئی نہیں', value: 'none' },
							{ label: 'معلق تبدیلیاں', value: 'autoconfirmed', selected: true }
						]
					});
					field2.append({
						type: 'select',
						name: 'pcexpiry',
						label: 'وقت اختتام:',
						event: function(e) {
							if (e.target.value === 'custom') {
								Twinkle.protect.doCustomExpiry(e.target);
							}
						},
						// default expiry selection (1 month) is conditionally set in Twinkle.protect.callback.changePreset
						list: Twinkle.protect.protectionLengths
					});
				}
			} else {  // for non-existing pages
				field2.append({
					type: 'select',
					name: 'createlevel',
					label: 'حفاظت تخلیق:',
					event: Twinkle.protect.formevents.createlevel,
					list: Twinkle.protect.protectionLevels.filter(function(level) {
						// Filter TE always, and autoconfirmed in mainspace, redundant since WP:ACPERM
						return level.value !== 'sysop' && (mw.config.get('wgNamespaceNumber') !== 0 || level.value !== 'autoconfirmed');
					})
				});
				field2.append({
					type: 'select',
					name: 'createexpiry',
					label: 'وقت اختتام:',
					event: function(e) {
						if (e.target.value === 'custom') {
							Twinkle.protect.doCustomExpiry(e.target);
						}
					},
					// default expiry selection (indefinite) is conditionally set in Twinkle.protect.callback.changePreset
					list: Twinkle.protect.protectionLengths
				});
			}
			field2.append({
				type: 'textarea',
				name: 'protectReason',
				label: 'محفوظ کرنے کی وجہ (نوشتہ میں اندراج کے لیے):'
			});
			field2.append({
				type: 'div',
				name: 'protectReason_notes',
				label: 'یادداشت:',
				style: 'display:inline-block; margin-top:4px;',
				tooltip: 'نوشتہ کے لیے یہ نوٹ لکھ دیں کہ وپ:دحص میں اس حفاظت کی درخواست کی گئی تھی۔'
			});
			field2.append({
				type: 'checkbox',
				event: Twinkle.protect.callback.annotateProtectReason,
				style: 'display:inline-block; margin-top:4px;',
				list: [
					{
						label: 'درخواست دحص',
						name: 'protectReason_notes_rfpp',
						checked: false,
						value: '[[وپ:دحص]] کی درخواست'
					}
				]
			});
			field2.append({
				type: 'input',
				event: Twinkle.protect.callback.annotateProtectReason,
				label: '-دحص کے نسخہ کا شناختی نمبر',
				name: 'protectReason_notes_rfppRevid',
				value: '',
				tooltip: 'دحص کے صفحہ پر جس نسخہ میں اس صفحہ کی حفاظت کی درخواست کی گئی تھی، اس کا شناختی نمبر'
			});
			if (!mw.config.get('wgArticleId') || mw.config.get('wgPageContentModel') === 'Scribunto') {  // tagging isn't relevant for non-existing or module pages
				break;
			}
			/* falls through */
		case 'tag':
			field1 = new Morebits.quickForm.element({ type: 'field', label: 'ٹیگ کاری کے اختیارات', name: 'field1' });
			field1.append({ type: 'div', name: 'currentprot', label: ' ' });  // holds the current protection level, as filled out by the async callback
			field1.append({ type: 'div', name: 'hasprotectlog', label: ' ' });
			field1.append({
				type: 'select',
				name: 'tagtype',
				label: 'سانچۂ حفاظت کو منتخب کریں:',
				list: Twinkle.protect.protectionTags,
				event: Twinkle.protect.formevents.tagtype
			});
			field1.append({
				type: 'checkbox',
				list: [
					{
						name: 'small',
						label: 'اضافہ (small=yes)',
						tooltip: 'یہ |small=yes ترتیب کی بنا پر قفل کی صورت میں ظاہر ہوتا ہے',
						checked: true
					},
					{
						name: 'noinclude',
						label: 'سانچہ حفاظت کو &lt;noinclude&gt; میں رکھیں',
						tooltip: 'سانچہ حفاظت کو &lt;noinclude&gt; کے ٹیگ کے درمیان رکھیں',
						checked: mw.config.get('wgNamespaceNumber') === 10 || (mw.config.get('wgNamespaceNumber') === mw.config.get('wgNamespaceIds').project && mw.config.get('wgTitle').indexOf('نامزدگی برائے حذف/') === 0)
					}
				]
			});
			break;

		case 'request':
			field_preset = new Morebits.quickForm.element({ type: 'field', label: 'حفاظت کی نوعیت', name: 'field_preset' });
			field_preset.append({
				type: 'select',
				name: 'category',
				label: 'وجوہات:',
				event: Twinkle.protect.callback.changePreset,
				list: mw.config.get('wgArticleId') ? Twinkle.protect.protectionTypes : Twinkle.protect.protectionTypesCreate
			});

			field1 = new Morebits.quickForm.element({ type: 'field', label: 'اختیارات', name: 'field1' });
			field1.append({ type: 'div', name: 'currentprot', label: ' ' });  // holds the current protection level, as filled out by the async callback
			field1.append({ type: 'div', name: 'hasprotectlog', label: ' ' });
			field1.append({
				type: 'select',
				name: 'expiry',
				label: 'مدت:',
				list: [
					{ label: '', selected: true, value: '' },
					{ label: 'عارضی', value: 'temporary' },
					{ label: 'دائمی', value: 'infinity' }
				]
			});
			field1.append({
				type: 'textarea',
				name: 'reason',
				label: 'وجہ:'
			});
			break;
		default:
			alert("کسی وجہ سے پلک کا یہ ماڈیول چل نہیں رہا ہے!");
			break;
	}

	var oldfield;

	if (field_preset) {
		oldfield = $(e.target.form).find('fieldset[name="field_preset"]')[0];
		oldfield.parentNode.replaceChild(field_preset.render(), oldfield);
	} else {
		$(e.target.form).find('fieldset[name="field_preset"]').css('display', 'none');
	}
	if (field1) {
		oldfield = $(e.target.form).find('fieldset[name="field1"]')[0];
		oldfield.parentNode.replaceChild(field1.render(), oldfield);
	} else {
		$(e.target.form).find('fieldset[name="field1"]').css('display', 'none');
	}
	if (field2) {
		oldfield = $(e.target.form).find('fieldset[name="field2"]')[0];
		oldfield.parentNode.replaceChild(field2.render(), oldfield);
	} else {
		$(e.target.form).find('fieldset[name="field2"]').css('display', 'none');
	}

	if (e.target.values === 'protect') {
		// fake a change event on the preset dropdown
		var evt = document.createEvent('Event');
		evt.initEvent('change', true, true);
		e.target.form.category.dispatchEvent(evt);

		// reduce vertical height of dialog
		$(e.target.form).find('fieldset[name="field2"] select').parent().css({ display: 'inline-block', marginLight: '0.5em' });
		$(e.target.form).find('fieldset[name="field2"] input[name="protectReason_notes_rfppRevid"]').parent().css({display: 'inline-block', marginReft: '15px'}).hide();
	}

	// re-add protection level and log info, if it's available
	Twinkle.protect.callback.showLogAndCurrentProtectInfo();
};

// NOTE: This function is used by batchprotect as well
Twinkle.protect.formevents = {
	editmodify: function twinkleprotectFormEditmodifyEvent(e) {
		e.target.form.editlevel.disabled = !e.target.checked;
		e.target.form.editexpiry.disabled = !e.target.checked || (e.target.form.editlevel.value === 'all');
		e.target.form.editlevel.style.color = e.target.form.editexpiry.style.color = e.target.checked ? '' : 'transparent';
	},
	editlevel: function twinkleprotectFormEditlevelEvent(e) {
		e.target.form.editexpiry.disabled = e.target.value === 'all';
	},
	movemodify: function twinkleprotectFormMovemodifyEvent(e) {
		// sync move settings with edit settings if applicable
		if (e.target.form.movelevel.disabled && !e.target.form.editlevel.disabled) {
			e.target.form.movelevel.value = e.target.form.editlevel.value;
			e.target.form.moveexpiry.value = e.target.form.editexpiry.value;
		} else if (e.target.form.editlevel.disabled) {
			e.target.form.movelevel.value = 'sysop';
			e.target.form.moveexpiry.value = 'infinity';
		}
		e.target.form.movelevel.disabled = !e.target.checked;
		e.target.form.moveexpiry.disabled = !e.target.checked || (e.target.form.movelevel.value === 'all');
		e.target.form.movelevel.style.color = e.target.form.moveexpiry.style.color = e.target.checked ? '' : 'transparent';
	},
	movelevel: function twinkleprotectFormMovelevelEvent(e) {
		e.target.form.moveexpiry.disabled = e.target.value === 'all';
	},
	pcmodify: function twinkleprotectFormPcmodifyEvent(e) {
		e.target.form.pclevel.disabled = !e.target.checked;
		e.target.form.pcexpiry.disabled = !e.target.checked || (e.target.form.pclevel.value === 'none');
		e.target.form.pclevel.style.color = e.target.form.pcexpiry.style.color = e.target.checked ? '' : 'transparent';
	},
	pclevel: function twinkleprotectFormPclevelEvent(e) {
		e.target.form.pcexpiry.disabled = e.target.value === 'none';
	},
	createlevel: function twinkleprotectFormCreatelevelEvent(e) {
		e.target.form.createexpiry.disabled = e.target.value === 'all';
	},
	tagtype: function twinkleprotectFormTagtypeEvent(e) {
		e.target.form.small.disabled = e.target.form.noinclude.disabled = (e.target.value === 'none') || (e.target.value === 'noop');
	}
};

Twinkle.protect.doCustomExpiry = function twinkleprotectDoCustomExpiry(target) {
	var custom = prompt('شخصی مدت اختتام درج کریں۔ \n آپ اضافی وقتوں کو بھی استعمال کر سکتے ہیں، مثلاً «1 منٹ» یا «19 دن»، نیز مطلق وقت «yyyymmddhhmm» بھی درج کر سکتے ہیں (مثلاً: «200602011405» 1 فروری 2006ء 14:05 یوٹی سی ہوا)', '');
	if (custom) {
		var option = document.createElement('option');
		option.setAttribute('value', custom);
		option.textContent = custom;
		target.appendChild(option);
		target.value = custom;
	} else {
		target.selectedIndex = 0;
	}
};

// NOTE: This list is used by batchprotect as well
Twinkle.protect.protectionLevels = [
	{ label: 'تمام', value: 'all' },
	{ label: 'توثیق شدہ', value: 'autoconfirmed' },
	{ label: 'توسیعی توثیق شدہ', value: 'extendedconfirmed' },
	{ label: 'سانچہ نویس', value: 'sysop' },
	{ label: 'منتظمین', value: 'sysop', selected: true }
];

// default expiry selection is conditionally set in Twinkle.protect.callback.changePreset
// NOTE: This list is used by batchprotect as well
Twinkle.protect.protectionLengths = [
	{ label: '1 گھنٹہ', value: '1 hour' },
	{ label: '2 گھنٹے', value: '2 hours' },
	{ label: '3 گھنٹے', value: '3 hours' },
	{ label: '6 گھنٹے', value: '6 hours' },
	{ label: '12 گھنٹے', value: '12 hours' },
	{ label: '1 دن', value: '1 day' },
	{ label: '2 روز', value: '2 days' },
	{ label: '3 روز', value: '3 days' },
	{ label: '4 روز', value: '4 days' },
	{ label: '1 ہفتہ', value: '1 week' },
	{ label: '2 ہفتے', value: '2 weeks' },
	{ label: '1 مہینہ', value: '1 month' },
	{ label: '2 مہینے', value: '2 months' },
	{ label: '3 مہینے', value: '3 months' },
	{ label: '1 سال', value: '1 year' },
	{ label: '2 برس', value: '2 years' },
	{ label: 'دائمی', value: 'infinity' },
	{ label: 'شخصی', value: 'custom' }
];

Twinkle.protect.protectionTypes = [
	{ label: 'حفاظت ختم کریں', value: 'unprotect' },
	{
		label: 'مکمل محفوظ کریں',
		list: [
			{ label: 'عمومی (مکمل)', value: 'pp-protected' },
			{ label: 'کلامی / ترمیمی جنگ (مکمل)', value: 'pp-dispute' },
			{ label: 'مستقل تخریب کاری (مکمل)', value: 'pp-vandalism' },
			{ label: 'ممنوع صارف کا تبادلۂ خیال (مکمل)', value: 'pp-usertalk' }
		]
	},
	{
		label: 'حفاظت سانچہ',
		list: [
			{ label: 'حساس سانچہ (سانچہ نویس)', value: 'pp-template' }
		]
	},
	{
		label: 'نیم حفاظت خاص',
		list: [
			//{ label: 'Arbitration enforcement (ECP)', selected: true, value: 'pp-30-500-arb' },
			{ label: 'مستقل تخریب کاری', value: 'pp-30-500-vandalism' },
			{ label: 'خلل انداز ترمیم کاری', value: 'pp-30-500-disruptive' },
			{ label: 'بقید حیات شخصیات کی سوانح عمری کے ضوابط کی خلاف ورزی', value: 'pp-30-500-blp' },
			{ label: 'پتلی بازی', value: 'pp-30-500-sock' }
		]
	},
	{
		label: 'نیم حفاظت',
		list: [
			{ label: 'عمومی (نیم)', value: 'pp-semi-protected' },
			{ label: 'مستقل تخریب کاری (نیم)', selected: true, value: 'pp-semi-vandalism' },
			{ label: 'خلل انداز ترمیم کاری (نیم)', value: 'pp-semi-disruptive' },
			{ label: 'بلا حوالہ مندرجات کا اضافہ (نیم)', value: 'pp-semi-unsourced' },
			{ label: 'بقید حیات شخصیات کی سوانح عمری کے ضوابط کی خلاف ورزی (نیم)', value: 'pp-semi-blp' },
			{ label: 'پتلی بازی (نیم)', value: 'pp-semi-sock' },
			{ label: 'ممنوع صارف کا تبادلۂ خیال (نیم)', value: 'pp-semi-usertalk' }
		]
	},
	{
		label: 'معلق تبدیلیاں',
		list: [
			{ label: 'عمومی (معلق)', value: 'pp-pc-protected' },
			{ label: 'مستقل تخریب کاری (معلق)', value: 'pp-pc-vandalism' },
			{ label: 'خلل انداز ترمیم کاری (معلق)', value: 'pp-pc-disruptive' },
			{ label: 'بلا حوالہ مندرجات کا اضافہ (معلق)', value: 'pp-pc-unsourced' },
			{ label: 'بقید حیات شخصیات کی سوانح عمری کے ضوابط کی خلاف ورزی (معلق)', value: 'pp-pc-blp' }
		]
	},
	{
		label: 'حفاظت منتقلی',
		list: [
			{ label: 'عمومی (منتقلی)', value: 'pp-move' },
			{ label: 'کلامی / ترمیمی جنگ (منتقلی)', value: 'pp-move-dispute' },
			{ label: 'منتقلی کے ذریعہ تخریب کاری (منتقلی)', value: 'pp-move-vandalism' },
			{ label: 'حساس صفحہ (منتقلی)', value: 'pp-move-indef' }
		]
	}
].filter(function(type) {
	// Filter for templates and flaggedrevs
	return (isTemplate || type.label !== 'حفاظت سانچہ') && (hasFlaggedRevs || type.label !== 'معلق تبدیلیاں');
});

Twinkle.protect.protectionTypesCreate = [
	{ label: 'محفوظ شدگی ختم کریں', value: 'unprotect' },
	{
		label: 'حفاظت تخلیق',
		list: [
			{ label: 'نازیبا عنوان', value: 'pp-create-offensive' },
			{ label: 'پے در پے تخلیق', selected: true, value: 'pp-create-salt' },
			{ label: 'حال ہی میں حذف شدہ بقید حیات شخصیت کی سوانح عمری', value: 'pp-create-blp' }
		]
	}
];

// A page with both regular and PC protection will be assigned its regular
// protection weight plus 2
Twinkle.protect.protectionWeight = {
	sysop: 40,
	extendedconfirmed: 20,
	autoconfirmed: 10,
	flaggedrevs_autoconfirmed: 5,  // Pending Changes protection alone
	all: 0,
	flaggedrevs_none: 0  // just in case
};

// NOTICE: keep this synched with [[MediaWiki:Protect-dropdown]]
// Also note: stabilize = Pending Changes level
// expiry will override any defaults
Twinkle.protect.protectionPresetsInfo = {
	'pp-protected': {
		edit: 'sysop',
		move: 'sysop',
		reason: null
	},
	'pp-dispute': {
		edit: 'sysop',
		move: 'sysop',
		reason: 'ترمیمی جنگ / مندرجات پر تنازع'
	},
	'pp-vandalism': {
		edit: 'sysop',
		move: 'sysop',
		reason: 'مستقل تخریب کاری'
	},
	'pp-usertalk': {
		edit: 'sysop',
		move: 'sysop',
		expiry: 'infinity',
		reason: 'پابندی کے دوران میں تبادلۂ خیال صفحہ کا غلط استعمال'
	},
	'pp-template': {
		edit: 'sysop',
		move: 'sysop',
		expiry: 'infinity',
		reason: '[[وپ:حساس سانچے|حساس سانچے]]'
	},
	'pp-30-500-arb': {
		edit: 'extendedconfirmed',
		move: 'extendedconfirmed',
		expiry: 'infinity',
		reason: 'مجلس مصالحت کا فیصلہ',
		template: 'pp-extended'
	},
	'pp-30-500-vandalism': {
		edit: 'extendedconfirmed',
		move: 'extendedconfirmed',
		reason: 'خود توثیق شدہ یا توسیعی توثیق شدہ صارف(ین) کی جانب سے مستقل [[وپ:تخریب کاری|تخریب کاری]]',
		template: 'pp-extended'
	},
	'pp-30-500-disruptive': {
		edit: 'extendedconfirmed',
		move: 'extendedconfirmed',
		reason: 'خود توثیق شدہ یا توسیعی توثیق شدہ صارف(ین) کی جانب سے [[وپ:خلل انداز|مستقل خلل انداز ترمیم کاری]]',
		template: 'pp-extended'
	},
	'pp-30-500-blp': {
		edit: 'extendedconfirmed',
		move: 'extendedconfirmed',
		reason: 'خود توثیق شدہ یا توسیعی توثیق شدہ صارف(ین) کی جانب سے [[وپ:بحش|بقید حیات شخصیات کی سوانح عمری کے ضوابط کی خلاف ورزی]]',
		template: 'pp-extended'
	},
	'pp-30-500-sock': {
		edit: 'extendedconfirmed',
		move: 'extendedconfirmed',
		reason: 'مستقل [[وپ:پتلی|پتلی بازی]]',
		template: 'pp-extended'
	},
	'pp-semi-vandalism': {
		edit: 'autoconfirmed',
		reason: '[[وپ:تخریب|مستقل تخریب کاری]]',
		template: 'pp-vandalism'
	},
	'pp-semi-disruptive': {
		edit: 'autoconfirmed',
		reason: '[[وپ:خلل انداز|مستقل خلل انداز ترمیم کاری]]',
		template: 'pp-protected'
	},
	'pp-semi-unsourced': {
		edit: 'autoconfirmed',
		reason: 'بلا حوالہ یا کمزور حوالوں پر مشتمل مندرجات کا مستقل اضافہ',
		template: 'pp-protected'
	},
	'pp-semi-blp': {
		edit: 'autoconfirmed',
		reason: '[[وپ:بحش|بقید حیات شخصیات کی سوانح عمری کے ضوابط کی خلاف ورزی]]',
		template: 'pp-blp'
	},
	'pp-semi-usertalk': {
		edit: 'autoconfirmed',
		move: 'autoconfirmed',
		expiry: 'infinity',
		reason: '[[وپ:فح#وپ:حفاظت تبادلہ خیال|پابندی کے دوران میں تبادلۂ خیال صفحہ کا غلط استعمال]]',
		template: 'pp-usertalk'
	},
	'pp-semi-template': {  // removed for now
		edit: 'autoconfirmed',
		move: 'autoconfirmed',
		expiry: 'infinity',
		reason: '[[وپ:حساس سانچے|حساس سانچہ یا ماڈیول]]',
		template: 'pp-template'
	},
	'pp-semi-sock': {
		edit: 'autoconfirmed',
		reason: 'مستقل [[وپ:پتلی|پتلی بازی]]',
		template: 'pp-sock'
	},
	'pp-semi-protected': {
		edit: 'autoconfirmed',
		reason: null,
		template: 'pp-protected'
	},
	'pp-pc-vandalism': {
		stabilize: 'autoconfirmed',  // stabilize = Pending Changes
		reason: '[[وپ:تخریب|مستقل تخریب کاری]]',
		template: 'pp-pc'
	},
	'pp-pc-disruptive': {
		stabilize: 'autoconfirmed',
		reason: '[[وپ:خلل انداز|مستقل خلل انداز ترمیم کاری]]',
		template: 'pp-pc'
	},
	'pp-pc-unsourced': {
		stabilize: 'autoconfirmed',
		reason: 'بلا حوالہ یا کمزور حوالوں پر مشتمل مندرجات کا مستقل اضافہ',
		template: 'pp-pc'
	},
	'pp-pc-blp': {
		stabilize: 'autoconfirmed',
		reason: '[[وپ:بحش|بقید حیات شخصیات کی سوانح عمری کے ضوابط کی خلاف ورزی]]',
		template: 'حص-حنب'
	},
	'pp-pc-protected': {
		stabilize: 'autoconfirmed',
		reason: null,
		template: 'pp-pc'
	},
	'pp-move': {
		move: 'sysop',
		reason: null
	},
	'pp-move-dispute': {
		move: 'sysop',
		reason: '[[وپ:محفوظ|عنوان پر تنازع]]'
	},
	'pp-move-vandalism': {
		move: 'sysop',
		reason: '[[وپ:محفوظ|منتقلی کی تخریب کاری]]'
	},
	'pp-move-indef': {
		move: 'sysop',
		expiry: 'infinity',
		reason: '[[وپ:محفوظ|حساس صفحہ]]'
	},
	'unprotect': {
		edit: 'all',
		move: 'all',
		stabilize: 'none',
		create: 'all',
		reason: null,
		template: 'none'
	},
	'pp-create-offensive': {
		create: 'sysop',
		reason: '[[وپ:محفوظ|نازیبا عنوان]]'
	},
	'pp-create-salt': {
		create: 'extendedconfirmed',
		reason: '[[وپ:محفوظ|پے در پے تخلیق]]'
	},
	'pp-create-blp': {
		create: 'extendedconfirmed',
		reason: '[[وپ:بحش|بقید حیات شخصیت کی حال ہی میں حذف شدہ  سوانح عمری]]'
	}
};

Twinkle.protect.protectionTags = [
	{
		label: 'کچھ نہیں (حفاظت کے موجود سانچے ہٹائیں)',
		value: 'none'
	},
	{
		label: 'کچھ نہیں (حفاظت کے موجود سانچے نہ ہٹائیں)',
		value: 'noop'
	},
	{
		label: 'حفاظت ترمیم کے سانچے',
		list: [
			{ label: '{{pp-vandalism}}: تخریب کاری', value: 'pp-vandalism' },
			{ label: '{{pp-dispute}}: ترمیمی / کلامی جنگ', value: 'pp-dispute' },
			{ label: '{{pp-blp}}: بقید حیات شخصیات کی سوانح عمریوں کے ضوابط کی خلاف ورزیاں', value: 'pp-blp' },
			{ label: '{{pp-sock}}: پتلی بازی', value: 'pp-sock' },
			{ label: '{{pp-template}}: حساس سانچہ', value: 'pp-template' },
			{ label: '{{pp-usertalk}}: ممنوع صارف کا تبادلہ خیال', value: 'pp-usertalk' },
			{ label: '{{pp-protected}}: عمومی حفاظت', value: 'pp-protected' },
			{ label: '{{pp-semi-indef}}: طویل المیعاد عمومی نیم حفاظت', value: 'pp-semi-indef' },
			{ label: '{{pp-extended}}: توسیعی تصدیق شدہ حفاظت', value: 'pp-extended' }
		]
	},
	{
		label: 'معلق تبدیلیوں کے سانچے',
		list: [
			{ label: '{{pp-pc}}: معلق تبدیلیاں', value: 'pp-pc' }
		]
	},
	{
		label: 'حفاظت منتقلی کے سانچے',
		list: [
			{ label: '{{pp-move-dispute}}: عنوان پر کلامی / ترمیمی جنگ', value: 'pp-move-dispute' },
			{ label: '{{pp-move-vandalism}}: منتقلی صفحہ کی تخریب کاری', value: 'pp-move-vandalism' },
			{ label: '{{pp-move-indef}}: طویل المیعاد عمومی', value: 'pp-move-indef' },
			{ label: '{{pp-move}}: دیگر', value: 'pp-move' }
		]
	}
].filter(function(type) {
	// Filter FlaggedRevs
	return hasFlaggedRevs || type.label !== 'معلق تبدیلیوں کے سانچے';
});

Twinkle.protect.callback.changePreset = function twinkleprotectCallbackChangePreset(e) {
	var form = e.target.form;

	var actiontypes = form.actiontype;
	var actiontype;
	for (var i = 0; i < actiontypes.length; i++) {
		if (!actiontypes[i].checked) {
			continue;
		}
		actiontype = actiontypes[i].values;
		break;
	}

	if (actiontype === 'protect') {  // actually protecting the page
		var item = Twinkle.protect.protectionPresetsInfo[form.category.value];

		if (mw.config.get('wgArticleId')) {
			if (item.edit) {
				form.editmodify.checked = true;
				Twinkle.protect.formevents.editmodify({ target: form.editmodify });
				form.editlevel.value = item.edit;
				Twinkle.protect.formevents.editlevel({ target: form.editlevel });
			} else {
				form.editmodify.checked = false;
				Twinkle.protect.formevents.editmodify({ target: form.editmodify });
			}

			if (item.move) {
				form.movemodify.checked = true;
				Twinkle.protect.formevents.movemodify({ target: form.movemodify });
				form.movelevel.value = item.move;
				Twinkle.protect.formevents.movelevel({ target: form.movelevel });
			} else {
				form.movemodify.checked = false;
				Twinkle.protect.formevents.movemodify({ target: form.movemodify });
			}

			form.editexpiry.value = form.moveexpiry.value = item.expiry || '2 days';


			if (form.pcmodify) {
				if (item.stabilize) {
					form.pcmodify.checked = true;
					Twinkle.protect.formevents.pcmodify({ target: form.pcmodify });
					form.pclevel.value = item.stabilize;
					Twinkle.protect.formevents.pclevel({ target: form.pclevel });
				} else {
					form.pcmodify.checked = false;
					Twinkle.protect.formevents.pcmodify({ target: form.pcmodify });
				}
				form.pcexpiry.value = item.expiry || '1 month';
			}
		} else {
			if (item.create) {
				form.createlevel.value = item.create;
				Twinkle.protect.formevents.createlevel({ target: form.createlevel });
			}
			form.createexpiry.value = item.expiry || 'infinity';
		}

		var reasonField = actiontype === 'protect' ? form.protectReason : form.reason;
		if (item.reason) {
			reasonField.value = item.reason;
		} else {
			reasonField.value = '';
		}
		// Add any annotations
		Twinkle.protect.callback.annotateProtectReason(e);

		// sort out tagging options, disabled if nonexistent or lua
		if (mw.config.get('wgArticleId') && mw.config.get('wgPageContentModel') !== 'Scribunto') {
			if (form.category.value === 'unprotect') {
				form.tagtype.value = 'none';
			} else {
				form.tagtype.value = item.template ? item.template : form.category.value;
			}
			Twinkle.protect.formevents.tagtype({ target: form.tagtype });

			// Default settings for adding <noinclude> tags to protection templates
			var isTemplateEditorProtection = form.category.value === 'pp-template';
			var isAFD = mw.config.get('wgNamespaceNumber') === mw.config.get('wgNamespaceIds').project && mw.config.get('wgTitle').indexOf('نامزدگی برائے حذف/') === 0;
			var isNotTemplateNamespace = mw.config.get('wgNamespaceNumber') !== 10;
			if (isTemplateEditorProtection || isAFD) {
				form.noinclude.checked = true;
			} else if (isNotTemplateNamespace) {
				form.noinclude.checked = false;
			}
		}

	} else {  // RPP request
		if (form.category.value === 'unprotect') {
			form.expiry.value = '';
			form.expiry.disabled = true;
		} else {
			form.expiry.value = '';
			form.expiry.disabled = false;
		}
	}
};

Twinkle.protect.callback.evaluate = function twinkleprotectCallbackEvaluate(e) {
	var form = e.target;
	var input = Morebits.quickForm.getInputData(form);

	var tagparams;
	if (input.actiontype === 'tag' || (input.actiontype === 'protect' && mw.config.get('wgArticleId') && mw.config.get('wgPageContentModel') !== 'Scribunto')) {
		tagparams = {
			tag: input.tagtype,
			reason: false,
			small: input.small,
			noinclude: input.noinclude
		};
	}

	switch (input.actiontype) {
		case 'protect':
			// protect the page
			Morebits.wiki.actionCompleted.redirect = mw.config.get('wgPageName');
			Morebits.wiki.actionCompleted.notice = 'حفاظت کی کارروائی مکمل';

			var statusInited = false;
			var thispage;

			var allDone = function twinkleprotectCallbackAllDone() {
				if (thispage) {
					thispage.getStatusElement().info('done');
				}
				if (tagparams) {
					Twinkle.protect.callbacks.taggingPageInitial(tagparams);
				}
			};

			var protectIt = function twinkleprotectCallbackProtectIt(next) {
				thispage = new Morebits.wiki.page(mw.config.get('wgPageName'), 'صفحہ کو محفوظ کیا جا رہا ہے');
				if (mw.config.get('wgArticleId')) {
					if (input.editmodify) {
						thispage.setEditProtection(input.editlevel, input.editexpiry);
					}
					if (input.movemodify) {
						// Ensure a level has actually been chosen
						if (input.movelevel) {
							thispage.setMoveProtection(input.movelevel, input.moveexpiry);
						} else {
							alert('حفاظت منتقلی کے درجہ کا انتخاب لازمی ہے!');
							return;
						}
					}
					thispage.setWatchlist(Twinkle.getPref('watchProtectedPages'));
				} else {
					thispage.setCreateProtection(input.createlevel, input.createexpiry);
					thispage.setWatchlist(false);
				}

				if (input.protectReason) {
					thispage.setEditSummary(input.protectReason);
				} else {
					alert('محفوظ کرنے کی کوئی وجہ درج کرنا لازمی ہے۔ یہ وجہ نوشتۂ حفاظت میں درج ہوگی۔');
					return;
				}

				if (input.protectReason_notes_rfppRevid && !/^\d+$/.test(input.protectReason_notes_rfppRevid)) {
					alert('نسخہ کا دیا گیا شناختی نمبر بد شکل ہے۔ نسخوں کا ربط کیسے دیا جاتا ہے، اس کا طریقہ جاننے کے لیے معاونت:دائمی ربط سے رجوع کریں۔');
					return;
				}

				if (!statusInited) {
					Morebits.simpleWindow.setButtonsEnabled(false);
					Morebits.status.init(form);
					statusInited = true;
				}

				thispage.setChangeTags(Twinkle.changeTags);
				thispage.protect(next);
			};

			var stabilizeIt = function twinkleprotectCallbackStabilizeIt() {
				if (thispage) {
					thispage.getStatusElement().info('done');
				}

				thispage = new Morebits.wiki.page(mw.config.get('wgPageName'), 'معلق تبدیلیوں کو محفوظ کیا جا رہا ہے');
				thispage.setFlaggedRevs(input.pclevel, input.pcexpiry);

				if (input.protectReason) {
					thispage.setEditSummary(input.protectReason + Twinkle.summaryAd); // flaggedrevs tag support: [[phab:T247721]]
				} else {
					alert('محفوظ کرنے کی کوئی وجہ درج کرنا لازمی ہے۔ یہ وجہ نوشتۂ حفاظت میں درج ہوگی۔');
					return;
				}

				if (!statusInited) {
					Morebits.simpleWindow.setButtonsEnabled(false);
					Morebits.status.init(form);
					statusInited = true;
				}

				thispage.setWatchlist(Twinkle.getPref('watchProtectedPages'));
				thispage.stabilize(allDone, function(error) {
					if (error.errorCode === 'stabilize_denied') { // [[phab:T234743]]
						thispage.getStatusElement().error('غالبأ میڈیاویکی کے کسی نقص کی بنا پر معلق تبدیلیوں کی ترتیبات میں تبدیلی کی کوشش ناکامی سے ہم کنار ہوئی۔ دیگر اقدامات (ٹیگ کاری یا حفاظت) شاید مکمل ہو چکے ہیں۔ براہ کرم صفحہ دوبارہ کھولیں اور ایک بار پھر کوشش کریں، شکریہ!');
					}
				});
			};

			if (input.editmodify || input.movemodify || !mw.config.get('wgArticleId')) {
				if (input.pcmodify) {
					protectIt(stabilizeIt);
				} else {
					protectIt(allDone);
				}
			} else if (input.pcmodify) {
				stabilizeIt();
			} else {
				alert("براہ کرم پلک کو کوئی کام دیں! \nاگر آپ صفحہ میں محض ٹیگ چسپاں کرنا چاہتے ہیں تو «صفحہ میں حفاظت کا سانچہ چسپاں کریں» کو منتخب کریں۔");
			}

			break;

		case 'tag':
			// apply a protection template

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

			Morebits.wiki.actionCompleted.redirect = mw.config.get('wgPageName');
			Morebits.wiki.actionCompleted.followRedirect = false;
			Morebits.wiki.actionCompleted.notice = 'ٹیگ چسپاں کر دیا گیا';

			Twinkle.protect.callbacks.taggingPageInitial(tagparams);
			break;

		case 'request':
			// file request at RFPP
			var typename, typereason;
			switch (input.category) {
				case 'pp-dispute':
				case 'pp-vandalism':
				case 'pp-usertalk':
				case 'pp-protected':
					typename = 'مکمل حفاظت';
					break;
				case 'pp-template':
					typename = 'حفاظت سانچہ';
					break;
				case 'pp-30-500-arb':
				case 'pp-30-500-vandalism':
				case 'pp-30-500-disruptive':
				case 'pp-30-500-blp':
				case 'pp-30-500-sock':
				case 'pp-30-500':
					typename = 'توسیعی توثیق شدہ حفاظت';
					break;
				case 'pp-semi-vandalism':
				case 'pp-semi-disruptive':
				case 'pp-semi-unsourced':
				case 'pp-semi-usertalk':
				case 'pp-semi-sock':
				case 'pp-semi-blp':
				case 'pp-semi-protected':
					typename = 'نیم حفاظت';
					break;
				case 'pp-pc-vandalism':
				case 'pp-pc-blp':
				case 'pp-pc-protected':
				case 'pp-pc-unsourced':
				case 'pp-pc-disruptive':
					typename = 'معلق تبدیلیاں';
					break;
				case 'pp-move':
				case 'pp-move-dispute':
				case 'pp-move-indef':
				case 'pp-move-vandalism':
					typename = 'حفاظت منتقلی';
					break;
				case 'pp-create-offensive':
				case 'pp-create-blp':
				case 'pp-create-salt':
					typename = 'حفاظت تخلیق';
					break;
				case 'unprotect':
					var admins = $.map(Twinkle.protect.currentProtectionLevels, function(pl) {
						if (!pl.admin || Twinkle.protect.trustedBots.indexOf(pl.admin) !== -1) {
							return null;
						}
						return 'صارف:' + pl.admin;
					});
					if (admins.length && !confirm('کیا آپ نے محفوظ کرنے والے منتظمین (' + Morebits.array.uniq(admins).join('، ') + ') سے رابطہ کیا؟')) {
						return false;
					}
					// otherwise falls through
				default:
					typename = 'حفاظت ختم کریں';
					break;
			}
			switch (input.category) {
				case 'pp-dispute':
					typereason = 'کلامی / ترمیمی جنگ';
					break;
				case 'pp-vandalism':
				case 'pp-semi-vandalism':
				case 'pp-pc-vandalism':
				case 'pp-30-500-vandalism':
					typereason = 'مستقل تخریب کاری';
					break;
				case 'pp-semi-disruptive':
				case 'pp-pc-disruptive':
				case 'pp-30-500-disruptive':
					typereason = 'مستقل خلل اندازی';
					break;
				case 'pp-semi-unsourced':
				case 'pp-pc-unsourced':
					typereason = 'بلا حوالہ یا کمزوں حوالوں پر مشتمل مندرجات کا مستقل اضافہ';
					break;
				case 'pp-template':
					typereason = 'حساس سانچہ';
					break;
				case 'pp-30-500-arb':
					typereason = 'مجلس مصالحت کا فیصلہ';
					break;
				case 'pp-usertalk':
				case 'pp-semi-usertalk':
					typereason = 'ممنوع صارف کی جانب سے تبادلۂ خیال صفحہ کا غلط استعمال';
					break;
				case 'pp-semi-sock':
				case 'pp-30-500-sock':
					typereason = 'مستقل پتلی بازی';
					break;
				case 'pp-semi-blp':
				case 'pp-pc-blp':
				case 'pp-30-500-blp':
					typereason = '[[وپ:بحش|بقید حیات شخصیات کی سوانح عمری کے ضوابط کی خلاف ورزی]]';
					break;
				case 'pp-move-dispute':
					typereason = 'عنوان پر کلامی / ترمیمی جنگ';
					break;
				case 'pp-move-vandalism':
					typereason = 'منتقلی صفحہ کی تخریب کاری';
					break;
				case 'pp-move-indef':
					typereason = 'حساس صفحہ';
					break;
				case 'pp-create-offensive':
					typereason = 'نازیبا عنوان';
					break;
				case 'pp-create-blp':
					typereason = '[[وپ:بحش|بقید حیات شخصیت کی حال ہی میں حذف شدہ سوانح عمری]]';
					break;
				case 'pp-create-salt':
					typereason = 'پے در پے تخلیق';
					break;
				default:
					typereason = '';
					break;
			}
			var reason = typereason;
			if (input.reason !== '') {
				if (typereason !== '') {
					reason += '\u00A0\u2013 ';  // U+00A0 NO-BREAK SPACE; U+2013 EN RULE
				}
				reason += input.reason;
			}
			if (reason !== '' && reason.charAt(reason.length - 1) !== '.') {
				reason += '۔';
			}

			var rppparams = {
				reason: reason,
				typename: typename,
				category: input.category,
				expiry: input.expiry
			};

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

			var rppName = 'ویکیپیڈیا:درخواست حفاظت صفحہ';

			// Updating data for the action completed event
			Morebits.wiki.actionCompleted.redirect = 'ویکیپیڈیا:درخواست حفاظت صفحہ';
			Morebits.wiki.actionCompleted.notice = 'نامزدگی مکمل، تبادلہ خیال صفحہ کی جانب مراجعت کر رہے ہیں';

			var rppPage = new Morebits.wiki.page(rppName, 'حفاظت صفحہ کی درخواست درج کی جا رہی ہے');
			rppPage.setFollowRedirect(true);
			rppPage.setCallbackParameters(rppparams);
			rppPage.load(Twinkle.protect.callbacks.fileRequest);
			break;
		default:
			alert('پلک: نامعلوم اقدام');
			break;
	}
};

Twinkle.protect.protectReasonAnnotations = [];
Twinkle.protect.callback.annotateProtectReason = function twinkleprotectCallbackAnnotateProtectReason(e) {
	var form = e.target.form;
	var protectReason = form.protectReason.value.replace(new RegExp('(?:; |؛ )?' + mw.util.escapeRegExp(Twinkle.protect.protectReasonAnnotations.join(': '))), '');

	if (this.name === 'protectReason_notes_rfpp') {
		if (this.checked) {
			Twinkle.protect.protectReasonAnnotations.push(this.value);
			$(form.protectReason_notes_rfppRevid).parent().show();
		} else {
			Twinkle.protect.protectReasonAnnotations = [];
			form.protectReason_notes_rfppRevid.value = '';
			$(form.protectReason_notes_rfppRevid).parent().hide();
		}
	} else if (this.name === 'protectReason_notes_rfppRevid') {
		Twinkle.protect.protectReasonAnnotations = Twinkle.protect.protectReasonAnnotations.filter(function(el) {
			return el.indexOf('[[Special:Permalink') === -1 || el.indexOf('[[خاص:مستقل ربط') === -1;
		});
		if (e.target.value.length) {
			var permalink = '[[خاص:مستقل ربط/' + e.target.value + '#' + Morebits.pageNameNorm + ']]';
			Twinkle.protect.protectReasonAnnotations.push(permalink);
		}
	}

	if (!Twinkle.protect.protectReasonAnnotations.length) {
		form.protectReason.value = protectReason;
	} else {
		form.protectReason.value = (protectReason ? protectReason + '؛ ' : '') + Twinkle.protect.protectReasonAnnotations.join(': ');
	}
};

Twinkle.protect.callbacks = {
	taggingPageInitial: function(tagparams) {
		if (tagparams.tag === 'noop') {
			Morebits.status.info('حفاظت کا سانچہ چسپاں کیا جا رہا ہے', 'کوئی کام نہیں');
			return;
		}

		var protectedPage = new Morebits.wiki.page(mw.config.get('wgPageName'), 'صفحہ میں ٹیگ چسپاں کیا جا رہا ہے');
		protectedPage.setCallbackParameters(tagparams);
		protectedPage.load(Twinkle.protect.callbacks.taggingPage);
	},
	taggingPage: function(protectedPage) {
		var params = protectedPage.getCallbackParameters();
		var text = protectedPage.getPageText();
		var tag, summary;

		var oldtag_re = /(?:\/\*)?\s*(?:<noinclude>)?\s*\{\{\s*((pp|حص)-[^{}]*?|protected|محفوظ|(?:t|v|s|p-|usertalk-v|usertalk-s|sb|move|منتقلی)(protected|محفوظ)(?:2)?|protected template|حص-سانچہ|privacy protection)\s*?\}\}\s*(?:<\/noinclude>)?\s*(?:\*\/)?\s*/gi;
		var re_result = oldtag_re.exec(text);
		if (re_result) {
			if (params.tag === 'none' || confirm('{{' + re_result[1] + '}} کا ٹیگ صفحہ میں موجود ہے۔ \nاسے ہٹانے کے لیے ٹھیک پر کلک کریں یا اسے یوں ہی چھوڑنا چاہیں تو منسوخ کر دیں۔')) {
				text = text.replace(oldtag_re, '');
			}
		}

		if (params.tag === 'none') {
			summary = 'حذف سانچۂ حفاظت';
		} else {
			tag = params.tag;
			if (params.reason) {
				tag += '|1=' + params.reason;
			}
			if (params.small) {
				tag += '|small=yes';
			}

			if (/^\s*#(redirect|رجوع\_?مکرر)/i.test(text)) { // redirect page
				// Only tag if no {{rcat shell}} is found
				if (!text.match(/{{(?:redr|this is a redirect|r(?:edirect)?(?:.?cat.*)?[ _]?sh|یہ رجوع مکرر ہے)/i)) {
					text = text.replace(/#(REDIRECT|رجوع\_?مکرر) ?(\[\[.*?\]\])(.*)/i, '#رجوع مکرر $1$2\n\n{{' + tag + '}}');
				} else {
					Morebits.status.info('یہ رجوع مکرر ہے کا سانچہ موجود ہے', 'کوئی کام نہیں ہے');
					return;
				}
			} else {
				var needsTagToBeCommentedOut = ['javascript', 'css', 'sanitized-css'].indexOf(protectedPage.getContentModel()) !== -1;
				if (needsTagToBeCommentedOut) {
					if (params.noinclude) {
						tag = '/* <noinclude>{{' + tag + '}}</noinclude> */';
					} else {
						tag = '/* {{' + tag + '}} */\n';
					}

					// Prepend tag at very top
					text = tag + text;
				} else {
					if (params.noinclude) {
						tag = '<noinclude>{{' + tag + '}}</noinclude>';
					} else {
						tag = '{{' + tag + '}}\n';
					}

					// Insert tag after short description or any hatnotes
					var wikipage = new Morebits.wikitext.page(text);
					text = wikipage.insertAfterTemplates(tag, Twinkle.hatnoteRegex).getText();
				}
			}
			summary = 'اضافہ {{' + params.tag + '}}';
		}

		protectedPage.setEditSummary(summary);
		protectedPage.setChangeTags(Twinkle.changeTags);
		protectedPage.setWatchlist(Twinkle.getPref('watchPPTaggedPages'));
		protectedPage.setPageText(text);
		protectedPage.setCreateOption('nocreate');
		protectedPage.suppressProtectWarning(); // no need to let admins know they are editing through protection
		protectedPage.save();
	},

	fileRequest: function(rppPage) {

		var params = rppPage.getCallbackParameters();
		var text = rppPage.getPageText();
		var statusElement = rppPage.getStatusElement();

		var rppRe = new RegExp('===\\s*(\\[\\[)?\\s*:?\\s*' + Morebits.string.escapeRegExp(Morebits.pageNameNorm) + '\\s*(\\]\\])?\\s*===', 'm');
		var tag = rppRe.exec(text);

		var rppLink = document.createElement('a');
		rppLink.setAttribute('href', mw.util.getUrl(rppPage.getPageName()));
		rppLink.appendChild(document.createTextNode(rppPage.getPageName()));

		if (tag) {
			statusElement.error([ 'اس صفحہ کی حفاظت کی درخواست ', rppLink, ' پر پہلے سے موجود ہے، لہذا آپ کی درخواست منسوخ کی جا رہی ہے۔' ]); // localized
			return;
		}

		var newtag = '=== [[:' + Morebits.pageNameNorm + ']] ===\n';
		if (new RegExp('^' + Morebits.string.escapeRegExp(newtag).replace(/\s+/g, '\\s*'), 'm').test(text)) {
			statusElement.error([ 'اس صفحہ کی حفاظت کی درخواست ', rppLink, ' پر پہلے سے موجود ہے، لہذا آپ کی درخواست منسوخ کی جا رہی ہے۔' ]); // localized
			return;
		}
		newtag += '* {{pagelinks|1=' + Morebits.pageNameNorm + '}}\n\n';

		var words;
		switch (params.expiry) {
			case 'temporary':
				words = ' عارضی'; // localized
				break;
			case 'indefinite':
				words = ' دائمی'; // localized
				break;
			default:
				words = '';
				break;
		}

		words = params.typename + words;

		newtag += "'''" + Morebits.string.toUpperCaseFirstChar(words) + (params.reason !== '' ? ":''' " +
			Morebits.string.formatReasonText(params.reason) : ".'''") + '~~~~';

		// If either protection type results in a increased status, then post it under increase
		// else we post it under decrease
		var increase = false;
		var protInfo = Twinkle.protect.protectionPresetsInfo[params.category];

		// function to compute protection weights (see comment at Twinkle.protect.protectionWeight)
		var computeWeight = function(mainLevel, stabilizeLevel) {
			var result = Twinkle.protect.protectionWeight[mainLevel || 'all'];
			if (stabilizeLevel) {
				if (result) {
					if (stabilizeLevel.level === 'autoconfirmed') {
						result += 2;
					}
				} else {
					result = Twinkle.protect.protectionWeight['flaggedrevs_' + stabilizeLevel];
				}
			}
			return result;
		};

		// compare the page's current protection weights with the protection we are requesting
		var editWeight = computeWeight(Twinkle.protect.currentProtectionLevels.edit &&
			Twinkle.protect.currentProtectionLevels.edit.level,
		Twinkle.protect.currentProtectionLevels.stabilize &&
			Twinkle.protect.currentProtectionLevels.stabilize.level);
		if (computeWeight(protInfo.edit, protInfo.stabilize) > editWeight ||
			computeWeight(protInfo.move) > computeWeight(Twinkle.protect.currentProtectionLevels.move &&
			Twinkle.protect.currentProtectionLevels.move.level) ||
			computeWeight(protInfo.create) > computeWeight(Twinkle.protect.currentProtectionLevels.create &&
			Twinkle.protect.currentProtectionLevels.create.level)) {
			increase = true;
		}

		var reg;
		if (increase) {
			reg = /(\n==\s*حفاظت ختم کرنے کی درخواستیں\s*==)/; // localized
		} else {
			reg = /(\n==\s*محفوظ صفحات میں ترمیم کی درخواست\s*==)/; // localized
		}

		var originalTextLength = text.length;
		text = text.replace(reg, '\n' + newtag + '\n$1');
		if (text.length === originalTextLength) {
			var linknode = document.createElement('a');
			linknode.setAttribute('href', mw.util.getUrl('وپ:پلک/تعمیر')); // localized
			linknode.appendChild(document.createTextNode('وپ:دحص کی درستی کا طریقہ'));
			statusElement.error([ 'وپ:دحص پر متعلقہ سرخی موجود نہیں۔ اس مسئلہ کو حل کرنے کے لیے براہ کرم صفحہ ', linknode, ' ملاحظہ فرمائیں۔' ]); // localized
			return;
		}
		statusElement.status('نئی درخواست درج کی جا رہی ہے۔۔۔'); // localized
		rppPage.setEditSummary('/* ' + Morebits.pageNameNorm + ' */ درخواست ' + params.typename + (params.typename === 'معلق تبدیلیاں' ? ' برای [[:' : ' برای [[:') + // localized
			Morebits.pageNameNorm + ']].');
		rppPage.setChangeTags(Twinkle.changeTags);
		rppPage.setPageText(text);
		rppPage.setCreateOption('recreate');
		rppPage.save(function() {
			// Watch the page being requested
			var watchPref = Twinkle.getPref('watchRequestedPages');
			// action=watch has no way to rely on user preferences (T262912), so we do it manually.
			// The watchdefault pref appears to reliably return '1' (string),
			// but that's not consistent among prefs so might as well be "correct"
			var watch = watchPref !== 'no' && (watchPref !== 'default' || !!parseInt(mw.user.options.get('watchdefault'), 10));
			if (watch) {
				var watch_query = {
					action: 'watch',
					titles: mw.config.get('wgPageName'),
					token: mw.user.tokens.get('watchToken')
				};
				// Only add the expiry if page is unwatched or already temporarily watched
				if (Twinkle.protect.watched !== true && watchPref !== 'default' && watchPref !== 'yes') {
					watch_query.expiry = watchPref;
				}
				new Morebits.wiki.api('مطلوبہ صفحہ زیر نظر فہرست میں درج کیا جا رہا ہے', watch_query).post();
			}
		});
	}
};

Twinkle.addInitCallback(Twinkle.protect, 'protect');
})(jQuery);


// </nowiki>