میدیاویکی:Gadget-twinkleconfig.js

لە ئینسایکڵۆپیدیای ئازادی ویکیپیدیاوە
تێبینی: دوای پاشەکەوتکردن، پێویستە کاشی وێبگەڕەکەت پاک بکەیتەوە تا گۆڕانکارییەکان ببینیت. بۆ گووگڵ کڕۆم، فایەرفۆکس، مایکرۆسۆفت ئێج و سافاری: پەنجە لەسەر دوگمەی ⇧ Shift ڕاگرە و کرتە لەسەر Reload بکە. بۆ وردەکاری و ڕێنمایییەکان لەسەر وێبگەڕەکانی تر، بڕوانە ئێرە.
// <nowiki>


(function($) {


/*
 ****************************************
 *** twinkleconfig.js: Preferences module
 ****************************************
 * Mode of invocation:     Adds configuration form to Wikipedia:Twinkle/Preferences,
                           and adds an ad box to the top of user subpages belonging to the
                           currently logged-in user which end in '.js'
 * Active on:              What I just said.  Yeah.

 I, [[User:This, that and the other]], originally wrote this.  If the code is misbehaving, or you have any
 questions, don't hesitate to ask me.  (This doesn't at all imply [[WP:OWN]]ership - it's just meant to
 point you in the right direction.)  -- TTO
 */


Twinkle.config = {};

Twinkle.config.watchlistEnums = {
	'yes': 'تا کاتێکی دیارینەکراو بۆ پێڕستی چاودێری زیادی بکە',
	'no': "بۆ پێڕستی چاودێری زیادی مەکە",
	'default': 'شوێنی ھەڵبژاردەکانی پێگەکەت بکەوە',
	'1 week': 'بۆ ماوەی ١ ھەفتە چاودێری بکە',
	'1 month': 'بۆ ماوەی ١ مانگ چاودێری بکە',
	'3 months': 'بۆ ماوەی ٣ مانگ چاودێری بکە',
	'6 months': 'بۆ ماوەی ٦ مانگ چاودێری بکە'
};

Twinkle.config.commonSets = {
	csdCriteria: {
		db: 'ھۆی لۆژیکیی دروستکراو ({{سخ}})',
		g1: 'G1', g2: 'G2', g3: 'G3', g4: 'G4', g5: 'G5', g6: 'G6', g7: 'G7', g8: 'G8', g10: 'G10', g11: 'G11', g12: 'G12', g13: 'G13', g14: 'G14', g15: 'G15',
		a1: 'A1', a2: 'A2', a3: 'A3', a7: 'A7', a9: 'A9', a10: 'A10', a11: 'A11',
		u1: 'U1', u2: 'U2', u5: 'U5',
		f1: 'F1', f2: 'F2', f3: 'F3', f7: 'F7', f8: 'F8', f9: 'F9',
		c1: 'C1',
		r2: 'R2', r3: 'R3', r4: 'R4'
	},
	csdCriteriaDisplayOrder: [
		'db',
		'g1', 'g2', 'g3', 'g4', 'g5', 'g6', 'g7', 'g8', 'g10', 'g11', 'g12', 'g13', 'g14', 'g15',
		'a1', 'a2', 'a3', 'a7', 'a9', 'a10', 'a11',
		'u1', 'u2', 'u5',
		'f1', 'f2', 'f3', 'f7', 'f8', 'f9',
		'c1',
		'r2', 'r3', 'r4'
	],
	csdCriteriaNotification: {
		db: 'ھۆی لۆژیکیی دروستکراو ({{سخ}})',
		g1: 'G1', g2: 'G2', g3: 'G3', g4: 'G4', g6: 'G6 ("copy-paste move" only)',
		g10: 'G10', g11: 'G11', g12: 'G12', g13: 'G13', g14: 'G14', g15: 'G15',
		a1: 'A1', a2: 'A2', a3: 'A3', a7: 'A7', a9: 'A9', a10: 'A10', a11: 'A11',
		u5: 'U5',
		f1: 'F1', f2: 'F2', f3: 'F3', f7: 'F7', f9: 'F9',
		c1: 'C1',
		r2: 'R2', r3: 'R3', r4: 'R4'
	},
	csdCriteriaNotificationDisplayOrder: [
		'db',
		'g1', 'g2', 'g3', 'g4', 'g6', 'g10', 'g11', 'g12', 'g13', 'g14', 'g15',
		'a1', 'a2', 'a3', 'a7', 'a9', 'a10', 'a11',
		'u5',
		'f1', 'f2', 'f3', 'f7', 'f9',
		'c1',
		'r2', 'r3', 'r4'
	],
	csdAndImageDeletionCriteria: {
		db: 'ھۆی لۆژیکیی دروستکراو ({{سخ}})',
		g1: 'G1', g2: 'G2', g3: 'G3', g4: 'G4', g5: 'G5', g6: 'G6', g7: 'G7', g8: 'G8', g10: 'G10', g11: 'G11', g12: 'G12', g13: 'G13', g14: 'G14', g15: 'G15',
		a1: 'A1', a2: 'A2', a3: 'A3', a7: 'A7', a9: 'A9', a10: 'A10', a11: 'A11',
		u1: 'U1', u2: 'U2', u5: 'U5',
		f1: 'F1', f2: 'F2', f3: 'F3', f4: 'F4', f5: 'F5', f6: 'F6', f7: 'F7', f8: 'F8', f9: 'F9', f11: 'F11',
		c1: 'C1',
		r2: 'R2', r3: 'R3', r4: 'R4'
	},
	csdAndImageDeletionCriteriaDisplayOrder: [
		'db',
		'g1', 'g2', 'g3', 'g4', 'g5', 'g6', 'g7', 'g8', 'g10', 'g11', 'g12', 'g13', 'g14', 'g15',
		'a1', 'a2', 'a3', 'a7', 'a9', 'a10', 'a11',
		'u1', 'u2', 'u5',
		'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f11',
		'c1',
		'r2', 'r3', 'r4'
	],
	namespacesNoSpecial: {
		0: 'وتار',
		1: 'وتووێژ (وتار)',
		2: 'بەکارھێنەر',
		3: 'لێدوانی بەکارھێنەر',
		4: 'ویکیپیدیا',
		5: 'لێدوانی ویکیپیدیا',
		6: 'پەڕگە',
		7: 'وتووێژی پەڕگە',
		8: 'میدیاویکی',
		9: 'وتووێژی میدیاویکی',
		10: 'داڕێژە',
		11: 'وتووێژی داڕێژە',
		12: 'یارمەتی',
		13: 'وتووێژی یارمەتی',
		14: 'پۆل',
		15: 'وتووێژی پۆل',
		100: 'دەروازە',
		101: 'لێدوانی دەروازە',
		118: 'ڕەشنووس',
		119: 'لێدوانی ڕەشنووس',
		710: 'TimedText',
		711: 'TimedText talk',
		828: 'مۆدیوول',
		829: 'لێدوانی مۆدیوول'
	}
};

/**
 * Section entry format:
 *
 * {
 *   title: <human-readable section title>,
 *   module: <name of the associated module, used to link to sections>,
 *   adminOnly: <true for admin-only sections>,
 *   hidden: <true for advanced preferences that rarely need to be changed - they can still be modified by manually editing twinkleoptions.js>,
 *   preferences: [
 *     {
 *       name: <TwinkleConfig property name>,
 *       label: <human-readable short description - used as a form label>,
 *       helptip: <(optional) human-readable text (using valid HTML) that complements the description, like limits, warnings, etc.>
 *       adminOnly: <true for admin-only preferences>,
 *       type: <string|boolean|integer|enum|set|customList> (customList stores an array of JSON objects { value, label }),
 *       enumValues: <for type = "enum": a JSON object where the keys are the internal names and the values are human-readable strings>,
 *       setValues: <for type = "set": a JSON object where the keys are the internal names and the values are human-readable strings>,
 *       setDisplayOrder: <(optional) for type = "set": an array containing the keys of setValues (as strings) in the order that they are displayed>,
 *       customListValueTitle: <for type = "customList": the heading for the left "value" column in the custom list editor>,
 *       customListLabelTitle: <for type = "customList": the heading for the right "label" column in the custom list editor>
 *     },
 *     . . .
 *   ]
 * },
 * . . .
 *
 */

Twinkle.config.sections = [
	{
		title: 'گشتی',
		module: 'general',
		preferences: [
			// TwinkleConfig.userTalkPageMode may take arguments:
			// 'window': open a new window, remember the opened window
			// 'tab': opens in a new tab, if possible.
			// 'blank': force open in a new window, even if such a window exists
			{
				name: 'userTalkPageMode',
				label: 'کاتی کردنەوەی پەڕەی لێدوانی بەکارھێنەرێک، ',
				type: 'enum',
				enumValues: { window: 'In a window, replacing other user talks', tab: 'لە تابێکی نوێ بیکەوە', blank: 'ھەر لە پەنجەرەیەکی تەواو نوێ بیکەوە' }
			},

			// TwinkleConfig.dialogLargeFont (boolean)
			{
				name: 'dialogLargeFont',
				label: 'لە دیالۆگەکانی توینکڵ دەقی گەورەتر بەکاربێنە',
				type: 'boolean'
			},

			// Twinkle.config.disabledModules (array)
			{
				name: 'disabledModules',
				label: 'مۆدیوولە دیاریکراوەکانی توینکڵ بکوژێنەوە',
				helptip: 'ھەر شتێک کە لێرەدا دیاریی دەکەیت، بۆ بەکارھێنان بەردەست نابێت بۆیە، بەوریایییەوە مامەڵەی لەگەڵ بکە. بۆ چالاککردنەوە، سەحەکان لابدە.',
				type: 'set',
				setValues: { arv: 'ARV', warn: 'ھۆشدار', welcome: 'بەخێرھاتن', shared: 'ئایپیی ھاوبەشیپێکراو', talkback: 'Talkback', speedy: 'پسخ', prod: 'سپ', xfd: 'شبس', image: 'وێنە (DI)', protect: 'پاراستن (RPP)', tag: 'تاگ', diff: 'جیاوازی', unlink: 'لابردنی بەستەر', fluff: 'گەڕاندنەوە' }
			},

			// Twinkle.config.disabledSysopModules (array)
			{
				name: 'disabledSysopModules',
				label: 'مۆدیوولە دیاریکراوەکانی تایبەت بە بەڕێوەبەران بکوژێنەوە',
				helptip: 'ھەر شتێک کە لێرەدا دیاریی دەکەیت، بۆ بەکارھێنان بەردەست نابێت بۆیە، بەوریایییەوە مامەڵەی لەگەڵ بکە. بۆ چالاککردنەوە، سەحەکان لابدە',
				adminOnly: true,
				type: 'set',
				setValues: { block: 'بەربەستن', deprod: 'DePROD', batchdelete: 'سڕینەوەی بەکۆمەڵ', batchprotect: 'پاراستنی بەکۆمەڵ', batchundelete: 'ھێنانەوەی بەکۆمەڵ' }
			}
		]
	},

	{
		title: 'ARV',
		module: 'arv',
		preferences: [
			{
				name: 'spiWatchReport',
				label: 'ئەو پەڕانەی کە ڕاپۆڕتی بووکەڵەکارین بە پێڕستی چاودێری زیاد بکە',
				type: 'enum',
				enumValues: Twinkle.config.watchlistEnums
			}
		]
	},

	{
		title: 'بەربەستکردنی بەکارھێنەر',
		module: 'block',
		adminOnly: true,
		preferences: [
			// TwinkleConfig.defaultToBlock64 (boolean)
			// Whether to default to just blocking the /64 on or off
			{
				name: 'defaultToBlock64',
				label: 'بۆ ناونیشانەکانی IPv6، بژاردەکە دیاری بکە تا مەودای /٦٤ بە دیفاڵت بەربەست بکەیت',
				type: 'boolean'
			},

			// TwinkleConfig.defaultToPartialBlocks (boolean)
			// Whether to default partial blocks on or off
			{
				name: 'defaultToPartialBlocks',
				label: 'کاتی کردنەوەی مێنیووی بەربەستکردنەکە ھەر بە دیفاڵت نیمچە بەربەستن دیاری بکە',
				helptip: 'ئەگەر بەکارھێنەرەکە پێشتر بەربەست کرابێت، لە بەرژوەندیی بە دیفاڵتکردنی چەشنی بەربەستی ئێستا ئەمە پشتگوێ دەخرێت',
				type: 'boolean'
			},

			// TwinkleConfig.blankTalkpageOnIndefBlock (boolean)
			// if true, blank the talk page when issuing an indef block notice (per [[WP:UWUL#Indefinitely blocked users]])
			{
				name: 'blankTalkpageOnIndefBlock',
				label: 'لەکاتی بەربەستکردنی بەکارھێنەران تا کاتێکی دیارینەکراو، پەڕەی لێدوانەکەی بەتاڵ بکەوە',
				helptip: 'بۆ زانیاریی زیاتر، بڕوانە <a href="' + mw.util.getUrl(':en:Wikipedia:WikiProject_User_warnings/Usage_and_layout#Indefinitely_blocked_users') + '">WP:UWUL</a>',
				type: 'boolean'
			}
		]
	},

	{
		title: 'سڕینەوەی وێنە (DI)',
		module: 'image',
		preferences: [
			// TwinkleConfig.notifyUserOnDeli (boolean)
			// If the user should be notified after placing a file deletion tag
			{
				name: 'notifyUserOnDeli',
				label: 'بە دیفاڵت سندووقی «بارکەری سەرەکی ئاگادار بکەوە» دیاری بکە',
				type: 'boolean'
			},

			// TwinkleConfig.deliWatchPage (string)
			// The watchlist setting of the page tagged for deletion.
			{
				name: 'deliWatchPage',
				label: 'کاتی تاگلێدان، پەڕەی وێنەکە بە پێڕستی چاودێری زیاد بکە',
				type: 'enum',
				enumValues: Twinkle.config.watchlistEnums
			},

			// TwinkleConfig.deliWatchUser (string)
			// The watchlist setting of the user talk page if a notification is placed.
			{
				name: 'deliWatchUser',
				label: 'کاتی ئاگادارکردنەوە، پەڕەی لێدوانی بەکارھێنەری بارکەری سەرەکی بە پێڕستی چاودێری زیاد بکە',
				type: 'enum',
				enumValues: Twinkle.config.watchlistEnums
			}
		]
	},

	{
		title: 'پاراستنتی پەڕە ' + (Morebits.userIsSysop ? '(پپ)' : '(دپپ)'),
		module: 'protect',
		preferences: [
			{
				name: 'watchRequestedPages',
				label: 'کاتی داواکردنی پاراستن، پەڕەکە بە پێڕستی چاودێری زیاد بکە',
				type: 'enum',
				enumValues: Twinkle.config.watchlistEnums
			},
			{
				name: 'watchPPTaggedPages',
				label: 'کاتی تاگلێدان بە داڕێژەی پاراستن، پەڕەکە بە پێڕستی چاودێری زیاد بکە',
				type: 'enum',
				enumValues: Twinkle.config.watchlistEnums
			},
			{
				name: 'watchProtectedPages',
				label: 'کاتی پاراستن، پەڕەکە بە پێڕستی چاودێری زیاد بکە',
				helptip: 'ھەروەھا ئەگەر دوای پاراستنەکە تاگ لە لە پەڕەکە بدەیت، ئەوا ئەو بژاردەیە خۆش دەبێت.',
				adminOnly: true,
				type: 'enum',
				enumValues: Twinkle.config.watchlistEnums
			}
		]
	},

	{
		title: 'سڕینەوەی پێشنیارکراو (سپ)',
		module: 'prod',
		preferences: [
			// TwinkleConfig.watchProdPages (string)
			// Watchlist setting when applying prod template to page
			{
				name: 'watchProdPages',
				label: 'کاتی تاگلێدان، وتارەکە بە پێڕستی چاودێری زیاد بکە',
				type: 'enum',
				enumValues: Twinkle.config.watchlistEnums
			},

			// TwinkleConfig.markProdPagesAsPatrolled (boolean)
			// If, when applying prod template to page, to mark the page as curated/patrolled (if the page was reached from NewPages)
			{
				name: 'markProdPagesAsPatrolled',
				label: 'کاتی تاگلێدان، پەرەکە وەک پاسدراو/بەسەرداچوونەوە بۆ کراو دیاری بکە (ئەگەر ڕێی تێ بچێت)',
				helptip: 'ڕەنگە پێویست بێ ئەمە دیاری نەکرێت چونکە گەر دیاری بکرێت، دژی باشترین کردەی یەکدەنگی دەبێت',
				type: 'boolean'
			},

			// TwinkleConfig.prodReasonDefault (string)
			// The prefilled PROD reason.
			{
				name: 'prodReasonDefault',
				label: 'ھۆکاری پێش پڕکردنەوەی سڕینەوەی پێشنیارکراو',
				type: 'string'
			},

			{
				name: 'logProdPages',
				label: 'Keep a log in userspace of all pages you tag for PROD',
				helptip: 'Since non-admins do not have access to their deleted contributions, the userspace log offers a good way to keep track of all pages you tag for PROD using Twinkle.',
				type: 'boolean'
			},
			{
				name: 'prodLogPageName',
				label: 'لۆگی سڕینەوەی پێشنیارکراوی بۆشاییی بەکارھێنەر لەم ژێرەپەڕەی بەکارھێنەرەدا بھێڵەوە',
				helptip: 'ناوی ژێرپەڕەیەک لەم سندووقەدا داخڵ بکە. لۆگی سڕینەوەی پێشنیارکراوی تایبەت بە خۆت لە ژێرپەڕەی بەکارھێنەر:<i>ناوی بەکارھێنەر</i>/<i>ناوی ژێرپەڕەکە</i> دەدۆزیتەوە. تەنیا ئەو کاتە کار دەکات کە لۆگی بۆشاییناوی سڕینەوەی پێشنیارکراوت داگیرساندبێت.',
				type: 'string'
			}
		]
	},

	{
		title: 'گەڕاندنەوە و ھەڵوەشاندنەوە',  // twinklefluff module
		module: 'fluff',
		preferences: [
			// TwinkleConfig.autoMenuAfterRollback (bool)
			// Option to automatically open the warning menu if the user talk page is opened post-reversion
			{
				name: 'autoMenuAfterRollback',
				label: 'دوای گەڕاندنەوە لەڕێگەی توینکڵ، بە شێوەیەکی خۆگەڕانە مێنیووی ئاگادارکردنەوەی توینکڵ لەسەر پەڕەی لێدوانی بەکارھێنەر بکەوە',
				helptip: 'تەنیا ئەو کاتە کار دەکات کە سندووقە پەیوەندیدارەکەی خوارەوە ھەڵبژێردرابێت.',
				type: 'boolean'
			},

			// TwinkleConfig.openTalkPage (array)
			// What types of actions that should result in opening of talk page
			{
				name: 'openTalkPage',
				label: 'دوای ئەم چەشنە پێداچوونەوانە، پەڕەی لێدوانی بەکارھێنەرەکە بکەوە',
				type: 'set',
				setValues: { agf: 'گەڕاندنەوەی لێکدانەوەت باش بێت', norm: 'گەڕاندنەوەی ئاسایی', vand: 'گەڕاندنەوەی خراپکاری' }
			},

			// TwinkleConfig.openTalkPageOnAutoRevert (bool)
			// Defines if talk page should be opened when calling revert from contribs or recent changes pages. If set to true, openTalkPage defines then if talk page will be opened.
			{
				name: 'openTalkPageOnAutoRevert',
				label: 'Open user talk page when invoking rollback from user contributions or recent changes',
				helptip: 'کاتێک ئەمە دادەگیرسێت، دەبێت بژاردەکانی سەرەوە چالاک کرابێتن تا ئەمە کار بکات.',
				type: 'boolean'
			},

			// TwinkleConfig.rollbackInPlace (bool)
			//
			{
				name: 'rollbackInPlace',
				label: "کاتی گەڕاندنەوەی لە بەشدارییەکان یان دوایین گۆڕانکارییەکان، پەڕەکە بار مەکەوە.",
				helptip: "کاتێک ئەمە دادەگیرسێت، توینکڵ دوای گەڕاندنەوەکە بەشدارییەکان یان دوایین گۆڕانکارییەکان بار ناکاتەوە، کە ئەمەش ڕێگەت پێ دەدات تا لە یەک کاتدا زیاتر لە یەک دەستکاری بگەڕێنیتەوە.",
				type: 'boolean'
			},

			// TwinkleConfig.markRevertedPagesAsMinor (array)
			// What types of actions that should result in marking edit as minor
			{
				name: 'markRevertedPagesAsMinor',
				label: 'دەستکاری بۆ ئەم چەشنە پێداچوونەوانە وەک بچووک دیاری بکە',
				type: 'set',
				setValues: { agf: 'گەڕاندنەوەی لێکدانەوەت باش بێت', norm: 'گەڕاندنەوەی ئاسایی', vand: 'گەڕاندنەوەی خراپکاری', torev: '«ھێنانەوەی ئەم وەشانە»' }
			},

			// TwinkleConfig.watchRevertedPages (array)
			// What types of actions that should result in forced addition to watchlist
			{
				name: 'watchRevertedPages',
				label: 'پەڕەکان بۆ ئەم چەشنە پێداچوونەوانە بە پێڕستی چاودێری زیاد بکە',
				type: 'set',
				setValues: { agf: 'گەڕاندنەوەی لێکدانەوەت باش بێت', norm: 'گەڕاندنەوەی ئاسایی', vand: 'گەڕاندنەوەی خراپکاری', torev: '«ھێنانەوەی ئەم وەشانە»' }
			},
			// TwinkleConfig.watchRevertedExpiry
			// If any of the above items are selected, whether to expire the watch
			{
				name: 'watchRevertedExpiry',
				label: 'کاتی گەڕاندنەوەی پەڕەیەک، بۆ ماوەی چەندێک چاودێریی دەکەیت',
				type: 'enum',
				enumValues: Twinkle.config.watchlistEnums
			},

			// TwinkleConfig.offerReasonOnNormalRevert (boolean)
			// If to offer a prompt for extra summary reason for normal reverts, default to true
			{
				name: 'offerReasonOnNormalRevert',
				label: 'بۆ گەڕاندنەوە ئاسایییەکان دەستبەجێ داوای ھۆکار بکە',
				helptip: 'گەڕاندنەوە ئاسایییەکان ئەوانەن کە دەکەونە ناوەڕاستی بەستەری گەڕاندنەوە.',
				type: 'boolean'
			},

			{
				name: 'confirmOnFluff',
				label: 'پێش گەڕاندنەوە ئاگادارم بکەوە (بۆ ھەموو ئامێرەکان)',
				helptip: 'بۆ ئەو بەکارھێنەرانەی کە ئامێری قەڵەم یان لەمسیان ھەیە، و ئەوانەی کە ھەمیشە ڕاڕان.',
				type: 'boolean'
			},

			{
				name: 'confirmOnMobileFluff',
				label: 'پێش گەڕاندنەوە ئاگادارم بکەوە (تەنیا بۆ ئامێرەکانی مۆبایل)',
				helptip: 'بۆ خۆلادان لە گەڕاندنەوەی بێمەبەست کاتێک لەسەر ئامێرەکانی مۆبایل بیت.',
				type: 'boolean'
			},

			// TwinkleConfig.showRollbackLinks (array)
			// Where Twinkle should show rollback links:
			// diff, others, mine, contribs, history, recent
			// Note from TTO: |contribs| seems to be equal to |others| + |mine|, i.e. redundant, so I left it out heres
			{
				name: 'showRollbackLinks',
				label: 'بەستەرەکانی گەڕاندنەوە لەسەر ئەم پەڕانە پیشان بدە',
				type: 'set',
				setValues: { diff: 'پەڕەکانی جیاوازی', others: 'پەڕەی بەشدارییەکانی بەکارھێنەرانی تر', mine: 'پەڕەی بەشدارییەکانی خۆم', recent: 'پەڕە تایبەتەکانی دوایین گۆڕانکارییەکان و گۆڕانکارییە پەیوەندیدارەکان', history: 'پەڕەکانی مێژوو' }
			}
		]
	},

	{
		title: 'تاگکردنی ئایپیی ھاوبەشیپێکراو',
		module: 'shared',
		preferences: [
			{
				name: 'markSharedIPAsMinor',
				label: 'تاگکردنی ئایپیی ھاوبەشیپێکراو وەک دەستکاریی بچووک دیاری بکە',
				type: 'boolean'
			}
		]
	},

	{
		title: 'سڕینەوەی خێرا (پسخ)',
		module: 'speedy',
		preferences: [
			{
				name: 'speedySelectionStyle',
				label: 'کەی پەڕەیەک تاگ بکەین یان بسڕینەوە؟',
				type: 'enum',
				enumValues: { buttonClick: 'کاتێک کرتە لەسەر «ناردن» دەکەم', radioClick: 'ھەر کە کرتەم لەسەر بژاردەیەک کرد' }
			},

			// TwinkleConfig.watchSpeedyPages (array)
			// Whether to add speedy tagged or deleted pages to watchlist
			{
				name: 'watchSpeedyPages',
				label: 'کاتی بەکارھێنانی ئەم پێوەرانە پەڕەکە بە پێڕستی چاودێری زیاد بکە',
				type: 'set',
				setValues: Twinkle.config.commonSets.csdCriteria,
				setDisplayOrder: Twinkle.config.commonSets.csdCriteriaDisplayOrder
			},
			// TwinkleConfig.watchSpeedyExpiry
			// If any of the above items are selected, whether to expire the watch
			{
				name: 'watchSpeedyExpiry',
				label: 'کاتی تاگکردنی پەڕەیەک، بۆ ماوەی چەندێک چاودێریی دەکەیت',
				type: 'enum',
				enumValues: Twinkle.config.watchlistEnums
			},

			// TwinkleConfig.markSpeedyPagesAsPatrolled (boolean)
			// If, when applying speedy template to page, to mark the page as triaged/patrolled (if the page was reached from NewPages)
			{
				name: 'markSpeedyPagesAsPatrolled',
				label: 'کاتی تاگکردن پەڕەکە وەک پاسدراو/بەسەرداچوونەوە بۆ کرا دیاری بکە (ئەگەر ڕێی تێ بچێت)',
				helptip: 'ڕەنگە پێویست بێ ئەمە دیاری نەکرێت چونکە گەر دیاری بکرێت، دژی باشترین کردەی یەکدەنگی دەبێت',
				type: 'boolean'
			},

			// TwinkleConfig.watchSpeedyUser (string)
			// The watchlist setting of the user talk page if they receive a notification.
			{
				name: 'watchSpeedyUser',
				label: 'کاتی ئاگادارکردنەوە، پەڕەی لێدوانی بەکارھێنەری بەشداربووی سەرەکی بە پێڕستی چاودێری زیاد بکە',
				type: 'enum',
				enumValues: Twinkle.config.watchlistEnums
			},

			// TwinkleConfig.welcomeUserOnSpeedyDeletionNotification (array of strings)
			// On what types of speedy deletion notifications shall the user be welcomed
			// with a "firstarticle" notice if their talk page has not yet been created.
			{
				name: 'welcomeUserOnSpeedyDeletionNotification',
				label: 'کاتی ئاگاداکردنەوە بەم پێوەرانە، دروستکەری پەڕەکە بەخێرھاتن بکە',
				helptip: 'بەخێرھاتنەکە تەنیا ئەو کاتە دەردەچێت کە بەکارھێنەرەکە سەبارەت بە سڕینەوەکە ئاگادار بکرێتەوە، و تەنیا ئەو کاتەی کە پەڕەی لێدوانەکەی پێشتر دروست نەکرابێت. داڕێژەی بەکاربراو بریتییە لە {{یەکەم وتار}}.',
				type: 'set',
				setValues: Twinkle.config.commonSets.csdCriteriaNotification,
				setDisplayOrder: Twinkle.config.commonSets.csdCriteriaNotificationDisplayOrder
			},

			// TwinkleConfig.notifyUserOnSpeedyDeletionNomination (array)
			// What types of actions should result in the author of the page being notified of nomination
			{
				name: 'notifyUserOnSpeedyDeletionNomination',
				label: 'کاتی تاگکردن بەم پێوەرانە، دروستکەری پەڕەکە ئاگادار بکەوە',
				helptip: 'Even if you choose to notify from the CSD screen, the notification will only take place for those criteria selected here.',
				type: 'set',
				setValues: Twinkle.config.commonSets.csdCriteriaNotification,
				setDisplayOrder: Twinkle.config.commonSets.csdCriteriaNotificationDisplayOrder
			},

			// TwinkleConfig.warnUserOnSpeedyDelete (array)
			// What types of actions should result in the author of the page being notified of speedy deletion (admin only)
			{
				name: 'warnUserOnSpeedyDelete',
				label: 'کاتی سڕینەوەی لەژێر ئەم پێوەرانە، دروستکەری پەڕەکە ئاگادار بکەوە',
				helptip: 'Even if you choose to notify from the CSD screen, the notification will only take place for those criteria selected here.',
				adminOnly: true,
				type: 'set',
				setValues: Twinkle.config.commonSets.csdCriteriaNotification,
				setDisplayOrder: Twinkle.config.commonSets.csdCriteriaNotificationDisplayOrder
			},

			// TwinkleConfig.promptForSpeedyDeletionSummary (array of strings)
			{
				name: 'promptForSpeedyDeletionSummary',
				label: 'کاتی سڕینەوە لەژێر ئەم پێوەرانە، ڕێگە بە دەستکاریکردنی ھۆکاری سڕینەوەکە بدە',
				adminOnly: true,
				type: 'set',
				setValues: Twinkle.config.commonSets.csdAndImageDeletionCriteria,
				setDisplayOrder: Twinkle.config.commonSets.csdAndImageDeletionCriteriaDisplayOrder
			},

			// TwinkleConfig.deleteTalkPageOnDelete (boolean)
			// If talk page if exists should also be deleted (CSD G8) when spedying a page (admin only)
			{
				name: 'deleteTalkPageOnDelete',
				label: 'بە دیفاڵت سندووقی «پەڕەی لێدوانیش بسڕەوە» دیاری بکە',
				adminOnly: true,
				type: 'boolean'
			},

			{
				name: 'deleteRedirectsOnDelete',
				label: 'بە دیفاڵت سندووقی «ڕەوانەکەرەکانیش بسڕەوە» دیاری بکە',
				adminOnly: true,
				type: 'boolean'
			},

			// TwinkleConfig.deleteSysopDefaultToDelete (boolean)
			// Make the CSD screen default to "delete" instead of "tag" (admin only)
			{
				name: 'deleteSysopDefaultToDelete',
				label: 'Default to outright deletion instead of speedy tagging',
				helptip: 'If there is a CSD tag already present, Twinkle will always default to "delete" mode',
				adminOnly: true,
				type: 'boolean'
			},

			// TwinkleConfig.speedyWindowWidth (integer)
			// Defines the width of the Twinkle SD window in pixels
			{
				name: 'speedyWindowWidth',
				label: 'پانیی پەنجەرەی سڕینەوەی خێرا (بە پیکسڵ)',
				type: 'integer'
			},

			// TwinkleConfig.speedyWindowWidth (integer)
			// Defines the width of the Twinkle SD window in pixels
			{
				name: 'speedyWindowHeight',
				label: 'بەرزیی پەنجەرەی سڕینەوەی خێرا (بە پیکسڵ)',
				helptip: 'ئەگەر مۆنیتەرێکی گەورەت ھەیە، لەوانەیە پێت خۆش بێت زیادی بکەیت.',
				type: 'integer'
			},

			{
				name: 'logSpeedyNominations',
				label: 'Keep a log in userspace of all CSD nominations',
				helptip: 'Since non-admins do not have access to their deleted contributions, the userspace log offers a good way to keep track of all pages you nominate for CSD using Twinkle. Files tagged using DI are also added to this log.',
				type: 'boolean'
			},
			{
				name: 'speedyLogPageName',
				label: 'لۆگی بۆشاییی بەکارھێنەری پسخ لەم ژێرپەڕەی بەکارھێنەرەدا بھێڵەوە',
				helptip: 'ناوی ژێرپەڕەیەک لەم سندووقەدا داخڵ بکە. لۆگی پێوەرەکانی سڕینەوەی خێرای تایبەت بە خۆت لە ژێرپەڕەی بەکارھێنەر:<i>ناوی بەکارھێنەر</i>/<i>ناوی ژێرپەڕەکە</i> دەدۆزیتەوە. تەنیا ئەو کاتە کار دەکات کە گەر لۆگی بۆشاییناوی بەکارھێنەری پێوەرەکانی سڕینەوەی خێرات داگیرساندبێت.',
				type: 'string'
			},
			{
				name: 'noLogOnSpeedyNomination',
				label: 'کاتی تاگکردن بەم پێوەرانە، لە لۆگی بۆشاییی بەکارھێنەر دروست و تۆماری مەکە',
				type: 'set',
				setValues: Twinkle.config.commonSets.csdAndImageDeletionCriteria,
				setDisplayOrder: Twinkle.config.commonSets.csdAndImageDeletionCriteriaDisplayOrder
			}
		]
	},

	{
		title: 'تاگ',
		module: 'tag',
		preferences: [
			{
				name: 'watchTaggedVenues',
				label: 'کاتی تاگکردنی ئەم جۆرە پەڕانە، پەڕەکە بە پێڕستی چاودێری زیاد بکە',
				type: 'set',
				setValues: { articles: 'وتارەکان', drafts: 'ڕەشنووسەکان', redirects: 'ڕەوانەکەرەکان', files: 'پەڕگەکان' }
			},
			{
				name: 'watchTaggedPages',
				label: 'کاتی تاگکردنی پەڕەیەک، ماوەی چەندێک چاودێریی دەکەیت',
				type: 'enum',
				enumValues: Twinkle.config.watchlistEnums
			},
			{
				name: 'watchMergeDiscussions',
				label: 'پەڕە وتووێژەکان بە پێڕستی چاودێری زیاد بکە کاتی دەستپێکردنی وتووێژەکانی کردنەیەک',
				type: 'enum',
				enumValues: Twinkle.config.watchlistEnums
			},
			{
				name: 'markTaggedPagesAsMinor',
				label: 'زیادکردنی تاگەکان وەک دەستکاریی بچووک دیاری بکە',
				type: 'boolean'
			},
			{
				name: 'markTaggedPagesAsPatrolled',
				label: 'سندووقی «پەڕەکە وەک پاسدراو/بەسەرداچوونەوە بۆ کراو دیاری بکە» بە دیفاڵت دیاری بکە',
				type: 'boolean'
			},
			{
				name: 'groupByDefault',
				label: 'سندووقی «گرووپ بۆناو {{چەند کێشەیەک}}» بە دیفاڵت دیاری بکە',
				type: 'boolean'
			},
			{
				name: 'tagArticleSortOrder',
				label: 'ڕێزبەندیی بینینی دیفاڵت بۆ تاگەکانی وتار',
				type: 'enum',
				enumValues: { cat: 'بەپێی پۆلەکان', alpha: 'بە ڕێزبەندیی ئەلفوبێ' }
			},
			{
				name: 'customTagList',
				label: 'تاگە دەستکردەکانی ڕاگرتنی وتار/ڕەشنووس بۆ پیشاندان',
				helptip: "ئەمانە وەک بژاردەی زیادە لە خوارەوەی پێڕستی تاگەکان دەردەکەون. بۆ نموونە، بۆی ھەیە تاگی نوێی ڕاگرتن کە لە دیفاڵتەکانی توینکڵ زیاد نەکراون زیاد بکەیت.",
				type: 'customList',
				customListValueTitle: 'ناوی داڕێژە (بەبێ کەوانە چرچەکان)',
				customListLabelTitle: 'ئەو دەقەی کە لە دیالۆگی تاگ پیشان دەدرێت'
			},
			{
				name: 'customFileTagList',
				label: 'تاگە دەستکردەکانی ڕاگرتنی پەڕگە بۆ پیشاندان',
				helptip: 'ئەو تاگە زیادانەی کە حەز دەکەیت بۆ پەڕگەکان زیادیان بکەیت.',
				type: 'customList',
				customListValueTitle: 'ناوی داڕێژە (بەبێ کەوانە چرچەکان)',
				customListLabelTitle: 'ئەو دەقەی کە لە دیالۆگی تاگ پیشان دەدرێت'
			},
			{
				name: 'customRedirectTagList',
				label: 'تاگە دەستکردەکانی پۆلی ڕەوانەکەر بۆ پیشاندان',
				helptip: 'ئەو تاگە زیادانەی کە حەز دەکەیت بۆ ڕەوانەکەرەکان زیادیان بکەیت',
				type: 'customList',
				customListValueTitle: 'ناوی داڕێژە (بەبێ کەوانە چرچەکان)',
				customListLabelTitle: 'ئەو دەقەی کە لە دیالۆگی تاگ پیشان دەدرێت'
			}
		]
	},

	{
		title: 'Talkback',
		module: 'talkback',
		preferences: [
			{
				name: 'markTalkbackAsMinor',
				label: 'Mark talkbacks as minor edits',
				type: 'boolean'
			},
			{
				name: 'insertTalkbackSignature',
				label: 'Insert signature within talkbacks',
				type: 'boolean'
			},
			{
				name: 'talkbackHeading',
				label: 'Section heading to use for talkback and please see',
				tooltip: 'Should NOT include the equals signs ("==") used for wikitext formatting',
				type: 'string'
			},
			{
				name: 'mailHeading',
				label: "Section heading to use for \"you've got mail\" notices",
				tooltip: 'Should NOT include the equals signs ("==") used for wikitext formatting',
				type: 'string'
			}
		]
	},

	{
		title: 'لابردنی بەستەر',
		module: 'unlink',
		preferences: [
			// TwinkleConfig.unlinkNamespaces (array)
			// In what namespaces unlink should happen, default in 0 (article), 10 (template), 100 (portal), and 118 (draft)
			{
				name: 'unlinkNamespaces',
				label: 'بەستەرەکان لە پەڕەکانی ئەم بۆشاییناوانە لابەرە',
				helptip: 'خۆت لە دیاریکردنی بۆشاییناوی وتووێژەکان بەدوور بگرە، چونکە لەوانەیە توینکڵ کۆتایی بە لابردنی بەستەر لەسەر ئەرشیڤەکانی وتووێژ بێنێت (کە ئەمە قبووڵ ناکرێت).',
				type: 'set',
				setValues: Twinkle.config.commonSets.namespacesNoSpecial
			}
		]
	},

	{
		title: 'بەکارھێنەر ئاگادار بکەوە',
		module: 'warn',
		preferences: [
			// TwinkleConfig.defaultWarningGroup (int)
			// Which level warning should be the default selected group, default is 1
			{
				name: 'defaultWarningGroup',
				label: 'ئاستی ئاگادارکردنەوەی دیفاڵت',
				type: 'enum',
				enumValues: {
					1: 'ئاستی ١',
					2: 'ئاستی ٢',
					3: 'ئاستی ٣',
					4: 'ئاستی ٤',
					5: 'ئاستی ٤im',
					6: 'Single-issue notices',
					7: 'Single-issue warnings',
					// 8 was used for block templates before #260
					9: 'ئاگادارکردنەوە دەستکردەکان',
					10: 'سەرجەم داڕێژەکانی ئاگادارکردنەوە',
					11: 'ئاستی خۆدیاریکەر (١-٤)'
				}
			},

			// TwinkleConfig.combinedSingletMenus (boolean)
			// if true, show one menu with both single-issue notices and warnings instead of two separately
			{
				name: 'combinedSingletMenus',
				label: 'Replace the two separate single-issue menus into one combined menu',
				helptip: 'Selecting either single-issue notices or single-issue warnings as your default will make this your default if enabled.',
				type: 'boolean'
			},

			// TwinkleConfig.showSharedIPNotice may take arguments:
			// true: to show shared ip notice if an IP address
			// false: to not print the notice
			{
				name: 'showSharedIPNotice',
				label: 'Add extra notice on shared IP talk pages',
				helptip: 'Notice used is {{Shared IP advice}}',
				type: 'boolean'
			},

			// TwinkleConfig.watchWarnings (string)
			// Watchlist setting for the page which has been dispatched an warning or notice
			{
				name: 'watchWarnings',
				label: 'کاتی ئاگادارکردنەوە پەڕەی لێدوانی بەکارھێنەر بە پێڕستی چاودێری زیاد بکە',
				type: 'enum',
				enumValues: Twinkle.config.watchlistEnums
			},

			// TwinkleConfig.oldSelect (boolean)
			// if true, use the native select menu rather the select2-based one
			{
				name: 'oldSelect',
				label: 'مێنیووی ھەڵبژاردنە کلاسیکەکە کە توانای گەڕانی نییە بەکاربێنە',
				type: 'boolean'
			},

			{
				name: 'customWarningList',
				label: 'داڕێژە دەستکردەکانی ئاگادارکردنەوە بۆ پیشاندان',
				helptip: 'دەتوانی داڕێژە تاکەکەسییەکان یان ژێرپەڕەکانی بەکارھێنەر زیاد بکەیت. ئاگادارکردنەوە دەستکردەکان لە پۆلی «ئاگادارکردنەوەی دەستکردەکان» لەنێو سندووقی دیالۆگی ئاگادارکردنەوەکان دەردەکەون.',
				type: 'customList',
				customListValueTitle: 'ناوی داڕێژە (بەبێ کەوانە چرچەکان)',
				customListLabelTitle: 'ئەو دەقەی کە لە پێڕستی ئاگادارکردنەوەکەدا پیشان دەدرێت (وەک کورتەی دەستکارییش بەکاردێت)'
			}
		]
	},

	{
		title: 'بەخێرھاتنی بەکارھێنەر',
		module: 'welcome',
		preferences: [
			{
				name: 'topWelcomes',
				label: 'بەخێرھاتنەکان لە سەرووی ئەو ناوەڕۆکانەی کە ئێستا لەسەر پەڕەی وتووێژی بەکارھێنەران ھەن، زیاد بکە',
				type: 'boolean'
			},
			{
				name: 'watchWelcomes',
				label: 'کاتی بەخێرھاتن پەڕەی وتووێژی بەکارھێنەران بە پێڕستی چاودێری زیاد بکە',
				helptip: 'Doing so adds to the personal element of welcoming a user - you will be able to see how they are coping as a newbie, and possibly help them.',
				type: 'enum',
				enumValues: Twinkle.config.watchlistEnums
			},
			{
				name: 'insertUsername',
				label: 'ناوی بەکارھێنەریت بۆ داڕێژەکە زیاد بکە (لەو شوێنەی کە بگونجێت)',
				helptip: "ھەندێ داڕێژەی بەخێرھاتن ڕستەیەکی سەرەتایییان ھەیە وەک «سڵاو، من &lt;ناوی بەکارھێنەرم&gt;. بەخێربێیت» ھتد. ئەگەر ئەم بژاردەیە بکوژێنیتەوە، ئەوا ئەم داڕێژانە ناوی بەکارھێنەرییەکەت بەو شێوەیە پیشان نادەن.",
				type: 'boolean'
			},
			{
				name: 'quickWelcomeMode',
				label: 'کرتەکردن لەسەر بەستەری «بەخێرھاتن» لەسەر پەڕەیەکی جیاوازی',
				helptip: 'ئەگەر بەخێرھاتن بە شێوەیەکی خۆگەڕانە ھەڵبژێریت، ئەوا ئەو داڕێژەی کە لە خوارەوە دیاریی دەکەیت، بەکاردێت.',
				type: 'enum',
				enumValues: { auto: 'بە شێوەیەکی خۆگەڕانە بەخێرھاتن دەکات', norm: 'ئاگادارت دەکاتەوە تا داڕێژەیەک ھەڵبژێریت' }
			},
			{
				name: 'quickWelcomeTemplate',
				label: 'داڕێژەی بەخێرھاتن بۆ بەکارھێنان بە شێوەیەکی خۆگەڕانە',
				helptip: 'ناوی داڕێژەیەکی بەخێرھاتن داخڵ بکە، بەبێ کەوانە چرچەکان. بەستەرێک بۆ وتارە دراوەکە زیاد دەبێت.',
				type: 'string'
			},
			{
				name: 'customWelcomeList',
				label: 'داڕێژە دەستکردەکانی بەخێرھاتن بۆ پیشاندان',
				helptip: "دەتوانیت داڕێژەکانی تری بەخێرھاتن یان ئەو ژێرپەڕانەی کە داڕێژەی بەخێرھاتنن (بە پێشگری «بەکارھێنەر:») زیاد بکەیت. ئەوە لەبیر مەکە کە ئەم داڕێژانە سەبستیووت دەکرێنە سەر پەڕەکانی وتووێژی بەکارھێنەر.",
				type: 'customList',
				customListValueTitle: 'داڕێژەی بەخێرھاتن (بەبێ کەوانە چرچەکان)',
				customListLabelTitle: 'ئەو دەقەی کە لە دیالۆگی بەخێرھاتنەکە پیشان دەدرێت'
			},
			{
				name: 'customWelcomeSignature',
				label: 'بە شێوەیەکی خۆگەڕانە واژووی داڕێژە دەستکردەکانی بەخێرھاتن بکە',
				helptip: 'ئەگەر داڕێژە دەستکردەکانی بەخێرھاتنەکانت خۆیان واژوویان تێدا بوو، ئەوا ئەم بژاردەیە بکوژێنەوە.',
				type: 'boolean'
			}
		]
	},

	{
		title: 'شبس (وتووێژەکانی سڕینەوە)',
		module: 'xfd',
		preferences: [
			{
				name: 'logXfdNominations',
				label: 'لۆگێک لە بۆشاییناوی بەکارھێنەر لە تەواوی ئەو پەڕانەی دەیانپاڵێوی بۆ وتووێژی سڕینەوە ھەڵگرە (شبس)',
				helptip: 'لۆگەکەی بۆشاییناوی بەکارھێنەر ڕێگەیەکی باش پێشکەش دەکات تا بەردەوام شوێنی سەرجەم ئەو پەڕانە بکەویت کە بە بەکارھێنانی توینکڵ دەیانپاڵێوی بۆ شبس',
				type: 'boolean'
			},
			{
				name: 'xfdLogPageName',
				label: 'لۆگی بۆشاییناوی بەکارھێنەر بۆ وتووێژی سڕینەوەکە لەم ژێرپەڕەی بەکارھێنەرەدا ھەڵگرە',
				helptip: 'ناوی ژێرپەڕەیەک لەم سندووقەدا داخڵ بکە. لۆگی شتەکان بۆ سڕینەوەی تایبەت بە خۆت لە بەکارھێنەر:<i>ناوی بەکارھێنەر</i>/<i>ناوی ژێرپەڕەکە</i> دەدۆزیتەوە. تەنیا ئەو کاتە کار دەکات کە گەر لۆگی بۆشاییناوی بەکارھێنەری شتەکان بۆ سڕینەوەت داگیرساندبێت.',
				type: 'string'
			},
			{
				name: 'noLogOnXfdNomination',
				label: 'کاتی پاڵاوتن لەم شوێنانەدا لە لۆگی بۆشاییناوی بەکارھێنەر دروست و داخڵی مەکە',
				type: 'set',
				setValues: { afd: 'وبس', tfd: 'TfD', ffd: 'FfD', cfd: 'CfD', cfds: 'CfD/S', mfd: 'MfD', rfd: 'RfD', rm: 'RM' }
			},

			// TwinkleConfig.xfdWatchPage (string)
			// The watchlist setting of the page being nominated for XfD.
			{
				name: 'xfdWatchPage',
				label: 'پەڕە پاڵێوراوەکە بە پێڕستی چاودێری زیاد بکە',
				type: 'enum',
				enumValues: Twinkle.config.watchlistEnums
			},

			// TwinkleConfig.xfdWatchDiscussion (string)
			// The watchlist setting of the newly created XfD page (for those processes that create discussion pages for each nomination),
			// or the list page for the other processes.
			{
				name: 'xfdWatchDiscussion',
				label: 'پەڕەی وتووێژی سڕینەوەکە بە پێڕستی چاودێری زیاد بکە',
				helptip: 'ئەمە ئاماژە بە وتووێژی ژێرپەڕە (بۆ وبس و MfD) یان پەڕەی لۆگی ڕۆژانە (بۆ TfD، CfD، RfD و FfD) دەکات',
				type: 'enum',
				enumValues: Twinkle.config.watchlistEnums
			},

			// TwinkleConfig.xfdWatchList (string)
			// The watchlist setting of the XfD list page, *if* the discussion is on a separate page.
			{
				name: 'xfdWatchList',
				label: 'Add the daily log/list page to the watchlist (AfD and MfD)',
				helptip: 'This only applies for AfD and MfD, where the discussions are transcluded onto a daily log page (for AfD) or the main MfD page (for MfD).',
				type: 'enum',
				enumValues: Twinkle.config.watchlistEnums
			},

			// TwinkleConfig.xfdWatchUser (string)
			// The watchlist setting of the user talk page if they receive a notification.
			{
				name: 'xfdWatchUser',
				label: 'پەڕەی لێدوانی بەکارھێنەری یەکەم بەشداریکەر بە پێڕستی چاودێری زیاد بکە (کاتی ئاگادارکردنەوە)',
				type: 'enum',
				enumValues: Twinkle.config.watchlistEnums
			},

			// TwinkleConfig.xfdWatchRelated (string)
			// The watchlist setting of the target of a redirect being nominated for RfD.
			{
				name: 'xfdWatchRelated',
				label: "پەڕەی مەبەستی ڕەوانەکەرەکە بە پێڕستی چاودێری زیاد بکە (کاتی ئاگادارکردنەوە)",
				helptip: 'ئەمە تەنیا بەسەر داواکارییەکان بۆ سڕینەوە (دبس) جێبەجێ دەبێت، کاتی بەجێھێشتنی ئاگادارییەک لەسەر پەڕەی وتووێژی ئامانجی ڕەوانەکەرەکە',
				type: 'enum',
				enumValues: Twinkle.config.watchlistEnums
			},

			{
				name: 'markXfdPagesAsPatrolled',
				label: 'کاتی پاڵاوتنی وبس، پەرەکە وەک پاسدراو/بەسەرداچوونەوە بۆ کراو دیاری بکە (ئەگەر ڕێی تێ بچێت)',
				type: 'boolean'
			}
		]
	},

	{
		title: 'شاراوە',
		hidden: true,
		preferences: [
			// twinkle.js: portlet setup
			{
				name: 'portletArea',
				type: 'string'
			},
			{
				name: 'portletId',
				type: 'string'
			},
			{
				name: 'portletName',
				type: 'string'
			},
			{
				name: 'portletType',
				type: 'string'
			},
			{
				name: 'portletNext',
				type: 'string'
			},
			// twinklefluff.js: defines how many revision to query maximum, maximum possible is 50, default is 50
			{
				name: 'revertMaxRevisions',
				type: 'integer'
			},
			// twinklewarn.js: When using the autolevel select option, how many days makes a prior warning stale
			// Huggle is three days ([[Special:Diff/918980316]] and [[Special:Diff/919417999]]) while ClueBotNG is two:
			// https://github.com/DamianZaremba/cluebotng/blob/4958e25d6874cba01c75f11debd2e511fd5a2ce5/bot/action_functions.php#L62
			{
				name: 'autolevelStaleDays',
				type: 'integer'
			},
			// How many pages should be queried by deprod and batchdelete/protect/undelete
			{
				name: 'batchMax',
				type: 'integer',
				adminOnly: true
			},
			// How many pages should be processed at a time by deprod and batchdelete/protect/undelete
			{
				name: 'batchChunks',
				type: 'integer',
				adminOnly: true
			}
		]
	}

]; // end of Twinkle.config.sections


Twinkle.config.init = function twinkleconfigInit() {

	// create the config page at Wikipedia:Twinkle/Preferences
	if ((mw.config.get('wgNamespaceNumber') === mw.config.get('wgNamespaceIds').project && mw.config.get('wgTitle') === 'توینکڵ/ھەڵبژاردەکان') &&
			mw.config.get('wgAction') === 'view') {

		if (!document.getElementById('twinkle-config')) {
			return;  // maybe the page is misconfigured, or something - but any attempt to modify it will be pointless
		}

		// set style (the url() CSS function doesn't seem to work from wikicode - ?!)
		document.getElementById('twinkle-config-titlebar').style.backgroundImage = 'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB%2FqqA%2BAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAEhQTFRFr73ZobTPusjdsMHZp7nVwtDhzNbnwM3fu8jdq7vUt8nbxtDkw9DhpbfSvMrfssPZqLvVztbno7bRrr7W1d%2Fs1N7qydXk0NjpkW7Q%2BgAAADVJREFUeNoMwgESQCAAAMGLkEIi%2FP%2BnbnbpdB59app5Vdg0sXAoMZCpGoFbK6ciuy6FX4ABAEyoAef0BXOXAAAAAElFTkSuQmCC)';

		var contentdiv = document.getElementById('twinkle-config-content');
		contentdiv.textContent = '';  // clear children

		// let user know about possible conflict with skin js/common.js file
		// (settings in that file will still work, but they will be overwritten by twinkleoptions.js settings)
		if (window.TwinkleConfig || window.FriendlyConfig) {
			var contentnotice = document.createElement('p');
			contentnotice.innerHTML = '<table class="plainlinks morebits-ombox morebits-ombox-content"><tr><td class="morebits-mbox-image">' +
				'<img alt="" src="https://upload.wikimedia.org/wikipedia/commons/3/38/Imbox_content.png" /></td>' +
				'<td class="morebits-mbox-text"><p><big><b>پێش دەستکاریکردنی ڕێکخستنەکانت لێرە،</b> دەبێت ڕێکخستنە کۆنەکانی توینکڵەکەت لە پێستە تایبەتەکەی جاڤاسکریپتەکەت لابەریت.</big></p>' +
				'<p>بۆ کردنی ئەمە، دەتوانیت <a href="' + mw.util.getUrl('بەکارھێنەر:' + mw.config.get('wgUserName') + '/' + mw.config.get('skin') +
				'.js', { action: 'edit' }) + '" target="_blank"><b>دەستکاریی پەڕگەی جاڤاسکریپتی پێستە تایبەتەکەت</b></a> یان <a href="' +
				mw.util.getUrl('بەکارھێنەر:' + mw.config.get('wgUserName') + '/common.js', { action: 'edit'}) + '" target="_blank"><b>پەڕگەی common.jsەکەت بکەیت</b></a>، بە لابردنی سەرجەم ئەو دێڕەکۆدانەی کە پەیوەندیدارن بە <code>TwinkleConfig</code> و <code>FriendlyConfig</code>.</p>' +
				'</td></tr></table>';
			contentdiv.appendChild(contentnotice);
		}

		// start a table of contents
		var toctable = document.createElement('div');
		toctable.className = 'toc';
		toctable.style.marginLeft = '0.4em';
		// create TOC title
		var toctitle = document.createElement('div');
		toctitle.id = 'toctitle';
		var toch2 = document.createElement('h2');
		toch2.textContent = 'ناوەڕۆکەکان ';
		toctitle.appendChild(toch2);
		// add TOC show/hide link
		var toctoggle = document.createElement('span');
		toctoggle.className = 'toctoggle';
		toctoggle.appendChild(document.createTextNode('['));
		var toctogglelink = document.createElement('a');
		toctogglelink.className = 'internal';
		toctogglelink.setAttribute('href', '#tw-tocshowhide');
		toctogglelink.textContent = 'بشارەوە';
		toctoggle.appendChild(toctogglelink);
		toctoggle.appendChild(document.createTextNode(']'));
		toctitle.appendChild(toctoggle);
		toctable.appendChild(toctitle);
		// create item container: this is what we add stuff to
		var tocul = document.createElement('ul');
		toctogglelink.addEventListener('click', function twinkleconfigTocToggle() {
			var $tocul = $(tocul);
			$tocul.toggle();
			if ($tocul.find(':visible').length) {
				toctogglelink.textContent = 'بشارەوە';
			} else {
				toctogglelink.textContent = 'پیشان بدە';
			}
		}, false);
		toctable.appendChild(tocul);
		contentdiv.appendChild(toctable);

		var contentform = document.createElement('form');
		contentform.setAttribute('action', 'javascript:void(0)');  // was #tw-save - changed to void(0) to work around Chrome issue
		contentform.addEventListener('submit', Twinkle.config.save, true);
		contentdiv.appendChild(contentform);

		var container = document.createElement('table');
		container.style.width = '100%';
		contentform.appendChild(container);

		$(Twinkle.config.sections).each(function(sectionkey, section) {
			if (section.hidden || (section.adminOnly && !Morebits.userIsSysop)) {
				return true;  // i.e. "continue" in this context
			}

			// add to TOC
			var tocli = document.createElement('li');
			tocli.className = 'toclevel-1';
			var toca = document.createElement('a');
			toca.setAttribute('href', '#' + section.module);
			toca.appendChild(document.createTextNode(section.title));
			tocli.appendChild(toca);
			tocul.appendChild(tocli);

			var row = document.createElement('tr');
			var cell = document.createElement('td');
			cell.setAttribute('colspan', '3');
			var heading = document.createElement('h4');
			heading.style.borderBottom = '1px solid gray';
			heading.style.marginTop = '0.2em';
			heading.id = section.module;
			heading.appendChild(document.createTextNode(section.title));
			cell.appendChild(heading);
			row.appendChild(cell);
			container.appendChild(row);

			var rowcount = 1;  // for row banding

			// add each of the preferences to the form
			$(section.preferences).each(function(prefkey, pref) {
				if (pref.adminOnly && !Morebits.userIsSysop) {
					return true;  // i.e. "continue" in this context
				}

				row = document.createElement('tr');
				row.style.marginBottom = '0.2em';
				// create odd row banding
				if (rowcount++ % 2 === 0) {
					row.style.backgroundColor = 'rgba(128, 128, 128, 0.1)';
				}
				cell = document.createElement('td');

				var label, input, gotPref = Twinkle.getPref(pref.name);
				switch (pref.type) {

					case 'boolean':  // create a checkbox
						cell.setAttribute('colspan', '2');

						label = document.createElement('label');
						input = document.createElement('input');
						input.setAttribute('type', 'checkbox');
						input.setAttribute('id', pref.name);
						input.setAttribute('name', pref.name);
						if (gotPref === true) {
							input.setAttribute('checked', 'checked');
						}
						label.appendChild(input);
						label.appendChild(document.createTextNode(pref.label));
						cell.appendChild(label);
						break;

					case 'string':  // create an input box
					case 'integer':
						// add label to first column
						cell.style.textAlign = 'right';
						cell.style.paddingRight = '0.5em';
						label = document.createElement('label');
						label.setAttribute('for', pref.name);
						label.appendChild(document.createTextNode(pref.label + ':'));
						cell.appendChild(label);
						row.appendChild(cell);

						// add input box to second column
						cell = document.createElement('td');
						cell.style.paddingRight = '1em';
						input = document.createElement('input');
						input.setAttribute('type', 'text');
						input.setAttribute('id', pref.name);
						input.setAttribute('name', pref.name);
						if (pref.type === 'integer') {
							input.setAttribute('size', 6);
							input.setAttribute('type', 'number');
							input.setAttribute('step', '1');  // integers only
						}
						if (gotPref) {
							input.setAttribute('value', gotPref);
						}
						cell.appendChild(input);
						break;

					case 'enum':  // create a combo box
						// add label to first column
						// note: duplicates the code above, under string/integer
						cell.style.textAlign = 'right';
						cell.style.paddingRight = '0.5em';
						label = document.createElement('label');
						label.setAttribute('for', pref.name);
						label.appendChild(document.createTextNode(pref.label + ':'));
						cell.appendChild(label);
						row.appendChild(cell);

						// add input box to second column
						cell = document.createElement('td');
						cell.style.paddingRight = '1em';
						input = document.createElement('select');
						input.setAttribute('id', pref.name);
						input.setAttribute('name', pref.name);
						$.each(pref.enumValues, function(enumvalue, enumdisplay) {
							var option = document.createElement('option');
							option.setAttribute('value', enumvalue);
							if ((gotPref === enumvalue) ||
								// Hack to convert old boolean watchlist prefs
								// to corresponding enums (added in v2.1)
								(typeof gotPref === 'boolean' &&
								((gotPref && enumvalue === 'yes') ||
								(!gotPref && enumvalue === 'no')))) {
								option.setAttribute('selected', 'selected');
							}
							option.appendChild(document.createTextNode(enumdisplay));
							input.appendChild(option);
						});
						cell.appendChild(input);
						break;

					case 'set':  // create a set of check boxes
						// add label first of all
						cell.setAttribute('colspan', '2');
						label = document.createElement('label');  // not really necessary to use a label element here, but we do it for consistency of styling
						label.appendChild(document.createTextNode(pref.label + ':'));
						cell.appendChild(label);

						var checkdiv = document.createElement('div');
						checkdiv.style.paddingLeft = '1em';
						var worker = function(itemkey, itemvalue) {
							var checklabel = document.createElement('label');
							checklabel.style.marginRight = '0.7em';
							checklabel.style.display = 'inline-block';
							var check = document.createElement('input');
							check.setAttribute('type', 'checkbox');
							check.setAttribute('id', pref.name + '_' + itemkey);
							check.setAttribute('name', pref.name + '_' + itemkey);
							if (gotPref && gotPref.indexOf(itemkey) !== -1) {
								check.setAttribute('checked', 'checked');
							}
							// cater for legacy integer array values for unlinkNamespaces (this can be removed a few years down the track...)
							if (pref.name === 'unlinkNamespaces') {
								if (gotPref && gotPref.indexOf(parseInt(itemkey, 10)) !== -1) {
									check.setAttribute('checked', 'checked');
								}
							}
							checklabel.appendChild(check);
							checklabel.appendChild(document.createTextNode(itemvalue));
							checkdiv.appendChild(checklabel);
						};
						if (pref.setDisplayOrder) {
							// add check boxes according to the given display order
							$.each(pref.setDisplayOrder, function(itemkey, item) {
								worker(item, pref.setValues[item]);
							});
						} else {
							// add check boxes according to the order it gets fed to us (probably strict alphabetical)
							$.each(pref.setValues, worker);
						}
						cell.appendChild(checkdiv);
						break;

					case 'customList':
						// add label to first column
						cell.style.textAlign = 'right';
						cell.style.paddingRight = '0.5em';
						label = document.createElement('label');
						label.setAttribute('for', pref.name);
						label.appendChild(document.createTextNode(pref.label + ':'));
						cell.appendChild(label);
						row.appendChild(cell);

						// add button to second column
						cell = document.createElement('td');
						cell.style.paddingRight = '1em';
						var button = document.createElement('button');
						button.setAttribute('id', pref.name);
						button.setAttribute('name', pref.name);
						button.setAttribute('type', 'button');
						button.addEventListener('click', Twinkle.config.listDialog.display, false);
						// use jQuery data on the button to store the current config value
						$(button).data({
							value: gotPref,
							pref: pref
						});
						button.appendChild(document.createTextNode('بڕگەکان دەستکاری بکە'));
						cell.appendChild(button);
						break;

					default:
						alert('twinkleconfig: unknown data type for preference ' + pref.name);
						break;
				}
				row.appendChild(cell);

				// add help tip
				cell = document.createElement('td');
				cell.style.fontSize = '90%';

				cell.style.color = 'gray';
				if (pref.helptip) {
					// convert mentions of templates in the helptip to clickable links
					cell.innerHTML = pref.helptip.replace(/{{(.+?)}}/g,
						'{{<a href="' + mw.util.getUrl('داڕێژە:') + '$1" target="_blank">$1</a>}}');
				}
				// add reset link (custom lists don't need this, as their config value isn't displayed on the form)
				if (pref.type !== 'customList') {
					var resetlink = document.createElement('a');
					resetlink.setAttribute('href', '#tw-reset');
					resetlink.setAttribute('id', 'twinkle-config-reset-' + pref.name);
					resetlink.addEventListener('click', Twinkle.config.resetPrefLink, false);
					resetlink.style.cssFloat = 'right';
					resetlink.style.margin = '0 0.6em';
					resetlink.appendChild(document.createTextNode('ڕێکخستنەوە'));
					cell.appendChild(resetlink);
				}
				row.appendChild(cell);

				container.appendChild(row);
				return true;
			});
			return true;
		});

		var footerbox = document.createElement('div');
		footerbox.setAttribute('id', 'twinkle-config-buttonpane');
		footerbox.style.backgroundColor = '#BCCADF';
		footerbox.style.padding = '0.5em';
		var button = document.createElement('button');
		button.setAttribute('id', 'twinkle-config-submit');
		button.setAttribute('type', 'submit');
		button.appendChild(document.createTextNode('گۆڕانکارییەکان پاشەکەوت بکە'));
		footerbox.appendChild(button);
		var footerspan = document.createElement('span');
		footerspan.className = 'plainlinks';
		footerspan.style.marginLeft = '2.4em';
		footerspan.style.fontSize = '90%';
		var footera = document.createElement('a');
		footera.setAttribute('href', '#tw-reset-all');
		footera.setAttribute('id', 'twinkle-config-resetall');
		footera.addEventListener('click', Twinkle.config.resetAllPrefs, false);
		footera.appendChild(document.createTextNode('دیفاڵتەکان بگەڕێنەوە'));
		footerspan.appendChild(footera);
		footerbox.appendChild(footerspan);
		contentform.appendChild(footerbox);

		// since all the section headers exist now, we can try going to the requested anchor
		if (window.location.hash) {
			var loc = window.location.hash;
			window.location.hash = '';
			window.location.hash = loc;
		}

	} else if (mw.config.get('wgNamespaceNumber') === mw.config.get('wgNamespaceIds').user &&
			mw.config.get('wgTitle').indexOf(mw.config.get('wgUserName')) === 0 &&
			mw.config.get('wgPageName').slice(-3) === '.js') {

		var box = document.createElement('div');
		// Styled in twinkle.css
		box.setAttribute('id', 'twinkle-config-headerbox');

		var link,
			scriptPageName = mw.config.get('wgPageName').slice(mw.config.get('wgPageName').lastIndexOf('/') + 1,
				mw.config.get('wgPageName').lastIndexOf('.js'));

		if (scriptPageName === 'twinkleoptions') {
			// place "why not try the preference panel" notice
			box.setAttribute('class', 'config-twopt-box');

			if (mw.config.get('wgArticleId') > 0) {  // page exists
				box.appendChild(document.createTextNode('ئەم پەڕە ھەڵبژاردەکانی توینکڵەکەتی تێدایە. دەتوانیت بیانگۆڕیت بە بەکارھێنانی '));
			} else {  // page does not exist
				box.appendChild(document.createTextNode('دەتوانیت بە خواستی خۆت توینکڵ دەستکاری بکەیت تا لەگەڵ ھەڵبژاردەکانت بیگونجێنیت لەڕێگەی بەکارھێنانی '));
			}
			link = document.createElement('a');
			link.setAttribute('href', mw.util.getUrl(mw.config.get('wgFormattedNamespaces')[mw.config.get('wgNamespaceIds').project] + ':توینکڵ/ھەڵبژاردەکان'));
			link.appendChild(document.createTextNode('پانێڵی ھەڵبژاردەکانی توینکڵ'));
			box.appendChild(link);
			box.appendChild(document.createTextNode('، یان بە دەستکاریکردنی ئەم پەڕە.'));
			$(box).insertAfter($('#contentSub'));

		} else if (['monobook', 'vector', 'vector-2022', 'cologneblue', 'modern', 'timeless', 'minerva', 'common'].indexOf(scriptPageName) !== -1) {
			// place "Looking for Twinkle options?" notice
			box.setAttribute('class', 'config-userskin-box');

			box.appendChild(document.createTextNode('ئەگەر دەتەوێت ھەڵبژاردەکانی توینکڵ ڕێک بخەیت، ئەوا دەتوانیت '));
			link = document.createElement('a');
			link.setAttribute('href', mw.util.getUrl(mw.config.get('wgFormattedNamespaces')[mw.config.get('wgNamespaceIds').project] + ':توینکڵ/ھەڵبژاردەکان'));
			link.appendChild(document.createTextNode('پانێڵی ھەڵبژاردەکانی توینکڵ'));
			box.appendChild(link);
			box.appendChild(document.createTextNode(' بەکاربێنیت.'));
			$(box).insertAfter($('#contentSub'));
		}
	}
};

// custom list-related stuff

Twinkle.config.listDialog = {};

Twinkle.config.listDialog.addRow = function twinkleconfigListDialogAddRow($dlgtable, value, label) {
	var $contenttr, $valueInput, $labelInput;

	$dlgtable.append(
		$contenttr = $('<tr>').append(
			$('<td>').append(
				$('<button>')
					.attr('type', 'button')
					.on('click', function () {
						$contenttr.remove();
					})
					.text('لابردن')
			),
			$('<td>').append(
				$valueInput = $('<input>')
					.attr('type', 'text')
					.addClass('twinkle-config-customlist-value')
					.css('width', '97%')
			),
			$('<td>').append(
				$labelInput = $('<input>')
					.attr('type', 'text')
					.addClass('twinkle-config-customlist-label')
					.css('width', '98%')
			)
		)
	);

	if (value) {
		$valueInput.val(value);
	}
	if (label) {
		$labelInput.val(label);
	}

};

Twinkle.config.listDialog.display = function twinkleconfigListDialogDisplay(e) {
	var $prefbutton = $(e.target);
	var curvalue = $prefbutton.data('value');
	var curpref = $prefbutton.data('pref');

	var dialog = new Morebits.simpleWindow(720, 400);
	dialog.setTitle(curpref.label);
	dialog.setScriptName('ھەڵبژاردەکانی توینکڵ');

	var $dlgtbody;

	dialog.setContent(
		$('<div>').append(
			$('<table>')
				.addClass('wikitable')
				.css({
					margin: '1.4em 1em',
					width: 'auto'
				})
				.append(
					$dlgtbody = $('<tbody>').append(
						// header row
						$('<tr>').append(
							$('<th>') // top-left cell
								.css('width', '5%'),
							$('<th>') // value column header
								.css('width', '35%')
								.text(curpref.customListValueTitle ? curpref.customListValueTitle : 'Value'),
							$('<th>') // label column header
								.css('width', '60%')
								.text(curpref.customListLabelTitle ? curpref.customListLabelTitle : 'Label')
						)
					),
					$('<tfoot>').append(
						$('<tr>').append(
							$('<td>')
								.attr('colspan', '3')
								.append(
									$('<button>')
										.text('زیادکردن')
										.css('min-width', '8em')
										.attr('type', 'button')
										.on('click', function () {
											Twinkle.config.listDialog.addRow($dlgtbody);
										})
								)
						)
					)
				),
			$('<button>')
				.text('گۆڕانکارییەکان پاشەکەوت بکە')
				.attr('type', 'submit') // so Morebits.simpleWindow puts the button in the button pane
				.on('click', function () {
					Twinkle.config.listDialog.save($prefbutton, $dlgtbody);
					dialog.close();
				}),
			$('<button>')
				.text('ڕێکخستنەوە')
				.attr('type', 'submit')
				.on('click', function () {
					Twinkle.config.listDialog.reset($prefbutton, $dlgtbody);
				}),
			$('<button>')
				.text('ھەڵوەشاندنەوە')
				.attr('type', 'submit')
				.on('click', function () {
					dialog.close();
				})
		)[0]
	);

	// content rows
	var gotRow = false;
	$.each(curvalue, function(k, v) {
		gotRow = true;
		Twinkle.config.listDialog.addRow($dlgtbody, v.value, v.label);
	});
	// if there are no values present, add a blank row to start the user off
	if (!gotRow) {
		Twinkle.config.listDialog.addRow($dlgtbody);
	}

	dialog.display();
};

// Resets the data value, re-populates based on the new (default) value, then saves the
// old data value again (less surprising behaviour)
Twinkle.config.listDialog.reset = function twinkleconfigListDialogReset($button, $tbody) {
	// reset value on button
	var curpref = $button.data('pref');
	var oldvalue = $button.data('value');
	Twinkle.config.resetPref(curpref);

	// reset form
	$tbody.find('tr').slice(1).remove();  // all rows except the first (header) row
	// add the new values
	var curvalue = $button.data('value');
	$.each(curvalue, function(k, v) {
		Twinkle.config.listDialog.addRow($tbody, v.value, v.label);
	});

	// save the old value
	$button.data('value', oldvalue);
};

Twinkle.config.listDialog.save = function twinkleconfigListDialogSave($button, $tbody) {
	var result = [];
	var current = {};
	$tbody.find('input[type="text"]').each(function(inputkey, input) {
		if ($(input).hasClass('twinkle-config-customlist-value')) {
			current = { value: input.value };
		} else {
			current.label = input.value;
			// exclude totally empty rows
			if (current.value || current.label) {
				result.push(current);
			}
		}
	});
	$button.data('value', result);
};

// reset/restore defaults

Twinkle.config.resetPrefLink = function twinkleconfigResetPrefLink(e) {
	var wantedpref = e.target.id.substring(21); // "twinkle-config-reset-" prefix is stripped

	// search tactics
	$(Twinkle.config.sections).each(function(sectionkey, section) {
		if (section.hidden || (section.adminOnly && !Morebits.userIsSysop)) {
			return true;  // continue: skip impossibilities
		}

		var foundit = false;

		$(section.preferences).each(function(prefkey, pref) {
			if (pref.name !== wantedpref) {
				return true;  // continue
			}
			Twinkle.config.resetPref(pref);
			foundit = true;
			return false;  // break
		});

		if (foundit) {
			return false;  // break
		}
	});
	return false;  // stop link from scrolling page
};

Twinkle.config.resetPref = function twinkleconfigResetPref(pref) {
	switch (pref.type) {

		case 'boolean':
			document.getElementById(pref.name).checked = Twinkle.defaultConfig[pref.name];
			break;

		case 'string':
		case 'integer':
		case 'enum':
			document.getElementById(pref.name).value = Twinkle.defaultConfig[pref.name];
			break;

		case 'set':
			$.each(pref.setValues, function(itemkey) {
				if (document.getElementById(pref.name + '_' + itemkey)) {
					document.getElementById(pref.name + '_' + itemkey).checked = Twinkle.defaultConfig[pref.name].indexOf(itemkey) !== -1;
				}
			});
			break;

		case 'customList':
			$(document.getElementById(pref.name)).data('value', Twinkle.defaultConfig[pref.name]);
			break;

		default:
			alert('twinkleconfig: unknown data type for preference ' + pref.name);
			break;
	}
};

Twinkle.config.resetAllPrefs = function twinkleconfigResetAllPrefs() {
	// no confirmation message - the user can just refresh/close the page to abort
	$(Twinkle.config.sections).each(function(sectionkey, section) {
		if (section.hidden || (section.adminOnly && !Morebits.userIsSysop)) {
			return true;  // continue: skip impossibilities
		}
		$(section.preferences).each(function(prefkey, pref) {
			if (!pref.adminOnly || Morebits.userIsSysop) {
				Twinkle.config.resetPref(pref);
			}
		});
		return true;
	});
	return false;  // stop link from scrolling page
};

Twinkle.config.save = function twinkleconfigSave(e) {
	Morebits.status.init(document.getElementById('twinkle-config-content'));

	var userjs = mw.config.get('wgFormattedNamespaces')[mw.config.get('wgNamespaceIds').user] + ':' + mw.config.get('wgUserName') + '/twinkleoptions.js';
	var wikipedia_page = new Morebits.wiki.page(userjs, 'پاشەکەوتکردنی ھەڵبژاردەکان لە ' + userjs);
	wikipedia_page.setCallbackParameters(e.target);
	wikipedia_page.load(Twinkle.config.writePrefs);

	return false;
};

Twinkle.config.writePrefs = function twinkleconfigWritePrefs(pageobj) {
	var form = pageobj.getCallbackParameters();

	// this is the object which gets serialized into JSON; only
	// preferences that this script knows about are kept
	var newConfig = {optionsVersion: 2.1};

	// a comparison function is needed later on
	// it is just enough for our purposes (i.e. comparing strings, numbers, booleans,
	// arrays of strings, and arrays of { value, label })
	// and it is not very robust: e.g. compare([2], ["2"]) === true, and
	// compare({}, {}) === false, but it's good enough for our purposes here
	var compare = function(a, b) {
		if (Array.isArray(a)) {
			if (a.length !== b.length) {
				return false;
			}
			var asort = a.sort(), bsort = b.sort();
			for (var i = 0; asort[i]; ++i) {
				// comparison of the two properties of custom lists
				if ((typeof asort[i] === 'object') && (asort[i].label !== bsort[i].label ||
					asort[i].value !== bsort[i].value)) {
					return false;
				} else if (asort[i].toString() !== bsort[i].toString()) {
					return false;
				}
			}
			return true;
		}
		return a === b;

	};

	$(Twinkle.config.sections).each(function(sectionkey, section) {
		if (section.adminOnly && !Morebits.userIsSysop) {
			return;  // i.e. "continue" in this context
		}

		// reach each of the preferences from the form
		$(section.preferences).each(function(prefkey, pref) {
			var userValue;  // = undefined

			// only read form values for those prefs that have them
			if (!pref.adminOnly || Morebits.userIsSysop) {
				if (!section.hidden) {
					switch (pref.type) {
						case 'boolean':  // read from the checkbox
							userValue = form[pref.name].checked;
							break;

						case 'string':  // read from the input box or combo box
						case 'enum':
							userValue = form[pref.name].value;
							break;

						case 'integer':  // read from the input box
							userValue = parseInt(form[pref.name].value, 10);
							if (isNaN(userValue)) {
								Morebits.status.warn('پاشەکەوتکردن', 'ئەو نرخەی دیاریت کردووە بۆ ' + pref.name + ' (' + pref.value + ') نادروست بوو.  پاشەکەوتەکە بەردەوام دەبێت، بەڵام دراوەی نرخە نادروستەکە دەپەڕێندرێت.');
								userValue = null;
							}
							break;

						case 'set':  // read from the set of check boxes
							userValue = [];
							if (pref.setDisplayOrder) {
							// read only those keys specified in the display order
								$.each(pref.setDisplayOrder, function(itemkey, item) {
									if (form[pref.name + '_' + item].checked) {
										userValue.push(item);
									}
								});
							} else {
							// read all the keys in the list of values
								$.each(pref.setValues, function(itemkey) {
									if (form[pref.name + '_' + itemkey].checked) {
										userValue.push(itemkey);
									}
								});
							}
							break;

						case 'customList':  // read from the jQuery data stored on the button object
							userValue = $(form[pref.name]).data('value');
							break;

						default:
							alert('twinkleconfig: unknown data type for preference ' + pref.name);
							break;
					}
				} else if (Twinkle.prefs) {
					// Retain the hidden preferences that may have customised by the user from twinkleoptions.js
					// undefined if not set
					userValue = Twinkle.prefs[pref.name];
				}
			}

			// only save those preferences that are *different* from the default
			if (userValue !== undefined && !compare(userValue, Twinkle.defaultConfig[pref.name])) {
				newConfig[pref.name] = userValue;
			}
		});
	});

	var text =
		'// twinkleoptions.js: personal Twinkle preferences file\n' +
		'//\n' +
		'// NOTE: The easiest way to change your Twinkle preferences is by using the\n' +
		'// Twinkle preferences panel, at [[' + Morebits.pageNameNorm + ']].\n' +
		'//\n' +
		'// This file is AUTOMATICALLY GENERATED.  Any changes you make (aside from\n' +
		'// changing the configuration parameters in a valid-JavaScript way) will be\n' +
		'// overwritten the next time you click "save" in the Twinkle preferences\n' +
		'// panel.  If modifying this file, make sure to use correct JavaScript.\n' +
		'// <no' + 'wiki>\n' +
		'\n' +
		'window.Twinkle.prefs = ';
	text += JSON.stringify(newConfig, null, 2);
	text +=
		';\n' +
		'\n' +
		'// </no' + 'wiki>\n' +
		'// End of twinkleoptions.js\n';

	pageobj.setPageText(text);
	pageobj.setEditSummary('پاشەکەوتکردنی ھەڵبژاردەکانی توینکڵ: دەستکارییە خۆگەڕەکە لە [[:' + Morebits.pageNameNorm + ']]');
	pageobj.setChangeTags(Twinkle.changeTags);
	pageobj.setCreateOption('recreate');
	pageobj.save(Twinkle.config.saveSuccess);
};

Twinkle.config.saveSuccess = function twinkleconfigSaveSuccess(pageobj) {
	pageobj.getStatusElement().info('سەرکەوتوو بوو');

	var noticebox = document.createElement('div');
	noticebox.className = 'mw-message-box mw-message-box-success';
	noticebox.style.fontSize = '100%';
	noticebox.style.marginTop = '2em';
	noticebox.innerHTML = '<p><b>ھەڵبژاردەکانی توینکڵەکەت پاشەکەوت کران.</b></p><p>بۆ بینینی گۆڕانکارییەکان، پێویست دەبێت <b>بەتەواوی کاشی وێبگەڕەکەت پاک بکەیتەوە</b> (بۆ ڕێنمایی، بڕوانە <a href="' + mw.util.getUrl('WP:BYPASS') + '" title="WP:BYPASS">WP:BYPASS</a>).</p>';
	Morebits.status.root.appendChild(noticebox);
	var noticeclear = document.createElement('br');
	noticeclear.style.clear = 'both';
	Morebits.status.root.appendChild(noticeclear);
};

Twinkle.addInitCallback(Twinkle.config.init);
})(jQuery);


// </nowiki>