مسابقه دانش‌دخت
اسلامیکال از تاریخ ۱۵ دی تا ۲۰ بهمن، میزبان یک همایه با موضوع زنان است. شما می‌توانید در مسابقه مقاله‌نویسی دانش‌دخت، شرکت کنید و با نگارش مقاله، از جوایز آن بهره‌مند باشید. اگر به موضوعات مربوط با زنان علاقه‌مندید، این فرصت را از دست ندهید. فهرستی از مقالات پیشنهادی جهت ایجاد یا ویرایش در اینجا وجود دارد.

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

از اسلامیکال
نسخهٔ تاریخ ‏۱۳ ژانویهٔ ۲۰۲۳، ساعت ۰۳:۴۲ توسط Aboammar (بحث | مشارکت‌ها) (صفحه‌ای تازه حاوی «// Based on en:User:Shubinator/DYKcheck.js mw.loader.using(['mediawiki.api', 'mediawiki.util'], function () { "use strict"; var onTTDYK, nextSection, urlJump, sections, currentTitle, partsProcessing, articleTitles, dates, nom5x; // Configurable options var dateFormat = window.dateFormat, unlock = window.unlock, hookLengthYellow = window.hookLengthYellow || 200, hookLengthRed = window.hookLengthRed || 220, check5xNoms = wi...» ایجاد کرد)
(تفاوت) → نسخهٔ قدیمی‌تر | نمایش نسخهٔ فعلی (تفاوت) | نسخهٔ جدیدتر ← (تفاوت)
پرش به ناوبری پرش به جستجو

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

  • فایرفاکس / سافاری: کلید Shift را نگه دارید و روی دکمهٔ Reload کلیک کنید، یا کلید‌های Ctrl-F5 یا Ctrl-R را با هم فشار دهید (در رایانه‌های اپل مکینتاش کلید‌های ⌘-R)
  • گوگل کروم: کلیدهای Ctrl+Shift+R را با هم فشار دهید (در رایانه‌های اپل مکینتاش کلید‌های ⌘-Shift-R)
  • اینترنت اکسپلورر/ Edge: کلید Ctrl را نگه‌دارید و روی دکمهٔ Refresh کلیک کنید، یا کلید‌های Ctrl-F5 را با هم فشار دهید
  • اپرا: Ctrl-F5 را بفشارید.
// Based on [[:en:User:Shubinator/DYKcheck.js]]

mw.loader.using(['mediawiki.api', 'mediawiki.util'], function () {
"use strict";

var onTTDYK, nextSection, urlJump, sections, currentTitle, partsProcessing,
	articleTitles, dates, nom5x;

// Configurable options
var
	dateFormat = window.dateFormat,
	unlock = window.unlock,
	hookLengthYellow = window.hookLengthYellow || 200,
	hookLengthRed = window.hookLengthRed || 220,
	check5xNoms = window.check5xNoms || "ifnom5x",
	fixedSidebar = window.fixedSidebar || "onttydk";

var mwConfig = mw.config.get([
	"wgAction",
	"wgTitle",
	"wgPageName",
	"wgUserName",
	"wgNamespaceNumber",
	"skin"
]);

var api = new mw.Api();

// Polyfill String.prototype.includes so that we don't have to write "!== -1" all over
// the codebase.
if (!String.prototype.includes) {
  String.prototype.includes = function() {
    return String.prototype.indexOf.apply(this, arguments) !== -1;
  };
}

function escapeHtml(s) {
	// Use the browser's built-in ability to escape HTML.
	var div = document.createElement('div');
	div.appendChild(document.createTextNode(s));
	return div.innerHTML;
}

function scanArticle(title, output, html) {
	// the meat of the DYKcheck tool
	// calculates prose size of the given html
	// checks for inline citations and stub templates in the given html
	// passes info to checkTalk(), getFirstRevision(), checkMove(), and checkExpansion()
	
	if (!onTTDYK || (check5xNoms === "always") || (check5xNoms === "ifnom5x" && nom5x)) {
		partsProcessing = new Array(4);
	} else {
		partsProcessing = new Array(3);
	}
	dates = new Array(4);

	var proseDisp = document.createElement("li");
	proseDisp.id = "dyk-prose";
	output.appendChild(proseDisp);

	// calculate prose size
	var prose = calculateProse(html, true);
	var pList = html.getElementsByTagName("p");
	var word_count = 0;
	for (var iPara = 0;iPara < pList.length; iPara++) {
		var para = pList[iPara];
		if (para.parentNode === html || (para.parentNode.parentNode.parentNode != null && para.parentNode.parentNode.parentNode.id === 'bodyContent')) {
			word_count += para.innerHTML.replace(/(<([^>]+)>)/ig,"").split(' ').length;
		}
	}
	proseDisp.innerHTML='<b>حجم متن مقاله: </b>' + escapeHtml(prose.toLocaleString('fa')) + '&nbsp;نویسه (' +
			escapeHtml(word_count.toLocaleString('fa')) + ' کلمه) «متن قابل خواندن»';
	if (prose < 1500) {
		proseDisp.style.cssText = "background-color:pink";
	}
	
	// check for inline citations
	if (!html.innerHTML.includes('id="cite_ref-') && !html.innerHTML.includes('id=cite_ref-')) {
		var noref = document.createElement("li");
		noref.id = "no-ref";
		output.appendChild(noref);
		noref.innerHTML = 'متن مقاله حاوی یادکرد نیست';
		noref.style.cssText = "background-color:pink";
	}
	
	// check if article is stub or if it has appeared in DYK or ITN
	if (html.innerHTML.includes('id="stub"') || html.innerHTML.includes('id=stub') || 
			html.innerHTML.includes('metadata plainlinks stub')) {
		var stubAlert = document.createElement("li");
		stubAlert.id = "stub-alert";
		output.appendChild(stubAlert);
		stubAlert.innerHTML = 'مقاله به عنوان مقاله‌ای خرد، طبقه‌بندی شده‌است.';
		stubAlert.style.cssText = "background-color:yellow";
	}
	checkTalk(title, output); //check talk page
	
	// check for various tags
	var alertColor = "yellow";
	var imageList = new Array("Text_document_with_red_question_mark.svg", 
			"Question book-new.svg", "Ambox content.png", "Ambox style.png", 
			"Imbox style.png", "Copyright-problem.svg", "Copyright-problem paste.svg", 
			"Ambox globe content.svg", "Unbalanced scales.svg", "Ambox scales.svg", 
			"Ambox_contradict.svg", "Ambox warning orange.svg", "Acap.svg");
	var tagList = new Array("unverified content", "insufficient citations", "dispute", "cleanup", "cleanup",
			"copyright violations", "copyright violations", "globalization", "neutrality", 
			"neutrality", "contradiction", "dispute", "copyedit");
	var tagsFound = false;
	var tagAlert = document.createElement("li");
	if (html.innerHTML.includes("This article is being considered for deletion in accordance with Wikipedia's")) {
		tagsFound = true;
		var afdIndex = html.innerHTML.indexOf('title="Wikipedia:Articles for deletion/') + 7;
		var afdLink = html.innerHTML.substring(afdIndex, html.innerHTML.indexOf('"', afdIndex));
		var afdBoldTag = document.createElement("b");
		var afdLinkTag = document.createElement("a");
		afdLinkTag.setAttribute("href", "//en.wikipedia.org/wiki/" + afdLink);
		afdLinkTag.appendChild(document.createTextNode("nominated for deletion"));
		afdBoldTag.appendChild(afdLinkTag);
		tagAlert.appendChild(document.createTextNode("Article has been "));
		tagAlert.appendChild(afdBoldTag);
		tagAlert.appendChild(document.createTextNode(". "));
		alertColor = "pink";			
	} else if ((html.innerHTML.toLowerCase().includes('<table class="plainlinks ombox ombox-speedy"')) || 
			(html.innerHTML.toLowerCase().includes('<table class="plainlinks ambox ambox-speedy"')) || 
			(html.innerHTML.toLowerCase().includes('<table class="metadata plainlinks ombox ombox-speedy"')) ||
			(html.innerHTML.toLowerCase().includes('<table class="metadata plainlinks ambox ambox-speedy"'))) {
		tagsFound = true;
		tagAlert.appendChild("Article has been <b>tagged for speedy deletion</b>. ");
		alertColor = "pink";
	}
	for (var iImage = 0; iImage < imageList.length; iImage++) {
		if (html.innerHTML.includes(imageList[iImage])) {
			tagsFound = true;
			tagAlert.appendChild(document.createTextNode("Article has a "));
			tagAlert.appendChild(document.createTextNode(tagList[iImage]));
			tagAlert.appendChild(document.createTextNode(" tag. "));
		}
	}
	if (tagsFound) {
		tagAlert.id = "tag-alert";
		tagAlert.style["background-color"] = alertColor;
		output.appendChild(tagAlert);
	}
		
	// find creator of article and date
	getFirstRevision(title, output);
	
	// check if the article has been moved from userspace within last 100 edits
	if (mwConfig.wgNamespaceNumber !== 2) {
		checkMove(title, output);
	} else {
		partsProcessing[2] = true;
	}
	
	// check for expansion start date, assuming now expanded to 5x (last 500 edits)
	if (!onTTDYK || (check5xNoms === "always") || (check5xNoms === "ifnom5x" && nom5x)) {
		checkExpansion(title, output, prose);
	}

	// Check if it was previously used in AMIK
	(new mw.Api() ).get({
		format: 'json',
		action: 'query',
		list: 'backlinks',
		bltitle: mw.config.get("wgPageName"),
		blnamespace: 4}
	).then(function(obj){
		var bl = obj.query.backlinks;
		$.each(bl, function(idx){
			title = bl[idx].title;
			if (title.indexOf('ویکی‌پدیا:آیا می‌دانستید که...') == 0 & title.indexOf('هفته ') > -1) {
				mw.notify($('<span>قبلاً در <b>' + title + '</b> استفاده شده</span>'), {autoHide: false})
			} 
		});
	});
}

function checkDocument() {
	// prepares for scan and passes info to scanArticle()
	onTTDYK = false;
	if (document.getElementById("dyk-stats-0")) {
		clearStats();
	} else {
		var output = document.createElement("ul");
		output.id = "dyk-stats-0";
		
		var body = getBody();
		var dummy = body.getElementsByTagName("div")[0];
		if (dummy.nextSibling && dummy.nextSibling.id === 'siteNotice') { // if siteNotice is below siteSub
			dummy = dummy.nextSibling;
		} else if (dummy.nextSibling.nextSibling && dummy.nextSibling.nextSibling.id === 'siteNotice') {
			dummy = dummy.nextSibling.nextSibling;
		}
		dummy.parentNode.insertBefore(output, dummy.nextSibling);
		createHeaderAndProcessing(output);
		currentTitle = 0;
		var title = mwConfig.wgTitle;
		if (mwConfig.wgNamespaceNumber === 2) {
			title = "User:" + title;
		}
		scanArticle(title, output, body);
	}
}

function checkTTDYK() {
	// finds the current nomination
	// can jump to a section if it shows up in the URL
	// (i.e. http://en.wikipedia.org/wiki/T:TDYK#Older_nominations)
	// prepares for scan and passes info to checkHooks() and scanArticle() (through pit stop)

	onTTDYK = true;
	if (!sections) {
		sections = document.getElementsByTagName("h4");
		nextSection = getFirstNom();
	}
	// Jumping code
	if (window.location.hash) {
		var sectionAt = window.location.hash;
		if (sectionAt !== urlJump) {
			var jump = document.getElementById(sectionAt.substring(1, sectionAt.length));
			var next = jump.parentNode;
			while (next.nodeName.toLowerCase() !== "h4") {
				next = next.nextSibling;
			}
			for (var iSection = 0; iSection < sections.length; iSection++) {
				if (sections[iSection] === next) {
					nextSection = iSection;
					urlJump = sectionAt;
					break;
				}
			}
		}
	}
	
	if (nextSection === sections.length) {
		alert("Reached end of nominations; looping to beginning");
		nextSection = getFirstNom();
	}
	if (document.getElementById("dyk-stats-0")) {
		clearStats();
	}
	var firstOutput = document.createElement("ul");
	firstOutput.id = "dyk-stats-0";
	sections[nextSection].parentNode.insertBefore(firstOutput, sections[nextSection]);
	var hook = checkHooks(firstOutput);
	if (!hook) {
		var hookErrorDisp = document.createElement("div");
		hookErrorDisp.id = "error-disp";
		hookErrorDisp.style.cssText = 'color:red; font-weight:bold;';
		hookErrorDisp.innerHTML = 'Error: Hook is not formatted correctly';
		firstOutput.parentNode.insertBefore(hookErrorDisp, firstOutput);
		nextSection++;
		return;
	}
	createHeaderAndProcessing(document.getElementById("dyk-stats-0"));
	var tempHolder = document.createElement("div");
	tempHolder.id = "temp-holder";
	tempHolder.innerHTML = hook;
	var bolded = tempHolder.getElementsByTagName("b");
	var articleTitlesTemp = new Array(bolded.length);
	var titlesCounter = 0;
	for (var iBolded = 0; iBolded < bolded.length; iBolded++) {
		var links = bolded[iBolded].getElementsByTagName("a");
		if (links.length > 0) {
			for (var iLink = 0; iLink < links.length; iLink++) {
				var linkTitle = links[iLink].getAttribute("title");
				if (!linkTitle) linkTitle = links[iLink].innerHTML; // links that aren't piped
				articleTitlesTemp[titlesCounter] = linkTitle;
				titlesCounter++;
			}
		} else {
			var pointer = bolded[iBolded];
			while (pointer !== tempHolder) {
				if (pointer.nodeName.toLowerCase() === "a") {
					var pointerTitle = pointer.getAttribute("title");
					if (!pointerTitle) pointerTitle = pointer.innerHTML; // links that aren't piped
					articleTitlesTemp[titlesCounter] = pointerTitle;
					titlesCounter++;
				}
				pointer = pointer.parentNode;
			}
		}
	}
	currentTitle = 0;
	articleTitles = new Array(titlesCounter);
	var hookOutput = document.getElementById("hook-container");
	for (var i = 0; i < titlesCounter; i++) {
		var output;
		if (i === 0) {
			output = firstOutput;
		} else {
			output = document.createElement("ul");
			output.id = "dyk-stats-" + i;
			hookOutput.parentNode.insertBefore(output, hookOutput);
		}
		var articleDisp = document.createElement("li");
		articleDisp.id = "article-title" + i;
		output.appendChild(articleDisp);
		articleDisp.innerHTML = '<b>Article ' + escapeHtml(i+1) + ':</b> ' + escapeHtml(articleTitlesTemp[i]);
		articleTitles[i] = articleTitlesTemp[i];
	}
	if (titlesCounter === 1) {
		document.getElementById("article-title0").innerHTML = '<b>Article:</b> ' + escapeHtml(articleTitles[0]);
	} else if (titlesCounter === 0) {
		if (document.getElementById("dyk-processing")) {
			var processing = document.getElementById("dyk-processing");
			processing.parentNode.removeChild(processing);
		}
		var boldErrorDisp = document.createElement("div");
		boldErrorDisp.id = "error-disp";
		boldErrorDisp.style.cssText = 'color:red; font-weight:bold;';
		boldErrorDisp.innerHTML = document.createTextNode('Error: The nominated article must appear in bold');
		sections[nextSection].parentNode.insertBefore(boldErrorDisp, firstOutput);
		nextSection++;
		return;
	}
	nextSection++;
	checkTitle(articleTitles[0], firstOutput, 0);
}

function checkHooks(output) {
	// gets the nomination section (complete with comments, etc) and passes this to helper function
	// returns the last suggested hook so the parent method can find article titles
	var hookOutput = document.createElement("ul");
	hookOutput.id = "hook-container";
	output.parentNode.insertBefore(hookOutput, output.nextSibling);
	var bodyHTML = getBody().innerHTML;
	var thisSection;
	if (nextSection !== sections.length - 1) {
		thisSection = bodyHTML.substring(bodyHTML.indexOf(sections[nextSection].innerHTML) + sections[nextSection].innerHTML.length, 
				bodyHTML.indexOf(sections[nextSection+1].innerHTML));
	} else {
		thisSection = bodyHTML.substring(bodyHTML.indexOf(sections[nextSection].innerHTML) + sections[nextSection].innerHTML.length, 
				bodyHTML.indexOf('NewPP limit report'));
	}
	thisSection = thisSection.replace('that,', 'that ').replace('...that ', '... that ');
	if (thisSection.includes("5x expan")) {
		nom5x = true;
	} else {
		nom5x = false;
	}
	return checkHooksHelper(hookOutput, thisSection, 0);
}

function checkHooksHelper(hookOutput, whatsLeft, num) {
	// recursively finds proposed hooks for a nom
	// identifies hooks starting with " ... that " and ending with "?"
	// does not count "... " or "(pictured)" in hook character count
	var hook;
	var questionIndex = whatsLeft.indexOf("?");
	var whatsLeftLowerCase = whatsLeft.toLowerCase();
	while ((whatsLeftLowerCase.indexOf("<a ", questionIndex) > 
			whatsLeftLowerCase.indexOf("</a>", questionIndex)) || 
			((!whatsLeftLowerCase.includes("<a ", questionIndex)) && 
			(whatsLeftLowerCase.includes("</a>", questionIndex))) ||
			(whatsLeftLowerCase.indexOf("<i>", questionIndex) > 
			whatsLeftLowerCase.indexOf("</i>", questionIndex)) || 
			((!whatsLeftLowerCase.includes("<i>", questionIndex)) && 
			(whatsLeftLowerCase.includes("</i>", questionIndex)))) {
		questionIndex = whatsLeft.indexOf("?", questionIndex + 1);
	}
	if (whatsLeft.includes("... that ") && questionIndex !== -1) {
		if (whatsLeft.indexOf("... that ") < questionIndex) {
			hook = whatsLeft.substring(whatsLeft.indexOf("... that ") + 4, 
					questionIndex + 1);
			var hookTemp = document.createElement("div");
			hookTemp.id = "hook-temp";
			hookTemp.innerHTML = "<p>" + hook + "</p>";
			var hookLength = calculateProse(hookTemp, false);
			if (hookTemp.innerHTML.includes("pictured)") || 
					hookTemp.innerHTML.includes("(pictured")) {
				hookLength = hookLength - 10;
			}
			var hookDisp = document.createElement("li");
			hookDisp.id = "hooks-" + num;
			if (num === 0) {
				hookDisp.innerHTML = '<b>Original Hook:</b> ' + escapeHtml(hookLength) + ' characters';
			} else {
				hookDisp.innerHTML = '<b>Alternate Hook ' + escapeHtml(num) +'</b>: ' +
					escapeHtml(hookLength) + ' characters';
			}
			if (hookLength > hookLengthRed) {
				hookDisp.style.cssText = 'background-color:pink';
			} else if (hookLength > hookLengthYellow) {
				hookDisp.style.cssText = 'background-color:yellow';
			}
			hookOutput.appendChild(hookDisp);
			num = num + 1;
		}
		var parsed = whatsLeft.substring(questionIndex + 1, whatsLeft.length - 1);
		var lastHook = checkHooksHelper(hookOutput, parsed, num);
		if (!lastHook && hook) {
			lastHook = hook;
		}
		return lastHook;
	}
	return;
}

function checkTitle(title, output, i) {
	// gets the given title from Wikipedia's server and passes it to scanArticle(),
	// resolving any redirects.
	var promise = api.get({
		format: 'json',
		action: 'parse',
		page: title,
		redirects: true,
		prop: 'text'
	});
	promise.done(function (obj) {
		var ttdykTemp = document.createElement("div");
		ttdykTemp.id = "ttdyk-temp" + i;
		ttdykTemp.innerHTML = obj.parse.text["*"];
		title = obj.parse.title; // Get the new title if we were redirected
		scanArticle(title, output, ttdykTemp);
	});
	promise.fail(function () {
		alert("API error");
	});
}

function clearStats() {
	// if scan results already exist, turn them off and remove highlighting
	if (!onTTDYK) {
		var oldStyle = document.getElementById("dyk-stats-0").className;
		var mainContent = getBody();
		var pList = mainContent.getElementsByTagName("p");
		for (var iPara = 0; iPara < pList.length; iPara++) {
			if (pList[iPara].parentNode === mainContent || (pList[iPara].parentNode.parentNode.parentNode != null && pList[iPara].parentNode.parentNode === mainContent)) {
				pList[iPara].style.cssText = oldStyle;
			}
		}
	}
	if (document.getElementById("error-disp")) {
		var errorDisp = document.getElementById("error-disp");
		errorDisp.parentNode.removeChild(errorDisp);
	}
	var iStat = 0;
	while (document.getElementById("dyk-stats-" + iStat)) {
		var output = document.getElementById("dyk-stats-" + iStat);
		output.parentNode.removeChild(output);
		iStat++;
	}
	if (document.getElementById("hook-container")) {
		var hookOutput = document.getElementById("hook-container");
		hookOutput.parentNode.removeChild(hookOutput);
	}
	if (document.getElementById("dyk-header")) {
		var header = document.getElementById("dyk-header");
		header.parentNode.removeChild(header);
	}
	if (document.getElementById("dyk-processing")) {
		var processing = document.getElementById("dyk-processing");
		processing.parentNode.removeChild(processing);
	}
}

function calculateProse(doc, visible) {
	// calculates the prose of a given document
	// this function and its helper below are modified versions of
	// the prosesize tool (http://en.wikipedia.org/wiki/User:Dr_pda/prosesize.js)
	var pList = doc.getElementsByTagName("p");
	var prose_size = 0;
	
	var i = 0;
	if (mwConfig.wgAction === 'submit' && visible) i = 1; // Avoid the "Remember that this is only a preview" text
	for (; i < pList.length; i++) {
		if (pList[i].parentNode !== doc && pList[i].parentNode.parentNode.parentNode == null) {
			// Should not occur, for error checking only
			$(pList[i]).addClass('textstat-ignored');
		} else if (pList[i].parentNode === doc || pList[i].parentNode.parentNode.parentNode.id === getBodyId()) {
			prose_size += getReadable(pList[i], visible);
			if (!onTTDYK && visible) {
				pList[i].style.cssText = 'background-color:yellow';
			}
		}
	}
	return prose_size;
}

function getReadable(id, visible) {
	// helper method for calculateProse()
	var textReadable = 0;
	for (var i = 0; i < id.childNodes.length; i++) {
		if (id.childNodes[i].nodeName === '#text') {
			textReadable += id.childNodes[i].nodeValue.length;
		} else if (id.childNodes[i].className !== 'reference' && !id.childNodes[i].className.includes('emplate') &&
				id.childNodes[i].id !== 'coordinates') {
			textReadable += getReadable(id.childNodes[i], visible);
		} else if (visible) { // if it's an inline maintenance tag (like [citation needed]) or geocoordinates
			if (document.getElementById("dyk-stats-0").className) {
				id.childNodes[i].style.cssText = document.getElementById("dyk-stats-0").className;
			} else {
				id.childNodes[i].style.cssText = 'background-color:white';
			}	
		}
	}
	return textReadable;
}

function checkExpansion(title, output, current) {  
	// finds the start of expansion date (last 500 edits)
	// gets the last 500 unique revision ids for past revisions of the article and passes to helper function
	var promise = getRevisions({
		titles: title,
		rvlimit: 500,
		rvprop: ['ids', 'timestamp'],
		rvdir: 'older'
	});
	promise.done(function (revisions) {
		var expandTemp = document.createElement("div");
		expandTemp.id = "expand-temp";
		checkExpansionHelper(title, current, output, expandTemp, revisions, 0, revisions.length-1, -1);
	});
}

function checkExpansionHelper(title, current, output, expandTemp, revisions, min, max, expandIndex) {
	// helper for expansion check, used recursively
	// searches for start of expansion date using a binary search algorithm
	// assumes the article has been more or less increasing in size all the time
	// if the article length has yoyo-ed, this function won't give accurate results
	var mid = Math.ceil((max + min)/2);
	if ((((max - min) < 2) && (max !== revisions.length - 1 || expandIndex !== -1)) || expandIndex === -2) {
		var expandResult = document.createElement("li");
		expandResult.id = "expand-result";
		output.appendChild(expandResult);
		if (expandIndex < 0) {
			if (revisions.length === 500) {
				expandResult.innerHTML = escapeHtml('حجم مقاله ظرف ۵۰۰ ویرایش گذشته پنج برابر نشده‌است');
			} else {
				expandResult.innerHTML = escapeHtml('حجم مقاله از زمان ایجاد پنج برابر نشده‌است');
			}
		} else {
			var date = revisions[expandIndex-1].timestamp;
			expandResult.innerHTML = 'به فرض این که حجم مقاله پنج برابر شده باشد، گسترش آن از ' + 
					escapeHtml(expandIndex) + ' ویرایش قبل در ' + escapeHtml(toNormalDate(date.substring(0,10))) + 'آغاز شده‌است';
			dates[2] = toDateObject(date);
		}
		partsProcessing[3] = true;
		doneProcessing();
		return;
	} else if ((max - min) < 2 && max === revisions.length - 1) {
		expandIndex = -2;
	}
	var promise = api.get({
		format: 'json',
		action: 'parse',
		oldid: revisions[mid].revid,
		prop: 'text'
	});
	promise.done(function (obj) {
		expandTemp.innerHTML = obj.parse.text['*'];
		var prose = calculateProse(expandTemp, false);
		// alert("Prose: " + prose + " 1x: " + current/5 + " Mid: " + mid + " Expand index: " + expandIndex); 
		// use above line to debug the expansion check
		if (prose < (current/5.0)) {
			if ((expandIndex > mid) || (expandIndex < 0)) {
				expandIndex = mid;
			}
			checkExpansionHelper(title, current, output, expandTemp, revisions, min, mid, expandIndex);
		} else {
			checkExpansionHelper(title, current, output, expandTemp, revisions, mid, max, expandIndex);
		}
	});
	promise.fail(function () {
		alert("API error");
		partsProcessing[3] = true;
		doneProcessing();
	});
}

function checkTalk(title, output) { 
	// checks the talk page of the article for DYK, ITN, or stub templates
	if (mwConfig.wgNamespaceNumber !== 2) {
		title = "Talk:" + title;
	} else {
		title = title.replace("User:", "User talk:");
	}
	var promise = getRevisions({
		titles: title,
		rvprop: 'content'
	});
	promise.done(function (revisions) {
		if (revisions && revisions[0]) {
			var talkPage = revisions[0]['*'];
			var result = '';
			var color = '';
			if (talkPage.match(/class\s*=\s*[sS]tub/) && 
					(document.getElementById("stub-alert") === null)) {
				result += 'Article is classified as a stub ';
				color = 'yellow';
			}
			var dyktalkRegexMatches = talkPage.match(/{{\s*[dD](yk|YK\s?)talk[^}]*}}/g);
			if (dyktalkRegexMatches) {
				// if there's a DYK tag, try to find the date of previous appearance
				result += 'Article has appeared on Did You Know before ';
				var dyktalkTag = dyktalkRegexMatches.pop();
				var firstPipeIndex = dyktalkTag.indexOf('|');
				var secondPipeIndex = dyktalkTag.indexOf('|', firstPipeIndex + 1);
				var thirdPipeIndex = dyktalkTag.indexOf('|', secondPipeIndex + 1);
				if (firstPipeIndex !== -1 && secondPipeIndex !== -1) {
					if (thirdPipeIndex === -1) {
						thirdPipeIndex = dyktalkTag.length - 2; // -2 to get rid of the }}
					}
					var monthDate = dyktalkTag.substring(firstPipeIndex + 1, secondPipeIndex);
					var year = dyktalkTag.substring(secondPipeIndex + 1, thirdPipeIndex);
					var featuredDate = new Date(monthDate + " " + year);
					if (featuredDate.toString() !== 'Invalid Date') {
						var month = featuredDate.getMonth() + 1;
						if (month < 10) {
							month = '0' + month;
						}
						var date = featuredDate.getDate();
						if (date < 10) {
							date = '0' + date;
						}
						var dateString = toNormalDate(featuredDate.getFullYear() + '-' + month + '-' + date);
						result = result.substring(0, result.length - 1) + ', on ' + escapeHtml(dateString);
					}
				}
				color = 'pink';
			} else if (talkPage.match(/rticle[ ]?[hH]istory[\s\S]*dykdate\s*=.*?\S/)) {
				result += 'Article has appeared on Did You Know before ';
				color = 'pink';
			}
			if (talkPage.match(/{{\s*[iI]TN(\st|t|T)alk/)) { // {{ITNtalk}}, {{ITN talk}}, {{ITNTalk}}
				result += 'Article has appeared on In The News before ';
				color = 'pink';
			}
			if (result) {
				var talkResult = document.createElement("li");
				talkResult.id = "talk-result";
				output.appendChild(talkResult);
				talkResult.innerHTML = result;
				if (color) {
					talkResult.style["background-color"] = color;
				}
			}
			checkTalkForGoodArticleStatus(talkPage, output);
		}
		partsProcessing[0] = true;
		doneProcessing();
	});
	promise.fail(function () {
		partsProcessing[0] = true;
		doneProcessing();
	});
}

function checkTalkForGoodArticleStatus(talkPage, output) {
	// Test cases:
	// Cathedral of the Immaculate Conception (Moscow) - ArticleHistory, two GANs (last successful), currently a featured article
	// LoveGame - ArticleHistory, one successful GAN, no GARs
	// Paparazzi (Lady Gaga song) - ArticleHistory, one successful GAN, unlisted after a GAR, another successful GAN, no-op GAR
	// Curtis (50 Cent album) - ArticleHistory, one successful GAN, unlisted after a GAR
	// G.U.Y. - ArticleHistory with unconventional formatting
	// Arthur Adams (comics) - ArticleHistory with unconventional formatting
	// Blackburn Firebrand - {{GA}}
	// Tony Hawk's Underground - {{GA}} with confounding {{Game}} tag
	var gaDate = '';
	var gaRegexMatches = talkPage.match(/{{\s*[gG][aA]\s*[|][^}]*}}/g);
	if (gaRegexMatches) {
		// if there's a GA tag, try to find the date of promotion to Good Article
		var gaTag = gaRegexMatches.pop();
		var firstPipeIndex = gaTag.indexOf('|');
		var secondPipeIndex = gaTag.indexOf('|', firstPipeIndex + 1);
		if (firstPipeIndex !== -1) {
			if (secondPipeIndex === -1) {
				secondPipeIndex = gaTag.length - 2; // -2 to get rid of the }}
			}
			gaDate = gaTag.substring(firstPipeIndex + 1, secondPipeIndex);
		}
	} else if (talkPage.match(/rticle[ ]?[hH]istory/)) {
		// check ArticleHistory tag for Good Article status
		
		// grab last GAN action
		// figure out action number
		// given action number, was action result "listed"?
		// if no, stop here - article is not a Good Article
		// if yes, grab the Good Article promotion date from actionXdate
		var ganMatches = talkPage.match(/action[0123456789]+\s*=\s*(gan|GAN)/g);
		if (ganMatches) {
			var lastGanAction = ganMatches.pop();
			var lastGanActionNumber = lastGanAction.substring(6, lastGanAction.indexOf('=')); // remove 'action' and everything at and after the equals sign
			lastGanActionNumber = lastGanActionNumber.trim();
			var ganResultIndex = talkPage.indexOf('action' + lastGanActionNumber +  'result');
			var ganResult = talkPage.substring(talkPage.indexOf('=', ganResultIndex) + 1, talkPage.indexOf('|', ganResultIndex)).trim();
			if (ganResult === 'listed' || ganResult === 'Listed' || ganResult === 'passed' || ganResult === 'Passed') {
				var ganDateIndex = talkPage.indexOf('action' + lastGanActionNumber +  'date');
				gaDate = talkPage.substring(talkPage.indexOf('=', ganDateIndex) + 1, talkPage.indexOf('|', ganDateIndex)).trim();
			}
			
			// then grab last GAR action
			// figure out action number
			// is GAR action number after GAN action number? if yes, carry on
			// given action number, was action result "not listed"?
			// if yes, article is not a Good Article
			var garMatches = talkPage.match(/action[0123456789]+\s*=\s*(gar|GAR)/g);
			if (garMatches) {
				var lastGarAction = garMatches.pop();
				var lastGarActionNumber = lastGarAction.substring(6, lastGarAction.indexOf('=')); // remove 'action' and everything at and after the equals sign
				lastGarActionNumber = lastGarActionNumber.trim();
				if (parseInt(lastGarActionNumber) > parseInt(lastGanActionNumber)) {
					var garResultIndex = talkPage.indexOf('action' + lastGarActionNumber +  'result');
					var garResult = talkPage.substring(talkPage.indexOf('=', garResultIndex) + 1, talkPage.indexOf('|', garResultIndex)).trim();
					if (garResult === 'delisted' || garResult === 'Delisted') {
						gaDate = ''; // Not a Good Article, GAR came after GAN and demoted the article
					}
				}
			}
		}
	}
	
	if (gaDate) {
		if (gaDate.length > 6 && gaDate.indexOf(' (UTC)') === gaDate.length - 6) {
			gaDate = gaDate.substring(0, gaDate.length - 6); // The Boat Race 1997 is not parsing correctly if (UTC) is left in
		}
		if (gaDate.length > 5 && gaDate[2] === ':' && gaDate[5] === ',') {
			gaDate = gaDate.substring(6, gaDate.length); // Chrome not parsing as expected for strings like "17:21, 26 June 2014"
		}
		
		var gaPromotion = document.createElement("li");
		gaPromotion.id = "ga-promotion";
		output.appendChild(gaPromotion);
		var gaPromotedDate = new Date();
		gaPromotedDate.setTime(Date.parse(gaDate));
		
		// ensure the Date object is in the right time zone
		gaPromotedDate = new Date(Date.UTC(gaPromotedDate.getFullYear(), gaPromotedDate.getMonth(), gaPromotedDate.getDate(), gaPromotedDate.getHours(), gaPromotedDate.getMinutes(), gaPromotedDate.getSeconds()));
		
		dates[3] = gaPromotedDate;
		gaPromotion.innerHTML = 'Article was promoted to Good Article status on ' +
			escapeHtml(toNormalDate(gaPromotedDate.toISOString()));
	}
}

function getRevisions(options) {
	// Returns a jQuery promise with an array of a title's revisions.
	// The first parameter is an options object accepting the following API fields:
	// - titles
	// - rvlimit
	// - rvprop
	// - rvdir
	options = options || {};
	return api.get({
		format: 'json',
		action: 'query',
		prop: 'revisions',
		titles: options.titles,
		rvlimit: options.rvlimit,
		rvprop: options.rvprop,
		rvdir: options.rvdir,
		indexpageids: true
	}).then(
		// On success
		function (obj) {
			var pageId = obj.query.pageids[0];
			return obj.query.pages[pageId].revisions;
		},
		// On failure
		function (err) {
			alert("API error");
			return err;
		}
	);
}

function getFirstRevision(title, output) {
	// finds the creator of the article, and the date created
	// also checks if the article was created as a redirect, finds non-redirect date if so

	var created = document.createElement("li");
	created.id = "creation-info";
	output.appendChild(created);
		
	var promise = getRevisions({
		titles: title,
		rvlimit: 4,
		rvprop: ['timestamp', 'user', 'content'],
		rvdir: 'newer'
	});
	promise.done(function (revisions) {
		var user = revisions[0].user;
		var timestamp = revisions[0].timestamp;
		created.innerHTML='<b>ایجاد مقاله</b> توسط ' + escapeHtml(user) + 
				'  در ' + escapeHtml(toNormalDate(timestamp.substring(0,10)));
		dates[0] = toDateObject(timestamp);
		for (var i = 0; i < revisions.length; i++) {
			var content = revisions[i]['*'];
			var isRedirect = content.replace(' ', '').replace(':', '').toUpperCase().includes('#REDIRECT[[');
			if (isRedirect && i === 0) {
				created.innerHTML = created.innerHTML + ' as a redirect';
			} else if (!isRedirect) {
				if (i !== 0) {
					var unRedirect = document.createElement("li");
					unRedirect.id = "expanded-from-redirect";
					output.appendChild(unRedirect);
					var urUser = revisions[i].user;
					var urTimestamp = revisions[i].timestamp;
					unRedirect.innerHTML = 'Article became a non-redirect on ' + 
							escapeHtml(toNormalDate(urTimestamp.substring(0,10))) +
							' by ' + escapeHtml(urUser);
					dates[0] = toDateObject(urTimestamp);
				}
				break;
			}
		}
		partsProcessing[1] = true;
		doneProcessing();
	});
	promise.fail(function () {
		partsProcessing[1] = true;
		doneProcessing();
	});
}

function checkMove(title, output) { 
	//checks the last 100 edits of an article for a move from userspace or AfC to current location
	var promise = getRevisions({
		titles: title,
		rvlimit: 100,
		rvprop: ['flags', 'user', 'timestamp', 'comment'],
		rvdir: 'older',
	});
	promise.done(function (revisions) {
		for (var i = 0; i < revisions.length; i++) {
			var comment = revisions[i].comment;
			var userName = revisions[i].user;
			if ((revisions[i].minor === "") && 
					comment.match(/moved (page )?((\[\[User:)|(\[\[Draft:)|(\[\[Wikipedia talk:Articles for creation\/))[\s\S]*to \[\[/)) {
				var movedFrom = comment.substring(comment.indexOf("[[") + 2, comment.indexOf("to [[") - 3);
				var date = revisions[i].timestamp;
				var moved = document.createElement("li");
				moved.id = "moved-userspace";
				output.appendChild(moved);
				moved.innerHTML = '<b>Article moved</b> from ' + escapeHtml(movedFrom) + 
						' on ' + escapeHtml(toNormalDate(date.substring(0,10)));
				dates[1] = toDateObject(date);
				break;
			}
		}
		partsProcessing[2] = true;
		doneProcessing();
	});
	promise.fail(function () {
		partsProcessing[2] = true;
		doneProcessing();
	});
}

function doneProcessing() {
	// checks if all parts are done processing
	// if they are, the dates of creation and expansion are checked for within 10 days (rounded down, in nominator's favor)
	// then the next title (for multiple article noms) is processed (required to combat asynchronous threads)
	// if there are no more titles left (or not on T:TDYK), the processing message is removed
	var titleComplete = true;
	for (var i = 0; i < partsProcessing.length; i++) {
		if (!partsProcessing[i]) {
			titleComplete = false;
			break;
		}
	}
	if (document.getElementById("dyk-processing") && titleComplete) {
		var curDate = new Date();
		var winner = new Date();
		if (dates[1]) {
			winner = dates[1]; 
		} else {
			winner = dates[0];
		}
		if (dates[2] > winner) {
			winner = dates[2];
		}
		if (dates[3] > winner) {
			winner = dates[3];
		}
		var dateDifference = Math.floor((curDate.getTime() - winner.getTime())/(1000*60*60*24));
		if (dateDifference > 10) {
			var output = document.getElementById("dyk-stats-" + currentTitle);
			var notRecent = document.createElement("li");
			notRecent.id = "not-recent";
			output.appendChild(notRecent);
			if (!onTTDYK || (check5xNoms === "always") || (check5xNoms === "ifnom5x" && nom5x)) {
				notRecent.innerHTML = "مقاله ظرف ده روز گذشته ایجاد نشده، حجمش پنج برابر نشده، و به عنوان مقالهٔ خوب برگزیده نشده‌است (" + 
						escapeHtml(dateDifference.toLocaleString('fa')) + " روز). " + " <small>آمیک‌سنج نسخه‌های قبلی که " +
						'<a href="//fa.wikipedia.org/wiki/ویکی‌پدیا:تفکیک">تفکیک شده‌اند</a> یا ' +
						'<a href="//fa.wikipedia.org/wiki/ویکی‌پدیا:نقض حق تکثیر">حق تکثیر را نقض کرده‌اند</a> نمی‌تواند در محاسبه وارد کند.</small>';
			} else {
				notRecent.innerHTML = "مقاله ظرف ده روز گذشته ایجاد نشده‌است (" + escapeHtml(dateDifference.toLocaleString('fa')) + " روز)";
			}
			notRecent.style.cssText = 'background-color:pink';
		}
		if (onTTDYK && currentTitle < (articleTitles.length - 1)) {
			currentTitle++;
			checkTitle(articleTitles[currentTitle], 
					document.getElementById("dyk-stats-" + (currentTitle)), currentTitle);
		} else {
			var processing = document.getElementById("dyk-processing");
			processing.parentNode.removeChild(processing);
		}
	}
}

// taken from the prosesize tool (http://en.wikipedia.org/wiki/User:Dr_pda/prosesize.js)
function getBodyId() {
	var contentName;
	if (mwConfig.skin === 'monobook' || mwConfig.skin === 'chick' || mwConfig.skin === 'mymwConfig.skin' || mwConfig.skin === 'simple') {
		contentName = 'bodyContent';
	} else if (mwConfig.skin === 'modern') {
		contentName = 'mw_contentholder';
	} else if (mwConfig.skin === 'standard' || mwConfig.skin === 'cologneblue' || mwConfig.skin === 'nostalgia') {
		contentName = 'article';
	} else {
		// fallback case; the above covers all currently existing skins
		contentName = 'bodyContent';
	}
	// Same for all skins if previewing page
	if (mwConfig.wgAction === 'submit') contentName = 'wikiPreview';
	return contentName;
}

function getBody() { 
	// gets the HTML body of the page
	// taken from the prosesize tool (http://en.wikipedia.org/wiki/User:Dr_pda/prosesize.js)
	return document.getElementById(getBodyId());
}

function getFirstNom() {
	var firstNom = 0;
	
	// Find the first "Articles created/expanded on ..." h3 section
	var elementIterator = sections[firstNom].previousSibling;
	while (elementIterator.nodeName.toLowerCase() !== "h3") {
		elementIterator = elementIterator.previousSibling;
	}
	while (!(elementIterator.nodeName.toLowerCase() === "h3" && 
			elementIterator.innerHTML.includes("Articles created/expanded on"))) {
		if (elementIterator.nodeName.toLowerCase() === "h4") {
			firstNom++;
		}
		elementIterator = elementIterator.nextSibling;
	}
	return firstNom;
}

function createHeaderAndProcessing(output) { 
	// makes the header above the scan results
	var header = document.createElement("span");
	header.id = "dyk-header";
	header.innerHTML = '<br /><b>نتیجهٔ بررسی برای مطابقت با شرایط <i>وپ:آمیک</i>: ' +
             '<small><i>(برای اطلاعات بیشتر <a href="//fa.wikipedia.org/wiki/' + 'ویکی‌پدیا:آمیک‌سنج">اینجا</a> را ببینید.)</i></small></b>';
	output.parentNode.insertBefore(header,output);
	var processing = document.createElement("span");
	processing.id = "dyk-processing";
	processing.innerHTML = '<br /><b><font color="crimson"> در حال بررسی... </font></b>';
	output.parentNode.insertBefore(processing, header);
}

function toNormalDate(utc) { 
	// converts the date part of a Wikipedia timestamp to a readable date
	var months = new Array("blank","ژانویه","فوریه", "مارس", "آوریل", "مه", "ژوئن", 
			"ژوئیه", "اوت", "سپتامبر", "اکتبر", "نوامبر", "دسامبر");
	/*if (dateFormat === "british") {
		return (utc.substring(8,10) * 1) + ' ' + months[utc.substring(5,7) * 1] + ' ' + utc.substring(0,4);
	} else {
		return months[utc.substring(5,7) * 1] + ' ' + (utc.substring(8,10) * 1) + ', ' + utc.substring(0,4);
	}*/
        return parseInt(utc.substring(8,10)).toLocaleString('fa') + ' ' + months[utc.substring(5,7) * 1] + ' ۲۰' + parseInt(utc.substring(2,4)).toLocaleString('fa');
}

function toDateObject(timestamp) { 
	// converts a Wikipedia timestamp to a Javascript Date object
	var date = new Date();
	date.setUTCFullYear(timestamp.substring(0,4), timestamp.substring(5,7) - 1, timestamp.substring(8,10));
	date.setUTCHours(timestamp.substring(11,13), timestamp.substring(14,16), timestamp.substring(17,19));
	return date;
}

function fixSidebar() { // part of the code to fix the sidebar; the rest is below the addOnloadHook function
	// this function is only necessary for the monobook skin
	var content = document.getElementById("column-content");    // Find the main content column

	var footer = document.getElementById("footer");  // Find the footer
	footer.parentNode.removeChild(footer);    // Remove the footer from the global wrapper
	content.appendChild(footer);    // Place footer at the end of the content column;

	var tabs = document.getElementById("p-cactions");   // Find the top tab list
	tabs.parentNode.removeChild(tabs);    // Remove the tab list from the side column
	content.insertBefore(tabs, content.lastChild);    // Place tab list in the content column

	var personal = document.getElementById("p-personal");   // Find the personal links list
	personal.parentNode.removeChild(personal);    // Remove the personal links list from the side column
	content.insertBefore(personal, content.lastChild);    // Place personal links list in the content column
}

window.dykCheck = function () { 
	// this function for casual use and anons
	if (((mwConfig.wgAction === 'view' || mwConfig.wgAction === 'submit' || mwConfig.wgAction === 'purge') && 
			(mwConfig.wgNamespaceNumber === 0 || mwConfig.wgNamespaceNumber === 2)) || unlock) {
		checkDocument();
	} else if (mwConfig.wgPageName === 'Template_talk:Did_you_know') {
		checkTTDYK();
	}
};

function addToolbarPortletLink(func, tooltip) {
	var link = mw.util.addPortletLink(
		'p-tb',
		'#',
		'آمیک‌سنج (بتا)',
		't-dyk-check',
		tooltip
	);
	$( link ).click( function (e) {
		e.preventDefault();
		func();
	});
}

// Add toolbar portlet links
if (unlock || (
		(mwConfig.wgAction === 'view' || mwConfig.wgAction === 'submit' || mwConfig.wgAction === 'purge') && 
		(mwConfig.wgNamespaceNumber === 0 || mwConfig.wgNamespaceNumber === 2)
)) {
	addToolbarPortletLink(checkDocument, 'Check if this article qualifies for DYK');
} else if (mwConfig.wgPageName === 'Template_talk:Did_you_know') {
	addToolbarPortletLink(checkTTDYK, 'Check DYK nominations for eligibility');
}

// Fix the sidebar
if (mwConfig.wgUserName && mwConfig.skin === 'monobook' && (
		fixedSidebar === "always" ||
		fixedSidebar === "onttydk" && mwConfig.wgPageName === 'Template_talk:Did_you_know'
)) {
	fixSidebar();
}

// The code below for the fixed sidebar is a blend of two sources:
//		http://meta.wikimedia.org/wiki/Help:User_style/floating_quickbar 
// 		http://en.wikipedia.org/wiki/User:Omegatron/monobook.js/floatingSidebar.js
// Very little of the code below was written by me (Shubinator)

// This CSS should be hidden from older versions of IE using javascript instead of the attribute selector?

// Include style sheet inline so that script is self-contained:
if (mwConfig.wgUserName && (
		fixedSidebar === "always" ||
		fixedSidebar === "onttydk" && mwConfig.wgPageName === 'Template_talk:Did_you_know'
)) {
	var head = document.getElementsByTagName("head")[0];
	var style = document.createElement('style');
	style.type = 'text/css';
	var sidebarDivHidden;
	var sidebarDiv;
	var langBody;
	if (mwConfig.skin === 'vector') { // default skin  (as of May 2010)
		sidebarDivHidden = 'div#mw-panel';
		sidebarDiv = 'div#mw-panel';
		langBody = '#p-lang .body';
	} else { // monobook, modern, and simple skins
		if (mwConfig.skin === 'modern') {
			sidebarDivHidden = 'div[id=mw_portlets]';
		} else if (mwConfig.skin === 'simple') {
			sidebarDivHidden = '#column-one';
		} else { // monobook skin
			sidebarDivHidden = 'div[id=column-one]'; /* Using the attribute selector hides this from IE */
		}
		sidebarDiv = '#column-one';
		langBody = '#p-lang .pBody';
	}
	var cssText = "   /* Fix the sidebar's position while you scroll */             "+
	    sidebarDivHidden + ' {                                                      '+
	'       position: fixed;                                                        ';
	if (mwConfig.skin === 'vector') { // force the sidebar to the upper left; only necessary in some skins
	    cssText += 'left: 0px;                                                      '+
	    '   top: 0px;                                                               ';
	} else if (mwConfig.skin === 'monobook') {
	    cssText += 'left: 0px;                                                      '+
	    '   top: -160px;                                                            ';
	}
	cssText += 'height: 100%;   /* If you shrink the browser too small, the     */  '+
	'       overflow: auto;     /* side column will become scrollable, so stuff */  '+
	'       z-index: 2;         /* is always accessible, albeit ugly            */  '+
	'   }                                                                           '+
	'                                                                               '+
	'   #p-logo {               /* Make logo inline with other divs             */  '+
	'       position:static;                                                        '+
	'   }                                                                           '+
	'                                                                               '+
	    sidebarDiv       + ' {  /* Sidebar column start at the top screen edge  */  '+
	'       padding-top: 0;                                                         '+
	'   }                                                                           '+
	'                                                                               '+
	    langBody + 	  ' ul{      /* Sets the language box to a fixed height and  */ '+
	'       height: 6em;        /* scrollable if too long to fit on screen      */  '+
	'       overflow: auto;                                                         '+
	'   }                                                                           '+
	'                                                                               '+
	'   /* Fix the background image, too, so it looks nice as you scroll */         '+
	'   body {                                                                      '+
	'       background-attachment: fixed;                                           '+
	'   }                                                                           '+
	'                                                                               '+
	"   /* Fix the footer so it looks nice and doesn't overlap the sidebar */       "+
	'   #footer {                                                                   '+
	'       margin-left: 13.6em;                                                    '+
	'       border-left: solid 1px rgb(250, 189, 35);                               '+
	'       -moz-border-radius-topleft: 1em;                                        '+
	'       -moz-border-radius-bottomleft: 1em;                                     '+
	'   }                                                                           ';
	if (mwConfig.skin === 'monobook') {
	    cssText += 	'   /* Keep personal links at the top right */                  '+
	'   #p-personal {                                                               '+
	'       width:100%;                                                             '+
	'       white-space:nowrap;                                                     '+
	'       padding:0 0 0 0;                                                        '+
	'       margin:0;                                                               '+
	'       position:absolute;                                                      '+
	'       left:0px;                                                               '+
	'       top:0px;                                                                '+
	'       z-index: 0;                                                             '+
	'       border: none;                                                           '+
	'       background: none;                                                       '+
	'       overflow: visible;                                                      '+
	'       line-height: 1.2em;                                                     '+
	'   }                                                                           '+
	'                                                                               '+
	'   #p-personal h5 {                                                            '+
	'       display:none;                                                           '+
	'   }                                                                           '+
	'   #p-personal .portlet,                                                       '+
	'   #p-personal .pBody {                                                        '+
	'       padding:0;                                                              '+
	'       margin:0;                                                               '+
	'       border: none;                                                           '+
	'       z-index:0;                                                              '+
	'       overflow: visible;                                                      '+
	'       background: none;                                                       '+
	'   }                                                                           '+
	'   /* this is the ul contained in the portlet */                               '+
	'   #p-personal ul {                                                            '+
	'       border: none;                                                           '+
	'       line-height: 1.4em;                                                     '+
	'       color: #2f6fab;                                                         '+
	'       padding: 0em 2em 0 3em;                                                 '+
	'       margin: 0;                                                              '+
	'       text-align: right;                                                      '+
	'       text-transform: lowercase;                                              '+
	'       list-style: none;                                                       '+
	'       z-index:0;                                                              '+
	'       background: none;                                                       '+
	'   }                                                                           '+
	'   #p-personal li {                                                            '+
	'       z-index:0;                                                              '+
	'       border:none;                                                            '+
	'       padding:0;                                                              '+
	'       display: inline;                                                        '+
	'       color: #2f6fab;                                                         '+
	'       margin-left: 1em;                                                       '+
	'       line-height: 1.2em;                                                     '+
	'       background: none;                                                       '+
	'   }                                                                           '+
	'   #p-personal li a {                                                          '+
	'       text-decoration: none;                                                  '+
	'       color: #005896;                                                         '+
	'       padding-bottom: 0.2em;                                                  '+
	'       background: none;                                                       '+
	'   }                                                                           '+
	'   #p-personal li a:hover {                                                    '+
	'       background-color: White;                                                '+
	'       padding-bottom: 0.2em;                                                  '+
	'       text-decoration: none;                                                  '+
	'   }                                                                           '+
	'   /* Keep the small user figure left of your user name */                     '+
	'   li#pt-userpage,                                                             '+
	'   li#pt-anonuserpage,                                                         '+
	'   li#pt-login {                                                               '+
	'       background: url(/w/skins/MonoBook/user.gif) top left no-repeat;       '+
	'       padding-left: 20px;                                                     '+
	'       text-transform: none;                                                   '+
	'   }                                                                           '+
	'                                                                               ';
	}
	var rules = document.createTextNode(cssText);
	if (style.styleSheet) {
		style.styleSheet.cssText = rules.nodeValue;
	} else {
		style.appendChild(rules);
	}
	head.appendChild(style);
}

});