مندرجات کا رخ کریں

میڈیاویکی:Common.js

نعت کائنات سے

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

  • فائرفاکس/ سفاری: جب Reload پر کلک کریں تو Shift دباکر رکھیں، یا Ctrl-F5 یا Ctrl-R دبائیں (Mac پر R-⌘)
  • گوگل کروم: Ctrl-Shift-R دبائیں (Mac پر Shift-R-⌘)
  • انٹرنیٹ ایکسپلورر: جب Refresh پر کلک کریں تو Ctrl یا Ctrl-F5 دبائیں
  • اوپیرا: Tools → Preferences میں جائیں اور کیش (cache) صاف کریں
// Refresh an outdated Approved Revs page restored from browser history.
( function () {
	'use strict';

	window.addEventListener( 'pageshow', function ( event ) {
		if (
			event.persisted &&
			document.getElementById( 'approvedrevs-approve-latest-notice' )
		) {
			window.location.reload();
		}
	} );
}() );

// Open rendered content links and category links in a new tab, without changing page controls.
( function () {
	'use strict';

	function applyArticleLinkTargets( $content ) {
		$content.find( '.mw-parser-output a, #catlinks a' ).each( function () {
			var $link = $( this );

			if ( $link.closest( '.toc, .mw-editsection, .reference, .mw-references-wrap' ).length ) {
				return;
			}

			$link.attr( {
				target: '_blank',
				rel: 'noopener noreferrer'
			} );
		} );
	}

	$( function () {
		applyArticleLinkTargets( $( document ) );
	} );
	mw.hook( 'wikipage.content' ).add( applyArticleLinkTargets );
}() );

// Search direct page members of Category:کتب from the decorated category page.
( function () {
	'use strict';

	function normaliseSearchText( value ) {
		return ( value || '' ).replace( /\s+/g, ' ' ).trim().toLowerCase();
	}

	function renderResults( root, results, query ) {
		var list = root.querySelector( '#nk-book-category-search-results' );
		var status = root.querySelector( '#nk-book-category-search-status' );
		list.textContent = '';

		if ( !query ) {
			status.textContent = 'کتاب کے عنوان کا کوئی لفظ لکھیں۔';
			return;
		}

		if ( !results.length ) {
			status.textContent = 'اس لفظ سے کوئی کتاب نہیں ملی۔';
			return;
		}

		status.textContent = results.length + ' عنوان ملے';
		results.slice( 0, 60 ).forEach( function ( title ) {
			var item = document.createElement( 'li' );
			var link = document.createElement( 'a' );
			link.href = mw.util.getUrl( title );
			link.textContent = title;
			item.appendChild( link );
			list.appendChild( item );
		} );
		if ( results.length > 60 ) {
			var more = document.createElement( 'li' );
			more.textContent = 'مزید نتائج کے لیے تلاش کو مخصوص کریں۔';
			list.appendChild( more );
		}
	}

	function loadBookTitles( api, cmcontinue, collected ) {
		var params = {
			action: 'query',
			list: 'categorymembers',
			cmtitle: 'Category:کتب',
			cmtype: 'page',
			cmprop: 'title',
			cmlimit: 'max',
			formatversion: 2
		};
		if ( cmcontinue ) {
			params.cmcontinue = cmcontinue;
		}

		return nkHomepageApiGet( api, params ).then( function ( data ) {
			var members = data.query && data.query.categorymembers ?
				data.query.categorymembers : [];
			members.forEach( function ( member ) {
				collected.push( member.title );
			} );
			if ( data.continue && data.continue.cmcontinue ) {
				return loadBookTitles( api, data.continue.cmcontinue, collected );
			}
			return collected.sort( function ( a, b ) {
				return a.localeCompare( b, 'ur' );
			} );
		} );
	}

	$( function () {
		var root = document.getElementById( 'nk-book-category-search' );
		if ( !root ) {
			return;
		}

		mw.loader.using( [ 'mediawiki.api', 'mediawiki.util' ] ).then( function () {
			var api = new mw.Api();
			var controls = root.querySelector( '#nk-book-category-search-controls' );
			var input = document.createElement( 'input' );
			var button = document.createElement( 'button' );
			var status = root.querySelector( '#nk-book-category-search-status' );
			var titlesPromise = null;
			var debounceTimer = null;

			input.id = 'nk-book-category-search-input';
			input.type = 'search';
			input.placeholder = 'کتاب کے عنوان کا کوئی لفظ لکھیں';
			input.setAttribute( 'aria-label', 'کتاب تلاش کریں' );
			button.id = 'nk-book-category-search-button';
			button.type = 'button';
			button.textContent = 'تلاش';
			if ( controls ) {
				controls.textContent = '';
				controls.appendChild( input );
				controls.appendChild( button );
			}

			function search() {
				var query = normaliseSearchText( input.value );
				if ( !titlesPromise ) {
					status.textContent = 'کتابوں کی فہرست لوڈ ہو رہی ہے۔';
					titlesPromise = loadBookTitles( api, null, [] );
				}
				titlesPromise.then( function ( titles ) {
					var results = query ? titles.filter( function ( title ) {
						return normaliseSearchText( title ).indexOf( query ) !== -1;
					} ) : [];
					renderResults( root, results, query );
				}, function () {
					status.textContent = 'فہرست لوڈ نہیں ہو سکی۔';
				} );
			}

			input.addEventListener( 'input', function () {
				clearTimeout( debounceTimer );
				debounceTimer = setTimeout( search, 180 );
			} );
			button.addEventListener( 'click', search );
		} );
	} );
}() );

// Automatically list Category:کتب subcategories that are not yet placed in custom category panels.
// Revision marker: refresh ResourceLoader after adding the automatic new-categories panel.
( function () {
	'use strict';

	function cleanCategoryName( value ) {
		return ( value || '' )
			.replace( /^زمرہ\s*:/, '' )
			.replace( /^Category\s*:/i, '' )
			.replace( /_/g, ' ' )
			.replace( /\s+/g, ' ' )
			.trim();
	}

	function categoryNameFromLink( link ) {
		var titleAttr = link.getAttribute( 'title' ) || '';
		var title = cleanCategoryName( titleAttr );
		if ( /^(زمرہ|Category)\s*:/i.test( titleAttr ) && title ) {
			return title;
		}
		try {
			var url = new URL( link.href, location.href );
			var path = decodeURIComponent( url.pathname || '' );
			var queryTitle = url.searchParams.get( 'title' );
			if ( queryTitle && /^(زمرہ|Category)\s*:/i.test( queryTitle ) ) {
				return cleanCategoryName( queryTitle );
			}
			var marker = '/زمرہ:';
			var markerIndex = path.indexOf( marker );
			if ( markerIndex !== -1 ) {
				return cleanCategoryName( path.slice( markerIndex + marker.length ) );
			}
		} catch ( e ) {}
		return '';
	}

	function collectClassifiedCategories( root ) {
		var classified = Object.create( null );
		var panels = root.querySelectorAll( '.nk-home-panel' );
		Array.prototype.forEach.call( panels, function ( panel ) {
			if ( panel.id === 'nk-book-category-new-categories' ) {
				return;
			}
			Array.prototype.forEach.call( panel.querySelectorAll( 'a[href]' ), function ( link ) {
				var category = categoryNameFromLink( link );
				if ( category ) {
					classified[category] = true;
				}
			} );
		} );
		return classified;
	}

	function ensureOtherCategoriesPanel( root ) {
		var existing = document.getElementById( 'nk-book-category-new-categories' );
		if ( existing ) {
			return existing;
		}

		var columns = root.querySelector( '.nk-home-columns-bottom' ) || root;
		var panel = document.createElement( 'div' );
		var headingWrapper = document.createElement( 'div' );
		var heading = document.createElement( 'h2' );
		var body = document.createElement( 'div' );
		var list = document.createElement( 'ul' );

		panel.id = 'nk-book-category-new-categories';
		panel.className = 'nk-home-panel nk-home-panel-dyk';
		headingWrapper.className = 'mw-heading mw-heading2';
		heading.textContent = 'نئے زمرہ جات';
		body.className = 'nk-home-panel-body';
		list.id = 'nk-book-category-new-categories-list';

		headingWrapper.appendChild( heading );
		body.appendChild( list );
		panel.appendChild( headingWrapper );
		panel.appendChild( body );
		columns.appendChild( panel );
		return panel;
	}

	function renderOtherCategories( root, categories ) {
		var existing = document.getElementById( 'nk-book-category-new-categories' );
		if ( !categories.length ) {
			if ( existing && existing.parentNode ) {
				existing.parentNode.removeChild( existing );
			}
			return;
		}

		var panel = ensureOtherCategoriesPanel( root );
		var list = panel.querySelector( '#nk-book-category-new-categories-list' );
		list.textContent = '';

		categories.forEach( function ( category ) {
			var item = document.createElement( 'li' );
			var link = document.createElement( 'a' );
			link.href = mw.util.getUrl( 'زمرہ:' + category );
			link.textContent = category;
			item.appendChild( link );
			list.appendChild( item );
		} );
	}

	function loadBookSubcategories( api, cmcontinue, collected ) {
		var params = {
			action: 'query',
			list: 'categorymembers',
			cmtitle: 'Category:کتب',
			cmtype: 'subcat',
			cmprop: 'title',
			cmlimit: 'max',
			formatversion: 2
		};
		if ( cmcontinue ) {
			params.cmcontinue = cmcontinue;
		}

		return nkHomepageApiGet( api, params ).then( function ( data ) {
			var members = data.query && data.query.categorymembers ?
				data.query.categorymembers : [];
			members.forEach( function ( member ) {
				collected.push( cleanCategoryName( member.title ) );
			} );
			if ( data.continue && data.continue.cmcontinue ) {
				return loadBookSubcategories( api, data.continue.cmcontinue, collected );
			}
			return collected.sort( function ( a, b ) {
				return a.localeCompare( b, 'ur' );
			} );
		} );
	}

	$( function () {
		var root = document.querySelector( '.nk-home' );
		if (
			!root ||
			(
				mw.config.get( 'wgPageName' ) !== 'زمرہ:کتب' &&
				!root.querySelector( '#nk-book-category-search' ) &&
				!root.querySelector( '#nk-book-category-new-categories' )
			)
		) {
			return;
		}

		mw.loader.using( [ 'mediawiki.api', 'mediawiki.util' ] ).then( function () {
			var api = new mw.Api();
			return loadBookSubcategories( api, null, [] ).then( function ( subcategories ) {
				var classified = collectClassifiedCategories( root );
				var others = subcategories.filter( function ( category ) {
					return category && !classified[category];
				} );
				renderOtherCategories( root, others );
			} );
		} );
	} );
}() );

var nkHomepageApiActive = 0;
var nkHomepageApiPending = [];
var nkHomepageApiConcurrency = 3;

function nkHomepageApiRunNext() {
	if (
		nkHomepageApiActive >= nkHomepageApiConcurrency ||
		!nkHomepageApiPending.length
	) {
		return;
	}

	var job = nkHomepageApiPending.shift();
	nkHomepageApiActive++;
	function complete() {
		nkHomepageApiActive--;
		nkHomepageApiRunNext();
	}
	job.run().then( function ( data ) {
		job.resolve( data );
		complete();
	}, function ( error ) {
		job.reject( error );
		complete();
	} );
}

function nkHomepageApiGet( api, params ) {
	function request( attempt ) {
		return api.get( params ).catch( function ( error ) {
			if ( attempt >= 2 ) {
				return Promise.reject( error );
			}
			return new Promise( function ( resolve ) {
				setTimeout( resolve, 250 * ( attempt + 1 ) );
			} ).then( function () {
				return request( attempt + 1 );
			} );
		} );
	}

	return new Promise( function ( resolve, reject ) {
		nkHomepageApiPending.push( {
			run: function () {
				return request( 0 );
			},
			resolve: resolve,
			reject: reject
		} );
		nkHomepageApiRunNext();
	} );
}

function nkLoadApprovedPage( api, title ) {
	return nkHomepageApiGet( api, {
		action: 'nkapprovedrevision',
		title: title
	} ).then( function ( data ) {
		var approvedPage = data.nkapprovedrevision;
		if ( !approvedPage || !approvedPage.revid ) {
			return Promise.reject( new Error( 'Page has no approved revision: ' + title ) );
		}

		return nkHomepageApiGet( api, {
			action: 'parse',
			oldid: approvedPage.revid,
			prop: 'text',
			disableeditsection: true,
			disabletoc: true,
			formatversion: 2
		} ).then( function ( parsed ) {
			return {
				page: approvedPage,
				html: parsed.parse.text
			};
		} );
	} );
}

function nkApprovedThumbnailFromHtml( html, defaultSize ) {
	var parsed = new DOMParser().parseFromString( html, 'text/html' );
	var parserOutput = parsed.querySelector( '.mw-parser-output' );
	var image = parserOutput && parserOutput.querySelector( 'img' );
	if ( !image ) {
		return null;
	}

	var source = image.getAttribute( 'src' );
	if ( !source ) {
		return null;
	}

	return {
		source: new URL( source, mw.config.get( 'wgServer' ) ).href,
		width: Number( image.getAttribute( 'width' ) ) || defaultSize,
		height: Number( image.getAttribute( 'height' ) ) || defaultSize
	};
}

// Six most recently edited or created article pages.
( function () {
	'use strict';

	if ( mw.config.get( 'wgPageName' ) !== 'صفحۂ_اول' ) {
		return;
	}

	// Urdu display names for non-human editor accounts.
	var nkEditorDisplayNames = {
		'Maintenance script': 'سکرپٹ'
	};

	function renderRecentChanges( container, changes, admins ) {
		container.replaceChildren();
		var table = document.createElement( 'table' );
		var body = document.createElement( 'tbody' );
		table.className = 'nk-home-recent-table';
		table.appendChild( body );

		changes.forEach( function ( change ) {
			var row = document.createElement( 'tr' );
			var cell = document.createElement( 'td' );
			var titleLink = document.createElement( 'a' );
			var editor = document.createElement( 'div' );
			var editorLink = document.createElement( 'a' );
			var editorLabel =
				admins[ change.user ] || /^ADMIN(?:\s|$)/i.test( change.user )
					? 'مدیر: '
					: 'معاون: ';

			titleLink.href = mw.util.getUrl( change.title );
			titleLink.textContent = change.title;
			editorLink.href = mw.util.getUrl( 'User:' + change.user );
			editorLink.textContent =
				nkEditorDisplayNames[ change.user ] || change.user;
			editor.appendChild( document.createTextNode( editorLabel ) );
			editor.appendChild( editorLink );
			cell.appendChild( titleLink );
			cell.appendChild( editor );
			row.appendChild( cell );
			body.appendChild( row );
		} );
		container.appendChild( table );
	}

	function isMaintenanceRevision( revision ) {
		var comment = revision.comment || '';
		return comment ===
				'تمام موجود تاریخوں اور سالوں کے صفحات کے روابط شامل کیے' ||
			comment === 'تاریخ اور سال کے روابط درست کیے' ||
			comment === 'تاریخ اور سال کے صفحے کا ربط شامل کیا';
	}

	function loadRecentChanges( api, continuation, state ) {
		var params = {
			action: 'query',
			list: 'allrevisions',
			arvnamespace: 0,
			arvprop: 'ids|flags|title|timestamp|user|comment',
			arvdir: 'older',
			arvlimit: 'max',
			formatversion: 2
		};
		if ( continuation ) {
			params.arvcontinue = continuation;
		}

		return nkHomepageApiGet( api, params ).then( function ( data ) {
			data.query.allrevisions.some( function ( page ) {
				if ( state.resolved[ page.title ] ) {
					return false;
				}
				if (
					page.title === 'صفحۂ اول' ||
					/[\u0400-\u052f]/.test( page.title )
				) {
					state.resolved[ page.title ] = true;
					return false;
				}

				var revisions = page.revisions || [];
				for ( var index = 0; index < revisions.length; index++ ) {
					var revision = revisions[ index ];
					if ( isMaintenanceRevision( revision ) ) {
						continue;
					}

					var editor = revision.user;
					state.resolved[ page.title ] = true;
					if (
						( revision.anon && !/[.:]/.test( editor ) ) ||
						( state.editorCounts[ editor ] || 0 ) >= 2
					) {
						return false;
					}

					state.editorCounts[ editor ] =
						( state.editorCounts[ editor ] || 0 ) + 1;
					state.changes.push( {
						title: page.title,
						user: editor
					} );
					return state.changes.length === 6;
				}
				return false;
			} );

			if (
				state.changes.length === 6 ||
				!data.continue ||
				!data.continue.arvcontinue
			) {
				return state.changes;
			}
			return loadRecentChanges(
				api, data.continue.arvcontinue, state
			);
		} );
	}

	mw.loader.using( 'mediawiki.api' ).then( function () {
		var container = document.getElementById( 'nk-home-recent-changes' );
		if ( !container ) {
			return;
		}

		var api = new mw.Api();
		return nkHomepageApiGet( api, {
			action: 'query',
			list: 'allusers',
			augroup: 'sysop',
			auprop: 'groups',
			aulimit: 'max',
			formatversion: 2
		} ).then( function ( result ) {
			var admins = {};
			result.query.allusers.forEach( function ( user ) {
				admins[ user.name ] = true;
			} );
			return loadRecentChanges( api, null, {
				changes: [],
				resolved: {},
				editorCounts: {}
			} ).then( function ( changes ) {
				if (
					changes.length > 1 &&
					( admins[ changes[ 0 ].user ] ||
						/^ADMIN(?:\s|$)/i.test( changes[ 0 ].user ) )
				) {
					var firstNonAdmin = changes.findIndex( function ( change ) {
						return !admins[ change.user ] &&
							!/^ADMIN(?:\s|$)/i.test( change.user );
					} );
					if ( firstNonAdmin > 0 ) {
						var firstChange = changes[ 0 ];
						changes[ 0 ] = changes[ firstNonAdmin ];
						changes[ firstNonAdmin ] = firstChange;
					}
				}

				renderRecentChanges( container, changes, admins );
			} );
		} );
	} ).catch( function ( error ) {
		mw.log.error( 'Could not load recent homepage changes:', error );
	} );
}() );

// Daily featured article and Naat Khawan on the main page.
( function () {
	'use strict';

	if ( mw.config.get( 'wgPageName' ) !== 'صفحۂ_اول' ) {
		return;
	}

	var dateValues = {};
	new Intl.DateTimeFormat( 'en-US', {
		timeZone: 'Asia/Karachi',
		year: 'numeric',
		month: 'numeric',
		day: 'numeric'
	} ).formatToParts( new Date() ).forEach( function ( part ) {
		dateValues[ part.type ] = part.value;
	} );
	var dailyDay = Math.floor( Date.UTC(
		Number( dateValues.year ),
		Number( dateValues.month ) - 1,
		Number( dateValues.day )
	) / 86400000 );

	function dailyIndex( key, length ) {
		var hash = 2166136261;
		for ( var index = 0; index < key.length; index++ ) {
			hash ^= key.charCodeAt( index );
			hash = Math.imul( hash, 16777619 );
		}
		return ( ( hash >>> 0 ) + dailyDay ) % length;
	}

	function preferredParagraphFromHtml( html ) {
		var parsed = new DOMParser().parseFromString( html, 'text/html' );
		var paragraphs = Array.prototype.slice.call(
			parsed.querySelectorAll( '.mw-parser-output p' )
		).filter( function ( paragraph ) {
			return paragraph.textContent.trim();
		} );
		var firstParagraph = Array.prototype.slice.call(
			parsed.querySelectorAll( '.mw-parser-output > p' )
		).filter( function ( paragraph ) {
			return paragraph.textContent.trim();
		} )[ 0 ] || paragraphs[ 0 ];

		if ( !firstParagraph || paragraphWordCount( firstParagraph ) > 100 ) {
			return firstParagraph || null;
		}
		var cleanParagraphs = paragraphs.filter( function ( paragraph ) {
			return paragraph !== firstParagraph &&
				isCleanProseParagraph( paragraph );
		} );
		if ( !cleanParagraphs.length ) {
			return firstParagraph;
		}
		return cleanParagraphs.reduce( function ( longest, paragraph ) {
			return paragraphWordCount( paragraph ) >
				paragraphWordCount( longest ) ? paragraph : longest;
		} );
	}

	function paragraphWordCount( paragraph ) {
		return paragraph.textContent.trim().split( /\s+/ ).filter( Boolean ).length;
	}

	function isCleanProseParagraph( paragraph ) {
		if (
			paragraph.closest( 'li, table, dl, blockquote, pre, .poem' ) ||
			paragraph.querySelector( 'br' )
		) {
			return false;
		}

		var text = paragraph.textContent.replace( /\s+/g, ' ' ).trim();
		var wordCount = paragraphWordCount( paragraph );
		var links = Array.prototype.slice.call(
			paragraph.querySelectorAll( 'a' )
		);
		var linkedWordCount = links.reduce( function ( total, link ) {
			return total + link.textContent.trim().split( /\s+/ )
				.filter( Boolean ).length;
		}, 0 );
		if (
			wordCount < 25 ||
			text.indexOf( '؎' ) !== -1 ||
			text.indexOf( '|' ) !== -1 ||
			links.length > 8 ||
			linkedWordCount / wordCount > 0.35
		) {
			return false;
		}

		return text.split( /[۔؟?!]+|\.(?:\s|$)/ )
			.some( function ( sentence ) {
				return sentence.trim().split( /\s+/ )
					.filter( Boolean ).length >= 12;
			} );
	}

	function limitedParagraph( paragraph, maximumWords ) {
		var clone = paragraph.cloneNode( true );
		if ( !maximumWords ) {
			return clone;
		}

		var walker = document.createTreeWalker(
			clone, NodeFilter.SHOW_TEXT
		);
		var remaining = maximumWords;
		var textNode;
		while ( ( textNode = walker.nextNode() ) ) {
			var words = textNode.nodeValue.match( /\S+/g ) || [];
			if ( words.length <= remaining ) {
				remaining -= words.length;
				continue;
			}

			textNode.nodeValue = words.slice( 0, remaining ).join( ' ' ) + '…';
			while ( ( textNode = walker.nextNode() ) ) {
				textNode.nodeValue = '';
			}
			break;
		}

		Array.prototype.slice.call( clone.querySelectorAll( '*' ) )
			.reverse()
			.forEach( function ( element ) {
				if ( !element.textContent.trim() ) {
					element.remove();
				}
			} );
		return clone;
	}

	function loadPreferredParagraph( api, title ) {
		return nkHomepageApiGet( api, {
			action: 'parse',
			page: title,
			prop: 'text',
			disableeditsection: true,
			disabletoc: true,
			formatversion: 2
		} ).then( function ( data ) {
			return preferredParagraphFromHtml( data.parse.text );
		} );
	}

	function renderDailyFeature( api, options, memberTitles ) {
		var container = document.getElementById( options.containerId );
		if ( !container ) {
			return Promise.resolve();
		}

		if ( !memberTitles.length ) {
			return Promise.reject( new Error(
				options.category + ' has no members with usable pictures.'
			) );
		}

		return findUsablePage(
			api,
			options,
			memberTitles,
			dailyIndex( options.seed, memberTitles.length ),
			0
		)
			.then( function ( page ) {
				var link = document.createElement( 'a' );
				var name = document.createElement( 'strong' );
				var imageLink = link.cloneNode();
				var image = document.createElement( 'img' );

				link.href = page.fullurl;
				link.textContent = page.title;
				name.appendChild( link );
				image.src = page.thumbnail.source;
				image.alt = page.title;
				image.width = page.thumbnail.width;
				image.height = page.thumbnail.height;
				imageLink.href = page.fullurl;
				imageLink.appendChild( image );

				container.replaceChildren();
				container.appendChild( imageLink );
				container.appendChild( name );

				if ( page.selectedParagraph ) {
					container.appendChild( limitedParagraph(
						page.selectedParagraph, options.maximumWords
					) );
				}

				var more = document.createElement( 'div' );
				var moreLink = link.cloneNode();
				more.className = 'nk-home-more';
				moreLink.textContent = options.moreLabel;
				more.appendChild( moreLink );
				container.appendChild( more );
			} );
	}

	function findUsablePage( api, options, members, startIndex, attempt ) {
		if ( attempt >= members.length ) {
			return Promise.reject( new Error(
				options.category + ' has no eligible pages.'
			) );
		}

		var selected = members[ ( startIndex + attempt ) % members.length ];

		return nkLoadApprovedPage( api, selected ).then( function ( approved ) {
			var page = approved.page;
			page.selectedParagraph = preferredParagraphFromHtml( approved.html );
			page.thumbnail = nkApprovedThumbnailFromHtml(
				approved.html, options.thumbnailSize
			);
			if ( !page.thumbnail || !page.selectedParagraph ) {
				return findUsablePage(
					api, options, members, startIndex, attempt + 1
				);
			}
			if (
				options.minimumWords &&
				paragraphWordCount( page.selectedParagraph ) <
					options.minimumWords
			) {
				return findUsablePage(
					api, options, members, startIndex, attempt + 1
				);
			}

			return new Promise( function ( resolve ) {
				var testImage = new Image();
				testImage.onload = function () {
					resolve( page );
				};
				testImage.onerror = function () {
					resolve( findUsablePage(
						api, options, members, startIndex, attempt + 1
					) );
				};
				testImage.src = page.thumbnail.source;
			} );
		} ).catch( function () {
			return findUsablePage(
				api, options, members, startIndex, attempt + 1
			);
		} );
	}

	mw.loader.using( 'mediawiki.api' ).then( function () {
		var api = new mw.Api();
		return nkHomepageApiGet( api, {
			action: 'query',
			prop: 'revisions',
			titles: 'MediaWiki:NKDailyPicturedPages.json',
			rvprop: 'content',
			rvslots: 'main',
			formatversion: 2
		} ).then( function ( data ) {
			var revision = data.query.pages[ 0 ].revisions[ 0 ];
			var pools = JSON.parse( revision.slots.main.content );
			return Promise.all( [
				renderDailyFeature( api, {
				containerId: 'nk-daily-article',
				category: 'زمرہ:مضامین و مقالات، زمرہ:کتب، ' +
					'زمرہ:مجموعہ کلام، زمرہ:کتابوں پر تبصرہ',
				seed: 'article',
				maximumWords: 350,
				thumbnailSize: 440,
				moreLabel: 'مکمل مضمون پڑھیے ←'
				}, pools.articles ),
				renderDailyFeature( api, {
				containerId: 'nk-daily-poet',
				category: 'زمرہ:شعراء، زمرہ:نعت گو شعراء',
				seed: 'poet',
				maximumWords: 60,
				thumbnailSize: 280,
				moreLabel: 'مزید پڑھیے ←'
				}, pools.poets ),
				renderDailyFeature( api, {
				containerId: 'nk-random-naatkhawan',
				category: 'زمرہ:نعت خواں',
				seed: 'naatkhawan',
				maximumWords: 60,
				thumbnailSize: 280,
				moreLabel: 'مزید پڑھیے ←'
				}, pools.reciters )
			] );
		} );
	} ).catch( function ( error ) {
		mw.log.error( 'Could not load the daily main-page features:', error );
	} );
}() );

// Daily Khadim-e-Naat and Did You Know articles on the main page.
( function () {
	'use strict';

	if ( mw.config.get( 'wgPageName' ) !== 'صفحۂ_اول' ) {
		return;
	}

	var dateValues = {};
	new Intl.DateTimeFormat( 'en-US', {
		timeZone: 'Asia/Karachi',
		year: 'numeric',
		month: 'numeric',
		day: 'numeric'
	} ).formatToParts( new Date() ).forEach( function ( part ) {
		dateValues[ part.type ] = part.value;
	} );
	var dailyDay = Math.floor( Date.UTC(
		Number( dateValues.year ),
		Number( dateValues.month ) - 1,
		Number( dateValues.day )
	) / 86400000 );

	function seedValue( key ) {
		var hash = 2166136261;
		for ( var index = 0; index < key.length; index++ ) {
			hash ^= key.charCodeAt( index );
			hash = Math.imul( hash, 16777619 );
		}
		return hash >>> 0;
	}

	function preferredParagraphFromHtml( html ) {
		var parsed = new DOMParser().parseFromString( html, 'text/html' );
		var paragraphs = Array.prototype.slice.call(
			parsed.querySelectorAll( '.mw-parser-output p' )
		).filter( function ( paragraph ) {
			return paragraph.textContent.trim();
		} );
		var firstParagraph = Array.prototype.slice.call(
			parsed.querySelectorAll( '.mw-parser-output > p' )
		).filter( function ( paragraph ) {
			return paragraph.textContent.trim();
		} )[ 0 ] || paragraphs[ 0 ];

		if ( !firstParagraph || paragraphWordCount( firstParagraph ) > 100 ) {
			return firstParagraph || null;
		}
		var cleanParagraphs = paragraphs.filter( function ( paragraph ) {
			return paragraph !== firstParagraph &&
				isCleanProseParagraph( paragraph );
		} );
		if ( !cleanParagraphs.length ) {
			return firstParagraph;
		}
		return cleanParagraphs.reduce( function ( longest, paragraph ) {
			return paragraphWordCount( paragraph ) >
				paragraphWordCount( longest ) ? paragraph : longest;
		} );
	}

	function paragraphWordCount( paragraph ) {
		return paragraph.textContent.trim().split( /\s+/ ).filter( Boolean ).length;
	}

	function isCleanProseParagraph( paragraph ) {
		if (
			paragraph.closest( 'li, table, dl, blockquote, pre, .poem' ) ||
			paragraph.querySelector( 'br' )
		) {
			return false;
		}

		var text = paragraph.textContent.replace( /\s+/g, ' ' ).trim();
		var wordCount = paragraphWordCount( paragraph );
		var links = Array.prototype.slice.call(
			paragraph.querySelectorAll( 'a' )
		);
		var linkedWordCount = links.reduce( function ( total, link ) {
			return total + link.textContent.trim().split( /\s+/ )
				.filter( Boolean ).length;
		}, 0 );
		if (
			wordCount < 25 ||
			text.indexOf( '؎' ) !== -1 ||
			text.indexOf( '|' ) !== -1 ||
			links.length > 8 ||
			linkedWordCount / wordCount > 0.35
		) {
			return false;
		}

		return text.split( /[۔؟?!]+|\.(?:\s|$)/ )
			.some( function ( sentence ) {
				return sentence.trim().split( /\s+/ )
					.filter( Boolean ).length >= 12;
			} );
	}

	function limitedParagraph( paragraph, maximumWords ) {
		var clone = paragraph.cloneNode( true );
		if ( !maximumWords ) {
			return clone;
		}

		var walker = document.createTreeWalker(
			clone, NodeFilter.SHOW_TEXT
		);
		var remaining = maximumWords;
		var textNode;
		while ( ( textNode = walker.nextNode() ) ) {
			var words = textNode.nodeValue.match( /\S+/g ) || [];
			if ( words.length <= remaining ) {
				remaining -= words.length;
				continue;
			}

			textNode.nodeValue = words.slice( 0, remaining ).join( ' ' ) + '…';
			while ( ( textNode = walker.nextNode() ) ) {
				textNode.nodeValue = '';
			}
			break;
		}

		Array.prototype.slice.call( clone.querySelectorAll( '*' ) )
			.reverse()
			.forEach( function ( element ) {
				if ( !element.textContent.trim() ) {
					element.remove();
				}
			} );
		return clone;
	}

	function loadPreferredParagraph( api, title ) {
		return nkHomepageApiGet( api, {
			action: 'parse',
			page: title,
			prop: 'text',
			disableeditsection: true,
			disabletoc: true,
			formatversion: 2
		} ).then( function ( data ) {
			return preferredParagraphFromHtml( data.parse.text );
		} );
	}

	function renderDailyArticle( api, options, candidates ) {
		var container = document.getElementById( options.containerId );
		if ( !container ) {
			return Promise.resolve();
		}

		if ( !candidates.length ) {
			return Promise.reject( new Error(
				options.seed + ' has no eligible articles.'
			) );
		}

		function loadCandidate( candidate ) {
			if ( typeof candidate !== 'string' ) {
				return Promise.resolve( {
					title: candidate.title || '',
					fullurl: mw.config.get( 'wgScript' ) + '?title=' +
						encodeURIComponent( candidate.page.replace( / /g, '_' ) ),
					extract: candidate.text
				} );
			}

			return nkLoadApprovedPage( api, candidate ).then( function ( approved ) {
				return {
					title: approved.page.title,
					fullurl: approved.page.fullurl,
					thumbnail: nkApprovedThumbnailFromHtml(
						approved.html, options.thumbnailSize
					),
					selectedParagraph: preferredParagraphFromHtml( approved.html )
				};
			} );
		}

		var count = Math.min( options.count || 1, candidates.length );
		var startIndex =
			( seedValue( options.seed ) + dailyDay * count ) % candidates.length;

		// Per the homepage picture-requirement rule, every daily-content panel
		// must show a picture except کیا آپ جانتے ہیں؟ (did-you-know); callers opt in
		// with options.requireThumbnail (verified the same way picture panels
		// verify theirs: an actual Image() load, not just a thumbnail URL).
		function isTextEligible( page ) {
			var wordCount = page.selectedParagraph ?
				paragraphWordCount( page.selectedParagraph ) :
				( page.extract || '' ).trim().split( /\s+/ )
					.filter( Boolean ).length;
			return ( page.selectedParagraph || page.extract ) &&
				( !options.minimumWords || wordCount >= options.minimumWords );
		}

		function isEligible( page ) {
			if ( !isTextEligible( page ) ) {
				return Promise.resolve( false );
			}
			if ( !options.requireThumbnail ) {
				return Promise.resolve( true );
			}
			if ( !page.thumbnail ) {
				return Promise.resolve( false );
			}
			return new Promise( function ( resolve ) {
				var testImage = new Image();
				testImage.onload = function () {
					resolve( true );
				};
				testImage.onerror = function () {
					resolve( false );
				};
				testImage.src = page.thumbnail.source;
			} );
		}

		function loadEligiblePages( attempt, pages ) {
			if ( pages.length >= count || attempt >= candidates.length ) {
				return Promise.resolve( pages );
			}

			var candidate = candidates[
				( startIndex + attempt ) % candidates.length
			];
			return loadCandidate( candidate ).then( function ( page ) {
				return isEligible( page ).then( function ( eligible ) {
					if ( eligible ) {
						pages.push( page );
					}
					return loadEligiblePages( attempt + 1, pages );
				} );
			} ).catch( function () {
				return loadEligiblePages( attempt + 1, pages );
			} );
		}

		return loadEligiblePages( 0, [] ).then( function ( pages ) {
			container.replaceChildren();
			pages.forEach( function ( page ) {
				var item = document.createElement( 'div' );
				var more = document.createElement( 'div' );
				var moreLink = document.createElement( 'a' );

				item.className = 'nk-home-daily-item';
				more.className = 'nk-home-more';
				moreLink.href = page.fullurl;
				moreLink.textContent = 'مزید پڑھیے ←';
				more.appendChild( moreLink );

				if ( page.thumbnail ) {
					var imageLink = document.createElement( 'a' );
					var image = document.createElement( 'img' );
					imageLink.href = page.fullurl;
					image.src = page.thumbnail.source;
					image.alt = page.title;
					image.width = page.thumbnail.width;
					image.height = page.thumbnail.height;
					imageLink.appendChild( image );
					item.appendChild( imageLink );
				}
				if ( page.title ) {
					var titleLink = document.createElement( 'a' );
					var title = document.createElement( 'strong' );
					titleLink.href = page.fullurl;
					titleLink.textContent = page.title;
					title.appendChild( titleLink );
					item.appendChild( title );
				}
				if ( page.selectedParagraph ) {
					item.appendChild( limitedParagraph(
						page.selectedParagraph, options.maximumWords
					) );
				} else if ( page.extract ) {
					var description = document.createElement( 'p' );
					var extract = page.extract.replace( /={2,}/g, '' ).trim();
					if ( options.maximumWords ) {
						var words = extract.split( /\s+/ );
						if ( words.length > options.maximumWords ) {
							extract = words.slice(
								0, options.maximumWords
							).join( ' ' ) + '…';
						}
					}
					description.textContent = extract;
					item.appendChild( description );
				}
				item.appendChild( more );
				container.appendChild( item );
			} );
		} );
	}

	mw.loader.using( 'mediawiki.api' ).then( function () {
		var api = new mw.Api();
		function loadJsonPage( title ) {
			return nkHomepageApiGet( api, {
				action: 'query',
				prop: 'revisions',
				titles: title,
				rvprop: 'content',
				rvslots: 'main',
				formatversion: 2
			} ).then( function ( data ) {
				return JSON.parse(
					data.query.pages[ 0 ].revisions[ 0 ].slots.main.content
				);
			} );
		}

		return Promise.all( [
			loadJsonPage( 'MediaWiki:NKDailyTextPages.json' ),
			loadJsonPage( 'MediaWiki:NKDidYouKnowEntries.json' )
		] ).then( function ( data ) {
			var pools = data[ 0 ];
			var customEntries = ( data[ 1 ].entries || [] ).filter(
				function ( entry ) {
					return entry && typeof entry.text === 'string' &&
						entry.text.trim() &&
						typeof entry.page === 'string' &&
						entry.page.trim();
				}
			);
			return Promise.all( [
				renderDailyArticle( api, {
				containerId: 'nk-daily-khadim',
				seed: 'khadim',
				maximumWords: 250,
				thumbnailSize: 280,
				requireThumbnail: true
				}, pools.khadim ),
				renderDailyArticle( api, {
				containerId: 'nk-daily-dyk',
				seed: 'did-you-know',
				thumbnailSize: 440,
				maximumWords: 40,
				count: 3
				}, pools.dyk.concat( customEntries ) )
			] );
		} );
	} ).catch( function ( error ) {
		mw.log.error( 'Could not load daily text panels:', error );
	} );
}() );

// Daily naat video on the main page, picked from زمرہ:وڈیو نعتیں.
( function () {
	'use strict';

	if ( mw.config.get( 'wgPageName' ) !== 'صفحۂ_اول' ) {
		return;
	}

	var dateValues = {};
	new Intl.DateTimeFormat( 'en-US', {
		timeZone: 'Asia/Karachi',
		year: 'numeric',
		month: 'numeric',
		day: 'numeric'
	} ).formatToParts( new Date() ).forEach( function ( part ) {
		dateValues[ part.type ] = part.value;
	} );
	var dailyDay = Math.floor( Date.UTC(
		Number( dateValues.year ),
		Number( dateValues.month ) - 1,
		Number( dateValues.day )
	) / 86400000 );

	function seedValue( key ) {
		var hash = 2166136261;
		for ( var index = 0; index < key.length; index++ ) {
			hash ^= key.charCodeAt( index );
			hash = Math.imul( hash, 16777619 );
		}
		return hash >>> 0;
	}

	// Accepts a watch?v=, youtu.be/, /embed/, or bare 11-char video id.
	function extractYoutubeId( param ) {
		param = param.trim();
		var match = param.match( /[?&]v=([A-Za-z0-9_-]{11})/ );
		if ( match ) {
			return match[ 1 ];
		}
		match = param.match( /youtu\.be\/([A-Za-z0-9_-]{11})/ );
		if ( match ) {
			return match[ 1 ];
		}
		match = param.match( /\/embed\/([A-Za-z0-9_-]{11})/ );
		if ( match ) {
			return match[ 1 ];
		}
		if ( /^[A-Za-z0-9_-]{11}$/.test( param ) ) {
			return param;
		}
		return null;
	}

	function loadVideoId( api, title ) {
		return nkHomepageApiGet( api, {
			action: 'query',
			titles: title,
			prop: 'revisions',
			rvprop: 'content',
			rvslots: 'main',
			formatversion: 2
		} ).then( function ( data ) {
			var page = data.query.pages[ 0 ];
			var revision = page && page.revisions && page.revisions[ 0 ];
			var content = revision ? revision.slots.main.content : '';
			var match = content.match( /\{\{#ev:youtube\|([^|}]+)/i );
			return match ? extractYoutubeId( match[ 1 ] ) : null;
		} );
	}

	function findUsableVideo( api, members, startIndex, attempt ) {
		if ( attempt >= members.length ) {
			return Promise.reject( new Error( 'زمرہ:وڈیو نعتیں has no eligible videos.' ) );
		}
		var member = members[ ( startIndex + attempt ) % members.length ];
		return loadVideoId( api, member.title ).then( function ( videoId ) {
			if ( !videoId ) {
				return findUsableVideo( api, members, startIndex, attempt + 1 );
			}
			return { title: member.title, videoId: videoId };
		} );
	}

	mw.loader.using( 'mediawiki.api' ).then( function () {
		var container = document.getElementById( 'nk-daily-video' );
		if ( !container ) {
			return;
		}

		var api = new mw.Api();
		return nkHomepageApiGet( api, {
			action: 'query',
			list: 'categorymembers',
			cmtitle: 'زمرہ:وڈیو نعتیں',
			cmlimit: 'max',
			formatversion: 2
		} ).then( function ( data ) {
			var members = data.query.categorymembers;
			if ( !members.length ) {
				return Promise.reject( new Error( 'زمرہ:وڈیو نعتیں has no members.' ) );
			}
			return findUsableVideo(
				api, members, seedValue( 'video' ) + dailyDay, 0
			);
		} ).then( function ( video ) {
			container.replaceChildren();

			var wrapper = document.createElement( 'div' );
			wrapper.className = 'nk-video-embed';
			var iframe = document.createElement( 'iframe' );
			iframe.src = 'https://www.youtube-nocookie.com/embed/' + video.videoId;
			iframe.title = video.title;
			iframe.loading = 'lazy';
			iframe.allow =
				'accelerometer; autoplay; clipboard-write; encrypted-media; ' +
				'gyroscope; picture-in-picture; web-share';
			iframe.allowFullscreen = true;
			wrapper.appendChild( iframe );
			container.appendChild( wrapper );

			var caption = document.createElement( 'strong' );
			var captionLink = document.createElement( 'a' );
			captionLink.href = mw.util.getUrl( video.title );
			captionLink.textContent = video.title;
			caption.appendChild( captionLink );
			container.appendChild( caption );

			var more = document.createElement( 'div' );
			var moreLink = document.createElement( 'a' );
			more.className = 'nk-home-more';
			moreLink.href = mw.util.getUrl( 'زمرہ:وڈیو نعتیں' );
			moreLink.textContent = 'مزید نعتیہ ویڈیوز ←';
			more.appendChild( moreLink );
			container.appendChild( more );
		} );
	} ).catch( function ( error ) {
		mw.log.error( 'Could not load the daily naat video:', error );
	} );
}() );

( function () {
	'use strict';

	var measurementId = 'G-YX4H2XLR38';
	var storageKey = 'naatkainaat-analytics-consent-v1';
	var analyticsLoaded = false;
	var consentCountries = [
		'AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR',
		'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL',
		'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'GB'
	];

	if (
		mw.config.get( 'wgUserName' ) !== null ||
		location.hostname === 'localhost' ||
		location.hostname === '127.0.0.1'
	) {
		return;
	}

	function getConsent() {
		try {
			return localStorage.getItem( storageKey );
		} catch ( e ) {
			return null;
		}
	}

	function setConsent( value ) {
		try {
			localStorage.setItem( storageKey, value );
		} catch ( e ) {
			// The current page can still honor the visitor's choice.
		}
	}

	function requiresConsent( countryCode ) {
		return consentCountries.indexOf( countryCode ) !== -1;
	}

	function detectCountry() {
		var lookup = fetch( 'https://api.country.is/', {
			cache: 'no-store',
			credentials: 'omit',
			referrerPolicy: 'no-referrer'
		} ).then( function ( response ) {
			if ( !response.ok ) {
				throw new Error( 'Country lookup failed.' );
			}
			return response.json();
		} ).then( function ( data ) {
			if ( !data || typeof data.country !== 'string' ) {
				throw new Error( 'Country lookup returned invalid data.' );
			}
			return data.country.toUpperCase();
		} );
		var timeout = new Promise( function ( resolve, reject ) {
			setTimeout( function () {
				reject( new Error( 'Country lookup timed out.' ) );
			}, 4000 );
		} );

		return Promise.race( [ lookup, timeout ] );
	}

	function gtag() {
		window.dataLayer.push( arguments );
	}

	function loadAnalytics() {
		var script;

		if ( analyticsLoaded ) {
			return;
		}
		analyticsLoaded = true;
		window.dataLayer = window.dataLayer || [];
		gtag( 'consent', 'default', {
			analytics_storage: 'denied',
			ad_storage: 'denied',
			ad_user_data: 'denied',
			ad_personalization: 'denied',
			wait_for_update: 500
		} );
		gtag( 'consent', 'update', {
			analytics_storage: 'granted'
		} );
		gtag( 'js', new Date() );
		gtag( 'config', measurementId, {
			cookie_flags: 'SameSite=Lax;Secure'
		} );

		script = document.createElement( 'script' );
		script.async = true;
		script.src = 'https://www.googletagmanager.com/gtag/js?id=' +
			encodeURIComponent( measurementId );
		document.head.appendChild( script );
	}

	function expireCookie( name, domain ) {
		var cookie = name + '=; Max-Age=0; path=/; SameSite=Lax; Secure';
		if ( domain ) {
			cookie += '; domain=' + domain;
		}
		document.cookie = cookie;
	}

	function revokeAnalytics() {
		var cookieNames = [ '_ga', '_ga_' + measurementId.substring( 2 ) ];
		var domains = [ '', location.hostname, '.' + location.hostname ];

		if ( window.dataLayer ) {
			gtag( 'consent', 'update', {
				analytics_storage: 'denied'
			} );
		}
		cookieNames.forEach( function ( cookieName ) {
			domains.forEach( function ( domain ) {
				expireCookie( cookieName, domain );
			} );
		} );
	}

	function addStyles() {
		mw.util.addCSS(
			'#nk-consent{position:fixed;z-index:10000;right:1rem;bottom:1rem;' +
			'max-width:32rem;padding:1rem 1.25rem;background:#fff;color:#202122;' +
			'border:1px solid #a2a9b1;border-radius:.5rem;box-shadow:0 4px 18px ' +
			'rgba(0,0,0,.2);font-size:16px;line-height:1.8;text-align:right;' +
			'direction:rtl}#nk-consent[hidden]{display:none}#nk-consent p{' +
			'margin:0 0 .75rem}#nk-consent-actions{display:flex;gap:.5rem;' +
			'flex-wrap:wrap}#nk-consent button{font:inherit;padding:.35rem .9rem;' +
			'border:1px solid #3366cc;border-radius:.25rem;cursor:pointer}' +
			'#nk-consent-accept{background:#3366cc;color:#fff}' +
			'#nk-consent-reject{background:#fff;color:#202122}' +
			'#nk-privacy-settings{position:fixed;z-index:9999;left:.75rem;' +
			'bottom:.75rem;padding:.25rem .6rem;border:1px solid #72777d;' +
			'border-radius:.25rem;background:#fff;color:#202122;cursor:pointer;' +
			'font-size:13px}#nk-privacy-settings[hidden]{display:none}' +
			'@media(max-width:600px){#nk-consent{right:.5rem;left:.5rem;' +
			'bottom:.5rem;max-width:none}}'
		);
	}

	function createInterface() {
		var banner = document.createElement( 'section' );
		var text = document.createElement( 'p' );
		var actions = document.createElement( 'div' );
		var accept = document.createElement( 'button' );
		var reject = document.createElement( 'button' );
		var settings = document.createElement( 'button' );

		banner.id = 'nk-consent';
		banner.setAttribute( 'role', 'dialog' );
		banner.setAttribute( 'aria-label', 'تجزیاتی کوکیز کی اجازت' );
		text.textContent =
			'ہم ویب سائٹ کے استعمال کو سمجھنے اور اسے بہتر بنانے کے لیے ' +
			'Google Analytics استعمال کرنا چاہتے ہیں۔ آپ کی اجازت کے بغیر ' +
			'تجزیاتی کوکیز یا Google Analytics لوڈ نہیں ہوں گے۔';

		actions.id = 'nk-consent-actions';
		accept.id = 'nk-consent-accept';
		accept.type = 'button';
		accept.textContent = 'اجازت دیں';
		reject.id = 'nk-consent-reject';
		reject.type = 'button';
		reject.textContent = 'اجازت نہ دیں';
		settings.id = 'nk-privacy-settings';
		settings.type = 'button';
		settings.textContent = 'رازداری کی ترتیبات';
		settings.hidden = true;

		accept.addEventListener( 'click', function () {
			setConsent( 'granted' );
			banner.hidden = true;
			settings.hidden = false;
			loadAnalytics();
		} );
		reject.addEventListener( 'click', function () {
			var shouldReload = analyticsLoaded;
			setConsent( 'denied' );
			revokeAnalytics();
			banner.hidden = true;
			settings.hidden = false;
			if ( shouldReload ) {
				location.reload();
			}
		} );
		settings.addEventListener( 'click', function () {
			banner.hidden = false;
			settings.hidden = true;
		} );

		actions.appendChild( accept );
		actions.appendChild( reject );
		banner.appendChild( text );
		banner.appendChild( actions );
		document.body.appendChild( banner );
		document.body.appendChild( settings );

		if ( getConsent() === 'granted' ) {
			banner.hidden = true;
			settings.hidden = false;
			loadAnalytics();
		} else if ( getConsent() === 'denied' ) {
			banner.hidden = true;
			settings.hidden = false;
		}
	}

	$( function () {
		detectCountry().then( function ( countryCode ) {
			if ( requiresConsent( countryCode ) ) {
				addStyles();
				createInterface();
			} else {
				loadAnalytics();
			}
		} ).catch( function () {
			addStyles();
			createInterface();
		} );
	} );
}() );

/* Auto-wrap naat poetry under the standard naat heading: centered at widest natural line, then justified. */
(function () {
	function stylePoetryBlock(block) {
		block.classList.add('nk-poetry');
		block.style.display = 'table';
		block.style.width = 'max-content';
		block.style.maxWidth = '100%';
		block.style.margin = '0 auto';
		block.style.direction = 'rtl';

		var lines = block.querySelectorAll('p');
		for (var i = 0; i < lines.length; i++) {
			lines[i].style.width = '100%';
			lines[i].style.textAlign = 'justify';
			lines[i].style.textAlignLast = 'justify';
			lines[i].style.textJustify = 'inter-word';
			lines[i].style.marginTop = '8px';
			lines[i].style.marginBottom = '8px';
		}
	}

	function isHeadingElement(element) {
		return !!element && (
			( element.classList && element.classList.contains('mw-heading') ) ||
			/^H[1-6]$/.test(element.tagName)
		);
	}

	function autoWrapNaatPoetry(root) {
		var container = root && root.querySelector ? root : document;
		var headings = container.querySelectorAll('.mw-heading, h2, h3, h4, h5, h6');
		for (var i = 0; i < headings.length; i++) {
			if (headings[i].textContent.indexOf('نعتِ رسولِ آخر صلی اللہ علیہ وآلہ وسلم') === -1) {
				continue;
			}

			var node = headings[i].nextElementSibling;
			if (node && node.classList && node.classList.contains('nk-poetry')) {
				stylePoetryBlock(node);
				continue;
			}

			var lines = [];
			while (node && !isHeadingElement(node)) {
				var next = node.nextElementSibling;
				if (node.tagName === 'P' && node.textContent.trim() !== '') {
					lines.push(node);
				} else if (lines.length) {
					break;
				}
				node = next;
			}

			if (lines.length < 2) {
				continue;
			}

			var wrapper = document.createElement('div');
			wrapper.className = 'nk-poetry';
			lines[0].parentNode.insertBefore(wrapper, lines[0]);
			for (var j = 0; j < lines.length; j++) {
				wrapper.appendChild(lines[j]);
			}
			stylePoetryBlock(wrapper);
		}
	}

	if (window.mw && mw.hook) {
		mw.hook('wikipage.content').add(function ($content) {
			autoWrapNaatPoetry($content && $content[0] ? $content[0] : document);
		});
	} else if (document.readyState === 'loading') {
		document.addEventListener('DOMContentLoaded', function () {
			autoWrapNaatPoetry(document);
		});
	} else {
		autoWrapNaatPoetry(document);
	}
}());