User:Anderjef/common.js

// /* jshint leanswitch: true, nonbsp: true, nonew: true, singleGroups: true, strict: true, undef: true, unused: true */ /* globals $, console, document, Event, mw, pathoschild, performance, window */ $(function {	"use strict";	try {		var forbiddenPages = [];		var dayOfWeek = (new Date).getDay;		if (1 <= dayOfWeek) {			forbiddenPages = ['Main_Page', 'Special:Search', 'Special:Homepage', 'Special:Watchlist', 'User:Uhai/Pages_without_short_descriptions_by_view_count'];		}		else {			var hour = (new Date).getHours;			if (hour < 7 || 19 <= hour) {				forbiddenPages = ['User:Uhai/Pages_without_short_descriptions_by_view_count'];			}		}		for (var i = 0; i < forbiddenPages.length; i++) {			if (window.location.pathname.includes(forbiddenPages[i]) || window.location.search.includes(forbiddenPages[i])) {				window.location.assign("https://www.wikipedia.org");				break;			}		}	}	catch (e) { //continue even if an error occurred		 console.error(e.message);	}	function reportCompletion(description, duration, notificationType, storageName, storageAdditionalSum, textSize) { //duration is assumed to be in milliseconds; notificationType being 'info', 'warn', 'error', or 'success'; notification becomes description + " in " + duration + "ms" var notificationString = description + " in " + duration + "ms"; if (notificationType !== 'info') { mw.notify(notificationString, { type: notificationType }); }		switch (notificationType) { case 'error': console.error(notificationString); break; case 'info': case 'success': console.info(notificationString); break; case 'warn': console.warn(notificationString); break; }		if (storageName !== undefined) { var attributeName = notificationType === 'info' ? 'count' : 'tries'; var existingItem = window.localStorage.getItem(storageName + ' ' + notificationType); if (existingItem !== null) { var existingStorageAdditionalSum = parseInt(existingItem.substring(existingItem.indexOf(attributeName + ': ') + (attributeName + ': ').length)); var existingTextSize = existingItem.indexOf('bytes: ') < 0 ? 'NaN' : parseInt(existingItem.substring(existingItem.indexOf('bytes: ') + 'bytes: '.length)); window.localStorage.setItem(storageName + ' ' + notificationType, 'milliseconds: ' + (parseInt(existingItem.substring(existingItem.indexOf('milliseconds: ') + 'milliseconds: '.length)) + duration) + ', ' + attributeName + ': ' + (isNaN(existingStorageAdditionalSum) ? (!isNaN(storageAdditionalSum) ? storageAdditionalSum : 'NaN') : existingStorageAdditionalSum + storageAdditionalSum) + ', tally: ' + (parseInt(existingItem.substring(existingItem.indexOf('tally: ') + 'tally: '.length)) + 1) + (isNaN(existingTextSize) ? (!isNaN(textSize) ? ', bytes: ' + textSize : '') : ', bytes: ' + (existingTextSize + textSize))); }			else { window.localStorage.setItem(storageName + ' ' + notificationType, 'milliseconds: ' + duration + ', ' + attributeName + ': ' + storageAdditionalSum + ', tally: 1' + (!isNaN(textSize) ? ', bytes: ' + textSize : '')); }		}	}	Number.prototype.round = function(numPlaces) { return +(Math.round(this + "e+" + numPlaces) + "e-" + numPlaces); //+ casts string back to number to strip excess zeroes };	function filterCurrentEvents(numTries, startTime) { if ($('.p-current-events-headlines ul').length && $('.itn-img').length) { var currentEventsFilter = ["basketball", "cricket", "Cricket World Cup", "Eurovision Song Contest", "filmmaker", "Film Awards", "Film Festival", "football", "golf", "hockey", "In television, ", "In tennis, ", "Japan Series", "NASCAR Cup Series", "PDC World Championship", "rugby", "World Baseball Classic"]; for (var i = 0; i < currentEventsFilter.length; i++) { for (var j = 0; j < $('.p-current-events-headlines ul li:contains(' + currentEventsFilter[i] + ')').length; j++) { if ($('.p-current-events-headlines ul li:contains(' + currentEventsFilter[i] + ')')[j].innerText.match(/\([^\(\)]*[pP]ictured[^\(\)]*\)/)) { $('.itn-img')[0].remove; }				}				$('.p-current-events-headlines ul li:contains(' + currentEventsFilter[i] + ')').hide; }			reportCompletion(numTries + " tries before current events were filtered", (performance.now - startTime).round(3), 'success', 'current-events-filtering', numTries, 'NaN'); }		else if (++numTries < 10000) { window.setTimeout(filterCurrentEvents, 5, numTries, startTime); } //try for 10000*5 milliseconds (that is 50 seconds) else { reportCompletion("Failed to filter current events", (performance.now - startTime).round(3), 'error', 'current-events-filtering', numTries, 'NaN'); } }	function scrollToEditWindow(numTries, startTime) { if ($('#wikiEditor-ui-toolbar').length) { $('#wikiEditor-ui-toolbar')[0].scrollIntoView; reportCompletion(numTries + " tries before editor window was scrolled to", (performance.now - startTime).round(3), 'success', 'editor-window-focusing', numTries, 'NaN'); }		else if (++numTries < 5000) { window.setTimeout(scrollToEditWindow, 5, numTries, startTime); } //try for 5000*5 milliseconds (that is 25 seconds) else { reportCompletion("Failed to scroll to editor window", (performance.now - startTime).round(3), 'error', 'editor-window-focusing', numTries, 'NaN'); } }	var watchlistExpiryIsSet = false; //basically a mutex for the watchlist expiry function setWatchlistExpiry(numTries, startTime, expiryValue) { if (expiryValue === undefined ? $('#wpWatchthis').length : $('#wpWatchlistExpiry').length) { if (expiryValue === undefined) { if ($('#wpWatchthis')[0].checked) { $('#wpWatchthis').first.click; //unset watching }			}			else { $('#wpWatchlistExpiry').val(expiryValue).trigger('change'); }			reportCompletion(numTries + " tries before watchlist expiry was set", (performance.now - startTime).round(3), 'success', 'watchlist-expiry-setting', numTries, 'NaN'); watchlistExpiryIsSet = true; }		else if (++numTries < 1000) { window.setTimeout(setWatchlistExpiry, 5, numTries, startTime, expiryValue); } //try for 1000*5 milliseconds (that is 5 seconds) else { reportCompletion("Failed to set watchlist expiry", (performance.now - startTime).round(3), 'error', 'watchlist-expiry-setting', numTries, 'NaN'); } }	function filterWatchlistExpiryOptions(numTries, startTime) { var watchlistExpiryElements = document.getElementsByClassName('oo-ui-widget oo-ui-widget-enabled oo-ui-labelElement oo-ui-optionWidget oo-ui-decoratedOptionWidget oo-ui-menuOptionWidget'); if ($('#wpWatchlistExpiry').length && watchlistExpiryElements.length) { var filteredWatchlistExpiryOptions = ["6 months", "1 year"]; for (var i = 0; i < $('#wpWatchlistExpiry')[0].children.length; i++) { for (var j = 0; j < filteredWatchlistExpiryOptions.length; j++) { if ($('#wpWatchlistExpiry')[0].children[i].innerText === filteredWatchlistExpiryOptions[j]) { $('#wpWatchlistExpiry')[0].children[i].remove; }				}			}			for (var k = 0; k < watchlistExpiryElements.length; k++) { for (var l = 0; l < filteredWatchlistExpiryOptions.length; l++) { if (watchlistExpiryElements[k].innerText === filteredWatchlistExpiryOptions[l]) { watchlistExpiryElements[k].remove; }				}			}			reportCompletion(numTries + " tries before watchlist expiry options were filtered", (performance.now - startTime).round(3), 'success', 'watchlist-expiry-filtering', numTries, 'NaN'); }		else if (++numTries < 5000) { window.setTimeout(filterWatchlistExpiryOptions, 5, numTries, startTime); } //try for 5000*5 milliseconds (that is 25 seconds) else { reportCompletion("Failed to filter watchlist expiry options", (performance.now - startTime).round(3), 'error', 'watchlist-expiry-filtering', numTries, 'NaN'); } }	function increaseEditorSpecialCharactersBarHeight(numTries, startTime) { if ($('#editpage-specialchars').length) { $('#editpage-specialchars').css('padding-top', '6.25vh'); window.dispatchEvent(new Event('resize')); reportCompletion(numTries + " tries before wikitext editor's special characters bar was heightened", (performance.now - startTime).round(3), 'success', 'special-characters-bar-heightening', numTries, 'NaN'); }		else if (++numTries < 5000) { window.setTimeout(increaseEditorSpecialCharactersBarHeight, 10, numTries, startTime); } //try for 5000*10 milliseconds (that is 50 seconds) else { reportCompletion("Failed to increase height of wikitext editor's special characters bar", (performance.now - startTime).round(3), 'error', 'special-characters-bar-heightening', numTries, 'NaN'); } }	function increaseWikitextEditorHeight(numTries, startTime) { if ($('.wikiEditor-ui-view-wikitext').length) { $('.wikiEditor-ui-view-wikitext').height('75vh'); window.dispatchEvent(new Event('resize')); reportCompletion(numTries + " tries before wikitext editor was heightened", (performance.now - startTime).round(3), 'success', 'wikitext-editor-heightening', numTries, 'NaN'); increaseEditorSpecialCharactersBarHeight(0, performance.now); }		else if (++numTries < 5000) { window.setTimeout(increaseWikitextEditorHeight, 10, numTries, startTime); } //try for 5000*10 milliseconds (that is 50 seconds) else { reportCompletion("Failed to increase height of wikitext editor", (performance.now - startTime).round(3), 'error', 'wikitext-editor-heightening', numTries, 'NaN'); } }	var allowLaterModificationOfWatchlistExpiry; try { if (['edit', 'submit'].includes(mw.config.get('wgAction'))) { allowLaterModificationOfWatchlistExpiry = !['User', 'User_talk'].includes(mw.config.get('wgCanonicalNamespace')); scrollToEditWindow(0, performance.now); if (!allowLaterModificationOfWatchlistExpiry) { if (mw.config.get('wgUserName') === mw.config.get('wgTitle').substring(0, mw.config.get('wgUserName').length)) { setWatchlistExpiry(0, performance.now, 'infinite'); } else { setWatchlistExpiry(0, performance.now, "1 week"); } }			else { setWatchlistExpiry(0, performance.now, "3 months"); } $('.editButtons').insertBefore('#editpage-copywarn'); filterWatchlistExpiryOptions(0, performance.now); if (mw.config.get('wgPageContentModel') === 'wikitext') { //if editing wikitext increaseWikitextEditorHeight(0, performance.now); }		}		else { allowLaterModificationOfWatchlistExpiry = false; if (mw.config.get('wgCanonicalSpecialPageName') === 'Homepage') { //hide suggested edits $('.growthexperiments-homepage-module-header')[0].remove; $('.growthexperiments-homepage-module-body')[1].style.display = 'none'; $('.growthexperiments-homepage-module-mobile-summary activated')[0].remove; }			else if (mw.config.get('wgCanonicalSpecialPageName') === 'Watchlist') { //add current events headlines var element = document.createElement('div'); element.setAttribute('class', 'my-class'); document.getElementById('mw-content-text').insertBefore(element, document.getElementsByClassName('mw-rcfilters-head')[0]); $('.my-class').load('https://en.wikipedia.org/wiki/Portal:Current_events .p-current-events-headlines'); filterCurrentEvents(0, performance.now); }			else if (mw.config.get('wgPageName') === 'User:' + mw.config.get('wgUserName')) { //add (primitive-looking) impact view counts var element = document.createElement('div'); element.setAttribute('class', 'my-class'); document.getElementById('bodyContent').insertBefore(element, document.getElementById('catlinks')[0]); $('.my-class').load('https://en.wikipedia.org/wiki/Special:Homepage .growthexperiments-homepage-group-sidebar-subgroup-primary'); }		}	}	catch (e) { //continue even if an error occurred console.error(e.message); }

/**	 * TemplateScript adds configurable templates and scripts to the sidebar, and adds an example regex editor. * @see https://meta.wikimedia.org/wiki/TemplateScript * @update-token */	mw.config.set('userjs-templatescript', { regexEditor: false }); //disable TemplateScript's regex editor $.ajax('//tools-static.wmflabs.org/meta/scripts/pathoschild.templatescript.js', { dataType:'script', cache:true }).then(function {		var watchlistExpiryMode = 0; //0 for don't watch, 1 for regular, 2 for extended		function waitForWatchlistIndicatorForAutomaticCleanup(numTries, startTime) {			if ($('#ca-watch').length || $('#ca-unwatch').length) {				reportCompletion(numTries + " tries before watchlist indicator was detected", (performance.now - startTime).round(3), 'success', 'watchlist-indicator-detection', numTries, 'NaN');				if ($('#ca-watch').length) { //presence of the #ca-watch element indicates the ability to watch the page because it is not already on the watchlist					var expiryValue;					switch (watchlistExpiryMode) {						case 0:							//leave expiryValue undefined							break;						case 1:							expiryValue = '1 week';							break;						case 2:							expiryValue = '1 month'; break; }					setWatchlistExpiry(0, performance.now, expiryValue); }			}			else if (++numTries < 1000) { window.setTimeout(waitForWatchlistIndicatorForAutomaticCleanup, 5, numTries, startTime); } //try for 1000*5 milliseconds (that is 5 seconds) else { reportCompletion("Failed to detect watchlist indicator", (performance.now - startTime).round(3), 'error', 'watchlist-indicator-detection', numTries, 'NaN'); } }		function setWatchlistExpiryForCleanupHelper(numTries, startTime) { if (watchlistExpiryIsSet) { watchlistExpiryIsSet = false; reportCompletion(numTries + " tries before setting watchlist expiry on cleanup", (performance.now - startTime).round(3), 'success', 'cleanup-watchlist-expiry-setting', numTries, 'NaN'); waitForWatchlistIndicatorForAutomaticCleanup(0, performance.now); }			else if (++numTries < 1000) { window.setTimeout(setWatchlistExpiryForCleanupHelper, 5, numTries, startTime); } //try for 1000*5 milliseconds (that is 5 seconds) else { reportCompletion("Failed to set watchlist expiry on cleanup", (performance.now - startTime).round(3), 'error', 'cleanup-watchlist-expiry-setting', numTries, 'NaN'); } }		function setWatchlistExpiryForCleanup(numTries, startTime) { if (allowLaterModificationOfWatchlistExpiry !== undefined) { reportCompletion(numTries + " tries before permission to set watchlist expiry on cleanup was detected", (performance.now - startTime).round(3), 'success', 'cleanup-watchlist-expiry-permission-detection', numTries, 'NaN'); if (allowLaterModificationOfWatchlistExpiry) { setWatchlistExpiryForCleanupHelper(0, performance.now); }			}			else if (++numTries < 1000) { window.setTimeout(setWatchlistExpiryForCleanup, 5, numTries, startTime); } //try for 1000*5 milliseconds (that is 5 seconds) else { reportCompletion("Failed to detect permission to set watchlist expiry on cleanup", (performance.now - startTime).round(3), 'error', 'cleanup-watchlist-expiry-permission-detection', numTries, 'NaN'); } }		var summaryAppendix; //globalized due to use in conductRegexReplacement which is used in both cleanup and HTML cleanup var count; //globalized as callback functions require variable to exist where callback functions are scoped rather than inside calling function function conductRegexReplacement(arrayOfMatchPatternsAndReplacementFunctions, editor, description, storageName, newWatchlistExpiryMode) { //arrayOfMatchPatternsAndReplacementFunctions is an array of arrays where each subarray has exactly two elements, the first being the regex pattern to match and the second being the regex replacement callback function; summaryAppendix relies on description being an explanatory wiki link; notification becomes count + description + " in " + duration + "ms" var startTime = performance.now; var textLength = editor.get.length; count = 0; for (var i = 0; i < arrayOfMatchPatternsAndReplacementFunctions.length; i++) { editor.replace(arrayOfMatchPatternsAndReplacementFunctions[i][0], arrayOfMatchPatternsAndReplacementFunctions[i][1]); }			if (count) { summaryAppendix += "" + description + " (" + count + "), "; watchlistExpiryMode = Math.max(watchlistExpiryMode, newWatchlistExpiryMode); }			reportCompletion(count + " " + description, (performance.now - startTime).round(3), 'info', storageName, count, textLength); }		function pluralize(num) { return num === 1 ? "" : "s"; }		pathoschild.TemplateScript.add(			[				{					name: 'Cleanup',					script: function(editor) {						summaryAppendix = "";						conductRegexReplacement(\r|\n)+)(\{\{\s*short\s+description\s*\|[^\}]+\}\})(?:\r\n)?/i, function(match, p1, p2) { count++; return p2 + "\r\n" + p1; }, editor, "MOS:ORDER", 'reorder-short-description', 1);						conductRegexReplacement(\{\}]*)\[\[([^=\r\n\[\]\|\{\}]*)\]\]([^=\r\n\[\]\|\{\}]*)\1(?=\n)/g, function(match, p1, p2, p3, p4) { count++; return p1 + p2 + p3 + p4 + p1; }, editor, "MOS:HEAD", 'remove-heading-wiki-links', 1); //should happen before any escaping of wiki links as well as geographical wiki links combination and wiki-link shortening

var templateEscapeString = ''; for (var i = 0; i < expansionDepthLimit * 2 - 1; i++) { //the expansion-depth limit is multiplied by two for each level requiring two nested curly braces and minus one for the outermost two pairs being supplied later; note the assumption that no single-paired nested braces will be used to surpass the limit of eighty nested pairs of curly braces templateEscapeString += '(?:[^\\{\\}]|\\{';						}						templateEscapeString += '[^\\{\\}]*';						for (var i = 0; i < expansionDepthLimit * 2 - 1; i++) { //the expansion-depth limit is multiplied by two for each level requiring two nested curly braces and minus one for the outermost two pairs being supplied later; note the assumption that no single-paired nested braces will be used to surpass the limit of eighty nested pairs of curly braces							templateEscapeString += '\\})*'; }						var wikiLinkEscapeRegex = RegExp('\[\\*(?:\|(?=[^\|\]]*\]\])|\]\])', 'g'); var HTMLEscapeRegex = RegExp(/<(?!(?:br|references)\s*\/?>)([a-zA-Z]+)[^<>]*>(?:(?!<\/\1\s*>)(?:.|\r|\n))*<\/\1\s*>/gi); var escaped1 = editor.escape(wikiLinkEscapeRegex); var escaped2 = editor.escape(HTMLEscapeRegex); var escaped3 = editor.escape(RegExp('\\{\\{' + templateEscapeString + '\\}\\}', 'g')); //note that this assumes that no single-paired nested braces will be used to surpass the expansion-depth limit

conductRegexReplacement([							[RegExp('(?<=\\d)\\s+(?=' + compoundNumbersRegex + '|(?:[km]g|[aApP][mM])(?![a-zA-Z]))', 'g'), function { count++; return " "; }],							[/(?<=[ \r\n])\u00A0|\u00A0(?=[ \r\n])/g, function { count++; return ""; }],							[/\u00A0/g, function { count++; return " "; }]						], editor, "MOS:NBSP", 'insert-nbsps', 1); //should happen before any regex relying on "\s" is used

editor .unescape(escaped1) .unescape(escaped2) .unescape(escaped3);

var headingEscapeRegex = /(?<=\n)(=+)[^=\r\n]*\1(?=\n)/g; escaped1 = editor.escape(wikiLinkEscapeRegex); escaped2 = editor.escape(HTMLEscapeRegex); escaped3 = editor.escape(RegExp('\\{\\{' + templateEscapeString + '\\}\\}', 'g')); //note that this assumes that no single-paired nested braces will be used to surpass the expansion-depth limit var escaped4 = editor.escape(headingEscapeRegex);

conductRegexReplacement(–)(?: |\{\{\s*[nN]dash\s*\}\}|–)/g, function { count++; return " – "; }, editor, "MOS:ENDASH", 'fix-ndashes', 1); //should happen after literal non-breaking space removal and replacement

editor .unescape(escaped1) .unescape(escaped2) .unescape(escaped3) .unescape(escaped4);

var fileRegex = /(?:File|Image):[^\|\]\r\n]+\|/g; var imageParameterRegex = /\|\s*image\s*=(?:(?!\||\}\})[^\|])*/g; // var escaped5 = editor.escape(fileRegex); // var escaped6 = editor.escape(imageParameterRegex); // var escaped7 = editor.escape(/„[^“]*“/);

// conductRegexReplacement([						// 	[/[“”]/g, function(match) { count++; return '"'; }],						// 	[/(?<![‘\'])‘(?![‘\'])/g, function(match) { count++; return "'"; }], //future consideration: add nowiki tags if preceding or proceeding text is a non-curly single quotation mark						// 	[/(?<![’\'])’(?![’\'])/g, function(match) { count++; return "'"; }] //future consideration: add nowiki tags if preceding or proceeding text is a non-curly single quotation mark						// ], editor, "MOS:CURLY", 'replace-curlies', 0);

// editor // 	.unescape(escaped5) // 	.unescape(escaped6) // 	.unescape(escaped7);

var nowikiEscapeRegex = RegExp('(?:(?:(?!<\/' + 'nowiki\s*>)(?:.|\r|\n))*<\/' + 'nowiki\s*>|\{\{\s*#tag:\s*nowiki\s*\}\})', 'gi'); //string is broken at closing nowiki tags to avoid throwing off Wikipedia wherever this document is loaded var escaped8 = editor.escape(nowikiEscapeRegex); var escaped9 = editor.escape(/(?:)(?:.|\r|\n))*-->|\{\{\s*#tag:\s*!--\s*\}\})/g);

var startTime = performance.now; var textLength = editor.get.length; count = 0; var emptyCitationBlacklistRegex = 'Gaia +DR2'; editor .replace(RegExp('<[rR][eE][fF][^>\\/]*>\\s*(?:\\{\\{\\s*[cC]ite +(?!' + emptyCitationBlacklistRegex + ')\\w+\\s*(?:\\|(?:\\s*[\\w-]+\\s*=)?\\s*)*\\}\\}\\s*)?', 'g'), function { count++; return ""; }) .replace(RegExp('\\{\\{\\s*[cC]ite +(?!' + emptyCitationBlacklistRegex + ')\\w+\\s*(?:\\|(?:\\s*[\\w-]+\\s*=)?\\s*)*\\}\\}\\s*', 'g'), function { count++; return ""; }); if (count) { summaryAppendix += "rm " + (count !== 1 ? count + " " : "") + "" + pluralize(count) + ", "; watchlistExpiryMode = 2; }						reportCompletion(count + " empty CS1 citation" + pluralize(count), (performance.now - startTime).round(3), 'info', 'remove-empty-citations', count, textLength); var openingRefHTMLRegex = '<[rR][eE][fF][^>]*>'; var closingRefHTMLRegex = ''; var openingRefParserRegex = '\\{\\{\\s*#tag:\\s*ref\\s*\\|'; var closingRefParserRegex = '\\}\\}'; var problematicIntermediaryRegex = '|||\\{\\{\\s*#tag:\\s*(?:nowiki|!--)\\s*\\}\\}'; //string is broken at closing nowiki tag to avoid throwing off Wikipedia wherever this document is loaded conductRegexReplacement([							[RegExp('\\s+(' + openingRefHTMLRegex + '(?:(?!\\|' + problematicIntermediaryRegex + '|' + closingRefHTMLRegex + ')(?:.|\r|\n))*' + closingRefHTMLRegex + ')', 'g'), function(match, p1) { count++; return p1; }],							[RegExp('\\s+(' + openingRefParserRegex + '(?:(?!\\|' + problematicIntermediaryRegex + '|' + closingRefParserRegex + ')(?:.|\r|\n))*' + closingRefParserRegex + ')', 'g'), function(match, p1) { count++; return p1; }]						], editor, "MOS:REFSPACE", 'add-spaces-before-refs', 1);

// // The following was removed for being broken (the conducted replacement of duplicate references is nonsensical) for unknown reasons. // startTime = performance.now; // textLength = editor.get.length; // count = 0; // var referencesArray = Array.from(editor.get.matchAll(RegExp(']+(?<!\/))?)>(?:(?!<\/ref\s*>)(?:.|\r|\n))*<\/ref\s*>', 'gi'))); // for (var i = 0; referencesArray.length; i++) { // 	var firstReplacement = true; // 	editor.replace(RegExp(referencesArray[0][0].replaceAll(/([\^\$\*\(\)\+\{\}\[\]\\\.\?\/\-])/g, function(match, p1) { return '\\' + p1; }), 'g'), function(match, p1) {						// 		if (firstReplacement) {						// 			firstReplacement = false;						// 			return match;						// 		}						// 		count++;						// 		return "";						// 	}); // 	var captureGroup1 = referencesArray[0][1]; // 	var referenceMatch = (captureGroup1 ? referencesArray[0][0].replace(captureGroup1, '') : referencesArray[0][0]); // 	referencesArray = referencesArray.filter(function(value) { return (captureGroup1 && value[0].indexOf(captureGroup1) === 4 ? value[0].replace(captureGroup1, '') : value[0]) !== referenceMatch; }); // }						// reportCompletion(count + " duplicate reference" + pluralize(count), (performance.now - startTime).round(3), 'info', 'merge-duplicate-references', count, textLength);

editor .unescape(escaped8) .unescape(escaped9);

escaped8 = editor.escape(nowikiEscapeRegex);

var openingCitationTemplateRegex = '\\{\\{\\s*[cC]ite +\\w+\\s*'; var closingCitationTemplateRegex = '\\}\\}'; var openingCitationHTMLRegex = openingRefHTMLRegex + '\\s*' + openingCitationTemplateRegex; var closingCitationHTMLRegex = closingCitationTemplateRegex + '\\s*' + closingRefHTMLRegex; var openingCitationParserRegex = openingRefParserRegex + '\\s*' + openingCitationTemplateRegex; var closingCitationParserRegex = '(?:\\|[^\\|\\}])*' + closingCitationTemplateRegex + '\\s*' + closingRefParserRegex; startTime = performance.now; textLength = editor.get.length; count = 0; var postscriptArg = '\\s*postscript\\s*='; editor .replace(RegExp('(' + openingCitationHTMLRegex + '(?:(?!\\|' + postscriptArg + '|' + problematicIntermediaryRegex + '|' + closingCitationHTMLRegex + ')(?:.|\r|\n))*)\\|' + postscriptArg + '\\s*\\.\\s*((?:\\|(?:(?!' + postscriptArg + '|' + problematicIntermediaryRegex + '|\\s*' + closingCitationHTMLRegex + ')[^\\|])*)*' + closingCitationHTMLRegex + ')', 'g'), function(match, p1, p2) { count++; return p1 + p2; }) .replace(RegExp('(' + openingCitationParserRegex + '(?:(?!\\|' + postscriptArg + '|' + problematicIntermediaryRegex + '|' + closingCitationParserRegex + ')(?:.|\r|\n))*)\\|' + postscriptArg + '\\s*\\.\\s*((?:\\|(?:(?!' + postscriptArg + '|' + problematicIntermediaryRegex + '|\\s*' + closingCitationParserRegex + ')[^\\|])*)*' + closingCitationParserRegex + ')', 'g'), function(match, p1, p2) { count++; return p1 + p2; }); if (count) { summaryAppendix += "rm " + (count !== 1 ? count + " " : "") + "" + pluralize(count) + ", "; watchlistExpiryMode = 2; }						reportCompletion(count + " redundant CS1 postscript" + pluralize(count), (performance.now - startTime).round(3), 'info', 'fix-postscript-period', count, textLength); startTime = performance.now; textLength = editor.get.length; count = 0; var urlStatusArg = '\\s*url-status\\s*='; var archiveArgs = '\\s*archive-(?:url|date)\\s*=\\s*\\w+'; editor .replace(RegExp('(' + openingCitationTemplateRegex + '(?:(?!\\|' + urlStatusArg + '|\\|' + archiveArgs + '|' + problematicIntermediaryRegex + '|' + closingCitationTemplateRegex + ')(?:.|\r|\n))*)\\|' + urlStatusArg + '\\s*live\\s*((?:\\|(?:(?!' + urlStatusArg + '|' + archiveArgs + '|' + problematicIntermediaryRegex + '|\\s*' + closingCitationTemplateRegex + ')[^\\|])*)*\\s*' + closingCitationTemplateRegex + ')', 'g'), function(match, p1, p2) { count++; return p1 + p2; }); if (count) { summaryAppendix += "rm " + (count !== 1 ? count + " " : "") + "" + (count === 1 ? "" : "es") + ", "; }						reportCompletion(count + " live CS1 url status" + (count === 1 ? "" : "es"), (performance.now - startTime).round(3), 'info', 'remove-live-url-status', count, textLength); conductRegexReplacement(\s*((?:[\w-]+(?:\s+[\w-]+)?)?)\s*\]\],\s*\[\[\s*([\w-]+(?:\s+[\w-]+)?)((?:,(?:\s+[\w-]+)*|\s+\([\w-]+(?:\s+[\w-]+)*\))?\s*(?:\|\s*[\w-]+(?:\s+[\w-]+)?\s*)?)\]\]/g, function(match, p1, p2, p3, p4, p5) {							var p2Temp = p2.replaceAll(/[‘’]/g, '\).replaceAll(/[“”]/g, '\"');							if (p1.replaceAll(/[‘’]/g, '\).replaceAll(/[“”]/g, '\"') === p3.replaceAll(/[‘’]/g, '\).replaceAll(/[“”]/g, '\"') && p2Temp === p4.replaceAll(/[‘’]/g, '\).replaceAll(/[“”]/g, '\"') && (!p5.length || (p5.indexOf('|') >= 0 && (p5.indexOf('|') === p5.length - 1 || p5.substring(p5.indexOf('|') + 1).trim.replaceAll(/[‘’]/g, '\'').replaceAll(/[“”]/g, '\"') === p2Temp)))) {								count++;								return "[[" + p1 + ", " + p2 + "";							}							return "" + p3 + ", " + p4 + p5 + "";						}]], editor, "MOS:GEOLINK", 'combine-geographical-wiki-links', 0); conductRegexReplacement(\r|\n))*.?)<\/u\s*>/gi, function(match, p1) { count++; return ""; }, editor, "MOS:EMPHASIS", 'fix-HTML-underlining', 2); startTime = performance.now; textLength = editor.get.length; var countArray = [0]; //an array style for two replacement segments sharing a summary excerpt editor .replace(/(?<!\n;[^\n]*)\n:\s*\n"; });						//note: appending message to summary is handled by the replacement segment after next						reportCompletion(countArray[0] + " HTML math tag" + pluralize(countArray[0]) + " display as block", (performance.now - startTime).round(3), 'info', 'fix-colon-indent-math', countArray[0], textLength);						conductRegexReplacement([^\n]*\n|)([^\n]*)\n(?=[:\*#])/g,							function(match, p1, p2, p3) {								if (p2.length && p2[0] === ":") {									count++;									return p1 + new Array(p2.length + 1).join('*') + p3 + "\n";								}								else {									return p1 + p2 + p3 + "\n";								}							}, editor, "MOS:DLIST", 'fix-dlist', 1);						startTime = performance.now;						textLength = editor.get.length;						countArray.push(0);						editor							.replace(/(?<=\n)([\*#]*)(:+|;[^\n]*\n|)([^\n]*)\n(?=\s*\n)/g, function(match, p1, p2, p3) { if (p2.length && p2[0] === ":") { countArray[1]++; return p1 + "\n"; }								else { return p1 + p2 + p3 + "\n"; }							})							.replace(/(?<=\n)([\*#]*)(:+|;[^\n]*\n|)([^\n]*)\n/g, function(match, p1, p2, p3) { if (p2.length && p2[0] === ":") { countArray[1]++; return p1 + "\n"; }								else { return p1 + p2 + p3 + "\n"; }							});						if (countArray[0] || countArray[1]) {							summaryAppendix += "MOS:INDENTGAP (" + (countArray[0] ? countArray[0] : "") + (countArray[0] && countArray[1] ? "+" : "") + (countArray[1] ? countArray[1] : "") + "), ";							watchlistExpiryMode = 2;						}						reportCompletion(countArray[1] + " colon indentation" + pluralize(countArray[1]), (performance.now - startTime).round(3), 'info', 'fix-colon-indent', countArray[1], textLength);						conductRegexReplacement(\{\}<>]+(?<!\s))\s*\|\s*([^\]\|\{\}<>]+)\s*\]\]/g, function(match, p1, p2) {							var p2Temp = p2.charAt(0).toLowerCase + p2.substring(1).replaceAll(/[‘’]/g, '\).replaceAll(/[“”]/g, '\"');							if (p2Temp.indexOf((p1.charAt(0).toLowerCase + p1.substring(1)).replaceAll(/[‘’]/g, '\).replaceAll(/[“”]/g, '\"')) === 0 && (p2Temp.length === p1.length || (p2Temp.substring(p1.length).match(/[^\s`~!@#$%^&*\(\)\-–—_=+\[\]\{\}\\\|;:\'\"‘’“”,\.<>\/?A-Z\d][^\s`~!@#$%^&*\(\)\-–—_=+\[\]\{\}\\\|;:\'\"‘’“”,\.<>\/?\d]*/g) !== null && p2Temp.substring(p1.length).match(/[^\s`~!@#$%^&*\(\)\-–—_=+\[\]\{\}\\\|;:\'\"‘’“”,\.<>\/?A-Z\d][^\s`~!@#$%^&*\(\)\-–—_=+\[\]\{\}\\\|;:\'\"‘’“”,\.<>\/?\d]*/g)[0].length === p2Temp.length - p1.length))) {								count++;								return "[[" + p2.charAt(0) + p2Temp.substring(1, p1.length) + "" + p2Temp.substring(p1.length);							}							return "" + p2 + "";						}]], editor, "MOS:PIPESTYLE", 'shorten-wiki-links', 0);

var tableEscapeString = ''; var expansionDepthLimit = 40; //40 is the expansion-depth limit (and is assumed to apply to table nesting) for (var i = 0; i < expansionDepthLimit; i++) { tableEscapeString += '(?:(?:(?!\\{\\||\\|\\})(?:.|\\r|\\n))*.?|\\{\\|';						}						tableEscapeString += '(?:(?!\\{\\||\\|\\})(?:.|\\r|\\n))*.?';						for (var i = 0; i < expansionDepthLimit; i++) {							tableEscapeString += '\\|\\})*'; }						var escaped10 = editor.escape(RegExp(tableEscapeString, 'g'));

conductRegexReplacement(, editor, "MOS:IMGSIZE", 'convert-image-pixel-sizes', 1); //convert pixels to upright (rounded to nearest thousandth due to the three significant digits of 220)

editor .unescape(escaped8) .unescape(escaped10);

// escaped1 = editor.escape(wikiLinkEscapeRegex); // escaped2 = editor.escape(HTMLEscapeRegex); // escaped3 = editor.escape(RegExp('\\{\\{' + templateEscapeString + '\\}\\}', 'g')); //note that this assumes that no single-paired nested braces will be used to surpass the expansion-depth limit // var escaped11 = editor.escape(/\"[^\"]*\"/g); //requires curly quotation marks to have been converted, though is of highly varying accuracy anyway

// var monthOfYearRegex = 'January|February|March|April|May|June|July|August|September|October|November|December|(?:Jan|Feb|Mar|Apr|Jun|Jul|Aug|Sep|Oct|Nov|Dec)'; var compoundNumbersRegex = '(?:m|b|tr|quadr)illion'; // conductRegexReplacement([						// 	[RegExp('(?<=[a-z](?<!' + monthOfYearRegex + '|version))\\s+(\\d)(?=\\s+(?!' + monthOfYearRegex + '|' + compoundNumbersRegex + ')[a-z])', 'gi'), function(match, p1) {						// 		count++;						// 		switch (p1) {						// 			case '0':						// 				return " zero";						// 			case '1':						// 				return " one";						// 			case '2':						// 				return " two";						// 			case '3':						// 				return " three";						// 			case '4':						// 				return " four";						// 			case '5':						// 				return " five";						// 			case '6':						// 				return " six";						// 			case '7':						// 				return " seven";						// 			case '8':						// 				return " eight";						// 			case '9':						// 				return " nine";						// 			default: //should never occur, but replace with original if it does						// 				return " " + p1;						// 		}						// 	}]						// ], editor, "MOS:SPELL09", 'spell-digits', 1);

// editor // 	.unescape(escaped1) // 	.unescape(escaped2) // 	.unescape(escaped3) // 	.unescape(escaped11);

escaped1 = editor.escape(wikiLinkEscapeRegex); escaped4 = editor.escape(headingEscapeRegex); var escaped5 = editor.escape(fileRegex); var escaped6 = editor.escape(imageParameterRegex); escaped8 = editor.escape(nowikiEscapeRegex); var escaped12 = editor.escape('\\{\\{\\s*[cC]ite +\\w+\\s*' + templateEscapeString + '\\}\\}');

var discouragedCircaRegex = '(?:circa|ca?(?:\\.|\\s)|C\\.|around|approx(?:imately|\\.))'; var eraAbbreviationRegex = 'BCE?|AD|CE|B\\.\\s?C\\.\\s?(?:E\\.)?|A\\.\\s?D\\.|C\\.\\s?E\\.'; var nbspRegex = '\\{\\{\\s*[nN]bsp\\s*\\}\\}| '; var ndashRegex = '\\{\\{\\s*[eE]n +[dD]ash\\s*\\}\\}|–|–'; var mdashRegex = '\\{\\{\\s*[mM]dash\\s*\\}\\}|&mdash;|—'; conductRegexReplacement((?:\\s{0,}(?:-|' + ndashRegex + '))|\\s{0,}(?:' + mdashRegex + ')|\\s+to\\s)|E\\.?(?:(?:' + nbspRegex + ')|(?:\\s{0,}(?:-|' + ndashRegex + '))|\\s{0,}(?:' + mdashRegex + ')|\\s+to\\s))|(?!\\d*(?:(?:(?:' + nbspRegex + ')|(?:\\s{0,}(?:-|' + ndashRegex + '))|\\s{0,}(?:' + mdashRegex + '))|[a-zA-Z%°\/]|[,\\.:]\\d+|\\s+(?:%|per\\s?cent|kilo|milli|' + compoundNumbersRegex + '|to\\s|' + eraAbbreviationRegex + '))))', 'g'), function(match, p1, p2) { count++; return "c. " + p1 + (p2 === undefined ? "" : " " + p2.replaceAll(' ', ).replaceAll('.', )) + ""; }, editor, "MOS:CIRCA", 'fix-circa-formatting', 1); //note that to minimize false positives, spelling single-digit numbers and non-breaking space insertion should be handled before this circa formatting

editor .unescape(escaped1) .unescape(escaped4) .unescape(escaped5) .unescape(escaped6) .unescape(escaped8) .unescape(escaped12);

// var escaped13 = editor.escape(/(?:)(?:.|\r|\n))*-->|\{\{\s*#tag:\s*!--\s*\}\})/g); // var escaped14 = editor.escape(RegExp('(?:]+(?<!\/))?>(?:(?!<\/ref\s*>)(?:.|\r|\n))*<\/ref\s*>|\{\{\s*#tag:\s*ref\s*\}\})', 'gi')); // var escaped15 = editor.escape(RegExp('(?:]+)>(?:(?!<\/gallery\s*>)(?:.|\r|\n))*<\/gallery\s*>|\{\{\s*#tag:\s*gallery\s*\}\})', 'gi'));

// editor // 	.unescape(escaped13) // 	.unescape(escaped14) // 	.unescape(escaped15);

startTime = performance.now; textLength = editor.get.length; countArray = [0, 0, 0, 0]; //ol then li in ol then ul then li in ul						editor .replace(/((?:(?!<\/?[ou]l\s*>)(?:.|\r|\n))*.?)<\/ol\s*>/gi, function(match, p1) { countArray[0]++; return p1.replace(/\n?((?:(?!<\/?li\s*>)(?:.|\r|\n))*.?)<\/li\s*>/gi, function(match, p1) { countArray[1]++; return "\n# " + p1; }); }) .replace(/((?:(?!<\/?[ou]l\s*>)(?:.|\r|\n))*.?)<\/ul\s*>/gi, function(match, p1) { countArray[2]++; return p1.replace(/\n?((?:(?!<\/?li\s*>)(?:.|\r|\n))*.?)<\/li\s*>/gi, function(match, p1) { countArray[3]++; return "\n* " + p1; }); }); if (countArray[0] || countArray[2]) { summaryAppendix += "converted " + (countArray[0] ? countArray[0] + " HTML ol tag" + pluralize(countArray[0]) + " containing " + countArray[1] + " list item" + pluralize(countArray[1]) : "") + (countArray[0] && countArray[2] ? " and " : "") + (countArray[2] ? countArray[2] + " HTML ul tag" + pluralize(countArray[2]) + " containing " + countArray[3] + " list item" + pluralize(countArray[3]) : "") + " to wikitext, "; watchlistExpiryMode = 2; }						reportCompletion((countArray[0] || !countArray[2] ? countArray[0] + " HTML ol tag" + pluralize(countArray[0]) + " containing " + countArray[1] + " HTML li tag" + pluralize(countArray[1]) : "") + (countArray[0] === countArray[2] ? " and " : "") + (!countArray[0] || countArray[2] ? countArray[2] + " HTML ul tag" + pluralize(countArray[2]) + " containing " + countArray[3] + " HTML li tag" + pluralize(countArray[3]) : "") + " converted", (performance.now - startTime).round(3), 'info', 'fix-HTML-lists', countArray[0] + " containing " + countArray[1] + " and " + countArray[2] + " containing " + countArray[3], textLength);

startTime = performance.now; textLength = editor.get.length; count = 0; editor .replace(/(?:\n\s*)?]*))?>(?=\s*]*)?>)\s*((?:(?!\s*<\/?t(?:r|able)\s*>)(?:.|\r|\n))*.?)\s*<\/tr\s*>\s*/gi, function(match, p1, p2) { count++; return "\n|-" + (p1 !== undefined ? " " + p1 : "") + "\n!" + p2; }) .replace(/(?:\n\s*)?<tr(?:\s+([^<>]*))?>\s*((?:(?!\s*<\/?t(?:r|able)\s*>)(?:.|\r|\n))*.?)\s*<\/tr\s*>\s*/gi, function(match, p1, p2) { count++; return "\n|-" + (p1 !== undefined ? " " + p1 : "") + "\n|" + p2; }); if (count) { summaryAppendix += "converted " + count + " HTML tr tag" + pluralize(count) + " to wikitext, "; watchlistExpiryMode = 2; }						reportCompletion(count + " HTML tr conversion" + pluralize(count), (performance.now - startTime).round(3), 'info', 'fix-HTML-tr', count, textLength); startTime = performance.now; textLength = editor.get.length; count = 0; editor .replace(/<td(?:\s+([^<>]*))?>\s*((?:(?!\s*<\/?t(?:[dhr]|able)\s*>)(?:.|\r|\n))*.?)\s*<\/td\s*>\s*(?=\s*<td(?:\s+[^<>]*)?>)/gi, function(match, p1, p2) { count++; return (p1 !== undefined ? " " + p1 + " |" : "") + " " + p2 + " ||"; }) .replace(/<td(?:\s+([^<>]*))?>\s*((?:(?!\s*<\/?t(?:[dhr]|able)\s*>)(?:.|\r|\n))*.?)\s*<\/td\s*>\s*/gi, function(match, p1, p2) { count++; return (p1 !== undefined ? " " + p1 + " |" : "") + " " + p2 + "\n"; }); if (count) { summaryAppendix += "converted " + count + " HTML td tag" + pluralize(count) + " to wikitext, "; watchlistExpiryMode = 2; }						reportCompletion(count + " HTML td conversion" + pluralize(count), (performance.now - startTime).round(3), 'info', 'fix-HTML-td', count, textLength); startTime = performance.now; textLength = editor.get.length; count = 0; editor .replace(/<th(?:\s+([^<>]*))?>\s*((?:(?!\s*<\/?t(?:[dhr]|able)\s*>)(?:.|\r|\n))*.?)\s*<\/th\s*>\s*(?=<th(?:\s+[^<>]*)?>)/gi, function(match, p1, p2) { count++; return (p1 !== undefined ? " " + p1 + " |" : "") + " " + p2 + " !!"; }) .replace(/<th(?:\s+([^<>]*))?>\s*((?:(?!\s*<\/?t(?:[dhr]|able)\s*>)(?:.|\r|\n))*.?)\s*<\/th\s*>\s*/gi, function(match, p1, p2) { count++; return (p1 !== undefined ? " " + p1 + " |" : "") + " " + p2 + "\n"; }); if (count) { summaryAppendix += "converted " + count + " HTML th tag" + pluralize(count) + " to wikitext, "; watchlistExpiryMode = 2; }						reportCompletion(count + " HTML th conversion" + pluralize(count), (performance.now - startTime).round(3), 'info', 'fix-HTML-th', count, textLength); startTime = performance.now; textLength = editor.get.length; count = 0; editor .replace(/ \n\n{| style="text-align: left;"\n|-\n! scope="row" | \'\'\'Anderjef\'\'\'\n| style="padding:0 1em" | \n| million\n|-\n! scope="row" | \'\'\'Anderjef/sandbox\'\'\'\n| style="padding:0 1em" | \n|  million\n|} ', //string is broken at closing nowiki tag to avoid throwing off Wikipedia wherever this document is loaded					position: 'cursor',					script: function {						if (!($('#wpSummary').val.length || /^(?:\s*\/\*(?:(?!\*\/)(?:.|\r|\n))*\*\/\s*)+$/.test($('#wpSummary').val)) && $('#wpMinoredit').checked) {							$('#wpMinoredit').prop( 'checked', false );						}					}				}			],			{ forActions: 'edit' }		); }); }); // importScript('User:SuperHamster/CiteUnseen.js'); // Backlink: User:SuperHamster/CiteUnseen.js importScript('User:Novem_Linguae/Scripts/CiteHighlighter.js'); // Backlink: User:Novem_Linguae/Scripts/CiteHighlighter.js importScript('User:Headbomb/unreliable.js'); // Backlink: User:Headbomb/unreliable.js