<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://eurovision.jobogamer.xyz/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-twinkleprod.js</id>
	<title>MediaWiki:Gadget-twinkleprod.js - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://eurovision.jobogamer.xyz/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-twinkleprod.js"/>
	<link rel="alternate" type="text/html" href="https://eurovision.jobogamer.xyz/index.php?title=MediaWiki:Gadget-twinkleprod.js&amp;action=history"/>
	<updated>2026-06-10T23:48:58Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://eurovision.jobogamer.xyz/index.php?title=MediaWiki:Gadget-twinkleprod.js&amp;diff=47&amp;oldid=prev</id>
		<title>Alfie: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://eurovision.jobogamer.xyz/index.php?title=MediaWiki:Gadget-twinkleprod.js&amp;diff=47&amp;oldid=prev"/>
		<updated>2026-03-19T09:58:25Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 05:58, 19 March 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Alfie</name></author>
	</entry>
	<entry>
		<id>https://eurovision.jobogamer.xyz/index.php?title=MediaWiki:Gadget-twinkleprod.js&amp;diff=46&amp;oldid=prev</id>
		<title>en&gt;SD0001: Repo at cb9119f: Move all non-test source files to a new src directory (#2254); use change tags on action=pagetriageaction requests (#2269)</title>
		<link rel="alternate" type="text/html" href="https://eurovision.jobogamer.xyz/index.php?title=MediaWiki:Gadget-twinkleprod.js&amp;diff=46&amp;oldid=prev"/>
		<updated>2026-01-01T16:52:51Z</updated>

		<summary type="html">&lt;p&gt;Repo at cb9119f: Move all non-test source files to a new src directory (#2254); use change tags on action=pagetriageaction requests (#2269)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;// &amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(function() {&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 ****************************************&lt;br /&gt;
 *** twinkleprod.js: PROD module&lt;br /&gt;
 ****************************************&lt;br /&gt;
 * Mode of invocation:     Tab (&amp;quot;PROD&amp;quot;)&lt;br /&gt;
 * Active on:              Existing articles, files which are not redirects&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
Twinkle.prod = function twinkleprod() {&lt;br /&gt;
	if ((![0, 6].includes(mw.config.get(&amp;#039;wgNamespaceNumber&amp;#039;))) ||&lt;br /&gt;
		!mw.config.get(&amp;#039;wgCurRevisionId&amp;#039;) ||&lt;br /&gt;
		Morebits.isPageRedirect()) {&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	Twinkle.addPortletLink(Twinkle.prod.callback, &amp;#039;PROD&amp;#039;, &amp;#039;tw-prod&amp;#039;, &amp;#039;Propose deletion via WP:PROD&amp;#039;);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// Used in edit summaries, for comparisons, etc.&lt;br /&gt;
let namespace;&lt;br /&gt;
&lt;br /&gt;
Twinkle.prod.callback = function twinkleprodCallback() {&lt;br /&gt;
	Twinkle.prod.defaultReason = Twinkle.getPref(&amp;#039;prodReasonDefault&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
	switch (mw.config.get(&amp;#039;wgNamespaceNumber&amp;#039;)) {&lt;br /&gt;
		case 0:&lt;br /&gt;
			namespace = &amp;#039;article&amp;#039;;&lt;br /&gt;
			break;&lt;br /&gt;
		case 6:&lt;br /&gt;
			namespace = &amp;#039;file&amp;#039;;&lt;br /&gt;
			break;&lt;br /&gt;
		// no default&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	const Window = new Morebits.SimpleWindow(800, 410);&lt;br /&gt;
	Window.setTitle(&amp;#039;Proposed deletion (PROD)&amp;#039;);&lt;br /&gt;
	Window.setScriptName(&amp;#039;Twinkle&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
	const form = new Morebits.QuickForm(Twinkle.prod.callback.evaluate);&lt;br /&gt;
&lt;br /&gt;
	if (namespace === &amp;#039;article&amp;#039;) {&lt;br /&gt;
		Window.addFooterLink(&amp;#039;Proposed deletion policy&amp;#039;, &amp;#039;WP:PROD&amp;#039;);&lt;br /&gt;
		Window.addFooterLink(&amp;#039;BLP PROD policy&amp;#039;, &amp;#039;WP:BLPPROD&amp;#039;);&lt;br /&gt;
	} else { // if file&lt;br /&gt;
		Window.addFooterLink(&amp;#039;Proposed deletion policy&amp;#039;, &amp;#039;WP:PROD&amp;#039;);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	const field = form.append({&lt;br /&gt;
		type: &amp;#039;field&amp;#039;,&lt;br /&gt;
		label: &amp;#039;PROD type&amp;#039;,&lt;br /&gt;
		id: &amp;#039;prodtype_fieldset&amp;#039;&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
	field.append({&lt;br /&gt;
		type: &amp;#039;div&amp;#039;,&lt;br /&gt;
		label: &amp;#039;&amp;#039;, // Added later by Twinkle.makeFindSourcesDiv()&lt;br /&gt;
		id: &amp;#039;twinkle-prod-findsources&amp;#039;,&lt;br /&gt;
		style: &amp;#039;margin-bottom: 5px; margin-top: -5px;&amp;#039;&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
	field.append({&lt;br /&gt;
		type: &amp;#039;radio&amp;#039;,&lt;br /&gt;
		name: &amp;#039;prodtype&amp;#039;,&lt;br /&gt;
		event: Twinkle.prod.callback.prodtypechanged,&lt;br /&gt;
		list: [&lt;br /&gt;
			{&lt;br /&gt;
				label: &amp;#039;PROD (proposed deletion)&amp;#039;,&lt;br /&gt;
				value: &amp;#039;prod&amp;#039;,&lt;br /&gt;
				checked: true,&lt;br /&gt;
				tooltip: &amp;#039;Normal proposed deletion, per [[WP:PROD]]&amp;#039;&lt;br /&gt;
			},&lt;br /&gt;
			{&lt;br /&gt;
				label: &amp;#039;BLP PROD (proposed deletion of unsourced BLPs)&amp;#039;,&lt;br /&gt;
				value: &amp;#039;prodblp&amp;#039;,&lt;br /&gt;
				tooltip: &amp;#039;Proposed deletion of new, completely unsourced biographies of living persons, per [[WP:BLPPROD]]&amp;#039;&lt;br /&gt;
			}&lt;br /&gt;
		]&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
	// Placeholder fieldset to be replaced in Twinkle.prod.callback.prodtypechanged&lt;br /&gt;
	form.append({&lt;br /&gt;
		type: &amp;#039;field&amp;#039;,&lt;br /&gt;
		name: &amp;#039;parameters&amp;#039;&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
	Window.addFooterLink(&amp;#039;PROD prefs&amp;#039;, &amp;#039;WP:TW/PREF#prod&amp;#039;);&lt;br /&gt;
	Window.addFooterLink(&amp;#039;Twinkle help&amp;#039;, &amp;#039;WP:TW/DOC#prod&amp;#039;);&lt;br /&gt;
	Window.addFooterLink(&amp;#039;Give feedback&amp;#039;, &amp;#039;WT:TW&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
	form.append({ type: &amp;#039;submit&amp;#039;, label: &amp;#039;Propose deletion&amp;#039; });&lt;br /&gt;
&lt;br /&gt;
	const result = form.render();&lt;br /&gt;
	Window.setContent(result);&lt;br /&gt;
	Window.display();&lt;br /&gt;
&lt;br /&gt;
	// Hide fieldset for File PROD type since only normal PROD is allowed&lt;br /&gt;
	if (namespace !== &amp;#039;article&amp;#039;) {&lt;br /&gt;
		$(result).find(&amp;#039;#prodtype_fieldset&amp;#039;).hide();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// Fake a change event on the first prod type radio, to initialize the type-dependent controls&lt;br /&gt;
	const evt = document.createEvent(&amp;#039;Event&amp;#039;);&lt;br /&gt;
	evt.initEvent(&amp;#039;change&amp;#039;, true, true);&lt;br /&gt;
	result.prodtype[0].dispatchEvent(evt);&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Twinkle.prod.callback.prodtypechanged = function(event) {&lt;br /&gt;
	// prepare frame for prod type dependant controls&lt;br /&gt;
	const field = new Morebits.QuickForm.Element({&lt;br /&gt;
		type: &amp;#039;field&amp;#039;,&lt;br /&gt;
		label: &amp;#039;Parameters&amp;#039;,&lt;br /&gt;
		name: &amp;#039;parameters&amp;#039;&lt;br /&gt;
	});&lt;br /&gt;
	// create prod type dependant controls&lt;br /&gt;
	switch (event.target.values) {&lt;br /&gt;
		case &amp;#039;prod&amp;#039;:&lt;br /&gt;
			field.append({&lt;br /&gt;
				type: &amp;#039;checkbox&amp;#039;,&lt;br /&gt;
				list: [&lt;br /&gt;
					{&lt;br /&gt;
						label: &amp;#039;Notify page creator if possible&amp;#039;,&lt;br /&gt;
						value: &amp;#039;notify&amp;#039;,&lt;br /&gt;
						name: &amp;#039;notify&amp;#039;,&lt;br /&gt;
						tooltip: &amp;quot;A notification template will be placed on the creator&amp;#039;s talk page if this is true.&amp;quot;,&lt;br /&gt;
						checked: true&lt;br /&gt;
					}&lt;br /&gt;
				]&lt;br /&gt;
			});&lt;br /&gt;
			field.append({&lt;br /&gt;
				type: &amp;#039;textarea&amp;#039;,&lt;br /&gt;
				name: &amp;#039;reason&amp;#039;,&lt;br /&gt;
				label: &amp;#039;Reason for proposed deletion:&amp;#039;,&lt;br /&gt;
				value: Twinkle.prod.defaultReason&lt;br /&gt;
			});&lt;br /&gt;
			break;&lt;br /&gt;
&lt;br /&gt;
		case &amp;#039;prodblp&amp;#039;:&lt;br /&gt;
			// first, remember the prod value that the user entered in the textarea, in case they want to switch back. We can abuse the config field for that.&lt;br /&gt;
			if (event.target.form.reason) {&lt;br /&gt;
				Twinkle.prod.defaultReason = event.target.form.reason.value;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			field.append({&lt;br /&gt;
				type: &amp;#039;checkbox&amp;#039;,&lt;br /&gt;
				list: [&lt;br /&gt;
					{&lt;br /&gt;
						label: &amp;#039;Notify page creator if possible&amp;#039;,&lt;br /&gt;
						value: &amp;#039;notify&amp;#039;,&lt;br /&gt;
						name: &amp;#039;notify&amp;#039;,&lt;br /&gt;
						tooltip: &amp;#039;Creator of article has to be notified.&amp;#039;,&lt;br /&gt;
						checked: true,&lt;br /&gt;
						disabled: true&lt;br /&gt;
					}&lt;br /&gt;
				]&lt;br /&gt;
			});&lt;br /&gt;
			// temp warning, can be removed down the line once BLPPROD is more established. Amalthea, May 2010.&lt;br /&gt;
			var boldtext = document.createElement(&amp;#039;b&amp;#039;);&lt;br /&gt;
			boldtext.appendChild(document.createTextNode(&amp;#039;Please note that only unsourced biographies of living persons are eligible for this tag, narrowly construed.&amp;#039;));&lt;br /&gt;
			field.append({&lt;br /&gt;
				type: &amp;#039;div&amp;#039;,&lt;br /&gt;
				label: boldtext&lt;br /&gt;
			});&lt;br /&gt;
			break;&lt;br /&gt;
&lt;br /&gt;
		default:&lt;br /&gt;
			break;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	Twinkle.makeFindSourcesDiv(&amp;#039;#twinkle-prod-findsources&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
	event.target.form.replaceChild(field.render(), $(event.target.form).find(&amp;#039;fieldset[name=&amp;quot;parameters&amp;quot;]&amp;#039;)[0]);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// global params object, initially set in evaluate(), and&lt;br /&gt;
// modified in various callback functions&lt;br /&gt;
let params = {};&lt;br /&gt;
&lt;br /&gt;
Twinkle.prod.callbacks = {&lt;br /&gt;
	checkPriors: function twinkleprodcheckPriors() {&lt;br /&gt;
		const talk_title = new mw.Title(mw.config.get(&amp;#039;wgPageName&amp;#039;)).getTalkPage().getPrefixedText();&lt;br /&gt;
		// Talk page templates for PROD-able discussions&lt;br /&gt;
		const blocking_templates = &amp;#039;Template:Old XfD multi|Template:Old MfD|Template:Oldffdfull|&amp;#039; + // Common prior XfD talk page templates&lt;br /&gt;
			&amp;#039;Template:Oldpuffull|&amp;#039; + // Legacy prior XfD template&lt;br /&gt;
			&amp;#039;Template:Olddelrev|&amp;#039; + // Prior DRV template&lt;br /&gt;
			&amp;#039;Template:Old prod&amp;#039;;&lt;br /&gt;
		const query = {&lt;br /&gt;
			action: &amp;#039;query&amp;#039;,&lt;br /&gt;
			titles: talk_title,&lt;br /&gt;
			prop: &amp;#039;templates&amp;#039;,&lt;br /&gt;
			tltemplates: blocking_templates,&lt;br /&gt;
			format: &amp;#039;json&amp;#039;&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		const wikipedia_api = new Morebits.wiki.Api(&amp;#039;Checking talk page for prior nominations&amp;#039;, query);&lt;br /&gt;
		return wikipedia_api.post().then((apiobj) =&amp;gt; {&lt;br /&gt;
			const statelem = apiobj.statelem;&lt;br /&gt;
&lt;br /&gt;
			// Check talk page for templates indicating prior XfD or PROD&lt;br /&gt;
			const templates = apiobj.getResponse().query.pages[0].templates;&lt;br /&gt;
			const numTemplates = templates &amp;amp;&amp;amp; templates.length;&lt;br /&gt;
			if (numTemplates) {&lt;br /&gt;
				const template = templates[0].title;&lt;br /&gt;
				if (numTemplates === 1 &amp;amp;&amp;amp; template === &amp;#039;Template:Old prod&amp;#039;) {&lt;br /&gt;
					params.oldProdPresent = true; // Mark for reference later, when deciding if to endorse&lt;br /&gt;
				// if there are multiple templates, at least one of them would be a prior xfd template&lt;br /&gt;
				} else {&lt;br /&gt;
					statelem.warn(&amp;#039;Previous XfD template found on talk page, aborting procedure&amp;#039;);&lt;br /&gt;
					return $.Deferred().reject();&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	fetchCreationInfo: function twinkleprodFetchCreationInfo() {&lt;br /&gt;
		const def = $.Deferred();&lt;br /&gt;
		const ts = new Morebits.wiki.Page(mw.config.get(&amp;#039;wgPageName&amp;#039;), &amp;#039;Looking up page creator&amp;#039;);&lt;br /&gt;
		ts.setFollowRedirect(true); // for NPP, and also because redirects are ineligible for PROD&lt;br /&gt;
		ts.setLookupNonRedirectCreator(true); // Look for author of first non-redirect revision&lt;br /&gt;
		ts.lookupCreation((pageobj) =&amp;gt; {&lt;br /&gt;
			params.initialContrib = pageobj.getCreator();&lt;br /&gt;
			params.creation = pageobj.getCreationTimestamp();&lt;br /&gt;
			pageobj.getStatusElement().info(&amp;#039;Done, found &amp;#039; + params.initialContrib);&lt;br /&gt;
			def.resolve();&lt;br /&gt;
		}, def.reject);&lt;br /&gt;
		return def;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	taggingPage: function twinkleprodTaggingPage() {&lt;br /&gt;
		const def = $.Deferred();&lt;br /&gt;
&lt;br /&gt;
		const wikipedia_page = new Morebits.wiki.Page(mw.config.get(&amp;#039;wgPageName&amp;#039;), &amp;#039;Tagging page&amp;#039;);&lt;br /&gt;
		wikipedia_page.setFollowRedirect(true); // for NPP, and also because redirects are ineligible for PROD&lt;br /&gt;
		wikipedia_page.load((pageobj) =&amp;gt; {&lt;br /&gt;
			const statelem = pageobj.getStatusElement();&lt;br /&gt;
&lt;br /&gt;
			if (!pageobj.exists()) {&lt;br /&gt;
				statelem.error(&amp;quot;It seems that the page doesn&amp;#039;t exist. Perhaps it has already been deleted.&amp;quot;);&lt;br /&gt;
				// reject, so that all dependent actions like notifyAuthor() and&lt;br /&gt;
				// addToLog() are cancelled&lt;br /&gt;
				return def.reject();&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			let text = pageobj.getPageText();&lt;br /&gt;
&lt;br /&gt;
			// Check for already existing deletion tags&lt;br /&gt;
			const tag_re = /{{(?:article for deletion\/dated|AfDM|ffd\b)|#invoke:RfD/i;&lt;br /&gt;
			if (tag_re.test(text)) {&lt;br /&gt;
				statelem.warn(&amp;#039;Page already tagged with a deletion template, aborting procedure&amp;#039;);&lt;br /&gt;
				return def.reject();&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			// Remove tags that become superfluous with this action&lt;br /&gt;
			text = text.replace(/{{\s*(userspace draft|mtc|(copy|move) to wikimedia commons|(copy |move )?to ?commons)\s*(\|(?:{{[^{}]*}}|[^{}])*)?}}\s*/gi, &amp;#039;&amp;#039;);&lt;br /&gt;
			const prod_re = /{{\s*(?:Prod blp|Proposed deletion)\/dated(?: files)?\s*\|(?:{{[^{}]*}}|[^{}])*}}/i;&lt;br /&gt;
			let summaryText;&lt;br /&gt;
&lt;br /&gt;
			if (!prod_re.test(text)) {&lt;br /&gt;
&lt;br /&gt;
				// Page previously PROD-ed&lt;br /&gt;
				if (params.oldProdPresent) {&lt;br /&gt;
					if (params.blp) {&lt;br /&gt;
						if (!confirm(&amp;#039;Previous PROD nomination found on talk page. Do you still want to continue applying BLPPROD? &amp;#039;)) {&lt;br /&gt;
							statelem.warn(&amp;#039;Previous PROD found on talk page, aborted by user&amp;#039;);&lt;br /&gt;
							return def.reject();&lt;br /&gt;
						}&lt;br /&gt;
						statelem.info(&amp;#039;Previous PROD found on talk page, continuing&amp;#039;);&lt;br /&gt;
					} else {&lt;br /&gt;
						statelem.warn(&amp;#039;Previous PROD found on talk page, aborting procedure&amp;#039;);&lt;br /&gt;
						return def.reject();&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
				let tag;&lt;br /&gt;
				if (params.blp) {&lt;br /&gt;
					summaryText = &amp;#039;Proposing article for deletion per [[WP:BLPPROD]].&amp;#039;;&lt;br /&gt;
					tag = &amp;#039;{{subst:prod blp&amp;#039; + (params.usertalk ? &amp;#039;|help=off&amp;#039; : &amp;#039;&amp;#039;) + &amp;#039;}}&amp;#039;;&lt;br /&gt;
				} else {&lt;br /&gt;
					summaryText = &amp;#039;Proposing &amp;#039; + namespace + &amp;#039; for deletion per [[WP:PROD]].&amp;#039;;&lt;br /&gt;
					tag = &amp;#039;{{subst:prod|1=&amp;#039; + Morebits.string.formatReasonText(params.reason) + (params.usertalk ? &amp;#039;|help=off&amp;#039; : &amp;#039;&amp;#039;) + &amp;#039;}}&amp;#039;;&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
				// Insert tag after short description or any hatnotes&lt;br /&gt;
				const wikipage = new Morebits.wikitext.Page(text);&lt;br /&gt;
				text = wikipage.insertAfterTemplates(tag + &amp;#039;\n&amp;#039;, Twinkle.hatnoteRegex).getText();&lt;br /&gt;
&lt;br /&gt;
			} else { // already tagged for PROD, so try endorsing it&lt;br /&gt;
				const prod2_re = /{{(?:Proposed deletion endorsed|prod-?2).*?}}/i;&lt;br /&gt;
				if (prod2_re.test(text)) {&lt;br /&gt;
					statelem.warn(&amp;#039;Page already tagged with {{proposed deletion}} and {{proposed deletion endorsed}} templates, aborting procedure&amp;#039;);&lt;br /&gt;
					return def.reject();&lt;br /&gt;
				}&lt;br /&gt;
				let confirmtext = &amp;#039;A {{proposed deletion}} tag was already found on this page. \nWould you like to add a {{proposed deletion endorsed}} tag with your explanation?&amp;#039;;&lt;br /&gt;
				if (params.blp &amp;amp;&amp;amp; !/{{\s*Prod blp\/dated/.test(text)) {&lt;br /&gt;
					confirmtext = &amp;#039;A non-BLP {{proposed deletion}} tag was found on this article.\nWould you like to add a {{proposed deletion endorsed}} tag with explanation &amp;quot;article is a biography of a living person with no sources&amp;quot;?&amp;#039;;&lt;br /&gt;
				}&lt;br /&gt;
				if (!confirm(confirmtext)) {&lt;br /&gt;
					statelem.warn(&amp;#039;Aborted per user request&amp;#039;);&lt;br /&gt;
					return def.reject();&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
				summaryText = &amp;#039;Endorsing proposed deletion per [[WP:&amp;#039; + (params.blp ? &amp;#039;BLP&amp;#039; : &amp;#039;&amp;#039;) + &amp;#039;PROD]].&amp;#039;;&lt;br /&gt;
				text = text.replace(prod_re, text.match(prod_re) + &amp;#039;\n{{Proposed deletion endorsed|1=&amp;#039; + (params.blp ?&lt;br /&gt;
					&amp;#039;article is a [[WP:BLPPROD|biography of a living person with no sources]]&amp;#039; :&lt;br /&gt;
					Morebits.string.formatReasonText(params.reason)) + &amp;#039;}}\n&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
				params.logEndorsing = true;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			pageobj.setPageText(text);&lt;br /&gt;
			pageobj.setEditSummary(summaryText);&lt;br /&gt;
			pageobj.setChangeTags(Twinkle.changeTags);&lt;br /&gt;
			pageobj.setWatchlist(Twinkle.getPref(&amp;#039;watchProdPages&amp;#039;));&lt;br /&gt;
			pageobj.setCreateOption(&amp;#039;nocreate&amp;#039;);&lt;br /&gt;
			pageobj.save(def.resolve, def.reject);&lt;br /&gt;
&lt;br /&gt;
			// curate/patrol the page&lt;br /&gt;
			if (Twinkle.getPref(&amp;#039;markProdPagesAsPatrolled&amp;#039;)) {&lt;br /&gt;
				pageobj.triage();&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
		}, def.reject);&lt;br /&gt;
		return def;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	addOldProd: function twinkleprodAddOldProd() {&lt;br /&gt;
		const def = $.Deferred();&lt;br /&gt;
&lt;br /&gt;
		if (params.oldProdPresent || params.blp) {&lt;br /&gt;
			return def.resolve();&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Add {{Old prod}} to the talk page&lt;br /&gt;
		const oldprodfull = &amp;#039;{{Old prod|nom=&amp;#039; + mw.config.get(&amp;#039;wgUserName&amp;#039;) + &amp;#039;|nomdate={{subst:#time: Y-m-d}}}}\n&amp;#039;;&lt;br /&gt;
		const talktitle = new mw.Title(mw.config.get(&amp;#039;wgPageName&amp;#039;)).getTalkPage().getPrefixedText();&lt;br /&gt;
		const talkpage = new Morebits.wiki.Page(talktitle, &amp;#039;Placing {{Old prod}} on talk page&amp;#039;);&lt;br /&gt;
		talkpage.setPrependText(oldprodfull);&lt;br /&gt;
		talkpage.setEditSummary(&amp;#039;Adding {{Old prod}}&amp;#039;);&lt;br /&gt;
		talkpage.setChangeTags(Twinkle.changeTags);&lt;br /&gt;
		talkpage.setFollowRedirect(true); // match behavior for page tagging&lt;br /&gt;
		talkpage.setCreateOption(&amp;#039;recreate&amp;#039;);&lt;br /&gt;
		talkpage.prepend(def.resolve, def.reject);&lt;br /&gt;
		return def;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	notifyAuthor: function twinkleprodNotifyAuthor() {&lt;br /&gt;
		const def = $.Deferred();&lt;br /&gt;
&lt;br /&gt;
		if (!params.blp &amp;amp;&amp;amp; !params.usertalk) {&lt;br /&gt;
			return def.resolve();&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Disallow warning yourself&lt;br /&gt;
		if (params.initialContrib === mw.config.get(&amp;#039;wgUserName&amp;#039;)) {&lt;br /&gt;
			Morebits.Status.info(&amp;#039;Notifying creator&amp;#039;, &amp;#039;You (&amp;#039; + params.initialContrib + &amp;#039;) created this page; skipping user notification&amp;#039;);&lt;br /&gt;
			return def.resolve();&lt;br /&gt;
		}&lt;br /&gt;
		// [[Template:Proposed deletion notify]] supports File namespace&lt;br /&gt;
		let notifyTemplate;&lt;br /&gt;
		if (params.blp) {&lt;br /&gt;
			notifyTemplate = &amp;#039;prodwarningBLP&amp;#039;;&lt;br /&gt;
		} else {&lt;br /&gt;
			notifyTemplate = &amp;#039;proposed deletion notify&amp;#039;;&lt;br /&gt;
		}&lt;br /&gt;
		const notifytext = &amp;#039;\n{{subst:&amp;#039; + notifyTemplate + &amp;#039;|1=&amp;#039; + Morebits.pageNameNorm + &amp;#039;|concern=&amp;#039; + params.reason + &amp;#039;}} ~~~~&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
		const usertalkpage = new Morebits.wiki.Page(&amp;#039;User talk:&amp;#039; + params.initialContrib, &amp;#039;Notifying initial contributor (&amp;#039; + params.initialContrib + &amp;#039;)&amp;#039;);&lt;br /&gt;
		usertalkpage.setAppendText(notifytext);&lt;br /&gt;
		usertalkpage.setEditSummary(&amp;#039;Notification: proposed deletion of [[:&amp;#039; + Morebits.pageNameNorm + &amp;#039;]].&amp;#039;);&lt;br /&gt;
		usertalkpage.setChangeTags(Twinkle.changeTags);&lt;br /&gt;
		usertalkpage.setCreateOption(&amp;#039;recreate&amp;#039;);&lt;br /&gt;
		usertalkpage.setFollowRedirect(true, false);&lt;br /&gt;
		usertalkpage.append(() =&amp;gt; {&lt;br /&gt;
			// add nomination to the userspace log, if the user has enabled it&lt;br /&gt;
			params.logInitialContrib = params.initialContrib;&lt;br /&gt;
			def.resolve();&lt;br /&gt;
		}, def.resolve); // resolves even if notification was unsuccessful&lt;br /&gt;
&lt;br /&gt;
		return def;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	addToLog: function twinkleprodAddToLog() {&lt;br /&gt;
		if (!Twinkle.getPref(&amp;#039;logProdPages&amp;#039;)) {&lt;br /&gt;
			return $.Deferred().resolve();&lt;br /&gt;
		}&lt;br /&gt;
		const usl = new Morebits.UserspaceLogger(Twinkle.getPref(&amp;#039;prodLogPageName&amp;#039;));&lt;br /&gt;
		usl.initialText =&lt;br /&gt;
			&amp;quot;This is a log of all [[WP:PROD|proposed deletion]] tags applied or endorsed by this user using [[WP:TW|Twinkle]]&amp;#039;s PROD module.\n\n&amp;quot; +&lt;br /&gt;
			&amp;#039;If you no longer wish to keep this log, you can turn it off using the [[Wikipedia:Twinkle/Preferences|preferences panel]], and &amp;#039; +&lt;br /&gt;
			&amp;#039;nominate this page for speedy deletion under [[WP:CSD#U1|CSD U1]].&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
		let logText = &amp;#039;# [[:&amp;#039; + Morebits.pageNameNorm + &amp;#039;]]&amp;#039;;&lt;br /&gt;
		let summaryText;&lt;br /&gt;
		// If a logged file is deleted but exists on commons, the wikilink will be blue, so provide a link to the log&lt;br /&gt;
		logText += namespace === &amp;#039;file&amp;#039; ? &amp;#039; ([{{fullurl:Special:Log|page=&amp;#039; + mw.util.wikiUrlencode(mw.config.get(&amp;#039;wgPageName&amp;#039;)) + &amp;#039;}} log]): &amp;#039; : &amp;#039;: &amp;#039;;&lt;br /&gt;
		if (params.logEndorsing) {&lt;br /&gt;
			logText += &amp;#039;endorsed &amp;#039; + (params.blp ? &amp;#039;BLP &amp;#039; : &amp;#039;&amp;#039;) + &amp;#039;PROD. ~~~~~&amp;#039;;&lt;br /&gt;
			if (params.reason) {&lt;br /&gt;
				logText += &amp;quot;\n#* &amp;#039;&amp;#039;&amp;#039;Reason&amp;#039;&amp;#039;&amp;#039;: &amp;quot; + params.reason + &amp;#039;\n&amp;#039;;&lt;br /&gt;
			}&lt;br /&gt;
			summaryText = &amp;#039;Logging endorsement of PROD nomination of [[:&amp;#039; + Morebits.pageNameNorm + &amp;#039;]].&amp;#039;;&lt;br /&gt;
		} else {&lt;br /&gt;
			logText += (params.blp ? &amp;#039;BLP &amp;#039; : &amp;#039;&amp;#039;) + &amp;#039;PROD&amp;#039;;&lt;br /&gt;
			if (params.logInitialContrib) {&lt;br /&gt;
				logText += &amp;#039;; notified {{user|&amp;#039; + params.logInitialContrib + &amp;#039;}}&amp;#039;;&lt;br /&gt;
			}&lt;br /&gt;
			logText += &amp;#039; ~~~~~\n&amp;#039;;&lt;br /&gt;
			if (!params.blp &amp;amp;&amp;amp; params.reason) {&lt;br /&gt;
				logText += &amp;quot;#* &amp;#039;&amp;#039;&amp;#039;Reason&amp;#039;&amp;#039;&amp;#039;: &amp;quot; + Morebits.string.formatReasonForLog(params.reason) + &amp;#039;\n&amp;#039;;&lt;br /&gt;
			}&lt;br /&gt;
			summaryText = &amp;#039;Logging PROD nomination of [[:&amp;#039; + Morebits.pageNameNorm + &amp;#039;]].&amp;#039;;&lt;br /&gt;
		}&lt;br /&gt;
		usl.changeTags = Twinkle.changeTags;&lt;br /&gt;
&lt;br /&gt;
		return usl.log(logText, summaryText);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Twinkle.prod.callback.evaluate = function twinkleprodCallbackEvaluate(e) {&lt;br /&gt;
	const form = e.target;&lt;br /&gt;
	const input = Morebits.QuickForm.getInputData(form);&lt;br /&gt;
&lt;br /&gt;
	params = {&lt;br /&gt;
		usertalk: input.notify || input.prodtype === &amp;#039;prodblp&amp;#039;,&lt;br /&gt;
		blp: input.prodtype === &amp;#039;prodblp&amp;#039;,&lt;br /&gt;
		reason: input.reason || &amp;#039;&amp;#039; // using an empty string here as fallback will help with prod-2.&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	if (!params.blp &amp;amp;&amp;amp; !params.reason) {&lt;br /&gt;
		if (!confirm(&amp;#039;You left the reason blank, do you really want to continue without providing one?&amp;#039;)) {&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	Morebits.SimpleWindow.setButtonsEnabled(false);&lt;br /&gt;
	Morebits.Status.init(form);&lt;br /&gt;
&lt;br /&gt;
	const tm = new Morebits.TaskManager();&lt;br /&gt;
	const cbs = Twinkle.prod.callbacks; // shortcut reference, cbs for `callbacks`&lt;br /&gt;
&lt;br /&gt;
	// Disable Morebits.wiki.numberOfActionsLeft system&lt;br /&gt;
	Morebits.wiki.numberOfActionsLeft = 1000;&lt;br /&gt;
&lt;br /&gt;
	// checkPriors() and fetchCreationInfo() have no dependencies, they&amp;#039;ll run first&lt;br /&gt;
	tm.add(cbs.checkPriors, []);&lt;br /&gt;
	tm.add(cbs.fetchCreationInfo, []);&lt;br /&gt;
	// tag the page once we&amp;#039;re clear of the pre-requisites&lt;br /&gt;
	tm.add(cbs.taggingPage, [ cbs.checkPriors, cbs.fetchCreationInfo ]);&lt;br /&gt;
	// notify the author once we know who&amp;#039;s the author, and also wait for the&lt;br /&gt;
	// taggingPage() as we don&amp;#039;t need to notify if tagging was not done, such as&lt;br /&gt;
	// there was already a tag and the user chose not to endorse.&lt;br /&gt;
	tm.add(cbs.notifyAuthor, [ cbs.fetchCreationInfo, cbs.taggingPage ]);&lt;br /&gt;
	// oldProd needs to be added only if there wasn&amp;#039;t one before, so need to wait&lt;br /&gt;
	// for checkPriors() to finish. Also don&amp;#039;t add oldProd if tagging itself was&lt;br /&gt;
	// aborted or unsuccessful&lt;br /&gt;
	tm.add(cbs.addOldProd, [ cbs.taggingPage, cbs.checkPriors ]);&lt;br /&gt;
	// add to log only after notifying author so that the logging can be adjusted if&lt;br /&gt;
	// notification wasn&amp;#039;t successful. Also, don&amp;#039;t run if tagging was not done.&lt;br /&gt;
	tm.add(cbs.addToLog, [ cbs.notifyAuthor, cbs.taggingPage ]);&lt;br /&gt;
	// All set, go!&lt;br /&gt;
	tm.execute().then(() =&amp;gt; {&lt;br /&gt;
		Morebits.Status.actionCompleted(&amp;#039;Tagging complete&amp;#039;);&lt;br /&gt;
		setTimeout(() =&amp;gt; {&lt;br /&gt;
			window.location.href = mw.util.getUrl(mw.config.get(&amp;#039;wgPageName&amp;#039;));&lt;br /&gt;
		}, Morebits.wiki.actionCompleted.timeOut);&lt;br /&gt;
	});&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Twinkle.addInitCallback(Twinkle.prod, &amp;#039;prod&amp;#039;);&lt;br /&gt;
}());&lt;br /&gt;
&lt;br /&gt;
// &amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>en&gt;SD0001</name></author>
	</entry>
</feed>