<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://montepedia.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Maintenance+script</id>
	<title>Montepedia - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://montepedia.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Maintenance+script"/>
	<link rel="alternate" type="text/html" href="https://montepedia.com/wiki/Special:Contributions/Maintenance_script"/>
	<updated>2026-07-28T21:53:43Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.45.2</generator>
	<entry>
		<id>https://montepedia.com/w/index.php?title=MediaWiki:Common.css&amp;diff=5326</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=MediaWiki:Common.css&amp;diff=5326"/>
		<updated>2026-06-15T14:32:42Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: ABC wiki: show arrow marker on Wikipedia fallback links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
/* ABC Wiki: missing imported article links that open English Wikipedia */&lt;br /&gt;
.abc-wikipedia-missing-link {&lt;br /&gt;
	border-bottom: 1px dotted currentColor;&lt;br /&gt;
}&lt;br /&gt;
.abc-wikipedia-missing-link::after {&lt;br /&gt;
	content: &amp;quot; ↗&amp;quot;;&lt;br /&gt;
	font-size: 85%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ABC-WIKIPEDIA-REDLINKS-CSS-START */&lt;br /&gt;
/* ABC Wiki: mark missing local article links that open Wikipedia in a new tab */&lt;br /&gt;
.abc-wikipedia-missing-link {&lt;br /&gt;
	border-bottom: 1px dotted currentColor;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.abc-wikipedia-missing-link::after {&lt;br /&gt;
	content: &amp;quot; ↗&amp;quot;;&lt;br /&gt;
	font-size: 85%;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
/* ABC-WIKIPEDIA-REDLINKS-CSS-END */&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=MediaWiki:Common.js&amp;diff=5325</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=MediaWiki:Common.js&amp;diff=5325"/>
		<updated>2026-06-15T14:21:12Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: ABC wiki: force missing article redlinks to open Wikipedia in new tab&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
/* ABC-WIKIPEDIA-REDLINKS-START */&lt;br /&gt;
/**&lt;br /&gt;
 * ABC Wiki:&lt;br /&gt;
 * Red/missing article links imported from Wikipedia should open Wikipedia,&lt;br /&gt;
 * not the local missing-page editor.&lt;br /&gt;
 *&lt;br /&gt;
 * Local existing pages are untouched.&lt;br /&gt;
 */&lt;br /&gt;
(function () {&lt;br /&gt;
	&#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
	function decodeTitle(title) {&lt;br /&gt;
		try {&lt;br /&gt;
			title = decodeURIComponent(title);&lt;br /&gt;
		} catch (e) {}&lt;br /&gt;
&lt;br /&gt;
		return title.replace(/_/g, &#039; &#039;);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function titleToWikipediaUrl(title) {&lt;br /&gt;
		return &#039;https://wikipedia.org/wiki/&#039; + encodeURIComponent(title.replace(/ /g, &#039;_&#039;));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function getMissingArticleTitle(link) {&lt;br /&gt;
		var href = link.getAttribute(&#039;href&#039;) || &#039;&#039;;&lt;br /&gt;
		var title = null;&lt;br /&gt;
		var match;&lt;br /&gt;
		var url;&lt;br /&gt;
&lt;br /&gt;
		if (!href) {&lt;br /&gt;
			return null;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		/* Format: /w/index.php?title=Thai_Airways_Flight_365&amp;amp;action=edit&amp;amp;redlink=1 */&lt;br /&gt;
		try {&lt;br /&gt;
			url = new URL(href, window.location.origin);&lt;br /&gt;
&lt;br /&gt;
			if (url.searchParams.get(&#039;redlink&#039;) === &#039;1&#039;) {&lt;br /&gt;
				title = url.searchParams.get(&#039;title&#039;);&lt;br /&gt;
			}&lt;br /&gt;
		} catch (e) {}&lt;br /&gt;
&lt;br /&gt;
		/* Fallback: catch title manually */&lt;br /&gt;
		if (!title) {&lt;br /&gt;
			match = href.match(/[?&amp;amp;]title=([^&amp;amp;]+)/);&lt;br /&gt;
			if (match &amp;amp;&amp;amp; href.indexOf(&#039;redlink=1&#039;) !== -1) {&lt;br /&gt;
				title = match[1];&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if (!title) {&lt;br /&gt;
			return null;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		title = decodeTitle(title);&lt;br /&gt;
&lt;br /&gt;
		/* Only normal article titles. Do not send Template:, Module:, File:, Category:, etc. */&lt;br /&gt;
		if (title.indexOf(&#039;:&#039;) !== -1) {&lt;br /&gt;
			return null;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		return title;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function rewriteOne(link) {&lt;br /&gt;
		var title = getMissingArticleTitle(link);&lt;br /&gt;
		var wikipediaUrl;&lt;br /&gt;
&lt;br /&gt;
		if (!title) {&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		wikipediaUrl = titleToWikipediaUrl(title);&lt;br /&gt;
&lt;br /&gt;
		link.setAttribute(&#039;href&#039;, wikipediaUrl);&lt;br /&gt;
		link.setAttribute(&#039;target&#039;, &#039;_blank&#039;);&lt;br /&gt;
		link.setAttribute(&#039;rel&#039;, &#039;noopener noreferrer&#039;);&lt;br /&gt;
&lt;br /&gt;
		link.classList.remove(&#039;new&#039;);&lt;br /&gt;
		link.classList.add(&#039;abc-wikipedia-missing-link&#039;);&lt;br /&gt;
&lt;br /&gt;
		link.setAttribute(&#039;title&#039;, title + &#039; — opens on Wikipedia in a new tab&#039;);&lt;br /&gt;
		link.setAttribute(&#039;data-abc-wikipedia-title&#039;, title);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function rewriteAllRedlinks() {&lt;br /&gt;
		document.querySelectorAll(&#039;a.new, a[href*=&amp;quot;redlink=1&amp;quot;], a[href*=&amp;quot;action=edit&amp;quot;]&#039;).forEach(rewriteOne);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (document.readyState === &#039;loading&#039;) {&lt;br /&gt;
		document.addEventListener(&#039;DOMContentLoaded&#039;, rewriteAllRedlinks);&lt;br /&gt;
	} else {&lt;br /&gt;
		rewriteAllRedlinks();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Some skins/modules add or touch content after ready. */&lt;br /&gt;
	window.setTimeout(rewriteAllRedlinks, 500);&lt;br /&gt;
	window.setTimeout(rewriteAllRedlinks, 1500);&lt;br /&gt;
&lt;br /&gt;
	/* Debug marker: check browser console with window.abcWikipediaRedlinksActive */&lt;br /&gt;
	window.abcWikipediaRedlinksActive = true;&lt;br /&gt;
}());&lt;br /&gt;
/* ABC-WIKIPEDIA-REDLINKS-END */&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=MediaWiki:Common.css&amp;diff=5324</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=MediaWiki:Common.css&amp;diff=5324"/>
		<updated>2026-06-15T13:55:42Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: ABC wiki: style missing imported article links that open Wikipedia&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
/* ABC Wiki: missing imported article links that open English Wikipedia */&lt;br /&gt;
.abc-wikipedia-missing-link {&lt;br /&gt;
	border-bottom: 1px dotted currentColor;&lt;br /&gt;
}&lt;br /&gt;
.abc-wikipedia-missing-link::after {&lt;br /&gt;
	content: &amp;quot; ↗&amp;quot;;&lt;br /&gt;
	font-size: 85%;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=MediaWiki:Common.js&amp;diff=5323</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=MediaWiki:Common.js&amp;diff=5323"/>
		<updated>2026-06-15T13:55:42Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: ABC wiki: send missing imported article links to English Wikipedia in new tab&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
/**&lt;br /&gt;
 * ABC Wiki compatibility:&lt;br /&gt;
 * Imported Wikipedia articles should work as entrance pages.&lt;br /&gt;
 *&lt;br /&gt;
 * Existing local pages stay local.&lt;br /&gt;
 * Missing article links (redlinks) open the matching English Wikipedia page in a new tab.&lt;br /&gt;
 */&lt;br /&gt;
(function () {&lt;br /&gt;
	&#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
	function getMissingPageTitle(link) {&lt;br /&gt;
		var href, url, title;&lt;br /&gt;
&lt;br /&gt;
		href = link.getAttribute(&#039;href&#039;) || &#039;&#039;;&lt;br /&gt;
		if (!href) {&lt;br /&gt;
			return null;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		try {&lt;br /&gt;
			url = new URL(href, window.location.origin);&lt;br /&gt;
		} catch (e) {&lt;br /&gt;
			return null;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if (url.searchParams.get(&#039;redlink&#039;) !== &#039;1&#039;) {&lt;br /&gt;
			return null;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		title = url.searchParams.get(&#039;title&#039;);&lt;br /&gt;
		if (!title) {&lt;br /&gt;
			return null;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		title = title.replace(/_/g, &#039; &#039;);&lt;br /&gt;
&lt;br /&gt;
		// Only auto-send normal article links to Wikipedia.&lt;br /&gt;
		// Avoid Template:, Module:, File:, Category:, User:, Talk:, Special:, etc.&lt;br /&gt;
		if (title.indexOf(&#039;:&#039;) !== -1) {&lt;br /&gt;
			return null;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		return title;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function rewriteMissingWikipediaLinks() {&lt;br /&gt;
		var content = document.querySelector(&#039;.mw-parser-output&#039;);&lt;br /&gt;
		if (!content) {&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		content.querySelectorAll(&#039;a.new&#039;).forEach(function (link) {&lt;br /&gt;
			var title = getMissingPageTitle(link);&lt;br /&gt;
			var wikipediaUrl;&lt;br /&gt;
&lt;br /&gt;
			if (!title) {&lt;br /&gt;
				return;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			wikipediaUrl = &#039;https://en.wikipedia.org/wiki/&#039; + encodeURIComponent(title.replace(/ /g, &#039;_&#039;));&lt;br /&gt;
&lt;br /&gt;
			link.href = wikipediaUrl;&lt;br /&gt;
			link.target = &#039;_blank&#039;;&lt;br /&gt;
			link.rel = &#039;noopener noreferrer&#039;;&lt;br /&gt;
			link.classList.remove(&#039;new&#039;);&lt;br /&gt;
			link.classList.add(&#039;abc-wikipedia-missing-link&#039;);&lt;br /&gt;
			link.title = title + &#039; — opens on English Wikipedia in a new tab&#039;;&lt;br /&gt;
		});&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (document.readyState === &#039;loading&#039;) {&lt;br /&gt;
		document.addEventListener(&#039;DOMContentLoaded&#039;, rewriteMissingWikipediaLinks);&lt;br /&gt;
	} else {&lt;br /&gt;
		rewriteMissingWikipediaLinks();&lt;br /&gt;
	}&lt;br /&gt;
}());&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Module:Jct&amp;diff=5322</id>
		<title>Module:Jct</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Module:Jct&amp;diff=5322"/>
		<updated>2026-06-15T12:50:07Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync shared ABC wiki compatibility fix from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
-- Change to &amp;quot;&amp;quot; upon deployment.&lt;br /&gt;
local moduleSuffix = &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
local parserModuleName = &amp;quot;Module:Road data/parser&amp;quot; .. moduleSuffix&lt;br /&gt;
local statenameModuleName = &amp;quot;Module:Jct/statename&amp;quot; .. moduleSuffix -- TODO transition&lt;br /&gt;
local cityModuleName = &amp;quot;Module:Jct/city&amp;quot; .. moduleSuffix&lt;br /&gt;
&lt;br /&gt;
local concat = table.concat&lt;br /&gt;
local insert = table.insert&lt;br /&gt;
local format = mw.ustring.format&lt;br /&gt;
local trim = mw.text.trim&lt;br /&gt;
&lt;br /&gt;
local parserModule = require(parserModuleName)&lt;br /&gt;
local parser = parserModule.parser&lt;br /&gt;
local util = require(&amp;quot;Module:Road data/util&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Shields&lt;br /&gt;
local defaultShieldSize = 24&lt;br /&gt;
&lt;br /&gt;
local function addContextBanner(route, name, suffix, bannerSpec)&lt;br /&gt;
	local bannerModule = &#039;Module:Road data/banners/&#039; .. string.upper(route.country)&lt;br /&gt;
	local shieldfield = name .. &#039;shield&#039;&lt;br /&gt;
	local shield = parser(route, shieldfield)&lt;br /&gt;
	if shield == nil then&lt;br /&gt;
		-- This route type does not define shield.&lt;br /&gt;
		-- Find shield in the default banner table.&lt;br /&gt;
		shield = parser(route, &#039;shield&#039;, name, bannerModule)&lt;br /&gt;
		if shield and shield ~= &#039;&#039; then&lt;br /&gt;
			if suffix == nil then&lt;br /&gt;
				suffix = parser(route, &#039;shield&#039;, &#039;suffix&#039;, bannerModule)&lt;br /&gt;
			end&lt;br /&gt;
			if suffix and suffix ~= &#039;&#039; then&lt;br /&gt;
				shield = shield .. &amp;quot; &amp;quot; .. suffix&lt;br /&gt;
			end&lt;br /&gt;
			shield = shield .. &amp;quot;.svg&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if shield and shield ~= &#039;&#039; then&lt;br /&gt;
		local shieldSize = defaultShieldSize&lt;br /&gt;
		-- Add banner plate.&lt;br /&gt;
		insert(bannerSpec, {shield, shieldSize})&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function bannerSpec(banner, bannerSize, bannerSuffix, route)&lt;br /&gt;
	local banners = {}&lt;br /&gt;
	if type(banner) == &amp;quot;table&amp;quot; then&lt;br /&gt;
		local bannerSizeIsNotTable = type(bannerSize) ~= &amp;quot;table&amp;quot;&lt;br /&gt;
		for i,filename in ipairs(banner) do&lt;br /&gt;
			local bannersize = bannerSizeIsNotTable and bannerSize or bannerSize[i] or defaultShieldSize&lt;br /&gt;
			insert(banners, {filename, bannersize})&lt;br /&gt;
		end&lt;br /&gt;
	elseif banner ~= &#039;&#039; then&lt;br /&gt;
		insert(banners, {banner, bannerSize})&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if route.dir then&lt;br /&gt;
		addContextBanner(route, &#039;dir&#039;, bannerSuffix, banners)&lt;br /&gt;
	end&lt;br /&gt;
	if route.to then&lt;br /&gt;
		addContextBanner(route, &#039;to&#039;, bannerSuffix, banners)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return banners&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function shieldSpec(route, mainShield, shieldList)&lt;br /&gt;
	local shieldSpec = {}&lt;br /&gt;
&lt;br /&gt;
	local shield&lt;br /&gt;
	local shieldto = parser(route, &#039;shieldto&#039;)&lt;br /&gt;
	&lt;br /&gt;
	if route.to then&lt;br /&gt;
		if not shield then shield = shieldto or parser(route, &#039;shield&#039;) or &#039;&#039; end&lt;br /&gt;
	else&lt;br /&gt;
		if not shield then shield = parser(route, &#039;shield&#039;) or &#039;&#039; end&lt;br /&gt;
	end&lt;br /&gt;
	if shield == &#039;&#039; then return shieldSpec end&lt;br /&gt;
	local orientation = parser(route, &#039;orientation&#039;)&lt;br /&gt;
&lt;br /&gt;
	local function size(route)&lt;br /&gt;
		if orientation == &amp;quot;upright&amp;quot; then&lt;br /&gt;
			return defaultShieldSize&lt;br /&gt;
			else return &amp;quot;x&amp;quot; .. defaultShieldSize&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local shieldsize = size(route)&lt;br /&gt;
	&lt;br /&gt;
	local banner = parser(route, &#039;banner&#039;) or {}&lt;br /&gt;
	local bannersize = defaultShieldSize&lt;br /&gt;
	local bannersuffix = parser(route, &#039;bannersuffix&#039;)&lt;br /&gt;
&lt;br /&gt;
	local bannerIsNotTable = type(banner) ~= &amp;quot;table&amp;quot;&lt;br /&gt;
	local bannersizeIsNotTable = type(bannersize) ~= &amp;quot;table&amp;quot;&lt;br /&gt;
	local bannersuffixIsNotTable = type(bannersuffix) ~= &amp;quot;table&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	if type(shield) == &amp;quot;table&amp;quot; then&lt;br /&gt;
		for i,filename in ipairs(shield) do&lt;br /&gt;
			local size = shieldsize or shieldsize[i]&lt;br /&gt;
			if size == &amp;quot;&amp;quot; then size = nil end&lt;br /&gt;
			-- banner.all describes banners that apply to all multiple shields.&lt;br /&gt;
			local shieldBanner = bannerIsNotTable and banner or (banner[i] or banner.all or {})&lt;br /&gt;
			-- Banner size is default if the corresponding entry&lt;br /&gt;
			-- in bannerSize table is not set.&lt;br /&gt;
			local shieldBannerSize =&lt;br /&gt;
				bannersizeIsNotTable and bannersize&lt;br /&gt;
				or (bannersize[i] or bannersize.all or defaultShieldSize)&lt;br /&gt;
			local shieldBannerSuffix = bannersuffix and (bannersuffixIsNotTable and bannersuffix or bannersuffix[i])&lt;br /&gt;
			insert(shieldSpec, {&lt;br /&gt;
				shield = {filename, size},&lt;br /&gt;
				banners = bannerSpec(shieldBanner, shieldBannerSize, shieldBannerSuffix, route)&lt;br /&gt;
			})&lt;br /&gt;
		end&lt;br /&gt;
	elseif shield ~= &#039;&#039; then&lt;br /&gt;
		if shieldsize == &amp;quot;&amp;quot; then shieldsize = nil end&lt;br /&gt;
		insert(shieldSpec, {&lt;br /&gt;
			shield = {shield, shieldsize},&lt;br /&gt;
			banners = bannerSpec(banner, bannersize,  bannersuffix, route)&lt;br /&gt;
		})&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return shieldSpec&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local missingShields&lt;br /&gt;
&lt;br /&gt;
local shieldExistsCache = {}&lt;br /&gt;
&lt;br /&gt;
local function render(shieldEntry, scale, showLink)&lt;br /&gt;
	local shield = shieldEntry.shield&lt;br /&gt;
	local banners = shieldEntry.banners&lt;br /&gt;
&lt;br /&gt;
	local size&lt;br /&gt;
	if shield[2] then&lt;br /&gt;
		local width, height = mw.ustring.match(shield[2], &amp;quot;(%d*)x?(%d*)&amp;quot;)&lt;br /&gt;
		width = tonumber(width)&lt;br /&gt;
		height = tonumber(height)&lt;br /&gt;
		local sizeparts = {}&lt;br /&gt;
		if width then&lt;br /&gt;
			insert(sizeparts, format(&amp;quot;%d&amp;quot;, width * scale))&lt;br /&gt;
		end&lt;br /&gt;
		if height then&lt;br /&gt;
			insert(sizeparts, format(&amp;quot;x%d&amp;quot;, height * scale))&lt;br /&gt;
		end&lt;br /&gt;
		size = concat(sizeparts)&lt;br /&gt;
	else&lt;br /&gt;
		size = format(&amp;quot;%s%d&amp;quot;, landscape and &amp;quot;x&amp;quot; or &amp;quot;&amp;quot;, defaultShieldSize * scale)&lt;br /&gt;
	end&lt;br /&gt;
	local shieldCode = format(&amp;quot;[[File:%s|%spx|link=|alt=]]&amp;quot;, shield[1], size)&lt;br /&gt;
	if not banners[1] then return shieldCode end&lt;br /&gt;
&lt;br /&gt;
	for _,banner in ipairs(banners) do&lt;br /&gt;
		shieldCode = format(&amp;quot;[[File:%s|%spx|link=|alt=]]&amp;lt;br&amp;gt;%s&amp;quot;,&lt;br /&gt;
			banner[1],&lt;br /&gt;
			defaultShieldSize,&lt;br /&gt;
			shieldCode)&lt;br /&gt;
	end&lt;br /&gt;
	return &#039;&amp;lt;span style=&amp;quot;display: inline-block; vertical-align: baseline; line-height: 0; text-align: center;&amp;quot;&amp;gt;&#039; .. shieldCode .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.shield(route, scale, showLink, mainShield, shieldList)&lt;br /&gt;
	missingShields = {}&lt;br /&gt;
&lt;br /&gt;
	scale = scale or 1&lt;br /&gt;
&lt;br /&gt;
	local rendered = {}&lt;br /&gt;
	for _,entry in ipairs(shieldSpec(route, mainShield, shieldList)) do&lt;br /&gt;
		insert(rendered, render(entry, scale, showLink))&lt;br /&gt;
	end&lt;br /&gt;
	return concat(rendered), missingShields&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Links/abbreviations&lt;br /&gt;
function p.link(route)&lt;br /&gt;
	local nolink = route.nolink&lt;br /&gt;
	local abbr = parser(route, &#039;abbr&#039;)&lt;br /&gt;
	if nolink then&lt;br /&gt;
		return abbr&lt;br /&gt;
	else&lt;br /&gt;
		local link = parser(route, &#039;link&#039;)&lt;br /&gt;
		if not link or link == &#039;&#039; then&lt;br /&gt;
			return abbr&lt;br /&gt;
		else&lt;br /&gt;
			return format(&amp;quot;[[%s|%s]]&amp;quot;, link, abbr)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
-------------------------------------------&lt;br /&gt;
&lt;br /&gt;
-- Links/abbreviations&lt;br /&gt;
local function routeText(route, jctname, frame)&lt;br /&gt;
	local link&lt;br /&gt;
	local type = route.type&lt;br /&gt;
	if not type or type == &#039;&#039; then&lt;br /&gt;
		link = route.route&lt;br /&gt;
	else&lt;br /&gt;
		link = p.link(route)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local dir = route.dir and &#039; &#039; .. string.lower(route.dir) or &#039;&#039;&lt;br /&gt;
	if link == false or link == nil then&lt;br /&gt;
		link = route.route or &#039;&#039;&lt;br /&gt;
	else&lt;br /&gt;
		link = tostring(link)&lt;br /&gt;
	end&lt;br /&gt;
	local routeText = link .. dir&lt;br /&gt;
&lt;br /&gt;
	local name = route.name&lt;br /&gt;
	if name and name ~= &#039;&#039; then&lt;br /&gt;
		local mainText = jctname and name or routeText&lt;br /&gt;
		local parenText = jctname and routeText or name&lt;br /&gt;
		&lt;br /&gt;
		return format(&#039;%s (%s)&#039;, mainText, parenText)&lt;br /&gt;
	else&lt;br /&gt;
		return routeText&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function extra(args)&lt;br /&gt;
	local extraTypes = mw.loadData(&#039;Module:Road data/extra&#039;)&lt;br /&gt;
	local extraIcon = extraTypes[string.lower(args.extra or &#039;&#039;)]&lt;br /&gt;
	if not extraIcon then return &#039;&#039; end&lt;br /&gt;
	local size = defaultShieldSize .. &#039;px&#039;&lt;br /&gt;
	local countryIcon = extraIcon[args.country] or extraIcon.default&lt;br /&gt;
	if type(countryIcon) == &#039;table&#039; then&lt;br /&gt;
		local localIcon = countryIcon[args.state] or countryIcon.default&lt;br /&gt;
		return string.format(&amp;quot;[[File:%s|%s|alt=|link=]]&amp;quot;, localIcon, size)&lt;br /&gt;
	else&lt;br /&gt;
		return string.format(&amp;quot;[[File:%s|%s|alt=|link=]]&amp;quot;, countryIcon, size)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function parseArgs(args)&lt;br /&gt;
	local state = args.state or args.province or &#039;&#039;&lt;br /&gt;
	args.state = state&lt;br /&gt;
	local country&lt;br /&gt;
	if args.country and args.country ~= &#039;&#039; then&lt;br /&gt;
		country = string.upper(args.country)&lt;br /&gt;
	else&lt;br /&gt;
		local countryModule = mw.loadData(&amp;quot;Module:Road data/countrymask&amp;quot;)&lt;br /&gt;
		country = countryModule[state] or &#039;UNK&#039;&lt;br /&gt;
	end&lt;br /&gt;
	args.country = country&lt;br /&gt;
&lt;br /&gt;
	local params = {&#039;denom&#039;, &#039;county&#039;, &#039;township&#039;, &#039;dab&#039;, &#039;nolink&#039;, &#039;noshield&#039;, &#039;to&#039;, &#039;dir&#039;, &#039;name&#039;}&lt;br /&gt;
	local routes = {}&lt;br /&gt;
	local routeCount = 1&lt;br /&gt;
	local seenTo = false&lt;br /&gt;
	while true do&lt;br /&gt;
		local routeType = args[routeCount * 2 - 1]&lt;br /&gt;
		if not routeType then break end&lt;br /&gt;
		local route = {type = routeType, route = args[routeCount * 2]}&lt;br /&gt;
		for _,v in pairs(params) do&lt;br /&gt;
			route[v] = args[v .. routeCount]&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if args.nolink then&lt;br /&gt;
			route.nolink = args.nolink&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		route.country = country&lt;br /&gt;
		route.state = state&lt;br /&gt;
&lt;br /&gt;
		-- Set the first .to to true.&lt;br /&gt;
		-- Set all following .to to &#039;&#039;.&lt;br /&gt;
		if seenTo then&lt;br /&gt;
			if route.to then&lt;br /&gt;
				-- Report duplicate to flag.&lt;br /&gt;
				route.toerror = true&lt;br /&gt;
			end&lt;br /&gt;
			route.to = &#039;&#039;&lt;br /&gt;
		elseif route.to then&lt;br /&gt;
			route.to = true&lt;br /&gt;
			seenTo = true&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		insert(routes, route)&lt;br /&gt;
		routeCount = routeCount + 1&lt;br /&gt;
	end&lt;br /&gt;
	return routes&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function prefix(to, num)&lt;br /&gt;
	if to and to ~= &#039;&#039; then&lt;br /&gt;
		return num == 1 and &#039;To &#039; or &#039; to &#039;&lt;br /&gt;
	end&lt;br /&gt;
	return num == 1 and &#039;&#039; or &#039;&amp;amp;nbsp;/ &#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function addErrorMsg(catCode, msg, errorMsg)&lt;br /&gt;
	errorMsg.code = errorMsg.code or catCode&lt;br /&gt;
	insert(errorMsg, format(&#039;&amp;lt;span style=&amp;quot;display: none;&amp;quot;&amp;gt;Module:Jct %s&amp;lt;/span&amp;gt;&#039;, msg))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._jct(args, frame)&lt;br /&gt;
	local routes = parseArgs(args)&lt;br /&gt;
	local shields = {}&lt;br /&gt;
	local links = {}&lt;br /&gt;
	local allMissingShields = {}&lt;br /&gt;
	local typeErr = false&lt;br /&gt;
	local toErr = false&lt;br /&gt;
	frame = frame or mw.getCurrentFrame()&lt;br /&gt;
	for num,route in ipairs(routes) do&lt;br /&gt;
		if not (args.noshield or route.noshield) then&lt;br /&gt;
			local shield, missingShields = p.shield(route)&lt;br /&gt;
			insert(shields, shield)&lt;br /&gt;
			if missingShields[1] then&lt;br /&gt;
				insert(allMissingShields, concat(missingShields, &#039; / &#039;))&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		local prefix = prefix(route.to, num)&lt;br /&gt;
		if prefix ~= &#039;&#039; then insert(links, prefix) end&lt;br /&gt;
		insert(links, routeText(route, args.jctname, frame))&lt;br /&gt;
		typeErr = typeErr or route.typeerror or false&lt;br /&gt;
		toErr = toErr or route.toerror or false&lt;br /&gt;
	end&lt;br /&gt;
	local graphics = concat(shields) .. extra(args) .. &#039; &#039;&lt;br /&gt;
	local linkText = concat(links)&lt;br /&gt;
	local cities = &#039;&#039;&lt;br /&gt;
	if args.city1 or args.location1 then&lt;br /&gt;
		local citiesPrefix&lt;br /&gt;
		if args.citiesprefix then&lt;br /&gt;
			citiesPrefix = args.citiesprefix ~= &#039;&#039; and format(&amp;quot; %s &amp;quot;, args.citiesprefix) or &#039;&#039;&lt;br /&gt;
		else&lt;br /&gt;
			citiesPrefix = &#039;&amp;amp;nbsp;&#039;&lt;br /&gt;
		end&lt;br /&gt;
		local cityModule = require(cityModuleName)&lt;br /&gt;
		cities = citiesPrefix .. cityModule.city(args)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local errorMsg = {}&lt;br /&gt;
	-- Errors must be reported by the level of severity, most severe first.&lt;br /&gt;
	if typeErr then&lt;br /&gt;
		-- Report invalid type errors.&lt;br /&gt;
		addErrorMsg(&amp;quot;§&amp;quot;, &#039;error: Invalid route type&#039;, errorMsg)&lt;br /&gt;
	end&lt;br /&gt;
	if #allMissingShields &amp;gt; 0 then&lt;br /&gt;
		-- Report missing shield error.&lt;br /&gt;
		-- shieldExists() would have populated missingShields if shields are missing.&lt;br /&gt;
		addErrorMsg(&amp;quot;¶&amp;quot;, &#039;error: Missing route marker graphics: &#039; .. concat(allMissingShields, &#039; / &#039;), errorMsg)&lt;br /&gt;
	end&lt;br /&gt;
	if toErr then&lt;br /&gt;
		-- Report invalid to errors.&lt;br /&gt;
		addErrorMsg(&amp;quot;&amp;amp;&amp;quot;, &#039;error: Invalid &amp;quot;to&amp;quot; argument&#039;, errorMsg)&lt;br /&gt;
	end&lt;br /&gt;
	if args.road then&lt;br /&gt;
		-- Report deprecated &amp;quot;road&amp;quot; warning.&lt;br /&gt;
		addErrorMsg(&amp;quot;∆&amp;quot;, &#039;warning: &amp;quot;road&amp;quot; parameter is deprecated&#039;, errorMsg)&lt;br /&gt;
	end&lt;br /&gt;
	if args.rdt then&lt;br /&gt;
		-- Report deprecated &amp;quot;rdt&amp;quot; warning.&lt;br /&gt;
		addErrorMsg(&amp;quot;£&amp;quot;, &#039;warning: &amp;quot;rdt&amp;quot; parameter is deprecated&#039;, errorMsg)&lt;br /&gt;
	end&lt;br /&gt;
	if #errorMsg &amp;gt; 0 then&lt;br /&gt;
		local page = mw.title.getCurrentTitle().prefixedText -- Get transcluding page&#039;s title&lt;br /&gt;
		-- Add a category for the first, most severe error.&lt;br /&gt;
		insert(errorMsg, format(&#039;[[Category:Jct template errors|%s %s]]&#039;, errorMsg.code, page))&lt;br /&gt;
		errorMsg = concat(errorMsg)&lt;br /&gt;
	else&lt;br /&gt;
		errorMsg = &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return graphics .. linkText .. cities .. errorMsg&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.jct(frame)&lt;br /&gt;
	-- Import module function to work with passed arguments&lt;br /&gt;
	local getArgs = require(&#039;Module:Arguments&#039;).getArgs&lt;br /&gt;
	local args = getArgs(frame, {removeBlanks = false})&lt;br /&gt;
	return p._jct(args, frame)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._roadlink(args, frame)&lt;br /&gt;
	local routes = parseArgs(args)&lt;br /&gt;
	local links = {}&lt;br /&gt;
	local typeErr = false&lt;br /&gt;
	local toErr = false&lt;br /&gt;
	frame = frame or mw.getCurrentFrame()&lt;br /&gt;
	for num,route in ipairs(routes) do&lt;br /&gt;
		local prefix = prefix(route.to, num)&lt;br /&gt;
		if prefix ~= &#039;&#039; then insert(links, prefix) end&lt;br /&gt;
		insert(links, routeText(route, args.jctname, frame))&lt;br /&gt;
		typeErr = typeErr or route.typeerror or false&lt;br /&gt;
		toErr = toErr or route.toerror or false&lt;br /&gt;
	end&lt;br /&gt;
	local linkText = concat(links)&lt;br /&gt;
	local cities = &#039;&#039;&lt;br /&gt;
	if args.city1 or args.location1 then&lt;br /&gt;
		local citiesPrefix&lt;br /&gt;
		if args.citiesprefix then&lt;br /&gt;
			citiesPrefix = args.citiesprefix ~= &#039;&#039; and format(&amp;quot; %s &amp;quot;, args.citiesprefix) or &#039;&#039;&lt;br /&gt;
		else&lt;br /&gt;
			citiesPrefix = &#039;&amp;amp;nbsp;&#039;&lt;br /&gt;
		end&lt;br /&gt;
		local cityModule = require(cityModuleName)&lt;br /&gt;
		cities = citiesPrefix .. cityModule.city(args)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local errorMsg = {}&lt;br /&gt;
	-- Errors must be reported by the level of severity, most severe first.&lt;br /&gt;
	if typeErr then&lt;br /&gt;
		-- Report invalid type errors.&lt;br /&gt;
		addErrorMsg(&amp;quot;2&amp;quot;, &#039;error: Invalid route type&#039;, errorMsg)&lt;br /&gt;
	end&lt;br /&gt;
	if toErr then&lt;br /&gt;
		-- Report invalid to errors.&lt;br /&gt;
		addErrorMsg(&amp;quot;3&amp;quot;, &#039;error: Invalid &amp;quot;to&amp;quot; argument&#039;, errorMsg)&lt;br /&gt;
	end&lt;br /&gt;
	if args.road then&lt;br /&gt;
		-- Report deprecated &amp;quot;road&amp;quot; warning.&lt;br /&gt;
		addErrorMsg(&amp;quot;W&amp;quot;, &#039;warning: &amp;quot;road&amp;quot; parameter is deprecated&#039;, errorMsg)&lt;br /&gt;
	end&lt;br /&gt;
	if #errorMsg &amp;gt; 0 then&lt;br /&gt;
		local page = mw.title.getCurrentTitle().prefixedText -- Get transcluding page&#039;s title&lt;br /&gt;
		-- Add a category for the first, most severe error.&lt;br /&gt;
		insert(errorMsg, format(&#039;[[Category:Jct template errors|%s %s]]&#039;, errorMsg.code, page))&lt;br /&gt;
		errorMsg = concat(errorMsg)&lt;br /&gt;
	else&lt;br /&gt;
		errorMsg = &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return linkText .. cities&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.roadlink(frame)&lt;br /&gt;
	-- Import module function to work with passed arguments&lt;br /&gt;
	local getArgs = require(&#039;Module:Arguments&#039;).getArgs&lt;br /&gt;
	local args = getArgs(frame, {removeBlanks = true})&lt;br /&gt;
	return p._roadlink(args, frame)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Module:Citation_mode&amp;diff=5321</id>
		<title>Module:Citation mode</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Module:Citation_mode&amp;diff=5321"/>
		<updated>2026-06-15T12:50:06Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync shared ABC wiki compatibility fix from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;require (&#039;strict&#039;)&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- determine whether we&#039;re being called from a sandbox&lt;br /&gt;
local isSandbox = mw.getCurrentFrame():getTitle():find(&#039;sandbox&#039;, 1, true)&lt;br /&gt;
local sandbox = isSandbox and &#039;/sandbox&#039; or &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
local cfg = mw.loadData (&#039;Module:Citation/CS1/Configuration&#039; .. sandbox)&lt;br /&gt;
&lt;br /&gt;
-- if cs1 config is set, return false, otherwise use supplied mode&lt;br /&gt;
-- this prevents putting articles into &amp;quot;overriden mode&amp;quot; tracking category&lt;br /&gt;
function p._main(mode)&lt;br /&gt;
	return not (cfg.global_cs1_config_t and cfg.global_cs1_config_t[&#039;Mode&#039;]) and mode&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
    return p._main(frame.args[1]) or &amp;quot;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Module:Make_Wikisource_link&amp;diff=5320</id>
		<title>Module:Make Wikisource link</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Module:Make_Wikisource_link&amp;diff=5320"/>
		<updated>2026-06-15T12:50:05Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync shared ABC wiki compatibility fix from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
local getArgs = require(&#039;Module:Arguments&#039;).getArgs&lt;br /&gt;
local yesno = require(&#039;Module:Yesno&#039;)&lt;br /&gt;
&lt;br /&gt;
function p.makeLink(frame)&lt;br /&gt;
	--[[---------&lt;br /&gt;
	Variable declaration&lt;br /&gt;
	--]]---------&lt;br /&gt;
	local args = getArgs(frame)&lt;br /&gt;
	local lang = args[&#039;explicit_lang_param&#039;] or args[&#039;implicit_lang_param&#039;] or &#039;en&#039;&lt;br /&gt;
	local page = mw.title.getCurrentTitle()&lt;br /&gt;
	local pagename = page.text&lt;br /&gt;
	local wikisourceEdition&lt;br /&gt;
	local linkTarget&lt;br /&gt;
	local displayText&lt;br /&gt;
	local toReturn&lt;br /&gt;
	local prefix&lt;br /&gt;
	&lt;br /&gt;
	--[[&lt;br /&gt;
	Create the prefix for the interwiki link&lt;br /&gt;
	It uses the lowest of:&lt;br /&gt;
	 1. &#039;Special:Search/&#039;, if using the enwiki pagename as the interwiki target&lt;br /&gt;
	 2. If not (1), an &#039;Author:&#039; prefix, localized, if given a works parameter and not under (1)&lt;br /&gt;
	 3. If not (1) or (2), the empty string&lt;br /&gt;
	We avoid &#039;Special:Search/Author:&#039; intentionally; this is rarely helpful&lt;br /&gt;
	Here we simply set it to (2) or (3), and override it when setting the link target if needed&lt;br /&gt;
	--]]&lt;br /&gt;
	prefix = args.works and frame:expandTemplate{ title = &#039;Wikisource/Author&#039;, args = { lang } } or &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Handle multilingual Wikisource (aka old Wikisource) correctly&lt;br /&gt;
	if lang == &#039;mul&#039; then&lt;br /&gt;
		wikisourceEdition = &#039;sourceswiki&#039; -- siteid for multilingual Wikisource&lt;br /&gt;
	else&lt;br /&gt;
		wikisourceEdition = lang .. &#039;wikisource&#039; -- other Wikisource editions are langcode + &#039;wikisource&#039; (e.g. &#039;enwikisource&#039;)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- get the Wikidata sitelink&lt;br /&gt;
	local currentEntityId = (mw.wikibase and mw.wikibase.getEntityIdForCurrentPage and mw.wikibase.getEntityIdForCurrentPage()) or &#039;&#039;&lt;br /&gt;
	local wikidataSitelink = (mw.wikibase and mw.wikibase.getSitelink and mw.wikibase.getSitelink(currentEntityId, wikisourceEdition)) or nil&lt;br /&gt;
		&lt;br /&gt;
	-- if we have a language parameter, we look at the second unnamed parameter for the source title&lt;br /&gt;
	local checkIndexForTarget = args[&#039;implicit_lang_param&#039;] and 2 or 1&lt;br /&gt;
	-- and then use the next index for display&lt;br /&gt;
	local checkIndexForDisplay = checkIndexForTarget + 1&lt;br /&gt;
	&lt;br /&gt;
	--[[---------&lt;br /&gt;
	Set the link target&lt;br /&gt;
	--]]---------&lt;br /&gt;
	if args[&#039;wslink&#039;] then&lt;br /&gt;
		linkTarget = args[&#039;wslink&#039;]&lt;br /&gt;
	elseif args[checkIndexForTarget] then&lt;br /&gt;
		-- we have a source title parameter, so return that&lt;br /&gt;
		linkTarget = args[checkIndexForTarget]&lt;br /&gt;
	elseif wikidataSitelink then&lt;br /&gt;
		-- use Wikidata&lt;br /&gt;
		linkTarget = wikidataSitelink&lt;br /&gt;
	else&lt;br /&gt;
		-- we have no parameters and nothing at Wikidata, so we are flying blind&lt;br /&gt;
		-- set the linkTarget to the pagename&lt;br /&gt;
		linkTarget = pagename&lt;br /&gt;
		-- and set prefix to &#039;Special:Search/&#039; to find the appropriate link&lt;br /&gt;
		prefix = &#039;Special:Search/&#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- clear prefixes for now; will add it back later if needed&lt;br /&gt;
	-- this prevents duplicate prefixes (Author:Author:Shakespeare; Special:Search/Special:Search/)&lt;br /&gt;
	-- and avoids displayText with any author prefix&lt;br /&gt;
	linkTarget = string.gsub(linkTarget, &#039;^&#039; .. prefix, &#039;&#039;)&lt;br /&gt;
	&lt;br /&gt;
	--[[---------	&lt;br /&gt;
	Now build the displayText&lt;br /&gt;
	--]]---------&lt;br /&gt;
	&lt;br /&gt;
	if not displayText then&lt;br /&gt;
		-- we did not set displayText in the above steps, so set it now&lt;br /&gt;
		-- first we check for an explicit display text, or else we set it to be the link target&lt;br /&gt;
		displayText = args[&#039;title&#039;] or args[checkIndexForDisplay] or linkTarget&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--[[---------	&lt;br /&gt;
	Now we check whether we should categorize in Category:Wikisource templates with missing id&lt;br /&gt;
	--]]---------&lt;br /&gt;
	&lt;br /&gt;
	-- initialize errorCategory as true&lt;br /&gt;
	local errorCategory = true&lt;br /&gt;
	&lt;br /&gt;
	-- helper to set errorCategory = false&lt;br /&gt;
	local function setFalse() errorCategory = false end&lt;br /&gt;
	&lt;br /&gt;
	if wikidataSitelink then&lt;br /&gt;
		-- we do have a sitelink at Wikidata&lt;br /&gt;
		setFalse()&lt;br /&gt;
	elseif yesno(args.nocat, true) then&lt;br /&gt;
		-- we have a |nocat parameter&lt;br /&gt;
		setFalse()&lt;br /&gt;
	elseif page.namespace ~= 0 then&lt;br /&gt;
		-- only care about mainspace&lt;br /&gt;
		setFalse()&lt;br /&gt;
	elseif string.match(pagename, &#039;^Lists? of &#039;) then&lt;br /&gt;
		-- we are on a list page, and those should not have Wikisource links&lt;br /&gt;
		setFalse()&lt;br /&gt;
	elseif string.match(pagename, &#039;^%d%d?%d?%d?s? in&#039;) then&lt;br /&gt;
		-- we are in a YEAR/DECADE in FOO page, and those also should not have anything else&lt;br /&gt;
		setFalse()&lt;br /&gt;
	else&lt;br /&gt;
		-- Now we check categories and determine whether this is something which does not need a Wikisource links&lt;br /&gt;
		-- Currently, we avoid categorizing:&lt;br /&gt;
		-- 1. Disambiguation pages&lt;br /&gt;
		-- 2. Set index articles&lt;br /&gt;
		-- 3. Articles about species. There is no universal category; [[Category:Articles with &#039;species&#039; microformats]] is a proxy&lt;br /&gt;
		-- we do this check last to avoid using [[WP:EXPENSIVE]] parser calls if possible&lt;br /&gt;
		for _, cat in ipairs(page.categories) do&lt;br /&gt;
			if cat == &amp;quot;All disambiguation pages&amp;quot; or cat == &amp;quot;All set index articles&amp;quot; or cat == &amp;quot;Articles with &#039;species&#039; microformats&amp;quot; then&lt;br /&gt;
				setFalse()&lt;br /&gt;
				break&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- build the link&lt;br /&gt;
	toReturn = &#039;[[:s:&#039; .. lang .. &#039;:&#039; .. prefix .. linkTarget .. &#039;|&#039; .. displayText .. &#039;]]&#039;&lt;br /&gt;
	&lt;br /&gt;
	-- append the error category if needed&lt;br /&gt;
	if errorCategory then&lt;br /&gt;
		toReturn = toReturn .. &#039;[[Category:Wikisource templates with missing id|&#039; .. pagename .. &#039;]]&#039; &lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return toReturn&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Module:Mapframe&amp;diff=5319</id>
		<title>Module:Mapframe</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Module:Mapframe&amp;diff=5319"/>
		<updated>2026-06-15T12:50:04Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync shared ABC wiki compatibility fix from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- Note: Originally written on English Wikipedia at https://en.wikipedia.org/wiki/Module:Mapframe&lt;br /&gt;
&lt;br /&gt;
--[[----------------------------------------------------------------------------&lt;br /&gt;
 ##### Localisation (L10n) settings #####&lt;br /&gt;
 Replace values in quotes (&amp;quot;&amp;quot;) with localised values&lt;br /&gt;
----------------------------------------------------------------------------]]--&lt;br /&gt;
local L10n = {}&lt;br /&gt;
local wb = mw.wikibase&lt;br /&gt;
&lt;br /&gt;
-- Modue dependencies&lt;br /&gt;
local parser -- local copy of https://www.mediawiki.org/wiki/Module:WikitextParser loaded lazily&lt;br /&gt;
-- &amp;quot;strict&amp;quot; should not be used, at least until all other modules which require this module are not using globals.&lt;br /&gt;
&lt;br /&gt;
-- Template parameter names (unnumbered versions only)&lt;br /&gt;
--   Specify each as either a single string, or a table of strings (aliases)&lt;br /&gt;
--   Aliases are checked left-to-right, i.e. `{ &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot; }` is equivalent to using `{{{one| {{{two|}}} }}}` in a template&lt;br /&gt;
L10n.para = {&lt;br /&gt;
	display			= &amp;quot;display&amp;quot;,&lt;br /&gt;
	type			= &amp;quot;type&amp;quot;,&lt;br /&gt;
	id				= { &amp;quot;id&amp;quot;, &amp;quot;ids&amp;quot; },&lt;br /&gt;
	from			= &amp;quot;from&amp;quot;,&lt;br /&gt;
	raw				= &amp;quot;raw&amp;quot;,&lt;br /&gt;
	title			= &amp;quot;title&amp;quot;,&lt;br /&gt;
	description		= &amp;quot;description&amp;quot;,&lt;br /&gt;
	strokeColor		= { &amp;quot;stroke-color&amp;quot;, &amp;quot;stroke-colour&amp;quot; },&lt;br /&gt;
	strokeWidth		= &amp;quot;stroke-width&amp;quot;,&lt;br /&gt;
	strokeOpacity	= &amp;quot;stroke-opacity&amp;quot;,&lt;br /&gt;
	fill			= &amp;quot;fill&amp;quot;,&lt;br /&gt;
	fillOpacity		= &amp;quot;fill-opacity&amp;quot;,&lt;br /&gt;
	coord			= &amp;quot;coord&amp;quot;,&lt;br /&gt;
	marker			= &amp;quot;marker&amp;quot;,&lt;br /&gt;
	markerColor		= { &amp;quot;marker-color&amp;quot;, &amp;quot;marker-colour&amp;quot; },&lt;br /&gt;
	markerSize		= &amp;quot;marker-size&amp;quot;,&lt;br /&gt;
	radius			= { &amp;quot;radius&amp;quot;, &amp;quot;radius_m&amp;quot; },&lt;br /&gt;
	radiusKm		= &amp;quot;radius_km&amp;quot;,&lt;br /&gt;
	radiusFt		= &amp;quot;radius_ft&amp;quot;,&lt;br /&gt;
	radiusMi		= &amp;quot;radius_mi&amp;quot;,&lt;br /&gt;
	edges			= &amp;quot;edges&amp;quot;,&lt;br /&gt;
	text			= &amp;quot;text&amp;quot;,&lt;br /&gt;
	icon			= &amp;quot;icon&amp;quot;,&lt;br /&gt;
	zoom			= &amp;quot;zoom&amp;quot;,&lt;br /&gt;
	frame			= &amp;quot;frame&amp;quot;,&lt;br /&gt;
	plain			= &amp;quot;plain&amp;quot;,&lt;br /&gt;
	frameWidth		= &amp;quot;frame-width&amp;quot;,&lt;br /&gt;
	frameHeight		= &amp;quot;frame-height&amp;quot;,&lt;br /&gt;
	frameCoordinates= { &amp;quot;frame-coordinates&amp;quot;, &amp;quot;frame-coord&amp;quot; },&lt;br /&gt;
	frameLatitude	= { &amp;quot;frame-lat&amp;quot;, &amp;quot;frame-latitude&amp;quot; },&lt;br /&gt;
	frameLongitude	= { &amp;quot;frame-long&amp;quot;, &amp;quot;frame-longitude&amp;quot; },&lt;br /&gt;
	frameAlign		= &amp;quot;frame-align&amp;quot;,&lt;br /&gt;
	switch			= &amp;quot;switch&amp;quot;,&lt;br /&gt;
	overlay						= &amp;quot;overlay&amp;quot;,&lt;br /&gt;
	overlayBorder				= &amp;quot;overlay-border&amp;quot;,&lt;br /&gt;
	overlayHorizontalAlignment	= &amp;quot;overlay-horizontal-alignment&amp;quot;,&lt;br /&gt;
	overlayVerticalAlignment	= &amp;quot;overlay-vertical-alignment&amp;quot;,&lt;br /&gt;
	overlayHorizontalOffset		= &amp;quot;overlay-horizontal-offset&amp;quot;,&lt;br /&gt;
	overlayVerticalOffset		= &amp;quot;overlay-vertical-offset&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Names of other templates this module can extract coordinates from&lt;br /&gt;
L10n.template = {&lt;br /&gt;
	templates = { -- The coord template, as well as templates with output that contains {{coord}}&lt;br /&gt;
		&amp;quot;Coord&amp;quot;, &amp;quot;Coord/sandbox&amp;quot;,&lt;br /&gt;
		&amp;quot;NRHP row&amp;quot;, &amp;quot;NRHP row/sandbox&amp;quot;,&lt;br /&gt;
		&amp;quot;WikidataCoord&amp;quot;, &amp;quot;WikidataCoord/sandbox&amp;quot;, &amp;quot;Wikidatacoord&amp;quot;, &amp;quot;Wikidata coord&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
	modules = { -- The coordinates module, as well as modules with output that contains {{coord}}&lt;br /&gt;
		&amp;quot;Coordinates&amp;quot;, &amp;quot;Coordinates/sandbox&amp;quot;,&lt;br /&gt;
		&amp;quot;WikidataCoord&amp;quot;, &amp;quot;WikidataCoord/sandbox&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Error messages&lt;br /&gt;
L10n.error = {&lt;br /&gt;
	badDisplayPara    = &amp;quot;Invalid display parameter&amp;quot;,&lt;br /&gt;
	noCoords	      = &amp;quot;Coordinates must be specified on Wikidata or in |&amp;quot; .. ( type(L10n.para.coord)== &#039;table&#039; and L10n.para.coord[1] or L10n.para.coord ) .. &amp;quot;=&amp;quot;,&lt;br /&gt;
	wikidataCoords    = &amp;quot;Coordinates not found on Wikidata&amp;quot;,&lt;br /&gt;
	noCircleCoords    = &amp;quot;Circle centre coordinates must be specified, or available via Wikidata&amp;quot;,&lt;br /&gt;
	negativeRadius    = &amp;quot;Circle radius must be a positive number&amp;quot;,&lt;br /&gt;
	noRadius          = &amp;quot;Circle radius must be specified&amp;quot;,&lt;br /&gt;
	negativeEdges     = &amp;quot;Circle edges must be a positive number&amp;quot;,&lt;br /&gt;
	noSwitchPara      = &amp;quot;Found only one switch value in |&amp;quot; .. ( type(L10n.para.switch)== &#039;table&#039; and L10n.para.switch[1] or L10n.para.switch ) .. &amp;quot;=&amp;quot;,&lt;br /&gt;
	oneSwitchLabel    = &amp;quot;Found only one label in |&amp;quot; .. ( type(L10n.para.switch)== &#039;table&#039; and L10n.para.switch[1] or L10n.para.switch ) .. &amp;quot;=&amp;quot;,&lt;br /&gt;
	noSwitchLists     = &amp;quot;At least one parameter must have a SWITCH: list&amp;quot;,&lt;br /&gt;
	switchMismatches  = &amp;quot;All SWITCH: lists must have the same number of values&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
	 -- &amp;quot;%s&amp;quot; and &amp;quot;%d&amp;quot; tokens will be replaced with strings and numbers when used&lt;br /&gt;
	oneSwitchValue    = &amp;quot;Found only one switch value in |%s=&amp;quot;,&lt;br /&gt;
	fewerSwitchLabels = &amp;quot;Found %d switch values but only %d labels in |&amp;quot; .. ( type(L10n.para.switch)== &#039;table&#039; and L10n.para.switch[1] or L10n.para.switch ) .. &amp;quot;=&amp;quot;,&lt;br /&gt;
	noNamedCoords     = &amp;quot;No named coordinates found in %s&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Other strings&lt;br /&gt;
L10n.str = {&lt;br /&gt;
	-- valid values for display parameter, e.g. (|display=inline) or (|display=title) or (|display=inline,title) or (|display=title,inline)&lt;br /&gt;
	inline		= &amp;quot;inline&amp;quot;,&lt;br /&gt;
	title		= &amp;quot;title&amp;quot;,&lt;br /&gt;
	dsep		= &amp;quot;,&amp;quot;,			-- separator between inline and title (comma in the example above)&lt;br /&gt;
&lt;br /&gt;
	-- valid values for type parameter&lt;br /&gt;
	line		= &amp;quot;line&amp;quot;,		-- geoline feature (e.g. a road)&lt;br /&gt;
	shape		= &amp;quot;shape&amp;quot;,		-- geoshape feature (e.g. a state or province)&lt;br /&gt;
	shapeInverse	= &amp;quot;shape-inverse&amp;quot;,	-- geomask feature (the inverse of a geoshape)&lt;br /&gt;
	data		= &amp;quot;data&amp;quot;,		-- geoJSON data page on Commons&lt;br /&gt;
	point		= &amp;quot;point&amp;quot;,		-- single point feature (coordinates)&lt;br /&gt;
	circle      = &amp;quot;circle&amp;quot;,     -- circular area around a point&lt;br /&gt;
	named       = &amp;quot;named&amp;quot;,      -- all named coordinates in an article or section&lt;br /&gt;
&lt;br /&gt;
	-- Keyword to indicate a switch list. Must NOT use the special characters ^$()%.[]*+-?&lt;br /&gt;
	switch = &amp;quot;SWITCH&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
	-- valid values for icon, frame, and plain parameters&lt;br /&gt;
	affirmedWords = &#039; &#039;..table.concat({&lt;br /&gt;
		&amp;quot;add&amp;quot;,&lt;br /&gt;
		&amp;quot;added&amp;quot;,&lt;br /&gt;
		&amp;quot;affirm&amp;quot;,&lt;br /&gt;
		&amp;quot;affirmed&amp;quot;,&lt;br /&gt;
		&amp;quot;include&amp;quot;,&lt;br /&gt;
		&amp;quot;included&amp;quot;,&lt;br /&gt;
		&amp;quot;on&amp;quot;,&lt;br /&gt;
		&amp;quot;true&amp;quot;,&lt;br /&gt;
		&amp;quot;yes&amp;quot;,&lt;br /&gt;
		&amp;quot;y&amp;quot;&lt;br /&gt;
	}, &#039; &#039;)..&#039; &#039;,&lt;br /&gt;
	declinedWords = &#039; &#039;..table.concat({&lt;br /&gt;
		&amp;quot;decline&amp;quot;,&lt;br /&gt;
		&amp;quot;declined&amp;quot;,&lt;br /&gt;
		&amp;quot;exclude&amp;quot;,&lt;br /&gt;
		&amp;quot;excluded&amp;quot;,&lt;br /&gt;
		&amp;quot;false&amp;quot;,&lt;br /&gt;
		&amp;quot;none&amp;quot;,&lt;br /&gt;
		&amp;quot;not&amp;quot;,&lt;br /&gt;
		&amp;quot;no&amp;quot;,&lt;br /&gt;
		&amp;quot;n&amp;quot;,&lt;br /&gt;
		&amp;quot;off&amp;quot;,&lt;br /&gt;
		&amp;quot;omit&amp;quot;,&lt;br /&gt;
		&amp;quot;omitted&amp;quot;,&lt;br /&gt;
		&amp;quot;remove&amp;quot;,&lt;br /&gt;
		&amp;quot;removed&amp;quot;&lt;br /&gt;
	}, &#039; &#039;)..&#039; &#039;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Default values for parameters&lt;br /&gt;
L10n.defaults = {&lt;br /&gt;
	display		= L10n.str.inline,&lt;br /&gt;
	text		= &amp;quot;Map&amp;quot;,&lt;br /&gt;
	frameWidth	= &amp;quot;300&amp;quot;,&lt;br /&gt;
	frameHeight	= &amp;quot;200&amp;quot;,&lt;br /&gt;
	frameAlign  = &amp;quot;right&amp;quot;,&lt;br /&gt;
	markerColor	= &amp;quot;5E74F3&amp;quot;,&lt;br /&gt;
	markerSize	= nil,&lt;br /&gt;
	strokeColor	= &amp;quot;#ff0000&amp;quot;,&lt;br /&gt;
	strokeWidth	= 6,&lt;br /&gt;
	edges = 32, -- number of edges used to approximate a circle&lt;br /&gt;
	overlayBorder = &amp;quot;1px solid white&amp;quot;,&lt;br /&gt;
	overlayHorizontalAlignment = &amp;quot;right&amp;quot;,&lt;br /&gt;
	overlayHorizontalOffset = &amp;quot;0&amp;quot;,&lt;br /&gt;
	overlayVerticalAlignment = &amp;quot;bottom&amp;quot;,&lt;br /&gt;
	overlayVerticalOffset = &amp;quot;0&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- #### End of L10n settings ####&lt;br /&gt;
&lt;br /&gt;
--[[----------------------------------------------------------------------------&lt;br /&gt;
 Utility methods&lt;br /&gt;
----------------------------------------------------------------------------]]--&lt;br /&gt;
local util = {}&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Looks up a parameter value based on the id (a key from the L10n.para table) and&lt;br /&gt;
optionally a suffix, for parameters that can be suffixed (e.g. type2 is type&lt;br /&gt;
with suffix 2).&lt;br /&gt;
@param {table} args  key-value pairs of parameter names and their values&lt;br /&gt;
@param {string} param_id  id for parameter name (key from the L10n.para table)&lt;br /&gt;
@param {string} [suffix]  suffix for parameter name&lt;br /&gt;
@returns {string|nil} parameter value if found, or nil if not found&lt;br /&gt;
]]--&lt;br /&gt;
function util.getParameterValue(args, param_id, suffix)&lt;br /&gt;
	suffix = suffix or &#039;&#039;&lt;br /&gt;
	if type( L10n.para[param_id] ) ~= &#039;table&#039; then&lt;br /&gt;
		return args[L10n.para[param_id]..suffix]&lt;br /&gt;
	end&lt;br /&gt;
	for _i, paramAlias in ipairs(L10n.para[param_id]) do&lt;br /&gt;
		if args[paramAlias..suffix] then&lt;br /&gt;
			return args[paramAlias..suffix]&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Trim whitespace from args, and remove empty args. Also fix control characters.&lt;br /&gt;
@param {table} argsTable&lt;br /&gt;
@returns {table} trimmed args table&lt;br /&gt;
]]--&lt;br /&gt;
function util.trimArgs(argsTable)&lt;br /&gt;
	local cleanArgs = {}&lt;br /&gt;
	for key, val in pairs(argsTable) do&lt;br /&gt;
		if type(key) == &#039;string&#039;  and type(val) == &#039;string&#039; then&lt;br /&gt;
			val = val:match(&#039;^%s*(.-)%s*$&#039;)&lt;br /&gt;
			if val ~= &#039;&#039; then&lt;br /&gt;
				-- control characters inside json need to be escaped, but stripping them is simpler&lt;br /&gt;
				-- See also T214984&lt;br /&gt;
				-- However, *don&#039;t* strip control characters from wikitext (text or description parameters) or you&#039;ll break strip markers&lt;br /&gt;
				-- Alternatively it might be better to only strip control char from raw parameter content&lt;br /&gt;
				if util.matchesParam(&#039;text&#039;, key) or util.matchesParam(&#039;description&#039;, key, key:gsub(&#039;^%D+(%d+)$&#039;, &#039;%1&#039;) ) then&lt;br /&gt;
					cleanArgs[key] = val&lt;br /&gt;
				else&lt;br /&gt;
					cleanArgs[key] = val:gsub(&#039;%c&#039;,&#039; &#039;)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			cleanArgs[key] = val&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return cleanArgs&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Check if a parameter name matches an unlocalized parameter key&lt;br /&gt;
@param {string} key - the unlocalized parameter name to search through&lt;br /&gt;
@param {string} name - the localized parameter name to check&lt;br /&gt;
@param {string|nil} - an optional suffix to apply to the value(s) from the localization key&lt;br /&gt;
@returns {boolean} true if the name matches the parameter, false otherwise&lt;br /&gt;
]]--&lt;br /&gt;
function util.matchesParam(key, name, suffix)&lt;br /&gt;
	local param = L10n.para[key]&lt;br /&gt;
	suffix = suffix or &#039;&#039;&lt;br /&gt;
	if type(param) == &#039;table&#039; then&lt;br /&gt;
		for _, v in pairs(param) do&lt;br /&gt;
			if (v .. suffix) == name then return true end&lt;br /&gt;
		end&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	return ((param .. suffix) == name)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Check if a value is affirmed (one of the values in L10n.str.affirmedWords)&lt;br /&gt;
@param {string} val  Value to be checked&lt;br /&gt;
@returns {boolean} true if affirmed, false otherwise&lt;br /&gt;
]]--&lt;br /&gt;
function util.isAffirmed(val)&lt;br /&gt;
	if not(val) then return false end&lt;br /&gt;
	return string.find(L10n.str.affirmedWords, &#039; &#039;..val..&#039; &#039;, 1, true ) and true or false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Check if a value is declined (one of the values in L10n.str.declinedWords)&lt;br /&gt;
@param {string} val  Value to be checked&lt;br /&gt;
@returns {boolean} true if declined, false otherwise&lt;br /&gt;
]]--&lt;br /&gt;
function util.isDeclined(val)&lt;br /&gt;
	if not(val) then return false end&lt;br /&gt;
	return string.find(L10n.str.declinedWords , &#039; &#039;..val..&#039; &#039;, 1, true ) and true or false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Check if the name of a template matches the known coord templates or wrappers&lt;br /&gt;
(in L10n.template.templates and L10n.template.modules). The name is normalised&lt;br /&gt;
when checked, so e.g. the names &amp;quot;Coord&amp;quot;, &amp;quot;coord&amp;quot;, and &amp;quot;  Coord&amp;quot; all return true.&lt;br /&gt;
@param {string} name&lt;br /&gt;
@returns {boolean} true if it is a coord template or wrapper, false otherwise&lt;br /&gt;
]]--&lt;br /&gt;
function util.isCoordTemplateOrWrapper(name)&lt;br /&gt;
	name = mw.text.trim(name)&lt;br /&gt;
	local modName = mw.ustring.gsub(name, &#039;#invoke:&#039;, &#039;&#039;)&lt;br /&gt;
	local inputTitle = mw.title.new(modName, (name ~= modName) and &#039;Module&#039; or &#039;Template&#039;)&lt;br /&gt;
	if not inputTitle then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Create (or reuse) mw.title objects for each known coord template/wrapper.&lt;br /&gt;
	-- Stored in L10n.template.title so that they don&#039;t need to be recreated&lt;br /&gt;
	-- each time this function is called&lt;br /&gt;
	if not L10n.template.titles then&lt;br /&gt;
		L10n.template.titles = {}&lt;br /&gt;
		for _, v in pairs(L10n.template.templates) do&lt;br /&gt;
			table.insert(L10n.template.titles, mw.title.new(v, &#039;Template&#039;))&lt;br /&gt;
		end&lt;br /&gt;
		for _, v in pairs(L10n.template.modules) do&lt;br /&gt;
			table.insert(L10n.template.titles, mw.title.new(v, &#039;Module&#039;))&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for _, templateTitle in pairs(L10n.template.titles) do&lt;br /&gt;
		if mw.title.equals(inputTitle, templateTitle) then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Recursively extract coord templates which have a name parameter.&lt;br /&gt;
@param {string} wikitext&lt;br /&gt;
@returns {table} table sequence of coord templates&lt;br /&gt;
]]--&lt;br /&gt;
function util.extractCoordTemplates(wikitext)&lt;br /&gt;
	local output = {}&lt;br /&gt;
	local templates = mw.ustring.gmatch(wikitext, &#039;{%b{}}&#039;)&lt;br /&gt;
	for template in templates do&lt;br /&gt;
		local templateName = mw.ustring.match(template, &#039;{{([^}|]+)&#039;)&lt;br /&gt;
		local nameParam = mw.ustring.match(template, &amp;quot;|%s*name%s*=%s*[^}|]+&amp;quot;)&lt;br /&gt;
		if util.isCoordTemplateOrWrapper(templateName) then&lt;br /&gt;
			if nameParam then table.insert(output, template) end&lt;br /&gt;
		elseif mw.ustring.find(mw.ustring.sub(template, 2), &amp;quot;{{&amp;quot;) then&lt;br /&gt;
			local subOutput = util.extractCoordTemplates(mw.ustring.sub(template, 2))&lt;br /&gt;
			for _, t in pairs(subOutput) do&lt;br /&gt;
				table.insert(output, t)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	-- ensure coords are not using title display&lt;br /&gt;
	for k, v in pairs(output) do&lt;br /&gt;
		output[k] = mw.ustring.gsub(v, &amp;quot;|%s*display%s*=[^|}]+&amp;quot;, &amp;quot;|display=inline&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	return output&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Gets all named coordiates from a page or a section of a page.&lt;br /&gt;
@param {string|nil} page  Page name, or name#section, to get named coordinates&lt;br /&gt;
  from. If the name is omitted, i.e. #section or nil or empty string, then&lt;br /&gt;
  the current page will be used.&lt;br /&gt;
@returns {table} sequence of {coord, name, description} tables where coord is&lt;br /&gt;
  the coordinates in a format suitable for #util.parseCoords, name is a string,&lt;br /&gt;
  and description is a string (coordinates in a format suitable for displaying&lt;br /&gt;
  to the reader). If for some reason the name can&#039;t be found, the description&lt;br /&gt;
  is nil and the name contains display-format coordinates.&lt;br /&gt;
@throws {L10n.error.noNamedCoords} if no named coordinates are found.&lt;br /&gt;
]]--&lt;br /&gt;
function util.getNamedCoords(page)&lt;br /&gt;
	local parts = mw.text.split(page or &amp;quot;&amp;quot;, &amp;quot;#&amp;quot;, true)&lt;br /&gt;
	local name = parts[1] == &amp;quot;&amp;quot; and mw.title.getCurrentTitle().prefixedText or parts[1]&lt;br /&gt;
	local section = parts[2]&lt;br /&gt;
	local title = mw.title.new(name)&lt;br /&gt;
	if title.isRedirect then&lt;br /&gt;
		title = title.redirectTarget&lt;br /&gt;
	end&lt;br /&gt;
	local pageWikitext = title:getContent()&lt;br /&gt;
	if section then&lt;br /&gt;
		if parser == nil then&lt;br /&gt;
			-- load [[Module:WikitextParser]] lazily so it is only transcluded on pages that use it&lt;br /&gt;
			parser = require(&amp;quot;Module:WikitextParser&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
		pageWikitext = parser.getSection(pageWikitext, section) or &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local coordTemplates = util.extractCoordTemplates(pageWikitext)&lt;br /&gt;
	if #coordTemplates == 0 then error(string.format(L10n.error.noNamedCoords, page or name), 0) end&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
	local sep = &amp;quot;________&amp;quot;&lt;br /&gt;
	local expandedContent = frame:preprocess(table.concat(coordTemplates, sep))&lt;br /&gt;
	local expandedTemplates = mw.text.split(expandedContent, sep)&lt;br /&gt;
	local namedCoords = {}&lt;br /&gt;
	for _, expandedTemplate in pairs(expandedTemplates) do&lt;br /&gt;
		local coord = mw.ustring.match(expandedTemplate, &amp;quot;&amp;lt;span class=\&amp;quot;geo%-dec\&amp;quot;.-&amp;gt;(.-)&amp;lt;/span&amp;gt;&amp;quot;)&lt;br /&gt;
		if coord then&lt;br /&gt;
			local coordname = (&lt;br /&gt;
				-- name specified by a wrapper template, e.g [[Article|Name]]&lt;br /&gt;
				mw.ustring.match(expandedTemplate, &amp;quot;&amp;lt;span class=\&amp;quot;mapframe%-coord%-name\&amp;quot;&amp;gt;(.-)&amp;lt;/span&amp;gt;&amp;quot;) or&lt;br /&gt;
				-- name passed into coord template&lt;br /&gt;
				mw.ustring.match(expandedTemplate, &amp;quot;&amp;lt;span class=\&amp;quot;fn org\&amp;quot;&amp;gt;(.-)&amp;lt;/span&amp;gt;&amp;quot;) or&lt;br /&gt;
				-- default to the coordinates if the name can&#039;t be retrieved&lt;br /&gt;
				coord&lt;br /&gt;
			)&lt;br /&gt;
			local description = coordname ~= coord and coord&lt;br /&gt;
			table.insert(namedCoords, {&lt;br /&gt;
					coord=mw.ustring.gsub(coord, &amp;quot;[° ]&amp;quot;, &amp;quot;_&amp;quot;),&lt;br /&gt;
					name=coordname, description=description&lt;br /&gt;
			})&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if #namedCoords == 0 then error(string.format(L10n.error.noNamedCoords, page or name), 0) end&lt;br /&gt;
	return namedCoords&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Parse coordinate values from the params passed in a GeoHack url (such as&lt;br /&gt;
//tools.wmflabs.org/geohack/geohack.php?pagename=Example&amp;amp;params=1_2_N_3_4_W_ or&lt;br /&gt;
//tools.wmflabs.org/geohack/geohack.php?pagename=Example&amp;amp;params=1.23_S_4.56_E_ )&lt;br /&gt;
or non-url string in the same format (such as `1_2_N_3_4_W_` or `1.23_S_4.56_E_`)&lt;br /&gt;
@param {string} coords  string containing coordinates&lt;br /&gt;
@returns {number, number} latitude, longitude&lt;br /&gt;
]]--&lt;br /&gt;
function util.parseCoords(coords)&lt;br /&gt;
	local coordsPatt&lt;br /&gt;
	if mw.ustring.find(coords, &amp;quot;params=&amp;quot;, 1, true) then&lt;br /&gt;
		-- prevent false matches from page name, e.g. ?pagename=Lorem_S._Ipsum&lt;br /&gt;
		coordsPatt = &#039;params=([_%.%d]+[NS][_%.%d]+[EW])&#039;&lt;br /&gt;
	else&lt;br /&gt;
		-- not actually a geohack url, just the same format&lt;br /&gt;
		coordsPatt = &#039;[_%.%d]+[NS][_%.%d]+[EW]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local parts = mw.text.split((mw.ustring.match(coords, coordsPatt) or &#039;&#039;), &#039;_&#039;)&lt;br /&gt;
&lt;br /&gt;
	local lat_d = tonumber(parts[1])&lt;br /&gt;
	assert(lat_d, &amp;quot;Unable to get latitude from input &#039;&amp;quot;..coords..&amp;quot;&#039;.&amp;quot;)&lt;br /&gt;
	local lat_m = tonumber(parts[2]) -- nil if coords are in decimal format&lt;br /&gt;
	local lat_s = lat_m and tonumber(parts[3]) -- nil if coords are either in decimal format or degrees and minutes only&lt;br /&gt;
	local lat = lat_d + (lat_m or 0)/60 + (lat_s or 0)/3600&lt;br /&gt;
	if parts[#parts/2] == &#039;S&#039; then&lt;br /&gt;
		lat = lat * -1&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local long_d = tonumber(parts[1+#parts/2])&lt;br /&gt;
	assert(long_d, &amp;quot;Unable to get longitude from input &#039;&amp;quot;..coords..&amp;quot;&#039;.&amp;quot;)&lt;br /&gt;
	local long_m = tonumber(parts[2+#parts/2]) -- nil if coords are in decimal format&lt;br /&gt;
	local long_s = long_m and tonumber(parts[3+#parts/2]) -- nil if coords are either in decimal format or degrees and minutes only&lt;br /&gt;
	local long = long_d + (long_m or 0)/60 + (long_s or 0)/3600&lt;br /&gt;
	if parts[#parts] == &#039;W&#039; then&lt;br /&gt;
		long = long * -1&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return lat, long&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Get coordinates from a Wikidata item&lt;br /&gt;
@param {string} item_id  Wikidata item id (Q number)&lt;br /&gt;
@returns {number, number} latitude, longitude&lt;br /&gt;
@throws {L10n.error.noCoords} if item_id is invalid or the item does not exist&lt;br /&gt;
@throws {L10n.error.wikidataCoords} if the the item does not have a P625&lt;br /&gt;
  statement (coordinates), or it is set to &amp;quot;no value&amp;quot;&lt;br /&gt;
]]--&lt;br /&gt;
function util.wikidataCoords(item_id)&lt;br /&gt;
	if not (item_id and wb.isValidEntityId(item_id) and wb.entityExists(item_id)) then&lt;br /&gt;
		error(L10n.error.noCoords, 0)&lt;br /&gt;
	end&lt;br /&gt;
	local coordStatements = wb.getBestStatements(item_id, &#039;P625&#039;)&lt;br /&gt;
	if not coordStatements or #coordStatements == 0 then&lt;br /&gt;
		error(L10n.error.wikidataCoords, 0)&lt;br /&gt;
	end&lt;br /&gt;
	local hasNoValue = ( coordStatements[1].mainsnak and (coordStatements[1].mainsnak.snaktype == &#039;novalue&#039; or coordStatements[1].mainsnak.snaktype == &#039;somevalue&#039;) )&lt;br /&gt;
	if hasNoValue then&lt;br /&gt;
		error(L10n.error.wikidataCoords, 0)&lt;br /&gt;
	end&lt;br /&gt;
	local wdCoords = coordStatements[1][&#039;mainsnak&#039;][&#039;datavalue&#039;][&#039;value&#039;]&lt;br /&gt;
	return tonumber(wdCoords[&#039;latitude&#039;]), tonumber(wdCoords[&#039;longitude&#039;])&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Creates a polygon that approximates a circle&lt;br /&gt;
@param {number} lat  Latitude&lt;br /&gt;
@param {number} long  Longitude&lt;br /&gt;
@param {number} radius  Radius in metres&lt;br /&gt;
@param {number} n  Number of edges for the polygon&lt;br /&gt;
@returns {table} sequence of {latitude, longitude} table sequences, where&lt;br /&gt;
  latitude and longitude are both numbers&lt;br /&gt;
]]--&lt;br /&gt;
function util.circleToPolygon(lat, long, radius, n) -- n is number of edges&lt;br /&gt;
	-- Based on https://github.com/gabzim/circle-to-polygon, ISC licence&lt;br /&gt;
&lt;br /&gt;
	local function offset(cLat, cLon, distance, bearing)&lt;br /&gt;
		local lat1 = math.rad(cLat)&lt;br /&gt;
		local lon1 = math.rad(cLon)&lt;br /&gt;
		local dByR = distance / 6378137 -- distance divided by 6378137 (radius of the earth) wgs84&lt;br /&gt;
		local offet_lat = math.asin(&lt;br /&gt;
			math.sin(lat1) * math.cos(dByR) +&lt;br /&gt;
			math.cos(lat1) * math.sin(dByR) * math.cos(bearing)&lt;br /&gt;
		)&lt;br /&gt;
		local offet_lon = lon1 + math.atan2(&lt;br /&gt;
			math.sin(bearing) * math.sin(dByR) * math.cos(lat1),&lt;br /&gt;
			math.cos(dByR) - math.sin(lat1) * math.sin(offet_lat)&lt;br /&gt;
		)&lt;br /&gt;
		return {math.deg(offet_lon), math.deg(offet_lat)}&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local coordinates = {};&lt;br /&gt;
	local i = 0;&lt;br /&gt;
	while i &amp;lt; n do&lt;br /&gt;
		table.insert(coordinates,&lt;br /&gt;
			offset(lat, long, radius, (2*math.pi*i*-1)/n)&lt;br /&gt;
		)&lt;br /&gt;
		i = i + 1&lt;br /&gt;
	end&lt;br /&gt;
	table.insert(coordinates, offset(lat, long, radius, 0))&lt;br /&gt;
	return coordinates&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Get the number of key-value pairs in a table, which might not be a sequence.&lt;br /&gt;
@param {table} t&lt;br /&gt;
@returns {number} count of key-value pairs&lt;br /&gt;
]]--&lt;br /&gt;
function util.tableCount(t)&lt;br /&gt;
	local count = 0&lt;br /&gt;
	for k, v in pairs(t) do&lt;br /&gt;
		count = count + 1&lt;br /&gt;
	end&lt;br /&gt;
	return count&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
For a table where the values are all tables, returns either the util.tableCount&lt;br /&gt;
of the subtables if they are all the same, or nil if they are not all the same.&lt;br /&gt;
@param {table} t&lt;br /&gt;
@returns {number|nil} count of key-value pairs of subtable, or nil if subtables&lt;br /&gt;
  have different counts&lt;br /&gt;
]]--&lt;br /&gt;
function util.subTablesCount(t)&lt;br /&gt;
	local count = nil&lt;br /&gt;
	for k, v in pairs(t) do&lt;br /&gt;
		if count == nil then&lt;br /&gt;
			count = util.tableCount(v)&lt;br /&gt;
		elseif count ~= util.tableCount(v) then&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return count&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Splits a list into a table sequence. The items in the list may be separated by&lt;br /&gt;
commas, or by semicolons (if items may contain commas), or by &amp;quot;###&amp;quot; (if items&lt;br /&gt;
may contain semicolons).&lt;br /&gt;
@param {string} listString&lt;br /&gt;
@returns {table} sequence of list items&lt;br /&gt;
]]--&lt;br /&gt;
function util.tableFromList(listString)&lt;br /&gt;
	if type(listString) ~= &amp;quot;string&amp;quot; or listString == &amp;quot;&amp;quot; then return nil end&lt;br /&gt;
	local separator = (mw.ustring.find(listString, &amp;quot;###&amp;quot;, 0, true ) and &amp;quot;###&amp;quot;) or&lt;br /&gt;
		(mw.ustring.find(listString, &amp;quot;;&amp;quot;, 0, true ) and &amp;quot;;&amp;quot;) or &amp;quot;,&amp;quot;&lt;br /&gt;
	local pattern = &amp;quot;%s*&amp;quot;..separator..&amp;quot;%s*&amp;quot;&lt;br /&gt;
	return mw.text.split(listString, pattern)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Boolean in outer scope indicating if Kartographer should be able to&lt;br /&gt;
-- automatically calculate coordinates (see phab:T227402)&lt;br /&gt;
local coordsDerivedFromFeatures = false;&lt;br /&gt;
&lt;br /&gt;
--[[----------------------------------------------------------------------------&lt;br /&gt;
 Make methods: These take in a table of arguments, and return either a string&lt;br /&gt;
 or a table to be used in the eventual output.&lt;br /&gt;
----------------------------------------------------------------------------]]--&lt;br /&gt;
local make = {}&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Makes content to go inside the maplink or mapframe tag.&lt;br /&gt;
&lt;br /&gt;
@param {table} args&lt;br /&gt;
@returns {string} tag content&lt;br /&gt;
]]--&lt;br /&gt;
function make.content(args)&lt;br /&gt;
	if util.getParameterValue(args, &#039;raw&#039;) then&lt;br /&gt;
		coordsDerivedFromFeatures = true -- Kartographer should be able to automatically calculate coords from raw geoJSON&lt;br /&gt;
		return util.getParameterValue(args, &#039;raw&#039;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local content = {}&lt;br /&gt;
&lt;br /&gt;
    local argsExpanded = {}&lt;br /&gt;
    for k, v in pairs(args) do&lt;br /&gt;
		local index = string.match( k, &#039;^[^0-9]+([0-9]*)$&#039; )&lt;br /&gt;
		if index ~= nil then&lt;br /&gt;
			local indexNumber&lt;br /&gt;
			if index ~= &#039;&#039; then&lt;br /&gt;
				indexNumber = tonumber(index)&lt;br /&gt;
			else&lt;br /&gt;
				indexNumber = 1&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			if argsExpanded[indexNumber] == nil then&lt;br /&gt;
				argsExpanded[indexNumber] = {}&lt;br /&gt;
			end&lt;br /&gt;
			argsExpanded[indexNumber][ string.gsub(k, index, &#039;&#039;) ] = v&lt;br /&gt;
		end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
	for contentIndex, contentArgs in pairs(argsExpanded) do&lt;br /&gt;
		local argType = util.getParameterValue(contentArgs, &amp;quot;type&amp;quot;)&lt;br /&gt;
		-- Kartographer automatically calculates coords if geolines/shapes are used (T227402)&lt;br /&gt;
		if not coordsDerivedFromFeatures then&lt;br /&gt;
			coordsDerivedFromFeatures = ( argType == L10n.str.line or argType == L10n.str.shape ) and true or false&lt;br /&gt;
		end&lt;br /&gt;
		if argType == L10n.str.named then&lt;br /&gt;
			local namedCoords = util.getNamedCoords(util.getParameterValue(contentArgs, &amp;quot;from&amp;quot;))&lt;br /&gt;
			local typeKey = type(L10n.para.type) == &amp;quot;table&amp;quot; and L10n.para.type[1] or L10n.para.type&lt;br /&gt;
			local coordKey = type(L10n.para.coord) == &amp;quot;table&amp;quot; and L10n.para.coord[1] or L10n.para.coord&lt;br /&gt;
			local titleKey = type(L10n.para.title) == &amp;quot;table&amp;quot; and L10n.para.title[1] or L10n.para.title&lt;br /&gt;
			local descKey = type(L10n.para.description) == &amp;quot;table&amp;quot; and L10n.para.description[1] or L10n.para.description&lt;br /&gt;
			for _, namedCoord in pairs(namedCoords) do&lt;br /&gt;
				contentArgs[typeKey] = &amp;quot;point&amp;quot;&lt;br /&gt;
				contentArgs[coordKey]  = namedCoord.coord&lt;br /&gt;
				contentArgs[titleKey]  = namedCoord.name&lt;br /&gt;
				contentArgs[descKey]  = namedCoord.description&lt;br /&gt;
				content[#content+1] = make.contentJson(contentArgs)&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			content[#content + 1] = make.contentJson(contentArgs)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--Single item, no array needed&lt;br /&gt;
	if #content==1 then return content[1] end&lt;br /&gt;
&lt;br /&gt;
	--Multiple items get placed in a FeatureCollection&lt;br /&gt;
	local contentArray = &#039;[\n&#039; .. table.concat( content, &#039;,\n&#039;) .. &#039;\n]&#039;&lt;br /&gt;
	return contentArray&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Make coordinates from the coord arg, or the id arg, or the current page&#039;s&lt;br /&gt;
Wikidata item.&lt;br /&gt;
@param {table} args&lt;br /&gt;
@param {boolean} [plainOutput]&lt;br /&gt;
@returns {Mixed} Either:&lt;br /&gt;
  {number, number} latitude, longitude  if plainOutput is true; or&lt;br /&gt;
  {table} table sequence of longitude, then latitude (gives the required format&lt;br /&gt;
   for GeoJSON when encoded)&lt;br /&gt;
]]--&lt;br /&gt;
function make.coords(args, plainOutput)&lt;br /&gt;
	local coords, lat, long&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
	if util.getParameterValue(args, &#039;coord&#039;) then&lt;br /&gt;
		coords = frame:preprocess( util.getParameterValue(args, &#039;coord&#039;) )&lt;br /&gt;
		lat, long = util.parseCoords(coords)&lt;br /&gt;
	else&lt;br /&gt;
		lat, long = util.wikidataCoords(util.getParameterValue(args, &#039;id&#039;) or wb.getEntityIdForCurrentPage())&lt;br /&gt;
	end&lt;br /&gt;
	if plainOutput then&lt;br /&gt;
		return lat, long&lt;br /&gt;
	end&lt;br /&gt;
	return {[0] = long, [1] = lat}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Makes a table of coordinates that approximate a circle.&lt;br /&gt;
@param {table} args&lt;br /&gt;
@returns {table} sequence of {latitude, longitude} table sequences, where&lt;br /&gt;
  latitude and longitude are both numbers&lt;br /&gt;
@throws {L10n.error.noCircleCoords} if centre coordinates are not specified&lt;br /&gt;
@throws {L10n.error.noRadius} if radius is not specified&lt;br /&gt;
@throws {L10n.error.negativeRadius} if radius is negative or zero&lt;br /&gt;
@throws {L10n.error.negativeEdges} if edges is negative or zero&lt;br /&gt;
]]--&lt;br /&gt;
function make.circleCoords(args)&lt;br /&gt;
	local lat, long = make.coords(args, true)&lt;br /&gt;
	local radius = util.getParameterValue(args, &#039;radius&#039;)&lt;br /&gt;
	if not radius then&lt;br /&gt;
		radius = util.getParameterValue(args, &#039;radiusKm&#039;) and tonumber(util.getParameterValue(args, &#039;radiusKm&#039;))*1000&lt;br /&gt;
		if not radius then&lt;br /&gt;
			radius = util.getParameterValue(args, &#039;radiusMi&#039;) and tonumber(util.getParameterValue(args, &#039;radiusMi&#039;))*1609.344&lt;br /&gt;
			if not radius then&lt;br /&gt;
				radius = util.getParameterValue(args, &#039;radiusFt&#039;) and tonumber(util.getParameterValue(args, &#039;radiusFt&#039;))*0.3048&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local edges = util.getParameterValue(args, &#039;edges&#039;) or L10n.defaults.edges&lt;br /&gt;
	if not lat or not long then&lt;br /&gt;
		error(L10n.error.noCircleCoords, 0)&lt;br /&gt;
	elseif not radius then&lt;br /&gt;
		error(L10n.error.noRadius, 0)&lt;br /&gt;
	elseif tonumber(radius) &amp;lt;= 0 then&lt;br /&gt;
		error(L10n.error.negativeRadius, 0)&lt;br /&gt;
	elseif tonumber(edges) &amp;lt;= 0 then&lt;br /&gt;
		error(L10n.error.negativeEdges, 0)&lt;br /&gt;
	end&lt;br /&gt;
	return util.circleToPolygon(lat, long, radius, tonumber(edges))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Makes JSON data for a feature&lt;br /&gt;
@param contentArgs  args for this feature. Keys must be the non-suffixed version&lt;br /&gt;
  of the parameter names, i.e. use type, stroke, fill,... rather than type3,&lt;br /&gt;
  stroke3, fill3,...&lt;br /&gt;
@returns {string} JSON encoded data&lt;br /&gt;
]]--&lt;br /&gt;
function make.contentJson(contentArgs)&lt;br /&gt;
	local data = {}&lt;br /&gt;
&lt;br /&gt;
	if util.getParameterValue(contentArgs, &#039;type&#039;) == L10n.str.point or util.getParameterValue(contentArgs, &#039;type&#039;) == L10n.str.circle then&lt;br /&gt;
		local isCircle = util.getParameterValue(contentArgs, &#039;type&#039;) == L10n.str.circle&lt;br /&gt;
		data.type = &amp;quot;Feature&amp;quot;&lt;br /&gt;
		data.geometry = {&lt;br /&gt;
			type = isCircle and &amp;quot;LineString&amp;quot; or &amp;quot;Point&amp;quot;,&lt;br /&gt;
			coordinates = isCircle and make.circleCoords(contentArgs) or make.coords(contentArgs)&lt;br /&gt;
		}&lt;br /&gt;
		data.properties = {&lt;br /&gt;
			title = util.getParameterValue(contentArgs, &#039;title&#039;) or mw.getCurrentFrame():getParent():getTitle()&lt;br /&gt;
		}&lt;br /&gt;
		if isCircle then&lt;br /&gt;
			-- TODO: This is very similar to below, should be extracted into a function&lt;br /&gt;
			data.properties.stroke = util.getParameterValue(contentArgs, &#039;strokeColor&#039;) or L10n.defaults.strokeColor&lt;br /&gt;
			data.properties[&amp;quot;stroke-width&amp;quot;] = tonumber(util.getParameterValue(contentArgs, &#039;strokeWidth&#039;)) or L10n.defaults.strokeWidth&lt;br /&gt;
			local strokeOpacity = util.getParameterValue(contentArgs, &#039;strokeOpacity&#039;)&lt;br /&gt;
			if strokeOpacity then&lt;br /&gt;
				data.properties[&#039;stroke-opacity&#039;] = tonumber(strokeOpacity)&lt;br /&gt;
			end&lt;br /&gt;
			local fill = util.getParameterValue(contentArgs, &#039;fill&#039;)&lt;br /&gt;
			if fill then&lt;br /&gt;
				data.properties.fill = fill&lt;br /&gt;
				local fillOpacity = util.getParameterValue(contentArgs, &#039;fillOpacity&#039;)&lt;br /&gt;
				data.properties[&#039;fill-opacity&#039;] = fillOpacity and tonumber(fillOpacity) or 0.6&lt;br /&gt;
			end&lt;br /&gt;
		else -- is a point&lt;br /&gt;
			local markerSymbol = util.getParameterValue(contentArgs, &#039;marker&#039;) or L10n.defaults.marker&lt;br /&gt;
			-- allow blank to be explicitly specified, for overriding infoboxes or other templates with a default value&lt;br /&gt;
			if markerSymbol ~= &amp;quot;blank&amp;quot; then&lt;br /&gt;
				data.properties[&amp;quot;marker-symbol&amp;quot;] = markerSymbol&lt;br /&gt;
			end&lt;br /&gt;
			data.properties[&amp;quot;marker-color&amp;quot;] = util.getParameterValue(contentArgs, &#039;markerColor&#039;) or L10n.defaults.markerColor&lt;br /&gt;
			data.properties[&amp;quot;marker-size&amp;quot;] = util.getParameterValue(contentArgs, &#039;markerSize&#039;) or L10n.defaults.markerSize&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		data.type = &amp;quot;ExternalData&amp;quot;&lt;br /&gt;
&lt;br /&gt;
		if util.getParameterValue(contentArgs, &#039;type&#039;) == L10n.str.data or util.getParameterValue(contentArgs, &#039;from&#039;) then&lt;br /&gt;
			data.service = &amp;quot;page&amp;quot;&lt;br /&gt;
		elseif util.getParameterValue(contentArgs, &#039;type&#039;) == L10n.str.line then&lt;br /&gt;
			data.service = &amp;quot;geoline&amp;quot;&lt;br /&gt;
		elseif util.getParameterValue(contentArgs, &#039;type&#039;) == L10n.str.shape then&lt;br /&gt;
			data.service = &amp;quot;geoshape&amp;quot;&lt;br /&gt;
		elseif util.getParameterValue(contentArgs, &#039;type&#039;) == L10n.str.shapeInverse then&lt;br /&gt;
			data.service = &amp;quot;geomask&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local explicitId = util.getParameterValue(contentArgs, &#039;id&#039;)&lt;br /&gt;
		local fromTitle = util.getParameterValue(contentArgs, &#039;from&#039;)&lt;br /&gt;
		local currentEntityId = (wb and wb.getEntityIdForCurrentPage and wb.getEntityIdForCurrentPage()) or nil&lt;br /&gt;
		if explicitId or (not fromTitle and currentEntityId) then&lt;br /&gt;
			data.ids = explicitId or currentEntityId&lt;br /&gt;
		else&lt;br /&gt;
			data.title = fromTitle&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		data.properties = {&lt;br /&gt;
			stroke = util.getParameterValue(contentArgs, &#039;strokeColor&#039;) or L10n.defaults.strokeColor,&lt;br /&gt;
			[&amp;quot;stroke-width&amp;quot;] = tonumber(util.getParameterValue(contentArgs, &#039;strokeWidth&#039;)) or L10n.defaults.strokeWidth&lt;br /&gt;
		}&lt;br /&gt;
		local strokeOpacity = util.getParameterValue(contentArgs, &#039;strokeOpacity&#039;)&lt;br /&gt;
		if strokeOpacity then&lt;br /&gt;
			data.properties[&#039;stroke-opacity&#039;] = tonumber(strokeOpacity)&lt;br /&gt;
		end&lt;br /&gt;
		local fill = util.getParameterValue(contentArgs, &#039;fill&#039;)&lt;br /&gt;
		if fill and (data.service == &amp;quot;geoshape&amp;quot; or data.service == &amp;quot;geomask&amp;quot;) then&lt;br /&gt;
			data.properties.fill = fill&lt;br /&gt;
			local fillOpacity = util.getParameterValue(contentArgs, &#039;fillOpacity&#039;)&lt;br /&gt;
			if fillOpacity then&lt;br /&gt;
				data.properties[&#039;fill-opacity&#039;] = tonumber(fillOpacity)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	data.properties.title = util.getParameterValue(contentArgs, &#039;title&#039;) or mw.title.getCurrentTitle().text&lt;br /&gt;
	if util.getParameterValue(contentArgs, &#039;description&#039;) then&lt;br /&gt;
		data.properties.description = util.getParameterValue(contentArgs, &#039;description&#039;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return mw.text.jsonEncode(data)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Makes attributes for the maplink or mapframe tag.&lt;br /&gt;
@param {table} args&lt;br /&gt;
@param {boolean} [isTitle]  Tag is to be displayed in the title of page rather&lt;br /&gt;
  than inline&lt;br /&gt;
@returns {table&amp;lt;string,string&amp;gt;} key-value pairs of attribute names and values&lt;br /&gt;
]]--&lt;br /&gt;
function make.tagAttribs(args, isTitle)&lt;br /&gt;
	local attribs = {}&lt;br /&gt;
	if util.getParameterValue(args, &#039;zoom&#039;) then&lt;br /&gt;
		attribs.zoom = util.getParameterValue(args, &#039;zoom&#039;)&lt;br /&gt;
	end&lt;br /&gt;
	if util.isDeclined(util.getParameterValue(args, &#039;icon&#039;)) then&lt;br /&gt;
		attribs.class = &amp;quot;no-icon&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	if util.getParameterValue(args, &#039;type&#039;) == L10n.str.point and not coordsDerivedFromFeatures then&lt;br /&gt;
		local lat, long = make.coords(args, &#039;plainOutput&#039;)&lt;br /&gt;
		attribs.latitude = tostring(lat)&lt;br /&gt;
		attribs.longitude = tostring(long)&lt;br /&gt;
	end&lt;br /&gt;
	if util.isAffirmed(util.getParameterValue(args, &#039;frame&#039;)) and not(isTitle) then&lt;br /&gt;
		attribs.width = util.getParameterValue(args, &#039;frameWidth&#039;) or L10n.defaults.frameWidth&lt;br /&gt;
		attribs.height = util.getParameterValue(args, &#039;frameHeight&#039;) or L10n.defaults.frameHeight&lt;br /&gt;
		if util.getParameterValue(args, &#039;frameCoordinates&#039;) then&lt;br /&gt;
			local frameLat, frameLong = util.parseCoords(util.getParameterValue(args, &#039;frameCoordinates&#039;))&lt;br /&gt;
			attribs.latitude = frameLat&lt;br /&gt;
			attribs.longitude = frameLong&lt;br /&gt;
		else&lt;br /&gt;
			if util.getParameterValue(args, &#039;frameLatitude&#039;) then&lt;br /&gt;
				attribs.latitude = util.getParameterValue(args, &#039;frameLatitude&#039;)&lt;br /&gt;
			end&lt;br /&gt;
			if util.getParameterValue(args, &#039;frameLongitude&#039;) then&lt;br /&gt;
				attribs.longitude = util.getParameterValue(args, &#039;frameLongitude&#039;)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if not attribs.latitude and not attribs.longitude and not coordsDerivedFromFeatures then&lt;br /&gt;
			local success, lat, long = pcall(util.wikidataCoords, util.getParameterValue(args, &#039;id&#039;) or wb.getEntityIdForCurrentPage())&lt;br /&gt;
			if success then&lt;br /&gt;
				attribs.latitude = tostring(lat)&lt;br /&gt;
				attribs.longitude = tostring(long)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if util.getParameterValue(args, &#039;frameAlign&#039;) then&lt;br /&gt;
			attribs.align = util.getParameterValue(args, &#039;frameAlign&#039;)&lt;br /&gt;
		end&lt;br /&gt;
		if util.isAffirmed(util.getParameterValue(args, &#039;plain&#039;)) then&lt;br /&gt;
			attribs.frameless = &amp;quot;1&amp;quot;&lt;br /&gt;
		else&lt;br /&gt;
			attribs.text = util.getParameterValue(args, &#039;text&#039;) or L10n.defaults.text&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		attribs.text = util.getParameterValue(args, &#039;text&#039;) or L10n.defaults.text&lt;br /&gt;
	end&lt;br /&gt;
	return attribs&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Makes maplink wikitext that will be located in the top-right of the title of the&lt;br /&gt;
page (the same place where coords with |display=title are positioned).&lt;br /&gt;
@param {table} args&lt;br /&gt;
@param {string} tagContent  Content for the maplink tag&lt;br /&gt;
@returns {string}&lt;br /&gt;
]]--&lt;br /&gt;
function make.titleOutput(args, tagContent)&lt;br /&gt;
	local titleTag = mw.text.tag(&#039;maplink&#039;, make.tagAttribs(args, true), tagContent)&lt;br /&gt;
	local spanAttribs = {&lt;br /&gt;
		style = &amp;quot;font-size: small;&amp;quot;,&lt;br /&gt;
		id = &amp;quot;mapframe-coordinates&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
	local indicatorContent = mw.text.tag(&#039;span&#039;, spanAttribs, titleTag)&lt;br /&gt;
	return mw.getCurrentFrame():extensionTag {&lt;br /&gt;
		name = &amp;quot;indicator&amp;quot;,&lt;br /&gt;
		content = indicatorContent,&lt;br /&gt;
		args = {&lt;br /&gt;
			name = &amp;quot;zzz-mapframe&amp;quot; --zzz: show as last indicator&lt;br /&gt;
		}&lt;br /&gt;
	} &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Makes maplink or mapframe wikitext that will be located inline.&lt;br /&gt;
@param {table} args&lt;br /&gt;
@param {string} tagContent  Content for the maplink tag&lt;br /&gt;
@returns {string}&lt;br /&gt;
]]--&lt;br /&gt;
function make.inlineOutput(args, tagContent)&lt;br /&gt;
	local tagName = &#039;maplink&#039;&lt;br /&gt;
	if util.getParameterValue(args, &#039;frame&#039;) then&lt;br /&gt;
		tagName = &#039;mapframe&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return mw.text.tag(tagName, make.tagAttribs(args), tagContent)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Makes the HTML required for the swicther to work, including the templatestyles&lt;br /&gt;
tag.&lt;br /&gt;
@param {table} params  table sequence of {map, label} tables&lt;br /&gt;
  @param {string} params{}.map  Wikitext for mapframe map&lt;br /&gt;
  @param {string} params{}.label  Label text for swicther option&lt;br /&gt;
@param {table} options&lt;br /&gt;
  @param {string} options.alignment  &amp;quot;left&amp;quot; or &amp;quot;center&amp;quot; or &amp;quot;right&amp;quot;&lt;br /&gt;
  @param {boolean} options.isThumbnail  Display in a thumbnail&lt;br /&gt;
  @param {string} options.width  Width of frame, e.g. &amp;quot;200&amp;quot;&lt;br /&gt;
  @param {string} [options.caption]  Caption wikitext for thumnail&lt;br /&gt;
@retruns {string} swicther HTML&lt;br /&gt;
]]--&lt;br /&gt;
function make.switcherHtml(params, options)&lt;br /&gt;
	options = options or {}&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
	local styles = frame:extensionTag{&lt;br /&gt;
		name = &amp;quot;templatestyles&amp;quot;,&lt;br /&gt;
		args = {src = &amp;quot;Template:Maplink/styles-multi.css&amp;quot;}&lt;br /&gt;
	}&lt;br /&gt;
	local container = mw.html.create(&amp;quot;div&amp;quot;)&lt;br /&gt;
		:addClass(&amp;quot;switcher-container&amp;quot;)&lt;br /&gt;
		:addClass(&amp;quot;mapframe-multi-container&amp;quot;)&lt;br /&gt;
	if options.alignment == &amp;quot;left&amp;quot; or options.alignment == &amp;quot;right&amp;quot; then&lt;br /&gt;
		container:addClass(&amp;quot;float&amp;quot;..options.alignment)&lt;br /&gt;
	else -- alignment is &amp;quot;center&amp;quot;&lt;br /&gt;
		container:addClass(&amp;quot;center&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	for i = 1, #params do&lt;br /&gt;
		container&lt;br /&gt;
			:tag(&amp;quot;div&amp;quot;)&lt;br /&gt;
				:wikitext(params[i].map)&lt;br /&gt;
				:tag(&amp;quot;span&amp;quot;)&lt;br /&gt;
					:addClass(&amp;quot;switcher-label&amp;quot;)&lt;br /&gt;
					:css(&amp;quot;display&amp;quot;, &amp;quot;none&amp;quot;)&lt;br /&gt;
					:wikitext(mw.text.trim(params[i].label))&lt;br /&gt;
	end&lt;br /&gt;
	if not options.isThumbnail then&lt;br /&gt;
		return styles .. tostring(container)&lt;br /&gt;
	end&lt;br /&gt;
	local classlist = container:getAttr(&amp;quot;class&amp;quot;)&lt;br /&gt;
	classlist = mw.ustring.gsub(classlist, &amp;quot;%a*&amp;quot;..options.alignment, &amp;quot;&amp;quot;)&lt;br /&gt;
	container:attr(&amp;quot;class&amp;quot;, classlist)&lt;br /&gt;
	local outerCountainer = mw.html.create(&amp;quot;div&amp;quot;)&lt;br /&gt;
		:addClass(&amp;quot;mapframe-multi-outer-container&amp;quot;)&lt;br /&gt;
		:addClass(&amp;quot;mw-kartographer-container&amp;quot;)&lt;br /&gt;
		:addClass(&amp;quot;thumb&amp;quot;)&lt;br /&gt;
	if options.alignment == &amp;quot;left&amp;quot; or options.alignment == &amp;quot;right&amp;quot; then&lt;br /&gt;
		outerCountainer:addClass(&amp;quot;float&amp;quot;..options.alignment)&lt;br /&gt;
	else -- alignment is &amp;quot;center&amp;quot;&lt;br /&gt;
		outerCountainer&lt;br /&gt;
			:addClass(&amp;quot;tnone&amp;quot;)&lt;br /&gt;
			:addClass(&amp;quot;center&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	outerCountainer&lt;br /&gt;
		:tag(&amp;quot;div&amp;quot;)&lt;br /&gt;
			:addClass(&amp;quot;thumbinner&amp;quot;)&lt;br /&gt;
			:css(&amp;quot;width&amp;quot;, options.width..&amp;quot;px&amp;quot;)&lt;br /&gt;
			:node(container)&lt;br /&gt;
			:node(options.caption and mw.html.create(&amp;quot;div&amp;quot;)&lt;br /&gt;
				:addClass(&amp;quot;thumbcaption&amp;quot;)&lt;br /&gt;
				:wikitext(options.caption)&lt;br /&gt;
			)&lt;br /&gt;
	return styles .. tostring(outerCountainer)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Makes the HTML required for an overlay map to work&lt;br /&gt;
tag.&lt;br /&gt;
@param {string} overlayMap  wikitext for the overlay map&lt;br /&gt;
@param {string} baseMap  wikitext for the base map&lt;br /&gt;
@param {table} options  various styling/display options&lt;br /&gt;
  @param {string} options.align  &amp;quot;left&amp;quot; or &amp;quot;center&amp;quot; or &amp;quot;right&amp;quot;&lt;br /&gt;
  @param {string|number} options.width  Width of the base map, e.g. &amp;quot;300&amp;quot;&lt;br /&gt;
  @param {string|number} options.width  Height of the base map, e.g. &amp;quot;200&amp;quot;&lt;br /&gt;
  @param {string} options.border  Border style for the overlayed map, e.g. &amp;quot;1px solid white&amp;quot;&lt;br /&gt;
  @param {string} options.horizontalAlignment  Horizontal alignment for overlay map, &amp;quot;left&amp;quot; or &amp;quot;right&amp;quot;&lt;br /&gt;
  @param {string|number} options.horizontalOffset  Horizontal offset in pixels from the alignment edge, e.g &amp;quot;10&amp;quot;&lt;br /&gt;
  @param {string} options.verticalAlignment  Vertical alignment for overlay map, &amp;quot;top&amp;quot; or &amp;quot;bottom&amp;quot;&lt;br /&gt;
  @param {string|number} options.verticalOffset  Vertical offset in pixels from the alignment edge, e.g. is &amp;quot;10&amp;quot;&lt;br /&gt;
  @param {boolean} options.isThumbnail  Display in a thumbnail&lt;br /&gt;
  @param {string} [options.caption]  Caption wikitext for thumnail&lt;br /&gt;
@retruns {string} HTML for basemap with overlay&lt;br /&gt;
]]--&lt;br /&gt;
function make.overlayHtml(overlayMap, baseMap, options)&lt;br /&gt;
	options = options or {}&lt;br /&gt;
	local containerFloatClass = &amp;quot;float&amp;quot;..(options.align or &amp;quot;none&amp;quot;)&lt;br /&gt;
	if options.align == &amp;quot;center&amp;quot; then&lt;br /&gt;
		containerFloatClass = &amp;quot;center&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	local containerStyle = {&lt;br /&gt;
		position = &amp;quot;relative&amp;quot;,&lt;br /&gt;
		width = options.width .. &amp;quot;px&amp;quot;,&lt;br /&gt;
		height = options.height .. &amp;quot;px&amp;quot;,&lt;br /&gt;
		overflow = &amp;quot;hidden&amp;quot; -- mobile/minerva tends to add scrollbars for a couple of pixels&lt;br /&gt;
	}&lt;br /&gt;
	if options.align == &amp;quot;center&amp;quot; then&lt;br /&gt;
		containerStyle[&amp;quot;margin-left&amp;quot;] = &amp;quot;auto&amp;quot;&lt;br /&gt;
		containerStyle[&amp;quot;margin-right&amp;quot;] = &amp;quot;auto&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	local container = mw.html.create(&amp;quot;div&amp;quot;)&lt;br /&gt;
		:addClass(&amp;quot;mapframe-withOverlay-container&amp;quot;)&lt;br /&gt;
		:addClass(containerFloatClass)&lt;br /&gt;
		:addClass(&amp;quot;noresize&amp;quot;)&lt;br /&gt;
		:css(containerStyle)&lt;br /&gt;
&lt;br /&gt;
	local overlayStyle = {&lt;br /&gt;
		position = &amp;quot;absolute&amp;quot;,&lt;br /&gt;
		[&amp;quot;z-index&amp;quot;] = &amp;quot;1&amp;quot;,&lt;br /&gt;
		border = options.border or &amp;quot;1px solid white&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
	if options.horizontalAlignment == &amp;quot;right&amp;quot; then&lt;br /&gt;
		overlayStyle.right = options.horizontalOffset .. &amp;quot;px&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		overlayStyle.left = options.horizontalOffset .. &amp;quot;px&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	if options.verticalAlignment == &amp;quot;bottom&amp;quot; then&lt;br /&gt;
		overlayStyle.bottom = options.verticalOffset .. &amp;quot;px&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		overlayStyle.top = options.verticalOffset .. &amp;quot;px&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	local overlayDiv = mw.html.create(&amp;quot;div&amp;quot;)&lt;br /&gt;
		:css(overlayStyle)&lt;br /&gt;
		:wikitext(overlayMap)&lt;br /&gt;
&lt;br /&gt;
	container&lt;br /&gt;
		:node(overlayDiv)&lt;br /&gt;
		:wikitext(baseMap)&lt;br /&gt;
&lt;br /&gt;
	if not options.isThumbnail then&lt;br /&gt;
		return tostring(container)&lt;br /&gt;
	end&lt;br /&gt;
	local classlist = container:getAttr(&amp;quot;class&amp;quot;)&lt;br /&gt;
	classlist = mw.ustring.gsub(classlist, &amp;quot;%a*&amp;quot;..options.align, &amp;quot;&amp;quot;)&lt;br /&gt;
	container:attr(&amp;quot;class&amp;quot;, classlist)&lt;br /&gt;
	local outerCountainer = mw.html.create(&amp;quot;div&amp;quot;)&lt;br /&gt;
		:addClass(&amp;quot;mapframe-withOverlay-outerContainer&amp;quot;)&lt;br /&gt;
		:addClass(&amp;quot;mw-kartographer-container&amp;quot;)&lt;br /&gt;
		:addClass(&amp;quot;thumb&amp;quot;)&lt;br /&gt;
	if options.align == &amp;quot;left&amp;quot; or options.align == &amp;quot;right&amp;quot; then&lt;br /&gt;
		outerCountainer:addClass(&amp;quot;t&amp;quot;..options.align)&lt;br /&gt;
	else -- alignment is &amp;quot;center&amp;quot;&lt;br /&gt;
		outerCountainer&lt;br /&gt;
			:addClass(&amp;quot;tnone&amp;quot;)&lt;br /&gt;
			:addClass(&amp;quot;center&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	outerCountainer&lt;br /&gt;
		:tag(&amp;quot;div&amp;quot;)&lt;br /&gt;
			:addClass(&amp;quot;thumbinner&amp;quot;)&lt;br /&gt;
			:css(&amp;quot;width&amp;quot;, options.width..&amp;quot;px&amp;quot;)&lt;br /&gt;
			:node(container)&lt;br /&gt;
			:node(options.caption and mw.html.create(&amp;quot;div&amp;quot;)&lt;br /&gt;
				:addClass(&amp;quot;thumbcaption&amp;quot;)&lt;br /&gt;
				:wikitext(options.caption)&lt;br /&gt;
			)&lt;br /&gt;
	return tostring(outerCountainer)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[----------------------------------------------------------------------------&lt;br /&gt;
 Package to be exported, i.e. methods which will available to templates and&lt;br /&gt;
 other modules.&lt;br /&gt;
----------------------------------------------------------------------------]]--&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Entry point for templates&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	local parent = frame.getParent(frame)&lt;br /&gt;
	-- Check for overlay option&lt;br /&gt;
	local overlay = util.getParameterValue(parent.args, &#039;overlay&#039;)&lt;br /&gt;
	local hasOverlay = overlay and mw.text.trim(overlay) ~= &amp;quot;&amp;quot;&lt;br /&gt;
	-- Check for switch option&lt;br /&gt;
	local switch = util.getParameterValue(parent.args, &#039;switch&#039;)&lt;br /&gt;
	local isMulti = switch and mw.text.trim(switch) ~= &amp;quot;&amp;quot;&lt;br /&gt;
	-- Create output by choosing method to suit options&lt;br /&gt;
	local output&lt;br /&gt;
	if hasOverlay then&lt;br /&gt;
		output = p.withOverlay(parent.args)&lt;br /&gt;
	elseif isMulti then&lt;br /&gt;
		output = p.multi(parent.args)&lt;br /&gt;
	else&lt;br /&gt;
		output = p._main(parent.args)&lt;br /&gt;
	end&lt;br /&gt;
	-- Preprocess output before returning it&lt;br /&gt;
	return frame:preprocess(output)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Entry points for modules&lt;br /&gt;
function p._main(_args)&lt;br /&gt;
	local args = util.trimArgs(_args)&lt;br /&gt;
&lt;br /&gt;
	local tagContent = make.content(args)&lt;br /&gt;
&lt;br /&gt;
	local display = mw.text.split(util.getParameterValue(args, &#039;display&#039;) or L10n.defaults.display, &#039;%s*&#039; .. L10n.str.dsep .. &#039;%s*&#039;)&lt;br /&gt;
	local displayInTitle = display[1] ==  L10n.str.title or display[2] ==  L10n.str.title&lt;br /&gt;
	local displayInline = display[1] ==  L10n.str.inline or display[2] ==  L10n.str.inline&lt;br /&gt;
&lt;br /&gt;
	local output&lt;br /&gt;
	if displayInTitle and displayInline then&lt;br /&gt;
		output = make.titleOutput(args, tagContent) .. make.inlineOutput(args, tagContent)&lt;br /&gt;
	elseif displayInTitle then&lt;br /&gt;
		output = make.titleOutput(args, tagContent)&lt;br /&gt;
	elseif displayInline then&lt;br /&gt;
		output = make.inlineOutput(args, tagContent)&lt;br /&gt;
	else&lt;br /&gt;
		error(L10n.error.badDisplayPara)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return output&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.multi(_args)&lt;br /&gt;
	local args = util.trimArgs(_args)&lt;br /&gt;
	if not args[L10n.para.switch] then error(L10n.error.noSwitchPara, 0) end&lt;br /&gt;
	local switchParamValue = util.getParameterValue(args, &#039;switch&#039;)&lt;br /&gt;
	local switchLabels = util.tableFromList(switchParamValue)&lt;br /&gt;
	if #switchLabels == 1 then error(L10n.error.oneSwitchLabel, 0) end&lt;br /&gt;
&lt;br /&gt;
	local mapframeArgs = {}&lt;br /&gt;
	local switchParams = {}&lt;br /&gt;
	for name, val in pairs(args) do&lt;br /&gt;
		-- Copy to mapframeArgs, if not the switch labels or a switch parameter&lt;br /&gt;
		if val ~= switchParamValue and not string.match(val, &amp;quot;^&amp;quot;..L10n.str.switch..&amp;quot;:&amp;quot;) then&lt;br /&gt;
			mapframeArgs[name] = val&lt;br /&gt;
		end&lt;br /&gt;
		-- Check if this is a param to switch. If so, store the name and switch&lt;br /&gt;
		-- values in switchParams table.&lt;br /&gt;
		local switchList = string.match(val, &amp;quot;^&amp;quot;..L10n.str.switch..&amp;quot;:(.+)&amp;quot;)&lt;br /&gt;
		if switchList ~= nil then&lt;br /&gt;
			local values = util.tableFromList(switchList)&lt;br /&gt;
			if #values == 1 then&lt;br /&gt;
				error(string.format(L10n.error.oneSwitchValue, name), 0)&lt;br /&gt;
			end&lt;br /&gt;
			switchParams[name] = values&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if util.tableCount(switchParams) == 0 then&lt;br /&gt;
		error(L10n.error.noSwitchLists, 0)&lt;br /&gt;
	end&lt;br /&gt;
	local switchCount = util.subTablesCount(switchParams)&lt;br /&gt;
	if not switchCount then&lt;br /&gt;
		error(L10n.error.switchMismatches, 0)&lt;br /&gt;
	elseif switchCount &amp;gt; #switchLabels then&lt;br /&gt;
		error(string.format(L10n.error.fewerSwitchLabels, switchCount, #switchLabels), 0)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Ensure a plain frame will be used (thumbnail will be built by the&lt;br /&gt;
	-- make.switcherHtml function if required, so that switcher options are&lt;br /&gt;
	-- inside the thumnail)&lt;br /&gt;
	mapframeArgs.plain = &amp;quot;yes&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	local switcher = {}&lt;br /&gt;
	for i = 1, switchCount do&lt;br /&gt;
		local label = switchLabels[i]&lt;br /&gt;
		for name, values in pairs(switchParams) do&lt;br /&gt;
			mapframeArgs[name] = values[i]&lt;br /&gt;
		end&lt;br /&gt;
		table.insert(switcher, {&lt;br /&gt;
			map = p._main(mapframeArgs),&lt;br /&gt;
			label = &amp;quot;Show &amp;quot;..label&lt;br /&gt;
		})&lt;br /&gt;
	end&lt;br /&gt;
	return make.switcherHtml(switcher, {&lt;br /&gt;
		alignment = args[&amp;quot;frame-align&amp;quot;] or &amp;quot;right&amp;quot;,&lt;br /&gt;
		isThumbnail = (args.frame and not args.plain) and true or false,&lt;br /&gt;
		width = args[&amp;quot;frame-width&amp;quot;] or L10n.defaults.frameWidth,&lt;br /&gt;
		caption = args.text&lt;br /&gt;
	})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.withOverlay(_args)&lt;br /&gt;
	-- Get and trim wikitext for overlay map&lt;br /&gt;
	local overlayMap = _args.overlay&lt;br /&gt;
	if type(overlayMap) == &#039;string&#039; then&lt;br /&gt;
		overlayMap = overlayMap:match(&#039;^%s*(.-)%s*$&#039;)&lt;br /&gt;
	end&lt;br /&gt;
	local isThumbnail = (util.getParameterValue(_args, &amp;quot;frame&amp;quot;) and not util.getParameterValue(_args, &amp;quot;plain&amp;quot;)) and true or false&lt;br /&gt;
	-- Get base map using the _main function, as a plain map&lt;br /&gt;
	local args = util.trimArgs(_args)&lt;br /&gt;
	args.plain = &amp;quot;yes&amp;quot;&lt;br /&gt;
	local basemap = p._main(args)&lt;br /&gt;
	-- Extract overlay options from args&lt;br /&gt;
	local overlayOptions = {&lt;br /&gt;
		width = util.getParameterValue(args, &amp;quot;frameWidth&amp;quot;) or L10n.defaults.frameWidth,&lt;br /&gt;
		height = util.getParameterValue(args, &amp;quot;frameHeight&amp;quot;) or L10n.defaults.frameHeight,&lt;br /&gt;
		align = util.getParameterValue(args, &amp;quot;frameAlign&amp;quot;) or L10n.defaults.frameAlign,&lt;br /&gt;
		border = util.getParameterValue(args, &amp;quot;overlayBorder&amp;quot;) or L10n.defaults.overlayBorder,&lt;br /&gt;
		horizontalAlignment = util.getParameterValue(args, &amp;quot;overlayHorizontalAlignment&amp;quot;) or L10n.defaults.overlayHorizontalAlignment,&lt;br /&gt;
		horizontalOffset = util.getParameterValue(args, &amp;quot;overlayHorizontalOffset&amp;quot;) or L10n.defaults.overlayHorizontalOffset,&lt;br /&gt;
		verticalAlignment = util.getParameterValue(args, &amp;quot;overlayVerticalAlignment&amp;quot;) or L10n.defaults.overlayVerticalAlignment,&lt;br /&gt;
		verticalOffset = util.getParameterValue(args, &amp;quot;overlayVerticalOffset&amp;quot;) or L10n.defaults.overlayVerticalOffset,&lt;br /&gt;
		isThumbnail = isThumbnail,&lt;br /&gt;
		caption = util.getParameterValue(args, &amp;quot;text&amp;quot;) or L10n.defaults.text&lt;br /&gt;
	}&lt;br /&gt;
	-- Make the HTML for the overlaying maps&lt;br /&gt;
	return make.overlayHtml(overlayMap, basemap, overlayOptions)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Entry point for testcase tests&lt;br /&gt;
p.test = util&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Module:WikidataIB&amp;diff=5318</id>
		<title>Module:WikidataIB</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Module:WikidataIB&amp;diff=5318"/>
		<updated>2026-06-15T12:50:03Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync shared ABC wiki compatibility fix from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- Version: 2023-07-10&lt;br /&gt;
-- Module to implement use of a blacklist and whitelist for infobox fields&lt;br /&gt;
-- Can take a named parameter |qid which is the Wikidata ID for the article&lt;br /&gt;
-- if not supplied, it will use the Wikidata ID associated with the current page.&lt;br /&gt;
-- Fields in blacklist are never to be displayed, i.e. module must return nil in all circumstances&lt;br /&gt;
-- Fields in whitelist return local value if it exists or the Wikidata value otherwise&lt;br /&gt;
-- The name of the field that this function is called from is passed in named parameter |name&lt;br /&gt;
-- The name is compulsory when blacklist or whitelist is used,&lt;br /&gt;
-- so the module returns nil if it is not supplied.&lt;br /&gt;
-- blacklist is passed in named parameter |suppressfields (or |spf)&lt;br /&gt;
-- whitelist is passed in named parameter |fetchwikidata (or |fwd)&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;strict&amp;quot;)&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local cdate -- initialise as nil and only load _complex_date function if needed&lt;br /&gt;
-- Module:Complex date is loaded lazily and has the following dependencies:&lt;br /&gt;
-- Module:Calendar&lt;br /&gt;
-- Module:ISOdate&lt;br /&gt;
-- Module:DateI18n&lt;br /&gt;
-- Module:I18n/complex date&lt;br /&gt;
-- Module:Ordinal&lt;br /&gt;
-- Module:I18n/ordinal&lt;br /&gt;
-- Module:Yesno&lt;br /&gt;
-- Module:Formatnum&lt;br /&gt;
-- Module:Linguistic&lt;br /&gt;
--&lt;br /&gt;
-- The following, taken from https://www.mediawiki.org/wiki/Wikibase/DataModel#Dates_and_times,&lt;br /&gt;
-- is needed to use Module:Complex date which seemingly requires date precision as a string.&lt;br /&gt;
-- It would work better if only the authors of the mediawiki page could spell &#039;millennium&#039;.&lt;br /&gt;
local dp = {&lt;br /&gt;
	[6] = &amp;quot;millennium&amp;quot;,&lt;br /&gt;
	[7] = &amp;quot;century&amp;quot;,&lt;br /&gt;
	[8] = &amp;quot;decade&amp;quot;,&lt;br /&gt;
	[9] = &amp;quot;year&amp;quot;,&lt;br /&gt;
	[10] = &amp;quot;month&amp;quot;,&lt;br /&gt;
	[11] = &amp;quot;day&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local i18n =&lt;br /&gt;
{&lt;br /&gt;
	[&amp;quot;errors&amp;quot;] =&lt;br /&gt;
	{&lt;br /&gt;
		[&amp;quot;property-not-found&amp;quot;] = &amp;quot;Property not found.&amp;quot;,&lt;br /&gt;
		[&amp;quot;No property supplied&amp;quot;] = &amp;quot;No property supplied&amp;quot;,&lt;br /&gt;
		[&amp;quot;entity-not-found&amp;quot;] = &amp;quot;Wikidata entity not found.&amp;quot;,&lt;br /&gt;
		[&amp;quot;unknown-claim-type&amp;quot;] = &amp;quot;Unknown claim type.&amp;quot;,&lt;br /&gt;
		[&amp;quot;unknown-entity-type&amp;quot;] = &amp;quot;Unknown entity type.&amp;quot;,&lt;br /&gt;
		[&amp;quot;qualifier-not-found&amp;quot;] = &amp;quot;Qualifier not found.&amp;quot;,&lt;br /&gt;
		[&amp;quot;site-not-found&amp;quot;] = &amp;quot;Wikimedia project not found.&amp;quot;,&lt;br /&gt;
		[&amp;quot;labels-not-found&amp;quot;] = &amp;quot;No labels found.&amp;quot;,&lt;br /&gt;
		[&amp;quot;descriptions-not-found&amp;quot;] = &amp;quot;No descriptions found.&amp;quot;,&lt;br /&gt;
		[&amp;quot;aliases-not-found&amp;quot;] = &amp;quot;No aliases found.&amp;quot;,&lt;br /&gt;
		[&amp;quot;unknown-datetime-format&amp;quot;] = &amp;quot;Unknown datetime format.&amp;quot;,&lt;br /&gt;
		[&amp;quot;local-article-not-found&amp;quot;] = &amp;quot;Article is available on Wikidata, but not on Wikipedia&amp;quot;,&lt;br /&gt;
		[&amp;quot;dab-page&amp;quot;] = &amp;quot; (dab)&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	[&amp;quot;months&amp;quot;] =&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;January&amp;quot;, &amp;quot;February&amp;quot;, &amp;quot;March&amp;quot;, &amp;quot;April&amp;quot;, &amp;quot;May&amp;quot;, &amp;quot;June&amp;quot;,&lt;br /&gt;
		&amp;quot;July&amp;quot;, &amp;quot;August&amp;quot;, &amp;quot;September&amp;quot;, &amp;quot;October&amp;quot;, &amp;quot;November&amp;quot;, &amp;quot;December&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
	[&amp;quot;century&amp;quot;] = &amp;quot;century&amp;quot;,&lt;br /&gt;
	[&amp;quot;BC&amp;quot;] = &amp;quot;BC&amp;quot;,&lt;br /&gt;
	[&amp;quot;BCE&amp;quot;] = &amp;quot;BCE&amp;quot;,&lt;br /&gt;
	[&amp;quot;ordinal&amp;quot;] =&lt;br /&gt;
	{&lt;br /&gt;
		[1] = &amp;quot;st&amp;quot;,&lt;br /&gt;
		[2] = &amp;quot;nd&amp;quot;,&lt;br /&gt;
		[3] = &amp;quot;rd&amp;quot;,&lt;br /&gt;
		[&amp;quot;default&amp;quot;] = &amp;quot;th&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
	[&amp;quot;filespace&amp;quot;] = &amp;quot;File&amp;quot;,&lt;br /&gt;
	[&amp;quot;Unknown&amp;quot;] = &amp;quot;Unknown&amp;quot;,&lt;br /&gt;
	[&amp;quot;NaN&amp;quot;] = &amp;quot;Not a number&amp;quot;,&lt;br /&gt;
	-- set the following to the name of a tracking category,&lt;br /&gt;
	-- e.g. &amp;quot;[[Category:Articles with missing Wikidata information]]&amp;quot;, or &amp;quot;&amp;quot; to disable:&lt;br /&gt;
	[&amp;quot;missinginfocat&amp;quot;] = &amp;quot;[[Category:Articles with missing Wikidata information]]&amp;quot;,&lt;br /&gt;
	[&amp;quot;editonwikidata&amp;quot;] = &amp;quot;Edit this on Wikidata&amp;quot;,&lt;br /&gt;
	[&amp;quot;latestdatequalifier&amp;quot;] = function (date) return &amp;quot;before &amp;quot; .. date end,&lt;br /&gt;
	-- some languages, e.g. Bosnian use a period as a suffix after each number in a date&lt;br /&gt;
	[&amp;quot;datenumbersuffix&amp;quot;] = &amp;quot;&amp;quot;,&lt;br /&gt;
	[&amp;quot;list separator&amp;quot;] = &amp;quot;, &amp;quot;,&lt;br /&gt;
	[&amp;quot;multipliers&amp;quot;] = {&lt;br /&gt;
		[0]  = &amp;quot;&amp;quot;,&lt;br /&gt;
		[3]  = &amp;quot; thousand&amp;quot;,&lt;br /&gt;
		[6]  = &amp;quot; million&amp;quot;,&lt;br /&gt;
		[9]  = &amp;quot; billion&amp;quot;,&lt;br /&gt;
		[12] = &amp;quot; trillion&amp;quot;,&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
-- This allows an internationisation module to override the above table&lt;br /&gt;
if &#039;en&#039; ~= mw.getContentLanguage():getCode() then&lt;br /&gt;
	require(&amp;quot;Module:i18n&amp;quot;).loadI18n(&amp;quot;Module:WikidataIB/i18n&amp;quot;, i18n)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- This piece of html implements a collapsible container. Check the classes exist on your wiki.&lt;br /&gt;
local collapsediv = &#039;&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; style=&amp;quot;width:100%; overflow:auto;&amp;quot; data-expandtext=&amp;quot;{{int:show}}&amp;quot; data-collapsetext=&amp;quot;{{int:hide}}&amp;quot;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
-- Some items should not be linked.&lt;br /&gt;
-- Each wiki can create a list of those in Module:WikidataIB/nolinks&lt;br /&gt;
-- It should return a table called itemsindex, containing true for each item not to be linked&lt;br /&gt;
local donotlink = {}&lt;br /&gt;
local nolinks_exists, nolinks = pcall(mw.loadData, &amp;quot;Module:WikidataIB/nolinks&amp;quot;)&lt;br /&gt;
if nolinks_exists then&lt;br /&gt;
	donotlink = nolinks.itemsindex&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- To satisfy Wikipedia:Manual of Style/Titles, certain types of items are italicised, and others are quoted.&lt;br /&gt;
-- The submodule [[Module:WikidataIB/titleformats]] lists the entity-ids used in &#039;instance of&#039; (P31),&lt;br /&gt;
-- which allows this module to identify the values that should be formatted.&lt;br /&gt;
-- WikidataIB/titleformats exports a table p.formats, which is indexed by entity-id, and contains the value &amp;quot; or &#039;&#039;&lt;br /&gt;
local formats = {}&lt;br /&gt;
local titleformats_exists, titleformats = pcall(mw.loadData, &amp;quot;Module:WikidataIB/titleformats&amp;quot;)&lt;br /&gt;
if titleformats_exists then&lt;br /&gt;
	formats = titleformats.formats&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Private functions&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
--&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- makeOrdinal needs to be internationalised along with the above:&lt;br /&gt;
-- takes cardinal number as a numeric and returns the ordinal as a string&lt;br /&gt;
-- we need three exceptions in English for 1st, 2nd, 3rd, 21st, .. 31st, etc.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local makeOrdinal = function(cardinal)&lt;br /&gt;
	local ordsuffix = i18n.ordinal.default&lt;br /&gt;
	if cardinal % 10 == 1 then&lt;br /&gt;
		ordsuffix = i18n.ordinal[1]&lt;br /&gt;
	elseif cardinal % 10 == 2 then&lt;br /&gt;
		ordsuffix = i18n.ordinal[2]&lt;br /&gt;
	elseif cardinal % 10 == 3 then&lt;br /&gt;
		ordsuffix = i18n.ordinal[3]&lt;br /&gt;
	end&lt;br /&gt;
	-- In English, 1, 21, 31, etc. use &#039;st&#039;, but 11, 111, etc. use &#039;th&#039;&lt;br /&gt;
	-- similarly for 12 and 13, etc.&lt;br /&gt;
	if (cardinal % 100 == 11) or (cardinal % 100 == 12) or (cardinal % 100 == 13) then&lt;br /&gt;
		ordsuffix = i18n.ordinal.default&lt;br /&gt;
	end&lt;br /&gt;
	return tostring(cardinal) .. ordsuffix&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- findLang takes a &amp;quot;langcode&amp;quot; parameter if supplied and valid&lt;br /&gt;
-- otherwise it tries to create it from the user&#039;s set language ({{int:lang}})&lt;br /&gt;
-- failing that it uses the wiki&#039;s content language.&lt;br /&gt;
-- It returns a language object&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local findLang = function(langcode)&lt;br /&gt;
	local langobj&lt;br /&gt;
	langcode = mw.text.trim(langcode or &amp;quot;&amp;quot;)&lt;br /&gt;
	if mw.language.isKnownLanguageTag(langcode) then&lt;br /&gt;
		langobj = mw.language.new( langcode )&lt;br /&gt;
	else&lt;br /&gt;
		langcode = mw.getCurrentFrame():callParserFunction(&#039;int&#039;, {&#039;lang&#039;})&lt;br /&gt;
		if mw.language.isKnownLanguageTag(langcode) then&lt;br /&gt;
			langobj = mw.language.new( langcode )&lt;br /&gt;
		else&lt;br /&gt;
			langobj = mw.language.getContentLanguage()&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return langobj&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- _getItemLangCode takes a qid parameter (using the current page&#039;s qid if blank)&lt;br /&gt;
-- If the item for that qid has property country (P17) it looks at the first preferred value&lt;br /&gt;
-- If the country has an official language (P37), it looks at the first preferred value&lt;br /&gt;
-- If that official language has a language code (P424), it returns the first preferred value&lt;br /&gt;
-- Otherwise it returns nothing.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local _getItemLangCode = function(qid)&lt;br /&gt;
	qid = mw.text.trim(qid or &amp;quot;&amp;quot;):upper()&lt;br /&gt;
	if qid == &amp;quot;&amp;quot; then qid = mw.wikibase.getEntityIdForCurrentPage() end&lt;br /&gt;
	if not qid then return end&lt;br /&gt;
	local prop17 = mw.wikibase.getBestStatements(qid, &amp;quot;P17&amp;quot;)[1]&lt;br /&gt;
	if not prop17 or prop17.mainsnak.snaktype ~= &amp;quot;value&amp;quot; then return end&lt;br /&gt;
	local qid17 = prop17.mainsnak.datavalue.value.id&lt;br /&gt;
	local prop37 = mw.wikibase.getBestStatements(qid17, &amp;quot;P37&amp;quot;)[1]&lt;br /&gt;
	if not prop37 or prop37.mainsnak.snaktype ~= &amp;quot;value&amp;quot; then return end&lt;br /&gt;
	local qid37 = prop37.mainsnak.datavalue.value.id&lt;br /&gt;
	local prop424 = mw.wikibase.getBestStatements(qid37, &amp;quot;P424&amp;quot;)[1]&lt;br /&gt;
	if not prop424 or prop424.mainsnak.snaktype ~= &amp;quot;value&amp;quot; then return end&lt;br /&gt;
	return prop424.mainsnak.datavalue.value&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- roundto takes a number (x)&lt;br /&gt;
-- and returns it rounded to (sf) significant figures&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local roundto = function(x, sf)&lt;br /&gt;
	if x == 0 then return 0 end&lt;br /&gt;
	local s = 1&lt;br /&gt;
	if x &amp;lt; 0 then&lt;br /&gt;
		x = -x&lt;br /&gt;
		s = -1&lt;br /&gt;
	end&lt;br /&gt;
	if sf &amp;lt; 1 then sf = 1 end&lt;br /&gt;
	local p = 10 ^ (math.floor(math.log10(x)) - sf + 1)&lt;br /&gt;
	x = math.floor(x / p + 0.5) * p * s&lt;br /&gt;
	-- if it&#039;s integral, cast to an integer:&lt;br /&gt;
	if x == math.floor(x) then x = math.floor(x) end&lt;br /&gt;
	return x&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- decimalToDMS takes a decimal degrees (x) with precision (p)&lt;br /&gt;
-- and returns degrees/minutes/seconds according to the precision&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local decimalToDMS = function(x, p)&lt;br /&gt;
	-- if p is not supplied, use a precision around 0.1 seconds&lt;br /&gt;
	if not tonumber(p) then p = 1e-4 end&lt;br /&gt;
	local d = math.floor(x)&lt;br /&gt;
	local ms = (x - d) * 60&lt;br /&gt;
	if p &amp;gt; 0.5 then -- precision is &amp;gt; 1/2 a degree&lt;br /&gt;
		if ms &amp;gt; 30 then d = d + 1 end&lt;br /&gt;
		ms = 0&lt;br /&gt;
	end&lt;br /&gt;
	local m = math.floor(ms)&lt;br /&gt;
	local s = (ms - m) * 60&lt;br /&gt;
	if p &amp;gt; 0.008 then -- precision is &amp;gt; 1/2 a minute&lt;br /&gt;
		if s &amp;gt; 30 then m = m +1 end&lt;br /&gt;
		s = 0&lt;br /&gt;
	elseif p &amp;gt; 0.00014 then -- precision is &amp;gt; 1/2 a second&lt;br /&gt;
		s = math.floor(s + 0.5)&lt;br /&gt;
	elseif p &amp;gt; 0.000014 then -- precision is &amp;gt; 1/20 second&lt;br /&gt;
		s = math.floor(10 * s + 0.5) / 10&lt;br /&gt;
	elseif p &amp;gt; 0.0000014 then -- precision is &amp;gt; 1/200 second&lt;br /&gt;
		s = math.floor(100 * s + 0.5) / 100&lt;br /&gt;
	else -- cap it at 3 dec places for now&lt;br /&gt;
		s = math.floor(1000 * s + 0.5) / 1000&lt;br /&gt;
	end&lt;br /&gt;
	return d, m, s&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- decimalPrecision takes a decimal (x) with precision (p)&lt;br /&gt;
-- and returns x rounded approximately to the given precision&lt;br /&gt;
-- precision should be between 1 and 1e-6, preferably a power of 10.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local decimalPrecision = function(x, p)&lt;br /&gt;
	local s = 1&lt;br /&gt;
	if x &amp;lt; 0 then&lt;br /&gt;
		x = -x&lt;br /&gt;
		s = -1&lt;br /&gt;
	end&lt;br /&gt;
	-- if p is not supplied, pick an arbitrary precision&lt;br /&gt;
	if not tonumber(p) then p = 1e-4&lt;br /&gt;
	elseif p &amp;gt; 1 then p = 1&lt;br /&gt;
	elseif p &amp;lt; 1e-6 then p = 1e-6&lt;br /&gt;
	else p = 10 ^ math.floor(math.log10(p))&lt;br /&gt;
	end&lt;br /&gt;
	x = math.floor(x / p + 0.5) * p * s&lt;br /&gt;
	-- if it&#039;s integral, cast to an integer:&lt;br /&gt;
	if  x == math.floor(x) then x = math.floor(x) end&lt;br /&gt;
	-- if it&#039;s less than 1e-4, it will be in exponent form, so return a string with 6dp&lt;br /&gt;
	-- 9e-5 becomes 0.000090&lt;br /&gt;
	if math.abs(x) &amp;lt; 1e-4 then x = string.format(&amp;quot;%f&amp;quot;, x) end&lt;br /&gt;
	return x&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- formatDate takes a datetime of the usual format from mw.wikibase.entity:formatPropertyValues&lt;br /&gt;
-- like &amp;quot;1 August 30 BCE&amp;quot; as parameter 1&lt;br /&gt;
-- and formats it according to the df (date format) and bc parameters&lt;br /&gt;
-- df = [&amp;quot;dmy&amp;quot; / &amp;quot;mdy&amp;quot; / &amp;quot;y&amp;quot;] default will be &amp;quot;dmy&amp;quot;&lt;br /&gt;
-- bc = [&amp;quot;BC&amp;quot; / &amp;quot;BCE&amp;quot;] default will be &amp;quot;BCE&amp;quot;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local format_Date = function(datetime, dateformat, bc)&lt;br /&gt;
	local datetime = datetime or &amp;quot;1 August 30 BCE&amp;quot; -- in case of nil value&lt;br /&gt;
	-- chop off multiple vales and/or any hours, mins, etc.&lt;br /&gt;
	-- keep anything before punctuation - we just want a single date:&lt;br /&gt;
	local dateval = string.match( datetime, &amp;quot;[%w ]+&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	local dateformat = string.lower(dateformat or &amp;quot;dmy&amp;quot;) -- default to dmy&lt;br /&gt;
&lt;br /&gt;
	local bc = string.upper(bc or &amp;quot;&amp;quot;) -- can&#039;t use nil for bc&lt;br /&gt;
	-- we only want to accept two possibilities: BC or default to BCE&lt;br /&gt;
	if bc == &amp;quot;BC&amp;quot; then&lt;br /&gt;
		bc = &amp;quot;&amp;amp;nbsp;&amp;quot; .. i18n[&amp;quot;BC&amp;quot;] -- prepend a non-breaking space.&lt;br /&gt;
	else&lt;br /&gt;
		bc = &amp;quot;&amp;amp;nbsp;&amp;quot; .. i18n[&amp;quot;BCE&amp;quot;]&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local postchrist = true -- start by assuming no BCE&lt;br /&gt;
	local dateparts = {}&lt;br /&gt;
	for word in string.gmatch(dateval, &amp;quot;%w+&amp;quot;) do&lt;br /&gt;
		if word == &amp;quot;BCE&amp;quot; or word == &amp;quot;BC&amp;quot; then -- *** internationalise later ***&lt;br /&gt;
			postchrist = false&lt;br /&gt;
		else&lt;br /&gt;
			-- we&#039;ll keep the parts that are not &#039;BCE&#039; in a table&lt;br /&gt;
			dateparts[#dateparts + 1] = word&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if postchrist then bc = &amp;quot;&amp;quot; end -- set AD dates to no suffix *** internationalise later ***&lt;br /&gt;
&lt;br /&gt;
	local sep = &amp;quot;&amp;amp;nbsp;&amp;quot; -- separator is nbsp&lt;br /&gt;
	local fdate = table.concat(dateparts, sep) -- set formatted date to same order as input&lt;br /&gt;
&lt;br /&gt;
	-- if we have day month year, check dateformat&lt;br /&gt;
	if #dateparts == 3 then&lt;br /&gt;
		if dateformat == &amp;quot;y&amp;quot; then&lt;br /&gt;
			fdate = dateparts[3]&lt;br /&gt;
		elseif dateformat == &amp;quot;mdy&amp;quot; then&lt;br /&gt;
			fdate = dateparts[2] .. sep .. dateparts[1] .. &amp;quot;,&amp;quot; .. sep .. dateparts[3]&lt;br /&gt;
		end&lt;br /&gt;
	elseif #dateparts == 2 and dateformat == &amp;quot;y&amp;quot; then&lt;br /&gt;
		fdate = dateparts[2]&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return fdate .. bc&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- dateFormat is the handler for properties that are of type &amp;quot;time&amp;quot;&lt;br /&gt;
-- It takes timestamp, precision (6 to 11 per mediawiki), dateformat (y/dmy/mdy), BC format (BC/BCE),&lt;br /&gt;
-- a plaindate switch (yes/no/adj) to en/disable &amp;quot;sourcing circumstances&amp;quot;/use adjectival form,&lt;br /&gt;
-- any qualifiers for the property, the language, and any adjective to use like &#039;before&#039;.&lt;br /&gt;
-- It passes the date through the &amp;quot;complex date&amp;quot; function&lt;br /&gt;
-- and returns a string with the internatonalised date formatted according to preferences.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: findLang(); cdate(); dp[]&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local dateFormat = function(timestamp, dprec, df, bcf, pd, qualifiers, lang, adj, model)&lt;br /&gt;
	-- output formatting according to preferences (y/dmy/mdy/ymd)&lt;br /&gt;
	df = (df or &amp;quot;&amp;quot;):lower()&lt;br /&gt;
	-- if ymd is required, return the part of the timestamp in YYYY-MM-DD form&lt;br /&gt;
	-- but apply Year zero#Astronomers fix: 1 BC = 0000; 2 BC = -0001; etc.&lt;br /&gt;
	if df == &amp;quot;ymd&amp;quot; then&lt;br /&gt;
		if timestamp:sub(1,1) == &amp;quot;+&amp;quot; then&lt;br /&gt;
			return timestamp:sub(2,11)&lt;br /&gt;
		else&lt;br /&gt;
			local yr = tonumber(timestamp:sub(2,5)) - 1&lt;br /&gt;
			yr = (&amp;quot;000&amp;quot; .. yr):sub(-4)&lt;br /&gt;
			if yr ~= &amp;quot;0000&amp;quot; then yr = &amp;quot;-&amp;quot; .. yr end&lt;br /&gt;
			return yr .. timestamp:sub(6,11)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	-- A year can be stored like this: &amp;quot;+1872-00-00T00:00:00Z&amp;quot;,&lt;br /&gt;
	-- which is processed here as if it were the day before &amp;quot;+1872-01-01T00:00:00Z&amp;quot;,&lt;br /&gt;
	-- and that&#039;s the last day of 1871, so the year is wrong.&lt;br /&gt;
	-- So fix the month 0, day 0 timestamp to become 1 January instead:&lt;br /&gt;
	timestamp = timestamp:gsub(&amp;quot;%-00%-00T&amp;quot;, &amp;quot;-01-01T&amp;quot;)&lt;br /&gt;
	-- just in case date precision is missing&lt;br /&gt;
	dprec = dprec or 11&lt;br /&gt;
	-- override more precise dates if required dateformat is year alone:&lt;br /&gt;
	if df == &amp;quot;y&amp;quot; and dprec &amp;gt; 9 then dprec = 9 end&lt;br /&gt;
	-- complex date only deals with precisions from 6 to 11, so clip range&lt;br /&gt;
	dprec = dprec&amp;gt;11 and 11 or dprec&lt;br /&gt;
	dprec = dprec&amp;lt;6 and 6 or dprec&lt;br /&gt;
	-- BC format is &amp;quot;BC&amp;quot; or &amp;quot;BCE&amp;quot;&lt;br /&gt;
	bcf = (bcf or &amp;quot;&amp;quot;):upper()&lt;br /&gt;
	-- plaindate only needs the first letter (y/n/a)&lt;br /&gt;
	pd = (pd or &amp;quot;&amp;quot;):sub(1,1):lower()&lt;br /&gt;
	if pd == &amp;quot;&amp;quot; or pd == &amp;quot;n&amp;quot; or pd == &amp;quot;f&amp;quot; or pd == &amp;quot;0&amp;quot; then pd = false end&lt;br /&gt;
	-- in case language isn&#039;t passed&lt;br /&gt;
	lang = lang or findLang().code&lt;br /&gt;
	-- set adj as empty if nil&lt;br /&gt;
	adj = adj or &amp;quot;&amp;quot;&lt;br /&gt;
	-- extract the day, month, year from the timestamp&lt;br /&gt;
	local bc = timestamp:sub(1, 1)==&amp;quot;-&amp;quot; and &amp;quot;BC&amp;quot; or &amp;quot;&amp;quot;&lt;br /&gt;
	local year, month, day = timestamp:match(&amp;quot;[+-](%d*)-(%d*)-(%d*)T&amp;quot;)&lt;br /&gt;
	local iso = tonumber(year) -- if year is missing, let it throw an error&lt;br /&gt;
	-- this will adjust the date format to be compatible with cdate&lt;br /&gt;
	-- possible formats are Y, YY, YYY0, YYYY, YYYY-MM, YYYY-MM-DD&lt;br /&gt;
	if dprec == 6 then iso = math.floor( (iso - 1) / 1000 ) + 1 end&lt;br /&gt;
	if dprec == 7 then iso = math.floor( (iso - 1) / 100 ) + 1 end&lt;br /&gt;
	if dprec == 8 then iso = math.floor( iso / 10 ) .. &amp;quot;0&amp;quot; end&lt;br /&gt;
	if dprec == 10 then iso = year .. &amp;quot;-&amp;quot; .. month end&lt;br /&gt;
	if dprec == 11 then iso = year .. &amp;quot;-&amp;quot; .. month .. &amp;quot;-&amp;quot; .. day end&lt;br /&gt;
	-- add &amp;quot;circa&amp;quot; (Q5727902) from &amp;quot;sourcing circumstances&amp;quot; (P1480)&lt;br /&gt;
	local sc = not pd and qualifiers and qualifiers.P1480&lt;br /&gt;
	if sc then&lt;br /&gt;
		for k1, v1 in pairs(sc) do&lt;br /&gt;
			if v1.datavalue and v1.datavalue.value.id == &amp;quot;Q5727902&amp;quot; then&lt;br /&gt;
				adj = &amp;quot;circa&amp;quot;&lt;br /&gt;
				break&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	-- deal with Julian dates:&lt;br /&gt;
	-- no point in saying that dates before 1582 are Julian - they are by default&lt;br /&gt;
	-- doesn&#039;t make sense for dates less precise than year&lt;br /&gt;
	-- we can suppress it by setting |plaindate, e.g. for use in constructing categories.&lt;br /&gt;
	local calendarmodel = &amp;quot;&amp;quot;&lt;br /&gt;
	if tonumber(year) &amp;gt; 1582&lt;br /&gt;
		and dprec &amp;gt; 8&lt;br /&gt;
		and not pd&lt;br /&gt;
		and model == &amp;quot;http://www.wikidata.org/entity/Q1985786&amp;quot; then&lt;br /&gt;
		calendarmodel = &amp;quot;julian&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	if not cdate then&lt;br /&gt;
		cdate = require(&amp;quot;Module:Complex date&amp;quot;)._complex_date&lt;br /&gt;
	end&lt;br /&gt;
	local fdate = cdate(calendarmodel, adj, tostring(iso), dp[dprec], bc, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;, lang, 1)&lt;br /&gt;
	-- this may have QuickStatements info appended to it in a div, so remove that&lt;br /&gt;
	fdate = fdate:gsub(&#039; &amp;lt;div style=&amp;quot;display: none;&amp;quot;&amp;gt;[^&amp;lt;]*&amp;lt;/div&amp;gt;&#039;, &#039;&#039;)&lt;br /&gt;
	-- it may also be returned wrapped in a microformat, so remove that&lt;br /&gt;
	fdate = fdate:gsub(&amp;quot;&amp;lt;[^&amp;gt;]*&amp;gt;&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
	-- there may be leading zeros that we should remove&lt;br /&gt;
	fdate = fdate:gsub(&amp;quot;^0*&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
	-- if a plain date is required, then remove any links (like BC linked)&lt;br /&gt;
	if pd then&lt;br /&gt;
		fdate = fdate:gsub(&amp;quot;%[%[.*|&amp;quot;, &amp;quot;&amp;quot;):gsub(&amp;quot;]]&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	-- if &#039;circa&#039;, use the abbreviated form *** internationalise later ***&lt;br /&gt;
	fdate = fdate:gsub(&#039;circa &#039;, &#039;&amp;lt;abbr title=&amp;quot;circa&amp;quot;&amp;gt;c.&amp;lt;/abbr&amp;gt;&amp;amp;nbsp;&#039;)&lt;br /&gt;
	-- deal with BC/BCE&lt;br /&gt;
	if bcf == &amp;quot;BCE&amp;quot; then&lt;br /&gt;
		fdate = fdate:gsub(&#039;BC&#039;, &#039;BCE&#039;)&lt;br /&gt;
	end&lt;br /&gt;
	-- deal with mdy format&lt;br /&gt;
	if df == &amp;quot;mdy&amp;quot; then&lt;br /&gt;
		fdate = fdate:gsub(&amp;quot;(%d+) (%w+) (%d+)&amp;quot;, &amp;quot;%2 %1, %3&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	-- deal with adjectival form *** internationalise later ***&lt;br /&gt;
	if pd == &amp;quot;a&amp;quot; then&lt;br /&gt;
		fdate = fdate:gsub(&#039; century&#039;, &#039;-century&#039;)&lt;br /&gt;
	end&lt;br /&gt;
	return fdate&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- parseParam takes a (string) parameter, e.g. from the list of frame arguments,&lt;br /&gt;
-- and makes &amp;quot;false&amp;quot;, &amp;quot;no&amp;quot;, and &amp;quot;0&amp;quot; into the (boolean) false&lt;br /&gt;
-- it makes the empty string and nil into the (boolean) value passed as default&lt;br /&gt;
-- allowing the parameter to be true or false by default.&lt;br /&gt;
-- It returns a boolean.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local parseParam = function(param, default)&lt;br /&gt;
	if type(param) == &amp;quot;boolean&amp;quot; then param = tostring(param) end&lt;br /&gt;
	if param and param ~= &amp;quot;&amp;quot; then&lt;br /&gt;
		param = param:lower()&lt;br /&gt;
		if (param == &amp;quot;false&amp;quot;) or (param:sub(1,1) == &amp;quot;n&amp;quot;) or (param == &amp;quot;0&amp;quot;) then&lt;br /&gt;
			return false&lt;br /&gt;
		else&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		return default&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- _getSitelink takes the qid of a Wikidata entity passed as |qid=&lt;br /&gt;
-- It takes an optional parameter |wiki= to determine which wiki is to be checked for a sitelink&lt;br /&gt;
-- If the parameter is blank, then it uses the local wiki.&lt;br /&gt;
-- If there is a sitelink to an article available, it returns the plain text link to the article&lt;br /&gt;
-- If there is no sitelink, it returns nil.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local _getSitelink = function(qid, wiki)&lt;br /&gt;
	qid = (qid or &amp;quot;&amp;quot;):upper()&lt;br /&gt;
	if qid == &amp;quot;&amp;quot; then qid = (mw.wikibase and mw.wikibase.getEntityIdForCurrentPage and mw.wikibase.getEntityIdForCurrentPage()) end&lt;br /&gt;
	if not qid or not mw.wikibase then return nil end&lt;br /&gt;
	wiki = wiki or &amp;quot;&amp;quot;&lt;br /&gt;
	local sitelink&lt;br /&gt;
	if wiki == &amp;quot;&amp;quot; then&lt;br /&gt;
		sitelink = mw.wikibase.getSitelink(qid)&lt;br /&gt;
	else&lt;br /&gt;
		sitelink = mw.wikibase.getSitelink(qid, wiki)&lt;br /&gt;
	end&lt;br /&gt;
	return sitelink&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- _getCommonslink takes an optional qid of a Wikidata entity passed as |qid=&lt;br /&gt;
-- It returns one of the following in order of preference:&lt;br /&gt;
-- 	the Commons sitelink of the Wikidata entity - but not if onlycat=true and it&#039;s not a category;&lt;br /&gt;
-- 	the Commons sitelink of the topic&#039;s main category of the Wikidata entity;&lt;br /&gt;
-- 	the Commons category of the Wikidata entity - unless fallback=false.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: _getSitelink(); parseParam()&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local _getCommonslink = function(qid, onlycat, fallback)&lt;br /&gt;
	qid = (qid or &amp;quot;&amp;quot;):upper()&lt;br /&gt;
	if qid == &amp;quot;&amp;quot; then&lt;br /&gt;
		qid = (mw.wikibase and mw.wikibase.getEntityIdForCurrentPage and mw.wikibase.getEntityIdForCurrentPage()) or nil&lt;br /&gt;
	end&lt;br /&gt;
	if not qid or not mw.wikibase then return nil end&lt;br /&gt;
	onlycat = parseParam(onlycat, false)&lt;br /&gt;
	if fallback == &amp;quot;&amp;quot; then fallback = nil end&lt;br /&gt;
	local sitelink = _getSitelink(qid, &amp;quot;commonswiki&amp;quot;)&lt;br /&gt;
	if onlycat and sitelink and sitelink:sub(1,9) ~= &amp;quot;Category:&amp;quot; then sitelink = nil end&lt;br /&gt;
	if not sitelink then&lt;br /&gt;
		-- check for topic&#039;s main category&lt;br /&gt;
		local prop910 = mw.wikibase.getBestStatements(qid, &amp;quot;P910&amp;quot;)[1]&lt;br /&gt;
		if prop910 then&lt;br /&gt;
			local tmcid = prop910.mainsnak.datavalue and prop910.mainsnak.datavalue.value.id&lt;br /&gt;
			sitelink = _getSitelink(tmcid, &amp;quot;commonswiki&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
		if not sitelink then&lt;br /&gt;
			-- check for list&#039;s main category&lt;br /&gt;
			local prop1754 = mw.wikibase.getBestStatements(qid, &amp;quot;P1754&amp;quot;)[1]&lt;br /&gt;
			if prop1754 then&lt;br /&gt;
				local tmcid = prop1754.mainsnak.datavalue and prop1754.mainsnak.datavalue.value.id&lt;br /&gt;
				sitelink = _getSitelink(tmcid, &amp;quot;commonswiki&amp;quot;)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if not sitelink and fallback then&lt;br /&gt;
		-- check for Commons category (string value)&lt;br /&gt;
		local prop373 = mw.wikibase.getBestStatements(qid, &amp;quot;P373&amp;quot;)[1]&lt;br /&gt;
		if prop373 then&lt;br /&gt;
			sitelink = prop373.mainsnak.datavalue and prop373.mainsnak.datavalue.value&lt;br /&gt;
			if sitelink then sitelink = &amp;quot;Category:&amp;quot; .. sitelink end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return sitelink&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- The label in a Wikidata item is subject to vulnerabilities&lt;br /&gt;
-- that an attacker might try to exploit.&lt;br /&gt;
-- It needs to be &#039;sanitised&#039; by removing any wikitext before use.&lt;br /&gt;
-- If it doesn&#039;t exist, return the id for the item&lt;br /&gt;
-- a second (boolean) value is also returned, value is true when the label exists&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local labelOrId = function(id, lang)&lt;br /&gt;
	if lang == &amp;quot;default&amp;quot; then lang = findLang().code end&lt;br /&gt;
	local label&lt;br /&gt;
	if lang then&lt;br /&gt;
		label = mw.wikibase.getLabelByLang(id, lang)&lt;br /&gt;
	else&lt;br /&gt;
		label = mw.wikibase.getLabel(id)&lt;br /&gt;
	end&lt;br /&gt;
	if label then&lt;br /&gt;
		return mw.text.nowiki(label), true&lt;br /&gt;
	else&lt;br /&gt;
		return id, false&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- linkedItem takes an entity-id and returns a string, linked if possible.&lt;br /&gt;
-- This is the handler for &amp;quot;wikibase-item&amp;quot;. Preferences:&lt;br /&gt;
-- 1. Display linked disambiguated sitelink if it exists&lt;br /&gt;
-- 2. Display linked label if it is a redirect&lt;br /&gt;
-- 3. TBA: Display an inter-language link for the label if it exists other than in default language&lt;br /&gt;
-- 4. Display unlinked label if it exists&lt;br /&gt;
-- 5. Display entity-id for now to indicate a label could be provided&lt;br /&gt;
-- dtxt is text to be used instead of label, or nil.&lt;br /&gt;
-- shortname is boolean switch to use P1813 (short name) instead of label if true.&lt;br /&gt;
-- lang is the current language code.&lt;br /&gt;
-- uselbl is boolean switch to force display of the label instead of the sitelink (default: false)&lt;br /&gt;
-- linkredir is boolean switch to allow linking to a redirect (default: false)&lt;br /&gt;
-- formatvalue is boolean switch to allow formatting as italics or quoted (default: false)&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: labelOrId(); donotlink[]&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local linkedItem = function(id, args)&lt;br /&gt;
	local lprefix = (args.lp or args.lprefix or args.linkprefix or &amp;quot;&amp;quot;):gsub(&#039;&amp;quot;&#039;, &#039;&#039;) -- toughen against nil values passed&lt;br /&gt;
	local lpostfix = (args.lpostfix or &amp;quot;&amp;quot;):gsub(&#039;&amp;quot;&#039;, &#039;&#039;)&lt;br /&gt;
	local prefix = (args.prefix or &amp;quot;&amp;quot;):gsub(&#039;&amp;quot;&#039;, &#039;&#039;)&lt;br /&gt;
	local postfix = (args.postfix or &amp;quot;&amp;quot;):gsub(&#039;&amp;quot;&#039;, &#039;&#039;)&lt;br /&gt;
	local dtxt = args.dtxt&lt;br /&gt;
	local shortname = args.shortname or args.sn&lt;br /&gt;
	local lang = args.lang or &amp;quot;en&amp;quot; -- fallback to default if missing&lt;br /&gt;
	local uselbl = args.uselabel or args.uselbl&lt;br /&gt;
	uselbl = parseParam(uselbl, false)&lt;br /&gt;
	local linkredir = args.linkredir&lt;br /&gt;
	linkredir = parseParam(linkredir, false)&lt;br /&gt;
	local formatvalue = args.formatvalue or args.fv&lt;br /&gt;
	formatvalue = parseParam(formatvalue, false)&lt;br /&gt;
	-- see if item might need italics or quotes&lt;br /&gt;
	local fmt = &amp;quot;&amp;quot;&lt;br /&gt;
	if next(formats) and formatvalue then&lt;br /&gt;
		for k, v in ipairs( mw.wikibase.getBestStatements(id, &amp;quot;P31&amp;quot;) ) do&lt;br /&gt;
			if v.mainsnak.datavalue and formats[v.mainsnak.datavalue.value.id] then&lt;br /&gt;
				fmt = formats[v.mainsnak.datavalue.value.id]&lt;br /&gt;
				break -- pick the first match&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local disp&lt;br /&gt;
	local sitelink = mw.wikibase.getSitelink(id)&lt;br /&gt;
	local label, islabel&lt;br /&gt;
	if dtxt then&lt;br /&gt;
		label, islabel = dtxt, true&lt;br /&gt;
	elseif shortname then&lt;br /&gt;
		-- see if there is a shortname in our language, and set label to it&lt;br /&gt;
		for k, v in ipairs( mw.wikibase.getBestStatements(id, &amp;quot;P1813&amp;quot;) ) do&lt;br /&gt;
			if v.mainsnak.datavalue.value.language == lang then&lt;br /&gt;
				label, islabel = v.mainsnak.datavalue.value.text, true&lt;br /&gt;
				break&lt;br /&gt;
			end -- test for language match&lt;br /&gt;
		end -- loop through values of short name&lt;br /&gt;
		-- if we have no label set, then there was no shortname available&lt;br /&gt;
		if not islabel then&lt;br /&gt;
			label, islabel = labelOrId(id)&lt;br /&gt;
			shortname = false&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		label, islabel = labelOrId(id)&lt;br /&gt;
	end&lt;br /&gt;
	if mw.site.siteName ~= &amp;quot;Wikimedia Commons&amp;quot; then&lt;br /&gt;
		if sitelink then&lt;br /&gt;
			if not (dtxt or shortname) then&lt;br /&gt;
				-- if sitelink and label are the same except for case, no need to process further&lt;br /&gt;
				if sitelink:lower() ~= label:lower() then&lt;br /&gt;
					-- strip any namespace or dab from the sitelink&lt;br /&gt;
					local pos = sitelink:find(&amp;quot;:&amp;quot;) or 0&lt;br /&gt;
					local slink = sitelink&lt;br /&gt;
					if pos &amp;gt; 0 then&lt;br /&gt;
						local pfx = sitelink:sub(1,pos-1)&lt;br /&gt;
						if mw.site.namespaces[pfx] then -- that prefix is a valid namespace, so remove it&lt;br /&gt;
							slink = sitelink:sub(pos+1)&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
					-- remove stuff after commas or inside parentheses - ie. dabs&lt;br /&gt;
					slink = slink:gsub(&amp;quot;%s%(.+%)$&amp;quot;, &amp;quot;&amp;quot;):gsub(&amp;quot;,.+$&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
					-- if uselbl is false, use sitelink instead of label&lt;br /&gt;
					if not uselbl then&lt;br /&gt;
						--  use slink as display, preserving label case - find(&amp;quot;^%u&amp;quot;) is true for 1st char uppercase&lt;br /&gt;
						if label:find(&amp;quot;^%u&amp;quot;) then&lt;br /&gt;
							label = slink:gsub(&amp;quot;^(%l)&amp;quot;, string.upper)&lt;br /&gt;
						else&lt;br /&gt;
							label = slink:gsub(&amp;quot;^(%u)&amp;quot;, string.lower)&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			if donotlink[label] then&lt;br /&gt;
				disp = prefix .. fmt .. label .. fmt .. postfix&lt;br /&gt;
			else&lt;br /&gt;
				disp = &amp;quot;[[&amp;quot; .. lprefix .. sitelink .. lpostfix .. &amp;quot;|&amp;quot; .. prefix .. fmt .. label .. fmt .. postfix .. &amp;quot;]]&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
		elseif islabel then&lt;br /&gt;
			-- no sitelink, label exists, so check if a redirect with that title exists, if linkredir is true&lt;br /&gt;
			-- display plain label by default&lt;br /&gt;
			disp = prefix .. fmt .. label .. fmt .. postfix&lt;br /&gt;
			if linkredir then&lt;br /&gt;
				local artitle = mw.title.new(label, 0) -- only nil if label has invalid chars&lt;br /&gt;
				if not donotlink[label] and artitle and artitle.redirectTarget then&lt;br /&gt;
					-- there&#039;s a redirect with the same title as the label, so let&#039;s link to that&lt;br /&gt;
					disp = &amp;quot;[[&amp;quot;.. lprefix .. label .. lpostfix .. &amp;quot;|&amp;quot; .. prefix .. fmt .. label .. fmt .. postfix .. &amp;quot;]]&amp;quot;&lt;br /&gt;
				end&lt;br /&gt;
			end -- test if article title exists as redirect on current Wiki&lt;br /&gt;
		else&lt;br /&gt;
			-- no sitelink and no label, so return whatever was returned from labelOrId for now&lt;br /&gt;
			-- add tracking category [[Category:Articles with missing Wikidata information]]&lt;br /&gt;
			-- for enwiki, just return the tracking category&lt;br /&gt;
			if mw.wikibase.getGlobalSiteId() == &amp;quot;enwiki&amp;quot; then&lt;br /&gt;
				disp = i18n.missinginfocat&lt;br /&gt;
			else&lt;br /&gt;
				disp = prefix .. label .. postfix .. i18n.missinginfocat&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		local ccat = mw.wikibase.getBestStatements(id, &amp;quot;P373&amp;quot;)[1]&lt;br /&gt;
		if ccat and ccat.mainsnak.datavalue then&lt;br /&gt;
			ccat = ccat.mainsnak.datavalue.value&lt;br /&gt;
			disp = &amp;quot;[[&amp;quot; .. lprefix .. &amp;quot;Category:&amp;quot; .. ccat .. lpostfix .. &amp;quot;|&amp;quot; .. prefix .. label .. postfix .. &amp;quot;]]&amp;quot;&lt;br /&gt;
		elseif sitelink then&lt;br /&gt;
			-- this asumes that if a sitelink exists, then a label also exists&lt;br /&gt;
			disp = &amp;quot;[[&amp;quot; .. lprefix .. sitelink .. lpostfix .. &amp;quot;|&amp;quot; .. prefix .. label .. postfix .. &amp;quot;]]&amp;quot;&lt;br /&gt;
		else&lt;br /&gt;
			-- no sitelink and no Commons cat, so return label from labelOrId for now&lt;br /&gt;
			disp = prefix .. label .. postfix&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return disp&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- sourced takes a table representing a statement that may or may not have references&lt;br /&gt;
-- it looks for a reference sourced to something not containing the word &amp;quot;wikipedia&amp;quot;&lt;br /&gt;
-- it returns a boolean = true if it finds a sourced reference.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local sourced = function(claim)&lt;br /&gt;
	if claim.references then&lt;br /&gt;
		for kr, vr in pairs(claim.references) do&lt;br /&gt;
			local ref = mw.wikibase.renderSnaks(vr.snaks)&lt;br /&gt;
			if not ref:find(&amp;quot;Wiki&amp;quot;) then&lt;br /&gt;
				return true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- setRanks takes a flag (parameter passed) that requests the values to return&lt;br /&gt;
-- &amp;quot;b[est]&amp;quot; returns preferred if available, otherwise normal&lt;br /&gt;
-- &amp;quot;p[referred]&amp;quot; returns preferred&lt;br /&gt;
-- &amp;quot;n[ormal]&amp;quot; returns normal&lt;br /&gt;
-- &amp;quot;d[eprecated]&amp;quot; returns deprecated&lt;br /&gt;
-- multiple values are allowed, e.g. &amp;quot;preferred normal&amp;quot; (which is the default)&lt;br /&gt;
-- &amp;quot;best&amp;quot; will override the other flags, and set p and n&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local setRanks = function(rank)&lt;br /&gt;
	rank = (rank or &amp;quot;&amp;quot;):lower()&lt;br /&gt;
	-- if nothing passed, return preferred and normal&lt;br /&gt;
	-- if rank == &amp;quot;&amp;quot; then rank = &amp;quot;p n&amp;quot; end&lt;br /&gt;
	local ranks = {}&lt;br /&gt;
	for w in string.gmatch(rank, &amp;quot;%a+&amp;quot;) do&lt;br /&gt;
		w = w:sub(1,1)&lt;br /&gt;
		if w == &amp;quot;b&amp;quot; or w == &amp;quot;p&amp;quot; or w == &amp;quot;n&amp;quot; or w == &amp;quot;d&amp;quot; then&lt;br /&gt;
			ranks[w] = true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	-- check if &amp;quot;best&amp;quot; is requested or no ranks requested; and if so, set preferred and normal&lt;br /&gt;
	if ranks.b or not next(ranks) then&lt;br /&gt;
		ranks.p = true&lt;br /&gt;
		ranks.n = true&lt;br /&gt;
	end&lt;br /&gt;
	return ranks&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- parseInput processes the Q-id , the blacklist and the whitelist&lt;br /&gt;
-- if an input parameter is supplied, it returns that and ends the call.&lt;br /&gt;
-- it returns (1) either the qid or nil indicating whether or not the call should continue&lt;br /&gt;
-- and (2) a table containing all of the statements for the propertyID and relevant Qid&lt;br /&gt;
-- if &amp;quot;best&amp;quot; ranks are requested, it returns those instead of all non-deprecated ranks&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local parseInput = function(frame, input_parm, property_id)&lt;br /&gt;
	-- There may be a local parameter supplied, if it&#039;s blank, set it to nil&lt;br /&gt;
	input_parm = mw.text.trim(input_parm or &amp;quot;&amp;quot;)&lt;br /&gt;
	if input_parm == &amp;quot;&amp;quot; then input_parm = nil end&lt;br /&gt;
&lt;br /&gt;
	-- return nil if Wikidata is not available&lt;br /&gt;
	if not mw.wikibase then return false, input_parm end&lt;br /&gt;
&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
&lt;br /&gt;
	-- can take a named parameter |qid which is the Wikidata ID for the article.&lt;br /&gt;
	-- if it&#039;s not supplied, use the id for the current page&lt;br /&gt;
	local qid = args.qid or &amp;quot;&amp;quot;&lt;br /&gt;
	if qid == &amp;quot;&amp;quot; then qid = mw.wikibase.getEntityIdForCurrentPage() end&lt;br /&gt;
	-- if there&#039;s no Wikidata item for the current page return nil&lt;br /&gt;
	if not qid then return false, input_parm end&lt;br /&gt;
&lt;br /&gt;
	-- The blacklist is passed in named parameter |suppressfields&lt;br /&gt;
	local blacklist = args.suppressfields or args.spf or &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	-- The whitelist is passed in named parameter |fetchwikidata&lt;br /&gt;
	local whitelist = args.fetchwikidata or args.fwd or &amp;quot;&amp;quot;&lt;br /&gt;
	if whitelist == &amp;quot;&amp;quot; then whitelist = &amp;quot;NONE&amp;quot; end&lt;br /&gt;
&lt;br /&gt;
	-- The name of the field that this function is called from is passed in named parameter |name&lt;br /&gt;
	local fieldname = args.name or &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	if blacklist ~= &amp;quot;&amp;quot; then&lt;br /&gt;
		-- The name is compulsory when blacklist is used, so return nil if it is not supplied&lt;br /&gt;
		if fieldname == &amp;quot;&amp;quot; then return false, nil end&lt;br /&gt;
		-- If this field is on the blacklist, then return nil&lt;br /&gt;
		if blacklist:find(fieldname) then return false, nil end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- If we got this far then we&#039;re not on the blacklist&lt;br /&gt;
	-- The blacklist overrides any locally supplied parameter as well&lt;br /&gt;
	-- If a non-blank input parameter was supplied return it&lt;br /&gt;
	if input_parm then return false, input_parm end&lt;br /&gt;
&lt;br /&gt;
	-- We can filter out non-valid properties&lt;br /&gt;
	if property_id:sub(1,1):upper() ~=&amp;quot;P&amp;quot; or property_id == &amp;quot;P0&amp;quot; then return false, nil end&lt;br /&gt;
&lt;br /&gt;
	-- Otherwise see if this field is on the whitelist:&lt;br /&gt;
	-- needs a bit more logic because find will return its second value = 0 if fieldname is &amp;quot;&amp;quot;&lt;br /&gt;
	-- but nil if fieldname not found on whitelist&lt;br /&gt;
	local _, found = whitelist:find(fieldname)&lt;br /&gt;
	found = ((found or 0) &amp;gt; 0)&lt;br /&gt;
	if whitelist ~= &#039;ALL&#039; and (whitelist:upper() == &amp;quot;NONE&amp;quot; or not found) then&lt;br /&gt;
		return false, nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- See what&#039;s on Wikidata (the call always returns a table, but it may be empty):&lt;br /&gt;
	local props = {}&lt;br /&gt;
	if args.reqranks.b then&lt;br /&gt;
		props = mw.wikibase.getBestStatements(qid, property_id)&lt;br /&gt;
	else&lt;br /&gt;
		props = mw.wikibase.getAllStatements(qid, property_id)&lt;br /&gt;
	end&lt;br /&gt;
	if props[1] then&lt;br /&gt;
		return qid, props&lt;br /&gt;
	end&lt;br /&gt;
	-- no property on Wikidata&lt;br /&gt;
	return false, nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- createicon assembles the &amp;quot;Edit at Wikidata&amp;quot; pen icon.&lt;br /&gt;
-- It returns a wikitext string inside a span class=&amp;quot;penicon&amp;quot;&lt;br /&gt;
-- if entityID is nil or empty, the ID associated with current page is used&lt;br /&gt;
-- langcode and propertyID may be nil or empty&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: i18n[];&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local createicon = function(langcode, entityID, propertyID)&lt;br /&gt;
	langcode = langcode or &amp;quot;&amp;quot;&lt;br /&gt;
	if not entityID or entityID == &amp;quot;&amp;quot; then entityID= mw.wikibase.getEntityIdForCurrentPage() end&lt;br /&gt;
	propertyID = propertyID or &amp;quot;&amp;quot;&lt;br /&gt;
	local icon = &amp;quot;&amp;amp;nbsp;&amp;lt;span class=&#039;penicon autoconfirmed-show&#039;&amp;gt;[[&amp;quot;&lt;br /&gt;
	-- &amp;quot;&amp;amp;nbsp;&amp;lt;span data-bridge-edit-flow=&#039;overwrite&#039; class=&#039;penicon&#039;&amp;gt;[[&amp;quot; -&amp;gt; enable Wikidata Bridge&lt;br /&gt;
	.. i18n[&amp;quot;filespace&amp;quot;]&lt;br /&gt;
	.. &amp;quot;:OOjs UI icon edit-ltr-progressive.svg |frameless |text-top |10px |alt=&amp;quot;&lt;br /&gt;
	.. i18n[&amp;quot;editonwikidata&amp;quot;]&lt;br /&gt;
	.. &amp;quot;|link=https://www.wikidata.org/wiki/&amp;quot; .. entityID&lt;br /&gt;
	if langcode ~= &amp;quot;&amp;quot; then icon = icon .. &amp;quot;?uselang=&amp;quot; .. langcode end&lt;br /&gt;
	if propertyID ~= &amp;quot;&amp;quot; then icon = icon .. &amp;quot;#&amp;quot; .. propertyID end&lt;br /&gt;
	icon = icon .. &amp;quot;|&amp;quot; .. i18n[&amp;quot;editonwikidata&amp;quot;] .. &amp;quot;]]&amp;lt;/span&amp;gt;&amp;quot;&lt;br /&gt;
	return icon&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- assembleoutput takes the sequence table containing the property values&lt;br /&gt;
-- and formats it according to switches given. It returns a string or nil.&lt;br /&gt;
-- It uses the entityID (and optionally propertyID) to create a link in the pen icon.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: parseParam();&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local assembleoutput = function(out, args, entityID, propertyID)&lt;br /&gt;
&lt;br /&gt;
	-- sorted is a boolean passed to enable sorting of the values returned&lt;br /&gt;
	-- if nothing or an empty string is passed set it false&lt;br /&gt;
	-- if &amp;quot;false&amp;quot; or &amp;quot;no&amp;quot; or &amp;quot;0&amp;quot; is passed set it false&lt;br /&gt;
	local sorted = parseParam(args.sorted, false)&lt;br /&gt;
&lt;br /&gt;
	-- noicon is a boolean passed to suppress the trailing &amp;quot;edit at Wikidata&amp;quot; icon&lt;br /&gt;
	-- for use when the value is processed further by the infobox&lt;br /&gt;
	-- if nothing or an empty string is passed set it false&lt;br /&gt;
	-- if &amp;quot;false&amp;quot; or &amp;quot;no&amp;quot; or &amp;quot;0&amp;quot; is passed set it false&lt;br /&gt;
	local noic = parseParam(args.noicon, false)&lt;br /&gt;
&lt;br /&gt;
	-- list is the name of a template that a list of multiple values is passed through&lt;br /&gt;
	-- examples include &amp;quot;hlist&amp;quot; and &amp;quot;ubl&amp;quot;&lt;br /&gt;
	-- setting it to &amp;quot;prose&amp;quot; produces something like &amp;quot;1, 2, 3, and 4&amp;quot;&lt;br /&gt;
	local list = args.list or &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	-- sep is a string that is used to separate multiple returned values&lt;br /&gt;
	-- if nothing or an empty string is passed set it to the default&lt;br /&gt;
	-- any double-quotes &amp;quot; are stripped out, so that spaces may be passed&lt;br /&gt;
	-- e.g. |sep=&amp;quot; - &amp;quot;&lt;br /&gt;
	local sepdefault = i18n[&amp;quot;list separator&amp;quot;]&lt;br /&gt;
	local separator = args.sep or &amp;quot;&amp;quot;&lt;br /&gt;
	separator = string.gsub(separator, &#039;&amp;quot;&#039;, &#039;&#039;)&lt;br /&gt;
	if separator == &amp;quot;&amp;quot; then&lt;br /&gt;
		separator = sepdefault&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- collapse is a number that determines the maximum number of returned values&lt;br /&gt;
	-- before the output is collapsed.&lt;br /&gt;
	-- Zero or not a number result in no collapsing (default becomes 0).&lt;br /&gt;
	local collapse = tonumber(args.collapse) or 0&lt;br /&gt;
&lt;br /&gt;
	-- replacetext (rt) is a string that is returned instead of any non-empty Wikidata value&lt;br /&gt;
	-- this is useful for tracking and debugging&lt;br /&gt;
	local replacetext = mw.text.trim(args.rt or args.replacetext or &amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	-- if there&#039;s anything to return, then return a list&lt;br /&gt;
	-- comma-separated by default, but may be specified by the sep parameter&lt;br /&gt;
	-- optionally specify a hlist or ubl or a prose list, etc.&lt;br /&gt;
	local strout&lt;br /&gt;
	if #out &amp;gt; 0 then&lt;br /&gt;
		if sorted then table.sort(out) end&lt;br /&gt;
		-- if there&#039;s something to display and a pen icon is wanted, add it the end of the last value&lt;br /&gt;
		local hasdisplay = false&lt;br /&gt;
		for i, v in ipairs(out) do&lt;br /&gt;
			if v ~= i18n.missinginfocat then&lt;br /&gt;
				hasdisplay = true&lt;br /&gt;
				break&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if not noic and hasdisplay then&lt;br /&gt;
			out[#out] = out[#out] .. createicon(args.langobj.code, entityID, propertyID)&lt;br /&gt;
		end&lt;br /&gt;
		if list == &amp;quot;&amp;quot; then&lt;br /&gt;
			strout = table.concat(out, separator)&lt;br /&gt;
		elseif list:lower() == &amp;quot;prose&amp;quot; then&lt;br /&gt;
			strout = mw.text.listToText( out )&lt;br /&gt;
		else&lt;br /&gt;
			strout = mw.getCurrentFrame():expandTemplate{title = list, args = out}&lt;br /&gt;
		end&lt;br /&gt;
		if collapse &amp;gt;0 and #out &amp;gt; collapse then&lt;br /&gt;
			strout = collapsediv .. strout .. &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		strout = nil -- no items had valid reference&lt;br /&gt;
	end&lt;br /&gt;
	if replacetext ~= &amp;quot;&amp;quot; and strout then strout = replacetext end&lt;br /&gt;
	return strout&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- rendersnak takes a table (propval) containing the information stored on one property value&lt;br /&gt;
-- and returns the value as a string and its language if monolingual text.&lt;br /&gt;
-- It handles data of type:&lt;br /&gt;
--		wikibase-item&lt;br /&gt;
--		time&lt;br /&gt;
--		string, url, commonsMedia, external-id&lt;br /&gt;
--		quantity&lt;br /&gt;
--		globe-coordinate&lt;br /&gt;
--		monolingualtext&lt;br /&gt;
-- It also requires linked, the link/pre/postfixes, uabbr, and the arguments passed from frame.&lt;br /&gt;
-- The optional filter parameter allows quantities to be be filtered by unit Qid.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: parseParam(); labelOrId(); i18n[]; dateFormat();&lt;br /&gt;
-- roundto(); decimalPrecision(); decimalToDMS(); linkedItem();&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local rendersnak = function(propval, args, linked, lpre, lpost, pre, post, uabbr, filter)&lt;br /&gt;
	lpre = lpre or &amp;quot;&amp;quot;&lt;br /&gt;
	lpost = lpost or &amp;quot;&amp;quot;&lt;br /&gt;
	pre = pre or &amp;quot;&amp;quot;&lt;br /&gt;
	post = post or &amp;quot;&amp;quot;&lt;br /&gt;
	args.lang = args.lang or findLang().code&lt;br /&gt;
	-- allow values to display a fixed text instead of label&lt;br /&gt;
	local dtxt = args.displaytext or args.dt&lt;br /&gt;
	if dtxt == &amp;quot;&amp;quot; then dtxt = nil end&lt;br /&gt;
	-- switch to use display of short name (P1813) instead of label&lt;br /&gt;
	local shortname = args.shortname or args.sn&lt;br /&gt;
	shortname = parseParam(shortname, false)&lt;br /&gt;
	local snak = propval.mainsnak or propval&lt;br /&gt;
	local dtype = snak.datatype&lt;br /&gt;
	local dv = snak.datavalue&lt;br /&gt;
	dv = dv and dv.value&lt;br /&gt;
	-- value and monolingual text language code returned&lt;br /&gt;
	local val, mlt&lt;br /&gt;
	if propval.rank and not args.reqranks[propval.rank:sub(1, 1)] then&lt;br /&gt;
		-- val is nil: value has a rank that isn&#039;t requested&lt;br /&gt;
		------------------------------------&lt;br /&gt;
	elseif snak.snaktype == &amp;quot;somevalue&amp;quot; then -- value is unknown&lt;br /&gt;
		val = i18n[&amp;quot;Unknown&amp;quot;]&lt;br /&gt;
		------------------------------------&lt;br /&gt;
	elseif snak.snaktype == &amp;quot;novalue&amp;quot; then -- value is none&lt;br /&gt;
		-- val = &amp;quot;No value&amp;quot; -- don&#039;t return anything&lt;br /&gt;
		------------------------------------&lt;br /&gt;
	elseif dtype == &amp;quot;wikibase-item&amp;quot; then -- data type is a wikibase item:&lt;br /&gt;
		-- it&#039;s wiki-linked value, so output as link if enabled and possible&lt;br /&gt;
		local qnumber = dv.id&lt;br /&gt;
		if linked then&lt;br /&gt;
			val = linkedItem(qnumber, args)&lt;br /&gt;
		else -- no link wanted so check for display-text, otherwise test for lang code&lt;br /&gt;
			local label, islabel&lt;br /&gt;
			if dtxt then&lt;br /&gt;
				label = dtxt&lt;br /&gt;
			else&lt;br /&gt;
				label, islabel = labelOrId(qnumber)&lt;br /&gt;
				local langlabel = mw.wikibase.getLabelByLang(qnumber, args.lang)&lt;br /&gt;
				if langlabel then&lt;br /&gt;
					label = mw.text.nowiki( langlabel )&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			val = pre .. label .. post&lt;br /&gt;
		end -- test for link required&lt;br /&gt;
		------------------------------------&lt;br /&gt;
	elseif dtype == &amp;quot;time&amp;quot; then -- data type is time:&lt;br /&gt;
		-- time is in timestamp format&lt;br /&gt;
		-- date precision is integer per mediawiki&lt;br /&gt;
		-- output formatting according to preferences (y/dmy/mdy)&lt;br /&gt;
		-- BC format as BC or BCE&lt;br /&gt;
		-- plaindate is passed to disable looking for &amp;quot;sourcing cirumstances&amp;quot;&lt;br /&gt;
		-- or to set the adjectival form&lt;br /&gt;
		-- qualifiers (if any) is a nested table or nil&lt;br /&gt;
		-- lang is given, or user language, or site language&lt;br /&gt;
		--&lt;br /&gt;
		-- Here we can check whether args.df has a value&lt;br /&gt;
		-- If not, use code from Module:Sandbox/RexxS/Getdateformat to set it from templates like {{Use mdy dates}}&lt;br /&gt;
		val = dateFormat(dv.time, dv.precision, args.df, args.bc, args.pd, propval.qualifiers, args.lang, &amp;quot;&amp;quot;, dv.calendarmodel)&lt;br /&gt;
		------------------------------------&lt;br /&gt;
	-- data types which are strings:&lt;br /&gt;
	elseif dtype == &amp;quot;commonsMedia&amp;quot; or dtype == &amp;quot;external-id&amp;quot; or dtype == &amp;quot;string&amp;quot; or dtype == &amp;quot;url&amp;quot; then&lt;br /&gt;
		-- commonsMedia or external-id or string or url&lt;br /&gt;
		-- all have mainsnak.datavalue.value as string&lt;br /&gt;
		if (lpre == &amp;quot;&amp;quot; or lpre == &amp;quot;:&amp;quot;) and lpost == &amp;quot;&amp;quot; then&lt;br /&gt;
			-- don&#039;t link if no linkpre/postfix or linkprefix is just &amp;quot;:&amp;quot;&lt;br /&gt;
			val = pre .. dv .. post&lt;br /&gt;
		elseif dtype == &amp;quot;external-id&amp;quot; then&lt;br /&gt;
			val = &amp;quot;[&amp;quot; .. lpre .. dv .. lpost .. &amp;quot; &amp;quot; .. pre .. dv .. post .. &amp;quot;]&amp;quot;&lt;br /&gt;
		else&lt;br /&gt;
			val = &amp;quot;[[&amp;quot; .. lpre .. dv .. lpost .. &amp;quot;|&amp;quot; .. pre .. dv .. post .. &amp;quot;]]&amp;quot;&lt;br /&gt;
		end -- check for link requested (i.e. either linkprefix or linkpostfix exists)&lt;br /&gt;
		------------------------------------&lt;br /&gt;
	-- data types which are quantities:&lt;br /&gt;
	elseif dtype == &amp;quot;quantity&amp;quot; then&lt;br /&gt;
		-- quantities have mainsnak.datavalue.value.amount and mainsnak.datavalue.value.unit&lt;br /&gt;
		-- the unit is of the form http://www.wikidata.org/entity/Q829073&lt;br /&gt;
		--&lt;br /&gt;
		-- implement a switch to turn on/off numerical formatting later&lt;br /&gt;
		local fnum = true&lt;br /&gt;
		--&lt;br /&gt;
		-- a switch to turn on/off conversions - only for en-wiki&lt;br /&gt;
		local conv = parseParam(args.conv or args.convert, false)&lt;br /&gt;
		-- if we have conversions, we won&#039;t have formatted numbers or scales&lt;br /&gt;
		if conv then&lt;br /&gt;
			uabbr = true&lt;br /&gt;
			fnum = false&lt;br /&gt;
			args.scale = &amp;quot;0&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
		--&lt;br /&gt;
		-- a switch to turn on/off showing units, default is true&lt;br /&gt;
		local showunits = parseParam(args.su or args.showunits, true)&lt;br /&gt;
		--&lt;br /&gt;
		-- convert amount to a number&lt;br /&gt;
		local amount = tonumber(dv.amount) or i18n[&amp;quot;NaN&amp;quot;]&lt;br /&gt;
		--&lt;br /&gt;
		-- scale factor for millions, billions, etc.&lt;br /&gt;
		local sc = tostring(args.scale or &amp;quot;&amp;quot;):sub(1,1):lower()&lt;br /&gt;
		local scale&lt;br /&gt;
		if sc == &amp;quot;a&amp;quot; then&lt;br /&gt;
			-- automatic scaling&lt;br /&gt;
			if amount &amp;gt; 1e15 then&lt;br /&gt;
				scale = 12&lt;br /&gt;
			elseif amount &amp;gt; 1e12 then&lt;br /&gt;
				scale = 9&lt;br /&gt;
			elseif amount &amp;gt; 1e9 then&lt;br /&gt;
				scale = 6&lt;br /&gt;
			elseif amount &amp;gt; 1e6 then&lt;br /&gt;
				scale = 3&lt;br /&gt;
			else&lt;br /&gt;
				scale = 0&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			scale = tonumber(args.scale) or 0&lt;br /&gt;
			if scale &amp;lt; 0 or scale &amp;gt; 12 then scale = 0 end&lt;br /&gt;
			scale = math.floor(scale/3) * 3&lt;br /&gt;
		end&lt;br /&gt;
		local factor = 10^scale&lt;br /&gt;
		amount = amount / factor&lt;br /&gt;
		-- ranges:&lt;br /&gt;
		local range = &amp;quot;&amp;quot;&lt;br /&gt;
		-- check if upper and/or lower bounds are given and significant&lt;br /&gt;
		local upb = tonumber(dv.upperBound)&lt;br /&gt;
		local lowb = tonumber(dv.lowerBound)&lt;br /&gt;
		if upb and lowb then&lt;br /&gt;
			-- differences rounded to 2 sig fig:&lt;br /&gt;
			local posdif = roundto(upb - amount, 2) / factor&lt;br /&gt;
			local negdif = roundto(amount - lowb, 2) / factor&lt;br /&gt;
			upb, lowb = amount + posdif, amount - negdif&lt;br /&gt;
			-- round scaled numbers to integers or 4 sig fig&lt;br /&gt;
			if (scale &amp;gt; 0 or sc == &amp;quot;a&amp;quot;) then&lt;br /&gt;
				if amount &amp;lt; 1e4 then&lt;br /&gt;
					amount = roundto(amount, 4)&lt;br /&gt;
				else&lt;br /&gt;
					amount = math.floor(amount + 0.5)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			if fnum then amount = args.langobj:formatNum( amount ) end&lt;br /&gt;
			if posdif ~= negdif then&lt;br /&gt;
				-- non-symmetrical&lt;br /&gt;
				range = &amp;quot; +&amp;quot; .. posdif .. &amp;quot; -&amp;quot; .. negdif&lt;br /&gt;
			elseif posdif ~= 0 then&lt;br /&gt;
				-- symmetrical and non-zero&lt;br /&gt;
				range = &amp;quot; ±&amp;quot; .. posdif&lt;br /&gt;
			else&lt;br /&gt;
				-- otherwise range is zero, so leave it as &amp;quot;&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			-- round scaled numbers to integers or 4 sig fig&lt;br /&gt;
			if (scale &amp;gt; 0 or sc == &amp;quot;a&amp;quot;) then&lt;br /&gt;
				if amount &amp;lt; 1e4 then&lt;br /&gt;
					amount = roundto(amount, 4)&lt;br /&gt;
				else&lt;br /&gt;
					amount = math.floor(amount + 0.5)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			if fnum then amount = args.langobj:formatNum( amount ) end&lt;br /&gt;
		end&lt;br /&gt;
		-- unit names and symbols:&lt;br /&gt;
		-- extract the qid in the form &#039;Qnnn&#039; from the value.unit url&lt;br /&gt;
		-- and then fetch the label from that - or symbol if unitabbr is true&lt;br /&gt;
		local unit = &amp;quot;&amp;quot;&lt;br /&gt;
		local usep = &amp;quot;&amp;quot;&lt;br /&gt;
		local usym = &amp;quot;&amp;quot;&lt;br /&gt;
		local unitqid = string.match( dv.unit, &amp;quot;(Q%d+)&amp;quot; )&lt;br /&gt;
		if filter and unitqid ~= filter then return nil end&lt;br /&gt;
		if unitqid and showunits then&lt;br /&gt;
			local uname = mw.wikibase.getLabelByLang(unitqid, args.lang) or &amp;quot;&amp;quot;&lt;br /&gt;
			if uname ~= &amp;quot;&amp;quot; then usep, unit = &amp;quot; &amp;quot;, uname end&lt;br /&gt;
			if uabbr then&lt;br /&gt;
				-- see if there&#039;s a unit symbol (P5061)&lt;br /&gt;
				local unitsymbols = mw.wikibase.getBestStatements(unitqid, &amp;quot;P5061&amp;quot;)&lt;br /&gt;
				-- construct fallback table, add local lang and multiple languages&lt;br /&gt;
				local fbtbl = mw.language.getFallbacksFor( args.lang, mw.language.FALLBACK_STRICT )&lt;br /&gt;
				table.insert( fbtbl, 1, args.lang )&lt;br /&gt;
				table.insert( fbtbl, &amp;quot;mul&amp;quot; )&lt;br /&gt;
				table.insert( fbtbl, &amp;quot;en&amp;quot; )&lt;br /&gt;
				local found = false&lt;br /&gt;
				for idx1, us in ipairs(unitsymbols) do&lt;br /&gt;
					for idx2, fblang in ipairs(fbtbl) do&lt;br /&gt;
						if us.mainsnak.datavalue.value.language == fblang then&lt;br /&gt;
							usym = us.mainsnak.datavalue.value.text&lt;br /&gt;
							found = true&lt;br /&gt;
							break&lt;br /&gt;
						end&lt;br /&gt;
					end -- loop through fallback table&lt;br /&gt;
					if found then break end&lt;br /&gt;
				end -- loop through values of P5061&lt;br /&gt;
				if found then usep, unit = &amp;quot;&amp;amp;nbsp;&amp;quot;, usym end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		-- format display:&lt;br /&gt;
		if conv then&lt;br /&gt;
			if range == &amp;quot;&amp;quot; then&lt;br /&gt;
				val = mw.getCurrentFrame():expandTemplate{title = &amp;quot;cvt&amp;quot;, args = {amount, unit}}&lt;br /&gt;
			else&lt;br /&gt;
				val = mw.getCurrentFrame():expandTemplate{title = &amp;quot;cvt&amp;quot;, args = {lowb, &amp;quot;to&amp;quot;, upb, unit}}&lt;br /&gt;
			end&lt;br /&gt;
		elseif unit == &amp;quot;$&amp;quot; or unit == &amp;quot;£&amp;quot; then&lt;br /&gt;
			val = unit .. amount .. range .. i18n.multipliers[scale]&lt;br /&gt;
		else&lt;br /&gt;
			val = amount .. range .. i18n.multipliers[scale] .. usep .. unit&lt;br /&gt;
		end&lt;br /&gt;
		------------------------------------&lt;br /&gt;
	-- datatypes which are global coordinates:&lt;br /&gt;
	elseif dtype == &amp;quot;globe-coordinate&amp;quot; then&lt;br /&gt;
		-- &#039;display&#039; parameter defaults to &amp;quot;inline, title&amp;quot; *** unused for now ***&lt;br /&gt;
		-- local disp = args.display or &amp;quot;&amp;quot;&lt;br /&gt;
		-- if disp == &amp;quot;&amp;quot; then disp = &amp;quot;inline, title&amp;quot; end&lt;br /&gt;
		--&lt;br /&gt;
		-- format parameter switches from deg/min/sec to decimal degrees&lt;br /&gt;
		-- default is deg/min/sec -- decimal degrees needs |format = dec&lt;br /&gt;
		local form = (args.format or &amp;quot;&amp;quot;):lower():sub(1,3)&lt;br /&gt;
		if form ~= &amp;quot;dec&amp;quot; then form = &amp;quot;dms&amp;quot; end -- not needed for now&lt;br /&gt;
		--&lt;br /&gt;
		-- show parameter allows just the latitude, or just the longitude, or both&lt;br /&gt;
		-- to be returned as a signed decimal, ignoring the format parameter.&lt;br /&gt;
		local show = (args.show or &amp;quot;&amp;quot;):lower()&lt;br /&gt;
		if show ~= &amp;quot;longlat&amp;quot; then show = show:sub(1,3) end&lt;br /&gt;
		--&lt;br /&gt;
		local lat, long, prec = dv.latitude, dv.longitude, dv.precision&lt;br /&gt;
		if show == &amp;quot;lat&amp;quot; then&lt;br /&gt;
			val = decimalPrecision(lat, prec)&lt;br /&gt;
		elseif show == &amp;quot;lon&amp;quot; then&lt;br /&gt;
			val = decimalPrecision(long, prec)&lt;br /&gt;
		elseif show == &amp;quot;longlat&amp;quot; then&lt;br /&gt;
			val = decimalPrecision(long, prec) .. &amp;quot;, &amp;quot; .. decimalPrecision(lat, prec)&lt;br /&gt;
		else&lt;br /&gt;
			local ns = &amp;quot;N&amp;quot;&lt;br /&gt;
			local ew = &amp;quot;E&amp;quot;&lt;br /&gt;
			if lat &amp;lt; 0 then&lt;br /&gt;
				ns = &amp;quot;S&amp;quot;&lt;br /&gt;
				lat = - lat&lt;br /&gt;
			end&lt;br /&gt;
			if long &amp;lt; 0 then&lt;br /&gt;
				ew = &amp;quot;W&amp;quot;&lt;br /&gt;
				long = - long&lt;br /&gt;
			end&lt;br /&gt;
			if form == &amp;quot;dec&amp;quot; then&lt;br /&gt;
				lat = decimalPrecision(lat, prec)&lt;br /&gt;
				long = decimalPrecision(long, prec)&lt;br /&gt;
				val = lat .. &amp;quot;°&amp;quot; .. ns .. &amp;quot; &amp;quot; .. long ..  &amp;quot;°&amp;quot; .. ew&lt;br /&gt;
			else&lt;br /&gt;
				local latdeg, latmin, latsec = decimalToDMS(lat, prec)&lt;br /&gt;
				local longdeg, longmin, longsec = decimalToDMS(long, prec)&lt;br /&gt;
&lt;br /&gt;
				if latsec == 0 and longsec == 0 then&lt;br /&gt;
					if latmin == 0 and longmin == 0 then&lt;br /&gt;
						val = latdeg .. &amp;quot;°&amp;quot; .. ns .. &amp;quot; &amp;quot; .. longdeg ..  &amp;quot;°&amp;quot; .. ew&lt;br /&gt;
					else&lt;br /&gt;
						val = latdeg .. &amp;quot;°&amp;quot; .. latmin .. &amp;quot;′&amp;quot; .. ns .. &amp;quot; &amp;quot;&lt;br /&gt;
						val = val .. longdeg .. &amp;quot;°&amp;quot;.. longmin .. &amp;quot;′&amp;quot; .. ew&lt;br /&gt;
					end&lt;br /&gt;
				else&lt;br /&gt;
					val = latdeg .. &amp;quot;°&amp;quot; .. latmin .. &amp;quot;′&amp;quot; .. latsec .. &amp;quot;″&amp;quot; .. ns .. &amp;quot; &amp;quot;&lt;br /&gt;
					val = val .. longdeg .. &amp;quot;°&amp;quot; .. longmin .. &amp;quot;′&amp;quot; .. longsec .. &amp;quot;″&amp;quot; .. ew&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		------------------------------------&lt;br /&gt;
	elseif dtype == &amp;quot;monolingualtext&amp;quot; then -- data type is Monolingual text:&lt;br /&gt;
		-- has mainsnak.datavalue.value as a table containing language/text pairs&lt;br /&gt;
		-- collect all the values in &#039;out&#039; and languages in &#039;mlt&#039; and process them later&lt;br /&gt;
		val = pre .. dv.text .. post&lt;br /&gt;
		mlt = dv.language&lt;br /&gt;
		------------------------------------&lt;br /&gt;
	else&lt;br /&gt;
		-- some other data type so write a specific handler&lt;br /&gt;
		val = &amp;quot;unknown data type: &amp;quot; .. dtype&lt;br /&gt;
	end -- of datatype/unknown value/sourced check&lt;br /&gt;
	return val, mlt&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- propertyvalueandquals takes a property object, the arguments passed from frame,&lt;br /&gt;
-- and a qualifier propertyID.&lt;br /&gt;
-- It returns a sequence (table) of values representing the values of that property&lt;br /&gt;
-- and qualifiers that match the qualifierID if supplied.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: parseParam(); sourced(); labelOrId(); i18n.latestdatequalifier(); format_Date();&lt;br /&gt;
-- makeOrdinal(); roundto(); decimalPrecision(); decimalToDMS(); assembleoutput();&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local function propertyvalueandquals(objproperty, args, qualID)&lt;br /&gt;
	-- needs this style of declaration because it&#039;s re-entrant&lt;br /&gt;
&lt;br /&gt;
	-- onlysourced is a boolean passed to return only values sourced to other than Wikipedia&lt;br /&gt;
	-- if nothing or an empty string is passed set it true&lt;br /&gt;
	local onlysrc = parseParam(args.onlysourced or args.osd, true)&lt;br /&gt;
&lt;br /&gt;
	-- linked is a a boolean that enables the link to a local page via sitelink&lt;br /&gt;
	-- if nothing or an empty string is passed set it true&lt;br /&gt;
	local linked = parseParam(args.linked, true)&lt;br /&gt;
&lt;br /&gt;
	-- prefix is a string that may be nil, empty (&amp;quot;&amp;quot;), or a string of characters&lt;br /&gt;
	-- this is prefixed to each value&lt;br /&gt;
	-- useful when when multiple values are returned&lt;br /&gt;
	-- any double-quotes &amp;quot; are stripped out, so that spaces may be passed&lt;br /&gt;
	local prefix = (args.prefix or &amp;quot;&amp;quot;):gsub(&#039;&amp;quot;&#039;, &#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
	-- postfix is a string that may be nil, empty (&amp;quot;&amp;quot;), or a string of characters&lt;br /&gt;
	-- this is postfixed to each value&lt;br /&gt;
	-- useful when when multiple values are returned&lt;br /&gt;
	-- any double-quotes &amp;quot; are stripped out, so that spaces may be passed&lt;br /&gt;
	local postfix = (args.postfix or &amp;quot;&amp;quot;):gsub(&#039;&amp;quot;&#039;, &#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
	-- linkprefix is a string that may be nil, empty (&amp;quot;&amp;quot;), or a string of characters&lt;br /&gt;
	-- this creates a link and is then prefixed to each value&lt;br /&gt;
	-- useful when when multiple values are returned and indirect links are needed&lt;br /&gt;
	-- any double-quotes &amp;quot; are stripped out, so that spaces may be passed&lt;br /&gt;
	local lprefix = (args.linkprefix or args.lp or &amp;quot;&amp;quot;):gsub(&#039;&amp;quot;&#039;, &#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
	-- linkpostfix is a string that may be nil, empty (&amp;quot;&amp;quot;), or a string of characters&lt;br /&gt;
	-- this is postfixed to each value when linking is enabled with lprefix&lt;br /&gt;
	-- useful when when multiple values are returned&lt;br /&gt;
	-- any double-quotes &amp;quot; are stripped out, so that spaces may be passed&lt;br /&gt;
	local lpostfix = (args.linkpostfix or &amp;quot;&amp;quot;):gsub(&#039;&amp;quot;&#039;, &#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
	-- wdlinks is a boolean passed to enable links to Wikidata when no article exists&lt;br /&gt;
	-- if nothing or an empty string is passed set it false&lt;br /&gt;
	local wdl = parseParam(args.wdlinks or args.wdl, false)&lt;br /&gt;
&lt;br /&gt;
	-- unitabbr is a boolean passed to enable unit abbreviations for common units&lt;br /&gt;
	-- if nothing or an empty string is passed set it false&lt;br /&gt;
	local uabbr = parseParam(args.unitabbr or args.uabbr, false)&lt;br /&gt;
&lt;br /&gt;
	-- qualsonly is a boolean passed to return just the qualifiers&lt;br /&gt;
	-- if nothing or an empty string is passed set it false&lt;br /&gt;
	local qualsonly = parseParam(args.qualsonly or args.qo, false)&lt;br /&gt;
&lt;br /&gt;
	-- maxvals is a string that may be nil, empty (&amp;quot;&amp;quot;), or a number&lt;br /&gt;
	-- this determines how many items may be returned when multiple values are available&lt;br /&gt;
	-- setting it = 1 is useful where the returned string is used within another call, e.g. image&lt;br /&gt;
	local maxvals = tonumber(args.maxvals) or 0&lt;br /&gt;
&lt;br /&gt;
	-- pd (plain date) is a string: yes/true/1 | no/false/0 | adj&lt;br /&gt;
	-- to disable/enable &amp;quot;sourcing cirumstances&amp;quot; or use adjectival form for the plain date&lt;br /&gt;
	local pd = args.plaindate or args.pd or &amp;quot;no&amp;quot;&lt;br /&gt;
	args.pd = pd&lt;br /&gt;
&lt;br /&gt;
	-- allow qualifiers to have a different date format; default to year unless qualsonly is set&lt;br /&gt;
	args.qdf = args.qdf or args.qualifierdateformat or args.df or (not qualsonly and &amp;quot;y&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	local lang = args.lang or findLang().code&lt;br /&gt;
&lt;br /&gt;
    -- qualID is a string list of wanted qualifiers or &amp;quot;ALL&amp;quot;&lt;br /&gt;
    qualID = qualID or &amp;quot;&amp;quot;&lt;br /&gt;
    -- capitalise list of wanted qualifiers and substitute &amp;quot;DATES&amp;quot;&lt;br /&gt;
    qualID = qualID:upper():gsub(&amp;quot;DATES&amp;quot;, &amp;quot;P580, P582&amp;quot;)&lt;br /&gt;
    local allflag = (qualID == &amp;quot;ALL&amp;quot;)&lt;br /&gt;
    -- create table of wanted qualifiers as key&lt;br /&gt;
    local qwanted = {}&lt;br /&gt;
    -- create sequence of wanted qualifiers&lt;br /&gt;
    local qorder = {}&lt;br /&gt;
    for q in mw.text.gsplit(qualID, &amp;quot;%p&amp;quot;) do -- split at punctuation and iterate&lt;br /&gt;
        local qtrim = mw.text.trim(q)&lt;br /&gt;
        if qtrim ~= &amp;quot;&amp;quot; then&lt;br /&gt;
            qwanted[mw.text.trim(q)] = true&lt;br /&gt;
            qorder[#qorder+1] = qtrim&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    -- qsep is the output separator for rendering qualifier list&lt;br /&gt;
    local qsep = (args.qsep or &amp;quot;&amp;quot;):gsub(&#039;&amp;quot;&#039;, &#039;&#039;)&lt;br /&gt;
    -- qargs are the arguments to supply to assembleoutput()&lt;br /&gt;
    local qargs = {&lt;br /&gt;
        [&amp;quot;osd&amp;quot;]         = &amp;quot;false&amp;quot;,&lt;br /&gt;
        [&amp;quot;linked&amp;quot;]      = tostring(linked),&lt;br /&gt;
        [&amp;quot;prefix&amp;quot;]      = args.qprefix,&lt;br /&gt;
        [&amp;quot;postfix&amp;quot;]     = args.qpostfix,&lt;br /&gt;
        [&amp;quot;linkprefix&amp;quot;]  = args.qlinkprefix or args.qlp,&lt;br /&gt;
        [&amp;quot;linkpostfix&amp;quot;] = args.qlinkpostfix,&lt;br /&gt;
        [&amp;quot;wdl&amp;quot;]         = &amp;quot;false&amp;quot;,&lt;br /&gt;
        [&amp;quot;unitabbr&amp;quot;]    = tostring(uabbr),&lt;br /&gt;
        [&amp;quot;maxvals&amp;quot;]     = 0,&lt;br /&gt;
        [&amp;quot;sorted&amp;quot;]      = tostring(args.qsorted),&lt;br /&gt;
        [&amp;quot;noicon&amp;quot;]      = &amp;quot;true&amp;quot;,&lt;br /&gt;
        [&amp;quot;list&amp;quot;]        = args.qlist,&lt;br /&gt;
        [&amp;quot;sep&amp;quot;]         = qsep,&lt;br /&gt;
        [&amp;quot;langobj&amp;quot;]     = args.langobj,&lt;br /&gt;
        [&amp;quot;lang&amp;quot;]        = args.langobj.code,&lt;br /&gt;
        [&amp;quot;df&amp;quot;]          = args.qdf,&lt;br /&gt;
        [&amp;quot;sn&amp;quot;]          = parseParam(args.qsn or args.qshortname, false),&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
	-- all proper values of a Wikidata property will be the same type as the first&lt;br /&gt;
	-- qualifiers don&#039;t have a mainsnak, properties do&lt;br /&gt;
	local datatype = objproperty[1].datatype or objproperty[1].mainsnak.datatype&lt;br /&gt;
&lt;br /&gt;
	-- out[] holds the a list of returned values for this property&lt;br /&gt;
	-- mlt[] holds the language code if the datatype is monolingual text&lt;br /&gt;
	local out = {}&lt;br /&gt;
	local mlt = {}&lt;br /&gt;
&lt;br /&gt;
	for k, v in ipairs(objproperty) do&lt;br /&gt;
		local hasvalue = true&lt;br /&gt;
		if (onlysrc and not sourced(v)) then&lt;br /&gt;
			-- no value: it isn&#039;t sourced when onlysourced=true&lt;br /&gt;
			hasvalue = false&lt;br /&gt;
		else&lt;br /&gt;
			local val, lcode = rendersnak(v, args, linked, lprefix, lpostfix, prefix, postfix, uabbr)&lt;br /&gt;
			if not val then&lt;br /&gt;
				hasvalue = false -- rank doesn&#039;t match&lt;br /&gt;
			elseif qualsonly and qualID then&lt;br /&gt;
				-- suppress value returned: only qualifiers are requested&lt;br /&gt;
			else&lt;br /&gt;
				out[#out+1], mlt[#out+1] = val, lcode&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- See if qualifiers are to be returned:&lt;br /&gt;
		local snak = v.mainsnak or v&lt;br /&gt;
		if hasvalue and v.qualifiers and qualID ~= &amp;quot;&amp;quot; and snak.snaktype~=&amp;quot;novalue&amp;quot; then&lt;br /&gt;
            -- collect all wanted qualifier values returned in qlist, indexed by propertyID&lt;br /&gt;
			local qlist = {}&lt;br /&gt;
			local timestart, timeend = &amp;quot;&amp;quot;, &amp;quot;&amp;quot;&lt;br /&gt;
            -- loop through qualifiers&lt;br /&gt;
            for k1, v1 in pairs(v.qualifiers) do&lt;br /&gt;
                if allflag or qwanted[k1] then&lt;br /&gt;
                    if k1 == &amp;quot;P1326&amp;quot; then&lt;br /&gt;
                        local ts = v1[1].datavalue.value.time&lt;br /&gt;
                        local dp = v1[1].datavalue.value.precision&lt;br /&gt;
                        qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, &amp;quot;&amp;quot;, lang, &amp;quot;before&amp;quot;)&lt;br /&gt;
                    elseif k1 == &amp;quot;P1319&amp;quot; then&lt;br /&gt;
                        local ts = v1[1].datavalue.value.time&lt;br /&gt;
                        local dp = v1[1].datavalue.value.precision&lt;br /&gt;
                        qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, &amp;quot;&amp;quot;, lang, &amp;quot;after&amp;quot;)&lt;br /&gt;
                    elseif k1 == &amp;quot;P580&amp;quot; then&lt;br /&gt;
                        timestart = propertyvalueandquals(v1, qargs)[1] or &amp;quot;&amp;quot; -- treat only one start time as valid&lt;br /&gt;
                    elseif k1 == &amp;quot;P582&amp;quot; then&lt;br /&gt;
                        timeend = propertyvalueandquals(v1, qargs)[1] or &amp;quot;&amp;quot; -- treat only one end time as valid&lt;br /&gt;
                    else&lt;br /&gt;
                        local q = assembleoutput(propertyvalueandquals(v1, qargs), qargs)&lt;br /&gt;
                        -- we already deal with circa via &#039;sourcing circumstances&#039; if the datatype was time&lt;br /&gt;
                        -- circa may be either linked or unlinked *** internationalise later ***&lt;br /&gt;
                        if datatype ~= &amp;quot;time&amp;quot; or q ~= &amp;quot;circa&amp;quot; and not (type(q) == &amp;quot;string&amp;quot; and q:find(&amp;quot;circa]]&amp;quot;)) then&lt;br /&gt;
                            qlist[k1] = q&lt;br /&gt;
                        end&lt;br /&gt;
                    end&lt;br /&gt;
                end -- of test for wanted&lt;br /&gt;
            end -- of loop through qualifiers&lt;br /&gt;
            -- set date separator&lt;br /&gt;
			local t = timestart .. timeend&lt;br /&gt;
			-- *** internationalise date separators later ***&lt;br /&gt;
			local dsep = &amp;quot;&amp;amp;ndash;&amp;quot;&lt;br /&gt;
			if t:find(&amp;quot;%s&amp;quot;) or t:find(&amp;quot;&amp;amp;nbsp;&amp;quot;) then dsep = &amp;quot; &amp;amp;ndash; &amp;quot; end&lt;br /&gt;
            -- set the order for the list of qualifiers returned; start time and end time go last&lt;br /&gt;
			if next(qlist) then&lt;br /&gt;
                local qlistout = {}&lt;br /&gt;
                if allflag then&lt;br /&gt;
                    for k2, v2 in pairs(qlist) do&lt;br /&gt;
                        qlistout[#qlistout+1] = v2&lt;br /&gt;
                    end&lt;br /&gt;
                else&lt;br /&gt;
                    for i2, v2 in ipairs(qorder) do&lt;br /&gt;
                        qlistout[#qlistout+1] = qlist[v2]&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
                if t ~= &amp;quot;&amp;quot; then&lt;br /&gt;
                    qlistout[#qlistout+1] = timestart .. dsep .. timeend&lt;br /&gt;
                end&lt;br /&gt;
				local qstr = assembleoutput(qlistout, qargs)&lt;br /&gt;
				if qualsonly then&lt;br /&gt;
					out[#out+1] = qstr&lt;br /&gt;
				else&lt;br /&gt;
					out[#out] = out[#out] .. &amp;quot; (&amp;quot; .. qstr .. &amp;quot;)&amp;quot;&lt;br /&gt;
				end&lt;br /&gt;
			elseif t ~= &amp;quot;&amp;quot; then&lt;br /&gt;
				if qualsonly then&lt;br /&gt;
					if timestart == &amp;quot;&amp;quot; then&lt;br /&gt;
						out[#out+1] = timeend&lt;br /&gt;
					elseif timeend == &amp;quot;&amp;quot; then&lt;br /&gt;
						out[#out+1] = timestart&lt;br /&gt;
					else&lt;br /&gt;
						out[#out+1] = timestart .. dsep .. timeend&lt;br /&gt;
					end&lt;br /&gt;
				else&lt;br /&gt;
					out[#out] = out[#out] .. &amp;quot; (&amp;quot; .. timestart .. dsep .. timeend .. &amp;quot;)&amp;quot;&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end -- of test for qualifiers wanted&lt;br /&gt;
&lt;br /&gt;
		if maxvals &amp;gt; 0 and #out &amp;gt;= maxvals then break end&lt;br /&gt;
	end -- of for each value loop&lt;br /&gt;
&lt;br /&gt;
	-- we need to pick one value to return if the datatype was &amp;quot;monolingualtext&amp;quot;&lt;br /&gt;
	-- if there&#039;s only one value, use that&lt;br /&gt;
	-- otherwise look through the fallback languages for a match&lt;br /&gt;
	if datatype == &amp;quot;monolingualtext&amp;quot; and #out &amp;gt;1 then&lt;br /&gt;
		lang = mw.text.split( lang, &#039;-&#039;, true )[1]&lt;br /&gt;
		local fbtbl = mw.language.getFallbacksFor( lang )&lt;br /&gt;
		table.insert( fbtbl, 1, lang )&lt;br /&gt;
		local bestval = &amp;quot;&amp;quot;&lt;br /&gt;
		local found = false&lt;br /&gt;
		for idx1, lang1 in ipairs(fbtbl) do&lt;br /&gt;
			for idx2, lang2 in ipairs(mlt) do&lt;br /&gt;
				if (lang1 == lang2) and not found then&lt;br /&gt;
					bestval = out[idx2]&lt;br /&gt;
					found = true&lt;br /&gt;
					break&lt;br /&gt;
				end&lt;br /&gt;
			end -- loop through values of property&lt;br /&gt;
		end -- loop through fallback languages&lt;br /&gt;
		if found then&lt;br /&gt;
			-- replace output table with a table containing the best value&lt;br /&gt;
			out = { bestval }&lt;br /&gt;
		else&lt;br /&gt;
			-- more than one value and none of them on the list of fallback languages&lt;br /&gt;
			-- sod it, just give them the first one&lt;br /&gt;
			out = { out[1] }&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return out&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Common code for p.getValueByQual and p.getValueByLang&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: parseParam; setRanks; parseInput; sourced; assembleoutput;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local _getvaluebyqual = function(frame, qualID, checkvalue)&lt;br /&gt;
&lt;br /&gt;
	-- The property ID that will have a qualifier is the first unnamed parameter&lt;br /&gt;
	local propertyID = mw.text.trim(frame.args[1] or &amp;quot;&amp;quot;)&lt;br /&gt;
	if propertyID == &amp;quot;&amp;quot; then return &amp;quot;no property supplied&amp;quot; end&lt;br /&gt;
&lt;br /&gt;
	if qualID == &amp;quot;&amp;quot; then return &amp;quot;no qualifier supplied&amp;quot; end&lt;br /&gt;
&lt;br /&gt;
	-- onlysourced is a boolean passed to return property values&lt;br /&gt;
	-- only when property values are sourced to something other than Wikipedia&lt;br /&gt;
	-- if nothing or an empty string is passed set it true&lt;br /&gt;
	-- if &amp;quot;false&amp;quot; or &amp;quot;no&amp;quot; or 0 is passed set it false&lt;br /&gt;
	local onlysrc = parseParam(frame.args.onlysourced or frame.args.osd, true)&lt;br /&gt;
&lt;br /&gt;
	-- set the requested ranks flags&lt;br /&gt;
	frame.args.reqranks = setRanks(frame.args.rank)&lt;br /&gt;
&lt;br /&gt;
	-- set a language object and code in the frame.args table&lt;br /&gt;
	frame.args.langobj = findLang(frame.args.lang)&lt;br /&gt;
	frame.args.lang = frame.args.langobj.code&lt;br /&gt;
&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
&lt;br /&gt;
	-- check for locally supplied parameter in second unnamed parameter&lt;br /&gt;
	-- success means no local parameter and the property exists&lt;br /&gt;
	local qid, props = parseInput(frame, args[2], propertyID)&lt;br /&gt;
&lt;br /&gt;
	local linked = parseParam(args.linked, true)&lt;br /&gt;
	local lpre = (args.linkprefix or args.lp or &amp;quot;&amp;quot;):gsub(&#039;&amp;quot;&#039;, &#039;&#039;)&lt;br /&gt;
	local lpost = (args.linkpostfix or &amp;quot;&amp;quot;):gsub(&#039;&amp;quot;&#039;, &#039;&#039;)&lt;br /&gt;
	local pre = (args.prefix or &amp;quot;&amp;quot;):gsub(&#039;&amp;quot;&#039;, &#039;&#039;)&lt;br /&gt;
	local post = (args.postfix or &amp;quot;&amp;quot;):gsub(&#039;&amp;quot;&#039;, &#039;&#039;)&lt;br /&gt;
	local uabbr = parseParam(args.unitabbr or args.uabbr, false)&lt;br /&gt;
	local filter = (args.unit or &amp;quot;&amp;quot;):upper()&lt;br /&gt;
	local maxvals = tonumber(args.maxvals) or 0&lt;br /&gt;
	if filter == &amp;quot;&amp;quot; then filter = nil end&lt;br /&gt;
&lt;br /&gt;
	if qid then&lt;br /&gt;
		local out = {}&lt;br /&gt;
		-- Scan through the values of the property&lt;br /&gt;
		-- we want something like property is &amp;quot;pronunciation audio (P443)&amp;quot; in propertyID&lt;br /&gt;
		-- with a qualifier like &amp;quot;language of work or name (P407)&amp;quot; in qualID&lt;br /&gt;
		-- whose value has the required ID, like &amp;quot;British English (Q7979)&amp;quot;, in qval&lt;br /&gt;
		for k1, v1 in ipairs(props) do&lt;br /&gt;
			if v1.mainsnak.snaktype == &amp;quot;value&amp;quot; then&lt;br /&gt;
				-- check if it has the right qualifier&lt;br /&gt;
				local v1q = v1.qualifiers&lt;br /&gt;
				if v1q and v1q[qualID] then&lt;br /&gt;
					if onlysrc == false or sourced(v1) then&lt;br /&gt;
						-- if we&#039;ve got this far, we have a (sourced) claim with qualifiers&lt;br /&gt;
						-- so see if matches the required value&lt;br /&gt;
						-- We&#039;ll only deal with wikibase-items and strings for now&lt;br /&gt;
						if v1q[qualID][1].datatype == &amp;quot;wikibase-item&amp;quot; then&lt;br /&gt;
							if checkvalue(v1q[qualID][1].datavalue.value.id) then&lt;br /&gt;
								out[#out + 1] = rendersnak(v1, args, linked, lpre, lpost, pre, post, uabbr, filter)&lt;br /&gt;
							end&lt;br /&gt;
						elseif v1q[qualID][1].datatype == &amp;quot;string&amp;quot; then&lt;br /&gt;
							if checkvalue(v1q[qualID][1].datavalue.value) then&lt;br /&gt;
								out[#out + 1] = rendersnak(v1, args, linked, lpre, lpost, pre, post, uabbr, filter)&lt;br /&gt;
							end&lt;br /&gt;
						end&lt;br /&gt;
					end -- of check for sourced&lt;br /&gt;
				end -- of check for matching required value and has qualifiers&lt;br /&gt;
			else&lt;br /&gt;
				return nil&lt;br /&gt;
			end -- of check for string&lt;br /&gt;
			if maxvals &amp;gt; 0 and #out &amp;gt;= maxvals then break end&lt;br /&gt;
		end -- of loop through values of propertyID&lt;br /&gt;
		return assembleoutput(out, frame.args, qid, propertyID)&lt;br /&gt;
	else&lt;br /&gt;
		return props -- either local parameter or nothing&lt;br /&gt;
	end -- of test for success&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- _location takes Q-id and follows P276 (location)&lt;br /&gt;
-- or P131 (located in the administrative territorial entity) or P706 (located on terrain feature)&lt;br /&gt;
-- from the initial item to higher level territories/locations until it reaches the highest.&lt;br /&gt;
-- An optional boolean, &#039;first&#039;, determines whether the first item is returned (default: false).&lt;br /&gt;
-- An optional boolean &#039;skip&#039; toggles the display to skip to the last item (default: false).&lt;br /&gt;
-- It returns a table containing the locations - linked where possible, except for the highest.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: findLang(); labelOrId(); linkedItem&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local _location = function(qid, first, skip)&lt;br /&gt;
	first = parseParam(first, false)&lt;br /&gt;
	skip = parseParam(skip, false)&lt;br /&gt;
	local locs = {&amp;quot;P276&amp;quot;, &amp;quot;P131&amp;quot;, &amp;quot;P706&amp;quot;}&lt;br /&gt;
	local out = {}&lt;br /&gt;
	local langcode = findLang():getCode()&lt;br /&gt;
	local finished = false&lt;br /&gt;
	local count = 0&lt;br /&gt;
	local prevqid = &amp;quot;Q0&amp;quot;&lt;br /&gt;
	repeat&lt;br /&gt;
		local prop&lt;br /&gt;
		for i1, v1 in ipairs(locs) do&lt;br /&gt;
			local proptbl = mw.wikibase.getBestStatements(qid, v1)&lt;br /&gt;
			if #proptbl &amp;gt; 1 then&lt;br /&gt;
				-- there is more than one higher location&lt;br /&gt;
				local prevP131, prevP131id&lt;br /&gt;
				if prevqid ~= &amp;quot;Q0&amp;quot; then&lt;br /&gt;
					prevP131 = mw.wikibase.getBestStatements(prevqid, &amp;quot;P131&amp;quot;)[1]&lt;br /&gt;
					prevP131id = prevP131&lt;br /&gt;
					and prevP131.mainsnak.datavalue&lt;br /&gt;
					and prevP131.mainsnak.datavalue.value.id&lt;br /&gt;
				end&lt;br /&gt;
				for i2, v2 in ipairs(proptbl) do&lt;br /&gt;
					local parttbl = v2.qualifiers and v2.qualifiers.P518&lt;br /&gt;
					if parttbl then&lt;br /&gt;
						-- this higher location has qualifier &#039;applies to part&#039; (P518)&lt;br /&gt;
						for i3, v3 in ipairs(parttbl) do&lt;br /&gt;
							if v3.snaktype == &amp;quot;value&amp;quot; and v3.datavalue.value.id == prevqid then&lt;br /&gt;
								-- it has a value equal to the previous location&lt;br /&gt;
								prop = proptbl[i2]&lt;br /&gt;
								break&lt;br /&gt;
							end -- of test for matching last location&lt;br /&gt;
						end -- of loop through values of &#039;applies to part&#039;&lt;br /&gt;
					else&lt;br /&gt;
						-- there&#039;s no qualifier &#039;applies to part&#039; (P518)&lt;br /&gt;
						-- so check if the previous location had a P131 that matches this alternate&lt;br /&gt;
						if qid == prevP131id then&lt;br /&gt;
								prop = proptbl[i2]&lt;br /&gt;
								break&lt;br /&gt;
						end -- of test for matching previous P131&lt;br /&gt;
					end&lt;br /&gt;
				end -- of loop through parent locations&lt;br /&gt;
				-- fallback to second value if match not found&lt;br /&gt;
				prop = prop or proptbl[2]&lt;br /&gt;
			elseif #proptbl &amp;gt; 0 then&lt;br /&gt;
				prop = proptbl[1]&lt;br /&gt;
			end&lt;br /&gt;
			if prop then break end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- check if it&#039;s an instance of (P31) a country (Q6256) or sovereign state (Q3624078)&lt;br /&gt;
		-- and terminate the chain if it is&lt;br /&gt;
		local inst = mw.wikibase.getAllStatements(qid, &amp;quot;P31&amp;quot;)&lt;br /&gt;
		if #inst &amp;gt; 0 then&lt;br /&gt;
			for k, v in ipairs(inst) do&lt;br /&gt;
				local instid = v.mainsnak.datavalue and v.mainsnak.datavalue.value.id&lt;br /&gt;
				-- stop if it&#039;s a country (or a country within the United Kingdom if skip is true)&lt;br /&gt;
				if instid == &amp;quot;Q6256&amp;quot; or instid == &amp;quot;Q3624078&amp;quot; or (skip and instid == &amp;quot;Q3336843&amp;quot;) then&lt;br /&gt;
					prop = nil -- this will ensure this is treated as top-level location&lt;br /&gt;
					break&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- get the name of this location and update qid to point to the parent location&lt;br /&gt;
		if prop and prop.mainsnak.datavalue then&lt;br /&gt;
			if not skip or count == 0 then&lt;br /&gt;
				local args = { lprefix = &amp;quot;:&amp;quot; }&lt;br /&gt;
				out[#out+1] = linkedItem(qid, args) -- get a linked value if we can&lt;br /&gt;
			end&lt;br /&gt;
			qid, prevqid = prop.mainsnak.datavalue.value.id, qid&lt;br /&gt;
		else&lt;br /&gt;
			-- This is top-level location, so get short name except when this is the first item&lt;br /&gt;
			-- Use full label if there&#039;s no short name or this is the first item&lt;br /&gt;
			local prop1813 = mw.wikibase.getAllStatements(qid, &amp;quot;P1813&amp;quot;)&lt;br /&gt;
			-- if there&#039;s a short name and this isn&#039;t the only item&lt;br /&gt;
			if prop1813[1] and (#out &amp;gt; 0)then&lt;br /&gt;
				local shortname&lt;br /&gt;
				-- short name is monolingual text, so look for match to the local language&lt;br /&gt;
				-- choose the shortest &#039;short name&#039; in that language&lt;br /&gt;
				for k, v in pairs(prop1813) do&lt;br /&gt;
					if v.mainsnak.datavalue.value.language == langcode then&lt;br /&gt;
						local name = v.mainsnak.datavalue.value.text&lt;br /&gt;
						if (not shortname) or (#name &amp;lt; #shortname) then&lt;br /&gt;
							shortname = name&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				-- add the shortname if one is found, fallback to the label&lt;br /&gt;
				-- but skip it if it&#039;s &amp;quot;USA&amp;quot;&lt;br /&gt;
				if shortname ~= &amp;quot;USA&amp;quot; then&lt;br /&gt;
					out[#out+1] = shortname or labelOrId(qid)&lt;br /&gt;
				else&lt;br /&gt;
					if skip then out[#out+1] = &amp;quot;US&amp;quot; end&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				-- no shortname, so just add the label&lt;br /&gt;
				local loc = labelOrId(qid)&lt;br /&gt;
				-- exceptions go here:&lt;br /&gt;
				if loc == &amp;quot;United States of America&amp;quot; then&lt;br /&gt;
					out[#out+1] = &amp;quot;United States&amp;quot;&lt;br /&gt;
				else&lt;br /&gt;
					out[#out+1] = loc&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			finished = true&lt;br /&gt;
		end&lt;br /&gt;
		count = count + 1&lt;br /&gt;
	until finished or count &amp;gt;= 10 -- limit to 10 levels to avoid infinite loops&lt;br /&gt;
&lt;br /&gt;
	-- remove the first location if not required&lt;br /&gt;
	if not first then table.remove(out, 1) end&lt;br /&gt;
&lt;br /&gt;
	-- we might have duplicate text for consecutive locations, so remove them&lt;br /&gt;
	if #out &amp;gt; 2 then&lt;br /&gt;
		local plain = {}&lt;br /&gt;
		for i, v in ipairs(out) do&lt;br /&gt;
			-- strip any links&lt;br /&gt;
			plain[i] = v:gsub(&amp;quot;^%[%[[^|]*|&amp;quot;, &amp;quot;&amp;quot;):gsub(&amp;quot;]]$&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
		local idx = 2&lt;br /&gt;
		repeat&lt;br /&gt;
			if plain[idx] == plain[idx-1] then&lt;br /&gt;
				-- duplicate found&lt;br /&gt;
				local removeidx = 0&lt;br /&gt;
				if (plain[idx] ~= out[idx]) and (plain[idx-1] == out[idx-1]) then&lt;br /&gt;
					-- only second one is linked, so drop the first&lt;br /&gt;
					removeidx = idx - 1&lt;br /&gt;
				elseif (plain[idx] == out[idx]) and (plain[idx-1] ~= out[idx-1]) then&lt;br /&gt;
					-- only first one is linked, so drop the second&lt;br /&gt;
					removeidx = idx&lt;br /&gt;
				else&lt;br /&gt;
					-- pick one&lt;br /&gt;
					removeidx = idx - (os.time()%2)&lt;br /&gt;
				end&lt;br /&gt;
				table.remove(out, removeidx)&lt;br /&gt;
				table.remove(plain, removeidx)&lt;br /&gt;
			else&lt;br /&gt;
				idx = idx +1&lt;br /&gt;
			end&lt;br /&gt;
		until idx &amp;gt;= #out&lt;br /&gt;
	end&lt;br /&gt;
	return out&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- _getsumofparts scans the property &#039;has part&#039; (P527) for values matching a list.&lt;br /&gt;
-- The list (args.vlist) consists of a string of Qids separated by spaces or any usual punctuation.&lt;br /&gt;
-- If the matched values have a qualifer &#039;quantity&#039; (P1114), those quantites are summed.&lt;br /&gt;
-- The sum is returned as a number (i.e. 0 if none)&lt;br /&gt;
-- a table of arguments is supplied implementing the usual parameters.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: setRanks; parseParam; parseInput; sourced; assembleoutput;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local _getsumofparts = function(args)&lt;br /&gt;
	local vallist = (args.vlist or &amp;quot;&amp;quot;):upper()&lt;br /&gt;
	if vallist == &amp;quot;&amp;quot; then return end&lt;br /&gt;
	args.reqranks = setRanks(args.rank)&lt;br /&gt;
	local f = {}&lt;br /&gt;
	f.args = args&lt;br /&gt;
	local qid, props = parseInput(f, &amp;quot;&amp;quot;, &amp;quot;P527&amp;quot;)&lt;br /&gt;
	if not qid then return 0 end&lt;br /&gt;
	local onlysrc = parseParam(args.onlysourced or args.osd, true)&lt;br /&gt;
	local sum = 0&lt;br /&gt;
	for k1, v1 in ipairs(props) do&lt;br /&gt;
		if (onlysrc == false or sourced(v1))&lt;br /&gt;
			and v1.mainsnak.snaktype == &amp;quot;value&amp;quot;&lt;br /&gt;
			and v1.mainsnak.datavalue.type == &amp;quot;wikibase-entityid&amp;quot;&lt;br /&gt;
			and vallist:match( v1.mainsnak.datavalue.value.id )&lt;br /&gt;
			and v1.qualifiers&lt;br /&gt;
			then&lt;br /&gt;
			local quals = v1.qualifiers[&amp;quot;P1114&amp;quot;]&lt;br /&gt;
			if quals then&lt;br /&gt;
				for k2, v2 in ipairs(quals) do&lt;br /&gt;
					sum = sum + v2.datavalue.value.amount&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return sum&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Public functions&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- _getValue makes the functionality of getValue available to other modules&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: setRanks; parseInput; propertyvalueandquals; assembleoutput; parseParam; sourced;&lt;br /&gt;
-- labelOrId; i18n.latestdatequalifier; format_Date; makeOrdinal; roundto; decimalPrecision; decimalToDMS;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p._getValue = function(args)&lt;br /&gt;
	-- parameter sets for commonly used groups of parameters&lt;br /&gt;
	local paraset = tonumber(args.ps or args.parameterset or 0)&lt;br /&gt;
	if paraset == 1 then&lt;br /&gt;
		-- a common setting, not usable in infoboxes because the 2018 RFC requires sources&lt;br /&gt;
		args.rank = &amp;quot;best&amp;quot;&lt;br /&gt;
		args.fetchwikidata = &amp;quot;ALL&amp;quot;&lt;br /&gt;
		args.onlysourced = &amp;quot;no&amp;quot;&lt;br /&gt;
		args.noicon = &amp;quot;true&amp;quot;&lt;br /&gt;
	elseif paraset == 2 then&lt;br /&gt;
		-- equivalent to raw, not usable in infoboxes because the 2018 RFC requires sources&lt;br /&gt;
		args.rank = &amp;quot;best&amp;quot;&lt;br /&gt;
		args.fetchwikidata = &amp;quot;ALL&amp;quot;&lt;br /&gt;
		args.onlysourced = &amp;quot;no&amp;quot;&lt;br /&gt;
		args.noicon = &amp;quot;true&amp;quot;&lt;br /&gt;
		args.linked = &amp;quot;no&amp;quot;&lt;br /&gt;
		args.pd = &amp;quot;true&amp;quot;&lt;br /&gt;
	elseif paraset == 3 then&lt;br /&gt;
		-- parameterset 1, but usable in infoboxes because the 2018 RFC requires sources&lt;br /&gt;
		args.rank = &amp;quot;best&amp;quot;&lt;br /&gt;
		args.fetchwikidata = &amp;quot;ALL&amp;quot;&lt;br /&gt;
		args.onlysourced = &amp;quot;yes&amp;quot;&lt;br /&gt;
		args.noicon = &amp;quot;true&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- implement eid parameter&lt;br /&gt;
	local eid = args.eid&lt;br /&gt;
	if eid == &amp;quot;&amp;quot; then&lt;br /&gt;
		return nil&lt;br /&gt;
	elseif eid then&lt;br /&gt;
		args.qid = eid&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local propertyID = mw.text.trim(args[1] or &amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	args.reqranks = setRanks(args.rank)&lt;br /&gt;
&lt;br /&gt;
	-- replacetext (rt) is a string that is returned instead of any non-empty Wikidata value&lt;br /&gt;
	-- this is useful for tracking and debugging, so we set fetchwikidata=ALL to fill the whitelist&lt;br /&gt;
	local replacetext = mw.text.trim(args.rt or args.replacetext or &amp;quot;&amp;quot;)&lt;br /&gt;
	if replacetext ~= &amp;quot;&amp;quot; then&lt;br /&gt;
		args.fetchwikidata = &amp;quot;ALL&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local f = {}&lt;br /&gt;
	f.args = args&lt;br /&gt;
	local entityid, props = parseInput(f, f.args[2], propertyID)&lt;br /&gt;
&lt;br /&gt;
	if not entityid then&lt;br /&gt;
		return props -- either the input parameter or nothing&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- qual is a string containing the property ID of the qualifier(s) to be returned&lt;br /&gt;
	-- if qual == &amp;quot;ALL&amp;quot; then all qualifiers returned&lt;br /&gt;
	-- if qual == &amp;quot;DATES&amp;quot; then qualifiers P580 (start time) and P582 (end time) returned&lt;br /&gt;
	-- if nothing or an empty string is passed set it nil -&amp;gt; no qualifiers returned&lt;br /&gt;
	local qualID = mw.text.trim(args.qual or &amp;quot;&amp;quot;):upper()&lt;br /&gt;
	if qualID == &amp;quot;&amp;quot; then qualID = nil end&lt;br /&gt;
&lt;br /&gt;
	-- set a language object and code in the args table&lt;br /&gt;
	args.langobj = findLang(args.lang)&lt;br /&gt;
	args.lang = args.langobj.code&lt;br /&gt;
&lt;br /&gt;
	-- table &#039;out&#039; stores the return value(s):&lt;br /&gt;
	local out = propertyvalueandquals(props, args, qualID)&lt;br /&gt;
&lt;br /&gt;
	-- format the table of values and return it as a string:&lt;br /&gt;
	return assembleoutput(out, args, entityid, propertyID)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getValue is used to get the value(s) of a property&lt;br /&gt;
-- The property ID is passed as the first unnamed parameter and is required.&lt;br /&gt;
-- A locally supplied parameter may optionaly be supplied as the second unnamed parameter.&lt;br /&gt;
-- The function will now also return qualifiers if parameter qual is supplied&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: _getValue; setRanks; parseInput; propertyvalueandquals; assembleoutput; parseParam; sourced;&lt;br /&gt;
-- labelOrId; i18n.latestdatequalifier; format_Date; makeOrdinal; roundto; decimalPrecision; decimalToDMS;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getValue = function(frame)&lt;br /&gt;
	local args= frame.args&lt;br /&gt;
	if not args[1] then&lt;br /&gt;
		args = frame:getParent().args&lt;br /&gt;
		if not args[1] then return i18n.errors[&amp;quot;No property supplied&amp;quot;] end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return p._getValue(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getPreferredValue is used to get a value,&lt;br /&gt;
-- (or a comma separated list of them if multiple values exist).&lt;br /&gt;
-- If preferred ranks are set, it will return those values, otherwise values with normal ranks&lt;br /&gt;
-- now redundant to getValue with |rank=best&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: p.getValue; setRanks; parseInput; propertyvalueandquals; assembleoutput;&lt;br /&gt;
-- parseParam; sourced; labelOrId; i18n.latestdatequalifier; format_Date;&lt;br /&gt;
-- makeOrdinal; roundto; decimalPrecision; decimalToDMS;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getPreferredValue = function(frame)&lt;br /&gt;
	frame.args.rank = &amp;quot;best&amp;quot;&lt;br /&gt;
	return p.getValue(frame)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getCoords is used to get coordinates for display in an infobox&lt;br /&gt;
-- whitelist and blacklist are implemented&lt;br /&gt;
-- optional &#039;display&#039; parameter is allowed, defaults to nil - was &amp;quot;inline, title&amp;quot;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: setRanks(); parseInput(); decimalPrecision();&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getCoords = function(frame)&lt;br /&gt;
	local propertyID = &amp;quot;P625&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	-- if there is a &#039;display&#039; parameter supplied, use it&lt;br /&gt;
	-- otherwise default to nothing&lt;br /&gt;
	local disp = frame.args.display or &amp;quot;&amp;quot;&lt;br /&gt;
	if disp == &amp;quot;&amp;quot; then&lt;br /&gt;
		disp = nil -- default to not supplying display parameter, was &amp;quot;inline, title&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- there may be a format parameter to switch from deg/min/sec to decimal degrees&lt;br /&gt;
	-- default is deg/min/sec&lt;br /&gt;
	-- decimal degrees needs |format = dec&lt;br /&gt;
	local form = (frame.args.format or &amp;quot;&amp;quot;):lower():sub(1,3)&lt;br /&gt;
	if form ~= &amp;quot;dec&amp;quot; then&lt;br /&gt;
		form = &amp;quot;dms&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- just deal with best values&lt;br /&gt;
	frame.args.reqranks = setRanks(&amp;quot;best&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	local qid, props = parseInput(frame, frame.args[1], propertyID)&lt;br /&gt;
	if not qid then&lt;br /&gt;
		return props -- either local parameter or nothing&lt;br /&gt;
	else&lt;br /&gt;
		local dv = props[1].mainsnak.datavalue.value&lt;br /&gt;
		local lat, long, prec = dv.latitude, dv.longitude, dv.precision&lt;br /&gt;
		lat = decimalPrecision(lat, prec)&lt;br /&gt;
		long = decimalPrecision(long, prec)&lt;br /&gt;
		local lat_long = { lat, long }&lt;br /&gt;
		lat_long[&amp;quot;display&amp;quot;] = disp&lt;br /&gt;
		lat_long[&amp;quot;format&amp;quot;] = form&lt;br /&gt;
		-- invoke template Coord with the values stored in the table&lt;br /&gt;
		return frame:expandTemplate{title = &#039;coord&#039;, args = lat_long}&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getQualifierValue is used to get a formatted value of a qualifier&lt;br /&gt;
--&lt;br /&gt;
-- The call needs:	a property (the unnamed parameter or 1=)&lt;br /&gt;
-- 					a target value for that property (pval=)&lt;br /&gt;
--					a qualifier for that target value (qual=)&lt;br /&gt;
-- The usual whitelisting and blacklisting of the property is implemented&lt;br /&gt;
-- The boolean onlysourced= parameter can be set to return nothing&lt;br /&gt;
-- when the property is unsourced (or only sourced to Wikipedia)&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: parseParam(); setRanks(); parseInput(); sourced();&lt;br /&gt;
-- propertyvalueandquals(); assembleoutput();&lt;br /&gt;
-- labelOrId(); i18n.latestdatequalifier(); format_Date();&lt;br /&gt;
-- findLang(); makeOrdinal(); roundto(); decimalPrecision(); decimalToDMS();&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getQualifierValue = function(frame)&lt;br /&gt;
&lt;br /&gt;
	-- The property ID that will have a qualifier is the first unnamed parameter&lt;br /&gt;
	local propertyID = mw.text.trim(frame.args[1] or &amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	-- The value of the property we want to match whose qualifier value is to be returned&lt;br /&gt;
	-- is passed in named parameter |pval=&lt;br /&gt;
	local propvalue = frame.args.pval&lt;br /&gt;
&lt;br /&gt;
	-- The property ID of the qualifier&lt;br /&gt;
	-- whose value is to be returned is passed in named parameter |qual=&lt;br /&gt;
	local qualifierID = frame.args.qual&lt;br /&gt;
&lt;br /&gt;
	-- A filter can be set like this: filter=P642==Q22674854&lt;br /&gt;
	local filter, fprop, fval&lt;br /&gt;
	local ftable = mw.text.split(frame.args.filter or &amp;quot;&amp;quot;, &amp;quot;==&amp;quot;)&lt;br /&gt;
	if ftable[2] then&lt;br /&gt;
		fprop = mw.text.trim(ftable[1])&lt;br /&gt;
		fval = mw.text.trim(ftable[2])&lt;br /&gt;
		filter = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- onlysourced is a boolean passed to return qualifiers&lt;br /&gt;
	-- only when property values are sourced to something other than Wikipedia&lt;br /&gt;
	-- if nothing or an empty string is passed set it true&lt;br /&gt;
	-- if &amp;quot;false&amp;quot; or &amp;quot;no&amp;quot; or 0 is passed set it false&lt;br /&gt;
	local onlysrc = parseParam(frame.args.onlysourced or frame.args.osd, true)&lt;br /&gt;
&lt;br /&gt;
	-- set a language object and language code in the frame.args table&lt;br /&gt;
	frame.args.langobj = findLang(frame.args.lang)&lt;br /&gt;
	frame.args.lang = frame.args.langobj.code&lt;br /&gt;
&lt;br /&gt;
	-- set the requested ranks flags&lt;br /&gt;
	frame.args.reqranks = setRanks(frame.args.rank)&lt;br /&gt;
&lt;br /&gt;
	-- check for locally supplied parameter in second unnamed parameter&lt;br /&gt;
	-- success means no local parameter and the property exists&lt;br /&gt;
	local qid, props = parseInput(frame, frame.args[2], propertyID)&lt;br /&gt;
	if qid then&lt;br /&gt;
		local out = {}&lt;br /&gt;
		-- Scan through the values of the property&lt;br /&gt;
		-- we want something like property is P793, significant event (in propertyID)&lt;br /&gt;
		-- whose value is something like Q385378, construction (in propvalue)&lt;br /&gt;
		-- then we can return the value(s) of a qualifier such as P580, start time (in qualifierID)&lt;br /&gt;
		for k1, v1 in pairs(props) do&lt;br /&gt;
			if v1.mainsnak.snaktype == &amp;quot;value&amp;quot; and v1.mainsnak.datavalue.type == &amp;quot;wikibase-entityid&amp;quot; then&lt;br /&gt;
				-- It&#039;s a wiki-linked value, so check if it&#039;s the target (in propvalue) and if it has qualifiers&lt;br /&gt;
				if v1.mainsnak.datavalue.value.id == propvalue and v1.qualifiers then&lt;br /&gt;
					if onlysrc == false or sourced(v1) then&lt;br /&gt;
						-- if we&#039;ve got this far, we have a (sourced) claim with qualifiers&lt;br /&gt;
						-- which matches the target, so apply the filter and find the value(s) of the qualifier we want&lt;br /&gt;
						if not filter or (v1.qualifiers[fprop] and v1.qualifiers[fprop][1].datavalue.value.id == fval) then&lt;br /&gt;
							local quals = v1.qualifiers[qualifierID]&lt;br /&gt;
							if quals then&lt;br /&gt;
								-- can&#039;t reference qualifer, so set onlysourced = &amp;quot;no&amp;quot; (args are strings, not boolean)&lt;br /&gt;
								local qargs = frame.args&lt;br /&gt;
								qargs.onlysourced = &amp;quot;no&amp;quot;&lt;br /&gt;
								local vals = propertyvalueandquals(quals, qargs, qid)&lt;br /&gt;
								for k, v in ipairs(vals) do&lt;br /&gt;
									out[#out + 1] = v&lt;br /&gt;
								end&lt;br /&gt;
							end&lt;br /&gt;
						end&lt;br /&gt;
					end -- of check for sourced&lt;br /&gt;
				end -- of check for matching required value and has qualifiers&lt;br /&gt;
			end -- of check for wikibase entity&lt;br /&gt;
		end -- of loop through values of propertyID&lt;br /&gt;
		return assembleoutput(out, frame.args, qid, propertyID)&lt;br /&gt;
	else&lt;br /&gt;
		return props -- either local parameter or nothing&lt;br /&gt;
	end -- of test for success&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getSumOfParts scans the property &#039;has part&#039; (P527) for values matching a list.&lt;br /&gt;
-- The list is passed in parameter vlist.&lt;br /&gt;
-- It consists of a string of Qids separated by spaces or any usual punctuation.&lt;br /&gt;
-- If the matched values have a qualifier &#039;quantity&#039; (P1114), those quantities are summed.&lt;br /&gt;
-- The sum is returned as a number or nothing if zero.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: _getsumofparts;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getSumOfParts = function(frame)&lt;br /&gt;
	local sum = _getsumofparts(frame.args)&lt;br /&gt;
	if sum == 0 then return end&lt;br /&gt;
	return sum&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getValueByQual gets the value of a property which has a qualifier with a given entity value&lt;br /&gt;
-- The call needs:&lt;br /&gt;
--					a property ID (the unnamed parameter or 1=Pxxx)&lt;br /&gt;
--					the ID of a qualifier for that property (qualID=Pyyy)&lt;br /&gt;
--					either the Wikibase-entity ID of a value for that qualifier (qvalue=Qzzz)&lt;br /&gt;
--					or a string value for that qualifier (qvalue=abc123)&lt;br /&gt;
-- The usual whitelisting, blacklisting, onlysourced, etc. are implemented&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: _getvaluebyqual; parseParam; setRanks; parseInput; sourced;&lt;br /&gt;
-- assembleoutput;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getValueByQual = function(frame)&lt;br /&gt;
	local qualID = frame.args.qualID&lt;br /&gt;
	-- The Q-id of the value for the qualifier we want to match is in named parameter |qvalue=&lt;br /&gt;
	local qval = frame.args.qvalue or &amp;quot;&amp;quot;&lt;br /&gt;
	if qval == &amp;quot;&amp;quot; then return &amp;quot;no qualifier value supplied&amp;quot; end&lt;br /&gt;
	local function checkQID(id)&lt;br /&gt;
		return id == qval&lt;br /&gt;
	end&lt;br /&gt;
	return _getvaluebyqual(frame, qualID, checkQID)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getValueByLang gets the value of a property which has a qualifier P407&lt;br /&gt;
-- (&amp;quot;language of work or name&amp;quot;) whose value has the given language code&lt;br /&gt;
-- The call needs:&lt;br /&gt;
--					a property ID (the unnamed parameter or 1=Pxxx)&lt;br /&gt;
--					the MediaWiki language code to match the language (lang=xx[-yy])&lt;br /&gt;
--					(if no code is supplied, it uses the default language)&lt;br /&gt;
-- The usual whitelisting, blacklisting, onlysourced, etc. are implemented&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: _getvaluebyqual; parseParam; setRanks; parseInput; sourced; assembleoutput;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getValueByLang = function(frame)&lt;br /&gt;
	-- The language code for the qualifier we want to match is in named parameter |lang=&lt;br /&gt;
	local langcode = findLang(frame.args.lang).code&lt;br /&gt;
	local function checkLanguage(id)&lt;br /&gt;
		-- id should represent a language like &amp;quot;British English (Q7979)&amp;quot;&lt;br /&gt;
		-- it should have string property &amp;quot;Wikimedia language code (P424)&amp;quot;&lt;br /&gt;
		-- qlcode will be a table:&lt;br /&gt;
		local qlcode = mw.wikibase.getBestStatements(id, &amp;quot;P424&amp;quot;)&lt;br /&gt;
		if (#qlcode &amp;gt; 0) and (qlcode[1].mainsnak.datavalue.value == langcode) then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return _getvaluebyqual(frame, &amp;quot;P407&amp;quot;, checkLanguage)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getValueByRefSource gets the value of a property which has a reference &amp;quot;stated in&amp;quot; (P248)&lt;br /&gt;
-- whose value has the given entity-ID.&lt;br /&gt;
-- The call needs:&lt;br /&gt;
--					a property ID (the unnamed parameter or 1=Pxxx)&lt;br /&gt;
--					the entity ID of a value to match where the reference is stated in (match=Qzzz)&lt;br /&gt;
-- The usual whitelisting, blacklisting, onlysourced, etc. are implemented&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getValueByRefSource = function(frame)&lt;br /&gt;
	-- The property ID that we want to check is the first unnamed parameter&lt;br /&gt;
	local propertyID = mw.text.trim(frame.args[1] or &amp;quot;&amp;quot;):upper()&lt;br /&gt;
	if propertyID == &amp;quot;&amp;quot; then return &amp;quot;no property supplied&amp;quot; end&lt;br /&gt;
&lt;br /&gt;
	-- The Q-id of the value we want to match is in named parameter |qvalue=&lt;br /&gt;
	local qval = (frame.args.match or &amp;quot;&amp;quot;):upper()&lt;br /&gt;
	if qval == &amp;quot;&amp;quot; then qval = &amp;quot;Q21540096&amp;quot; end&lt;br /&gt;
&lt;br /&gt;
	local unit = (frame.args.unit or &amp;quot;&amp;quot;):upper()&lt;br /&gt;
	if unit == &amp;quot;&amp;quot; then unit = &amp;quot;Q4917&amp;quot; end&lt;br /&gt;
&lt;br /&gt;
	local onlysrc = parseParam(frame.args.onlysourced or frame.args.osd, true)&lt;br /&gt;
&lt;br /&gt;
	-- set the requested ranks flags&lt;br /&gt;
	frame.args.reqranks = setRanks(frame.args.rank)&lt;br /&gt;
&lt;br /&gt;
	-- set a language object and code in the frame.args table&lt;br /&gt;
	frame.args.langobj = findLang(frame.args.lang)&lt;br /&gt;
	frame.args.lang = frame.args.langobj.code&lt;br /&gt;
&lt;br /&gt;
	local linked = parseParam(frame.args.linked, true)&lt;br /&gt;
&lt;br /&gt;
	local uabbr = parseParam(frame.args.uabbr or frame.args.unitabbr, false)&lt;br /&gt;
&lt;br /&gt;
	-- qid not nil means no local parameter and the property exists&lt;br /&gt;
	local qid, props = parseInput(frame, frame.args[2], propertyID)&lt;br /&gt;
&lt;br /&gt;
	if qid then&lt;br /&gt;
		local out = {}&lt;br /&gt;
		local mlt= {}&lt;br /&gt;
		for k1, v1 in ipairs(props) do&lt;br /&gt;
			if onlysrc == false or sourced(v1) then&lt;br /&gt;
				if v1.references then&lt;br /&gt;
					for k2, v2 in ipairs(v1.references) do&lt;br /&gt;
						if v2.snaks.P248 then&lt;br /&gt;
							for k3, v3 in ipairs(v2.snaks.P248) do&lt;br /&gt;
								if v3.datavalue.value.id == qval then&lt;br /&gt;
									out[#out+1], mlt[#out+1] = rendersnak(v1, frame.args, linked, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;, uabbr, unit)&lt;br /&gt;
									if not mlt[#out] then&lt;br /&gt;
										-- we only need one match per property value&lt;br /&gt;
										-- unless datatype was monolingual text&lt;br /&gt;
										break&lt;br /&gt;
									end&lt;br /&gt;
								end -- of test for match&lt;br /&gt;
							end -- of loop through values &amp;quot;stated in&amp;quot;&lt;br /&gt;
						end -- of test that &amp;quot;stated in&amp;quot; exists&lt;br /&gt;
					end -- of loop through references&lt;br /&gt;
				end -- of test that references exist&lt;br /&gt;
			end -- of test for sourced&lt;br /&gt;
		end -- of loop through values of propertyID&lt;br /&gt;
		if #mlt &amp;gt; 0 then&lt;br /&gt;
			local langcode = frame.args.lang&lt;br /&gt;
			langcode = mw.text.split( langcode, &#039;-&#039;, true )[1]&lt;br /&gt;
			local fbtbl = mw.language.getFallbacksFor( langcode )&lt;br /&gt;
			table.insert( fbtbl, 1, langcode )&lt;br /&gt;
			local bestval = &amp;quot;&amp;quot;&lt;br /&gt;
			local found = false&lt;br /&gt;
			for idx1, lang1 in ipairs(fbtbl) do&lt;br /&gt;
				for idx2, lang2 in ipairs(mlt) do&lt;br /&gt;
					if (lang1 == lang2) and not found then&lt;br /&gt;
						bestval = out[idx2]&lt;br /&gt;
						found = true&lt;br /&gt;
						break&lt;br /&gt;
					end&lt;br /&gt;
				end -- loop through values of property&lt;br /&gt;
			end -- loop through fallback languages&lt;br /&gt;
			if found then&lt;br /&gt;
				-- replace output table with a table containing the best value&lt;br /&gt;
				out = { bestval }&lt;br /&gt;
			else&lt;br /&gt;
				-- more than one value and none of them on the list of fallback languages&lt;br /&gt;
				-- sod it, just give them the first one&lt;br /&gt;
				out = { out[1] }&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return assembleoutput(out, frame.args, qid, propertyID)&lt;br /&gt;
	else&lt;br /&gt;
		return props -- no property or local parameter supplied&lt;br /&gt;
	end -- of test for success&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getPropertyIDs takes most of the usual parameters.&lt;br /&gt;
-- The usual whitelisting, blacklisting, onlysourced, etc. are implemented.&lt;br /&gt;
-- It returns the Entity-IDs (Qids) of the values of a property if it is a Wikibase-Entity.&lt;br /&gt;
-- Otherwise it returns nothing.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p._getPropertyIDs = function(args)&lt;br /&gt;
	args.reqranks = setRanks(args.rank)&lt;br /&gt;
	args.langobj = findLang(args.lang)&lt;br /&gt;
	args.lang = args.langobj.code&lt;br /&gt;
	-- change default for noicon to true&lt;br /&gt;
	args.noicon = tostring(parseParam(args.noicon or &amp;quot;&amp;quot;, true))&lt;br /&gt;
	local f = {}&lt;br /&gt;
	f.args = args&lt;br /&gt;
	local pid = mw.text.trim(args[1] or &amp;quot;&amp;quot;):upper()&lt;br /&gt;
&lt;br /&gt;
	-- get the qid and table of claims for the property, or nothing and the local value passed&lt;br /&gt;
	local qid, props = parseInput(f, args[2], pid)&lt;br /&gt;
	if not qid then return props end&lt;br /&gt;
	if not props[1] then return nil end&lt;br /&gt;
	local onlysrc = parseParam(args.onlysourced or args.osd, true)&lt;br /&gt;
	local maxvals = tonumber(args.maxvals) or 0&lt;br /&gt;
&lt;br /&gt;
	local out = {}&lt;br /&gt;
	for i, v in ipairs(props) do&lt;br /&gt;
		local snak = v.mainsnak&lt;br /&gt;
		if ( snak.datatype == &amp;quot;wikibase-item&amp;quot; )&lt;br /&gt;
			and ( v.rank and args.reqranks[v.rank:sub(1, 1)] )&lt;br /&gt;
			and ( snak.snaktype == &amp;quot;value&amp;quot; )&lt;br /&gt;
			and ( sourced(v) or not onlysrc )&lt;br /&gt;
			then&lt;br /&gt;
			out[#out+1] = snak.datavalue.value.id&lt;br /&gt;
		end&lt;br /&gt;
		if maxvals &amp;gt; 0 and #out &amp;gt;= maxvals then break end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return assembleoutput(out, args, qid, pid)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.getPropertyIDs = function(frame)&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
	return p._getPropertyIDs(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getQualifierIDs takes most of the usual parameters.&lt;br /&gt;
-- The usual whitelisting, blacklisting, onlysourced, etc. are implemented.&lt;br /&gt;
-- It takes a property-id as the first unnamed parameter, and an optional parameter qlist&lt;br /&gt;
-- which is a list of qualifier property-ids to search for (default is &amp;quot;ALL&amp;quot;)&lt;br /&gt;
-- It returns the Entity-IDs (Qids) of the values of a property if it is a Wikibase-Entity.&lt;br /&gt;
-- Otherwise it returns nothing.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getQualifierIDs = function(frame)&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
	args.reqranks = setRanks(args.rank)&lt;br /&gt;
	args.langobj = findLang(args.lang)&lt;br /&gt;
	args.lang = args.langobj.code&lt;br /&gt;
	-- change default for noicon to true&lt;br /&gt;
	args.noicon = tostring(parseParam(args.noicon or &amp;quot;&amp;quot;, true))&lt;br /&gt;
	local f = {}&lt;br /&gt;
	f.args = args&lt;br /&gt;
	local pid = mw.text.trim(args[1] or &amp;quot;&amp;quot;):upper()&lt;br /&gt;
&lt;br /&gt;
	-- get the qid and table of claims for the property, or nothing and the local value passed&lt;br /&gt;
	local qid, props = parseInput(f, args[2], pid)&lt;br /&gt;
	if not qid then return props end&lt;br /&gt;
	if not props[1] then return nil end&lt;br /&gt;
	-- get the other parameters&lt;br /&gt;
	local onlysrc = parseParam(args.onlysourced or args.osd, true)&lt;br /&gt;
	local maxvals = tonumber(args.maxvals) or 0&lt;br /&gt;
	local qlist = args.qlist or &amp;quot;&amp;quot;&lt;br /&gt;
	if qlist == &amp;quot;&amp;quot; then qlist = &amp;quot;ALL&amp;quot; end&lt;br /&gt;
	qlist = qlist:gsub(&amp;quot;[%p%s]+&amp;quot;, &amp;quot; &amp;quot;) .. &amp;quot; &amp;quot;&lt;br /&gt;
&lt;br /&gt;
	local out = {}&lt;br /&gt;
	for i, v in ipairs(props) do&lt;br /&gt;
		local snak = v.mainsnak&lt;br /&gt;
		if ( v.rank and args.reqranks[v.rank:sub(1, 1)] )&lt;br /&gt;
			and ( snak.snaktype == &amp;quot;value&amp;quot; )&lt;br /&gt;
			and ( sourced(v) or not onlysrc )&lt;br /&gt;
			then&lt;br /&gt;
			if v.qualifiers then&lt;br /&gt;
				for k1, v1 in pairs(v.qualifiers) do&lt;br /&gt;
					if qlist == &amp;quot;ALL &amp;quot; or qlist:match(k1 .. &amp;quot; &amp;quot;) then&lt;br /&gt;
						for i2, v2 in ipairs(v1) do&lt;br /&gt;
							if v2.datatype == &amp;quot;wikibase-item&amp;quot; and v2.snaktype == &amp;quot;value&amp;quot; then&lt;br /&gt;
								out[#out+1] = v2.datavalue.value.id&lt;br /&gt;
							end -- of test that id exists&lt;br /&gt;
						end -- of loop through qualifier values&lt;br /&gt;
					end -- of test for kq in qlist&lt;br /&gt;
				end -- of loop through qualifiers&lt;br /&gt;
			end -- of test for qualifiers&lt;br /&gt;
		end -- of test for rank value, sourced, and value exists&lt;br /&gt;
		if maxvals &amp;gt; 0 and #out &amp;gt;= maxvals then break end&lt;br /&gt;
	end -- of loop through property values&lt;br /&gt;
&lt;br /&gt;
	return assembleoutput(out, args, qid, pid)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getPropOfProp takes two propertyIDs: prop1 and prop2 (as well as the usual parameters)&lt;br /&gt;
-- If the value(s) of prop1 are of type &amp;quot;wikibase-item&amp;quot; then it returns the value(s) of prop2&lt;br /&gt;
-- of each of those wikibase-items.&lt;br /&gt;
-- The usual whitelisting, blacklisting, onlysourced, etc. are implemented&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p._getPropOfProp = function(args)&lt;br /&gt;
	-- parameter sets for commonly used groups of parameters&lt;br /&gt;
	local paraset = tonumber(args.ps or args.parameterset or 0)&lt;br /&gt;
	if paraset == 1 then&lt;br /&gt;
		-- a common setting&lt;br /&gt;
		args.rank = &amp;quot;best&amp;quot;&lt;br /&gt;
		args.fetchwikidata = &amp;quot;ALL&amp;quot;&lt;br /&gt;
		args.onlysourced = &amp;quot;no&amp;quot;&lt;br /&gt;
		args.noicon = &amp;quot;true&amp;quot;&lt;br /&gt;
	elseif paraset == 2 then&lt;br /&gt;
		-- equivalent to raw&lt;br /&gt;
		args.rank = &amp;quot;best&amp;quot;&lt;br /&gt;
		args.fetchwikidata = &amp;quot;ALL&amp;quot;&lt;br /&gt;
		args.onlysourced = &amp;quot;no&amp;quot;&lt;br /&gt;
		args.noicon = &amp;quot;true&amp;quot;&lt;br /&gt;
		args.linked = &amp;quot;no&amp;quot;&lt;br /&gt;
		args.pd = &amp;quot;true&amp;quot;&lt;br /&gt;
	elseif paraset == 3 then&lt;br /&gt;
		-- third set goes here&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	args.reqranks = setRanks(args.rank)&lt;br /&gt;
	args.langobj = findLang(args.lang)&lt;br /&gt;
	args.lang = args.langobj.code&lt;br /&gt;
	local pid1 = args.prop1 or args.pid1 or &amp;quot;&amp;quot;&lt;br /&gt;
	local pid2 = args.prop2 or args.pid2 or &amp;quot;&amp;quot;&lt;br /&gt;
	if pid1 == &amp;quot;&amp;quot; or pid2 == &amp;quot;&amp;quot; then return nil end&lt;br /&gt;
&lt;br /&gt;
	local f = {}&lt;br /&gt;
	f.args = args&lt;br /&gt;
	local qid1, statements1 = parseInput(f, args[1], pid1)&lt;br /&gt;
	-- parseInput nulls empty args[1] and returns args[1] if nothing on Wikidata&lt;br /&gt;
	if not qid1 then return statements1 end&lt;br /&gt;
	-- otherwise it returns the qid and a table for the statement&lt;br /&gt;
	local onlysrc = parseParam(args.onlysourced or args.osd, true)&lt;br /&gt;
	local maxvals = tonumber(args.maxvals) or 0&lt;br /&gt;
	local qualID = mw.text.trim(args.qual or &amp;quot;&amp;quot;):upper()&lt;br /&gt;
	if qualID == &amp;quot;&amp;quot; then qualID = nil end&lt;br /&gt;
	local out = {}&lt;br /&gt;
	for k, v in ipairs(statements1) do&lt;br /&gt;
		if not onlysrc or sourced(v) then&lt;br /&gt;
			local snak = v.mainsnak&lt;br /&gt;
			if snak.datatype == &amp;quot;wikibase-item&amp;quot; and snak.snaktype == &amp;quot;value&amp;quot; then&lt;br /&gt;
				local qid2 = snak.datavalue.value.id&lt;br /&gt;
				local statements2 = {}&lt;br /&gt;
				if args.reqranks.b then&lt;br /&gt;
					statements2 = mw.wikibase.getBestStatements(qid2, pid2)&lt;br /&gt;
				else&lt;br /&gt;
					statements2 = mw.wikibase.getAllStatements(qid2, pid2)&lt;br /&gt;
				end&lt;br /&gt;
				if statements2[1] then&lt;br /&gt;
					local out2 = propertyvalueandquals(statements2, args, qualID)&lt;br /&gt;
					out[#out+1] = assembleoutput(out2, args, qid2, pid2)&lt;br /&gt;
				end&lt;br /&gt;
			end -- of test for valid property1 value&lt;br /&gt;
		end -- of test for sourced&lt;br /&gt;
		if maxvals &amp;gt; 0 and #out &amp;gt;= maxvals then break end&lt;br /&gt;
	end -- of loop through values of property1&lt;br /&gt;
	return assembleoutput(out, args, qid1, pid1)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.getPropOfProp = function(frame)&lt;br /&gt;
	local args= frame.args&lt;br /&gt;
	if not args.prop1 and not args.pid1 then&lt;br /&gt;
		args = frame:getParent().args&lt;br /&gt;
		if not args.prop1 and not args.pid1 then return i18n.errors[&amp;quot;No property supplied&amp;quot;] end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return p._getPropOfProp(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getAwardCat takes most of the usual parameters. If the item has values of P166 (award received),&lt;br /&gt;
-- then it examines each of those awards for P2517 (category for recipients of this award).&lt;br /&gt;
-- If it exists, it returns the corresponding category,&lt;br /&gt;
-- with the item&#039;s P734 (family name) as sort key, or no sort key if there is no family name.&lt;br /&gt;
-- The sort key may be overridden by the parameter |sortkey (alias |sk).&lt;br /&gt;
-- The usual whitelisting, blacklisting, onlysourced, etc. are implemented&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getAwardCat = function(frame)&lt;br /&gt;
	frame.args.reqranks = setRanks(frame.args.rank)&lt;br /&gt;
	frame.args.langobj = findLang(frame.args.lang)&lt;br /&gt;
	frame.args.lang = frame.args.langobj.code&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
	args.sep = &amp;quot; &amp;quot;&lt;br /&gt;
	local pid1 = args.prop1 or &amp;quot;P166&amp;quot;&lt;br /&gt;
	local pid2 = args.prop2 or &amp;quot;P2517&amp;quot;&lt;br /&gt;
	if pid1 == &amp;quot;&amp;quot; or pid2 == &amp;quot;&amp;quot; then return nil end&lt;br /&gt;
	-- locally supplied value:&lt;br /&gt;
	local localval = mw.text.trim(args[1] or &amp;quot;&amp;quot;)&lt;br /&gt;
	local qid1, statements1 = parseInput(frame, localval, pid1)&lt;br /&gt;
	if not qid1 then return localval end&lt;br /&gt;
	-- linkprefix (strip quotes)&lt;br /&gt;
	local lp = (args.linkprefix or args.lp or &amp;quot;&amp;quot;):gsub(&#039;&amp;quot;&#039;, &#039;&#039;)&lt;br /&gt;
	-- sort key (strip quotes, hyphens and periods):&lt;br /&gt;
	local sk = (args.sortkey or args.sk or &amp;quot;&amp;quot;):gsub(&#039;[&amp;quot;-.]&#039;, &#039;&#039;)&lt;br /&gt;
	-- family name:&lt;br /&gt;
	local famname = &amp;quot;&amp;quot;&lt;br /&gt;
	if sk == &amp;quot;&amp;quot; then&lt;br /&gt;
		local p734 = mw.wikibase.getBestStatements(qid1, &amp;quot;P734&amp;quot;)[1]&lt;br /&gt;
		local p734id = p734 and p734.mainsnak.snaktype == &amp;quot;value&amp;quot; and p734.mainsnak.datavalue.value.id or &amp;quot;&amp;quot;&lt;br /&gt;
		famname = mw.wikibase.getSitelink(p734id) or &amp;quot;&amp;quot;&lt;br /&gt;
		-- strip namespace and disambigation&lt;br /&gt;
		local pos = famname:find(&amp;quot;:&amp;quot;) or 0&lt;br /&gt;
		famname = famname:sub(pos+1):gsub(&amp;quot;%s%(.+%)$&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
		if famname == &amp;quot;&amp;quot; then&lt;br /&gt;
			local lbl = mw.wikibase.getLabel(p734id)&lt;br /&gt;
			famname = lbl and mw.text.nowiki(lbl) or &amp;quot;&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local onlysrc = parseParam(args.onlysourced or args.osd, true)&lt;br /&gt;
	local maxvals = tonumber(args.maxvals) or 0&lt;br /&gt;
	local qualID = mw.text.trim(args.qual or &amp;quot;&amp;quot;):upper()&lt;br /&gt;
	if qualID == &amp;quot;&amp;quot; then qualID = nil end&lt;br /&gt;
	local out = {}&lt;br /&gt;
	for k, v in ipairs(statements1) do&lt;br /&gt;
		if not onlysrc or sourced(v) then&lt;br /&gt;
			local snak = v.mainsnak&lt;br /&gt;
			if snak.datatype == &amp;quot;wikibase-item&amp;quot; and snak.snaktype == &amp;quot;value&amp;quot; then&lt;br /&gt;
				local qid2 = snak.datavalue.value.id&lt;br /&gt;
				local statements2 = {}&lt;br /&gt;
				if args.reqranks.b then&lt;br /&gt;
					statements2 = mw.wikibase.getBestStatements(qid2, pid2)&lt;br /&gt;
				else&lt;br /&gt;
					statements2 = mw.wikibase.getAllStatements(qid2, pid2)&lt;br /&gt;
				end&lt;br /&gt;
				if statements2[1] and statements2[1].mainsnak.snaktype == &amp;quot;value&amp;quot; then&lt;br /&gt;
					local qid3 = statements2[1].mainsnak.datavalue.value.id&lt;br /&gt;
					local sitelink = mw.wikibase.getSitelink(qid3)&lt;br /&gt;
					-- if there&#039;s no local sitelink, create the sitelink from English label&lt;br /&gt;
					if not sitelink then&lt;br /&gt;
						local lbl = mw.wikibase.getLabelByLang(qid3, &amp;quot;en&amp;quot;)&lt;br /&gt;
						if lbl then&lt;br /&gt;
							if lbl:sub(1,9) == &amp;quot;Category:&amp;quot; then&lt;br /&gt;
								sitelink = mw.text.nowiki(lbl)&lt;br /&gt;
							else&lt;br /&gt;
								sitelink = &amp;quot;Category:&amp;quot; .. mw.text.nowiki(lbl)&lt;br /&gt;
							end&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
					if sitelink then&lt;br /&gt;
						if sk ~= &amp;quot;&amp;quot; then&lt;br /&gt;
							out[#out+1] = &amp;quot;[[&amp;quot; .. lp .. sitelink .. &amp;quot;|&amp;quot; .. sk .. &amp;quot;]]&amp;quot;&lt;br /&gt;
						elseif famname ~= &amp;quot;&amp;quot; then&lt;br /&gt;
							out[#out+1] = &amp;quot;[[&amp;quot; .. lp .. sitelink .. &amp;quot;|&amp;quot; .. famname .. &amp;quot;]]&amp;quot;&lt;br /&gt;
						else&lt;br /&gt;
							out[#out+1] = &amp;quot;[[&amp;quot; .. lp .. sitelink .. &amp;quot;]]&amp;quot;&lt;br /&gt;
						end -- of check for sort keys&lt;br /&gt;
					end -- of test for sitelink&lt;br /&gt;
				end -- of test for category&lt;br /&gt;
			end -- of test for wikibase item has a value&lt;br /&gt;
		end -- of test for sourced&lt;br /&gt;
		if maxvals &amp;gt; 0 and #out &amp;gt;= maxvals then break end&lt;br /&gt;
	end -- of loop through values of property1&lt;br /&gt;
	return assembleoutput(out, args, qid1, pid1)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getIntersectCat takes most of the usual parameters.&lt;br /&gt;
-- The usual whitelisting, blacklisting, onlysourced, etc. are implemented&lt;br /&gt;
-- It takes two properties, |prop1 and |prop2 (e.g. occupation and country of citizenship)&lt;br /&gt;
-- Each property&#039;s value is a wiki-base entity&lt;br /&gt;
-- For each value of the first parameter (ranks implemented) it fetches the value&#039;s main category&lt;br /&gt;
-- and then each value of the second parameter (possibly substituting a simpler description)&lt;br /&gt;
-- then it returns all of the categories representing the intersection of those properties,&lt;br /&gt;
-- (e.g. Category:Actors from Canada). A joining term may be supplied (e.g. |join=from).&lt;br /&gt;
-- The item&#039;s P734 (family name) is the sort key, or no sort key if there is no family name.&lt;br /&gt;
-- The sort key may be overridden by the parameter |sortkey (alias |sk).&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getIntersectCat = function(frame)&lt;br /&gt;
	frame.args.reqranks = setRanks(frame.args.rank)&lt;br /&gt;
	frame.args.langobj = findLang(frame.args.lang)&lt;br /&gt;
	frame.args.lang = frame.args.langobj.code&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
	args.sep = &amp;quot; &amp;quot;&lt;br /&gt;
	args.linked = &amp;quot;no&amp;quot;&lt;br /&gt;
	local pid1 = args.prop1 or &amp;quot;P106&amp;quot;&lt;br /&gt;
	local pid2 = args.prop2 or &amp;quot;P27&amp;quot;&lt;br /&gt;
	if pid1 == &amp;quot;&amp;quot; or pid2 == &amp;quot;&amp;quot; then return nil end&lt;br /&gt;
	local qid, statements1 = parseInput(frame, &amp;quot;&amp;quot;, pid1)&lt;br /&gt;
	if not qid then return nil end&lt;br /&gt;
	local qid, statements2 = parseInput(frame, &amp;quot;&amp;quot;, pid2)&lt;br /&gt;
	if not qid then return nil end&lt;br /&gt;
	-- topics like countries may have different names in categories from their label in Wikidata&lt;br /&gt;
	local subs_exists, subs = pcall(mw.loadData, &amp;quot;Module:WikidataIB/subs&amp;quot;)&lt;br /&gt;
	local join = args.join or &amp;quot;&amp;quot;&lt;br /&gt;
	local onlysrc = parseParam(args.onlysourced or args.osd, true)&lt;br /&gt;
	local maxvals = tonumber(args.maxvals) or 0&lt;br /&gt;
	-- linkprefix (strip quotes)&lt;br /&gt;
	local lp = (args.linkprefix or args.lp or &amp;quot;&amp;quot;):gsub(&#039;&amp;quot;&#039;, &#039;&#039;)&lt;br /&gt;
	-- sort key (strip quotes, hyphens and periods):&lt;br /&gt;
	local sk = (args.sortkey or args.sk or &amp;quot;&amp;quot;):gsub(&#039;[&amp;quot;-.]&#039;, &#039;&#039;)&lt;br /&gt;
	-- family name:&lt;br /&gt;
	local famname = &amp;quot;&amp;quot;&lt;br /&gt;
	if sk == &amp;quot;&amp;quot; then&lt;br /&gt;
		local p734 = mw.wikibase.getBestStatements(qid, &amp;quot;P734&amp;quot;)[1]&lt;br /&gt;
		local p734id = p734 and p734.mainsnak.snaktype == &amp;quot;value&amp;quot; and p734.mainsnak.datavalue.value.id or &amp;quot;&amp;quot;&lt;br /&gt;
		famname = mw.wikibase.getSitelink(p734id) or &amp;quot;&amp;quot;&lt;br /&gt;
		-- strip namespace and disambigation&lt;br /&gt;
		local pos = famname:find(&amp;quot;:&amp;quot;) or 0&lt;br /&gt;
		famname = famname:sub(pos+1):gsub(&amp;quot;%s%(.+%)$&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
		if famname == &amp;quot;&amp;quot; then&lt;br /&gt;
			local lbl = mw.wikibase.getLabel(p734id)&lt;br /&gt;
			famname = lbl and mw.text.nowiki(lbl) or &amp;quot;&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local cat1 = {}&lt;br /&gt;
	for k, v in ipairs(statements1) do&lt;br /&gt;
		if not onlysrc or sourced(v) then&lt;br /&gt;
			-- get the ID representing the value of the property&lt;br /&gt;
			local pvalID = (v.mainsnak.snaktype == &amp;quot;value&amp;quot;) and v.mainsnak.datavalue.value.id&lt;br /&gt;
			if pvalID then&lt;br /&gt;
				-- get the topic&#039;s main category (P910) for that entity&lt;br /&gt;
				local p910 = mw.wikibase.getBestStatements(pvalID, &amp;quot;P910&amp;quot;)[1]&lt;br /&gt;
				if p910 and p910.mainsnak.snaktype == &amp;quot;value&amp;quot; then&lt;br /&gt;
					local tmcID = p910.mainsnak.datavalue.value.id&lt;br /&gt;
					-- use sitelink or the English label for the cat&lt;br /&gt;
					local cat = mw.wikibase.getSitelink(tmcID)&lt;br /&gt;
					if not cat then&lt;br /&gt;
						local lbl = mw.wikibase.getLabelByLang(tmcID, &amp;quot;en&amp;quot;)&lt;br /&gt;
						if lbl then&lt;br /&gt;
							if lbl:sub(1,9) == &amp;quot;Category:&amp;quot; then&lt;br /&gt;
								cat = mw.text.nowiki(lbl)&lt;br /&gt;
							else&lt;br /&gt;
								cat = &amp;quot;Category:&amp;quot; .. mw.text.nowiki(lbl)&lt;br /&gt;
							end&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
					cat1[#cat1+1] = cat&lt;br /&gt;
				end -- of test for topic&#039;s main category exists&lt;br /&gt;
			end -- of test for property has vaild value&lt;br /&gt;
		end -- of test for sourced&lt;br /&gt;
		if maxvals &amp;gt; 0 and #cat1 &amp;gt;= maxvals then break end&lt;br /&gt;
	end&lt;br /&gt;
	local cat2 = {}&lt;br /&gt;
	for k, v in ipairs(statements2) do&lt;br /&gt;
		if not onlysrc or sourced(v) then&lt;br /&gt;
			local cat = rendersnak(v, args)&lt;br /&gt;
			if subs[cat] then cat = subs[cat] end&lt;br /&gt;
			cat2[#cat2+1] = cat&lt;br /&gt;
		end&lt;br /&gt;
		if maxvals &amp;gt; 0 and #cat2 &amp;gt;= maxvals then break end&lt;br /&gt;
	end&lt;br /&gt;
	local out = {}&lt;br /&gt;
	for k1, v1 in ipairs(cat1) do&lt;br /&gt;
		for k2, v2 in ipairs(cat2) do&lt;br /&gt;
			if sk ~= &amp;quot;&amp;quot; then&lt;br /&gt;
				out[#out+1] = &amp;quot;[[&amp;quot; .. lp .. v1 .. &amp;quot; &amp;quot; .. join .. &amp;quot; &amp;quot; .. v2 .. &amp;quot;|&amp;quot; .. sk .. &amp;quot;]]&amp;quot;&lt;br /&gt;
			elseif famname ~= &amp;quot;&amp;quot; then&lt;br /&gt;
				out[#out+1] = &amp;quot;[[&amp;quot; .. lp .. v1 .. &amp;quot; &amp;quot; .. join .. &amp;quot; &amp;quot; .. v2 .. &amp;quot;|&amp;quot; .. famname .. &amp;quot;]]&amp;quot;&lt;br /&gt;
			else&lt;br /&gt;
				out[#out+1] = &amp;quot;[[&amp;quot; .. lp .. v1 .. &amp;quot; &amp;quot; .. join .. &amp;quot; &amp;quot; .. v2 .. &amp;quot;]]&amp;quot;&lt;br /&gt;
			end -- of check for sort keys&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	args.noicon = &amp;quot;true&amp;quot;&lt;br /&gt;
	return assembleoutput(out, args, qid, pid1)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- qualsToTable takes most of the usual parameters.&lt;br /&gt;
-- The usual whitelisting, blacklisting, onlysourced, etc. are implemented.&lt;br /&gt;
-- A qid may be given, and the first unnamed parameter is the property ID, which is of type wikibase item.&lt;br /&gt;
-- It takes a list of qualifier property IDs as |quals=&lt;br /&gt;
-- For a given qid and property, it creates the rows of an html table,&lt;br /&gt;
-- each row being a value of the property (optionally only if the property matches the value in |pval= )&lt;br /&gt;
-- each cell being the first value of the qualifier corresponding to the list in |quals&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: parseParam; setRanks; parseInput; sourced;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.qualsToTable = function(frame)&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
&lt;br /&gt;
	local quals = args.quals or &amp;quot;&amp;quot;&lt;br /&gt;
	if quals == &amp;quot;&amp;quot; then return &amp;quot;&amp;quot; end&lt;br /&gt;
&lt;br /&gt;
	args.reqranks = setRanks(args.rank)&lt;br /&gt;
&lt;br /&gt;
	local propertyID = mw.text.trim(args[1] or &amp;quot;&amp;quot;)&lt;br /&gt;
	local f = {}&lt;br /&gt;
	f.args = args&lt;br /&gt;
	local entityid, props = parseInput(f, &amp;quot;&amp;quot;, propertyID)&lt;br /&gt;
	if not entityid then return &amp;quot;&amp;quot; end&lt;br /&gt;
&lt;br /&gt;
	args.langobj = findLang(args.lang)&lt;br /&gt;
	args.lang = args.langobj.code&lt;br /&gt;
&lt;br /&gt;
	local pval = args.pval or &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	local qplist = mw.text.split(quals, &amp;quot;%p&amp;quot;) -- split at punctuation and make a sequential table&lt;br /&gt;
	for i, v in ipairs(qplist) do&lt;br /&gt;
		qplist[i] = mw.text.trim(v):upper() -- remove whitespace and capitalise&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local col1 = args.firstcol or &amp;quot;&amp;quot;&lt;br /&gt;
	if col1 ~= &amp;quot;&amp;quot; then&lt;br /&gt;
		col1 = col1 .. &amp;quot;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local emptycell = args.emptycell or &amp;quot;&amp;amp;nbsp;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	-- construct a 2-D array of qualifier values in qvals&lt;br /&gt;
	local qvals = {}&lt;br /&gt;
	for i, v in ipairs(props) do&lt;br /&gt;
		local skip = false&lt;br /&gt;
		if pval ~= &amp;quot;&amp;quot; then&lt;br /&gt;
			local pid = v.mainsnak.datavalue and v.mainsnak.datavalue.value.id&lt;br /&gt;
			if pid ~= pval then skip = true end&lt;br /&gt;
		end&lt;br /&gt;
		if not skip then&lt;br /&gt;
			local qval = {}&lt;br /&gt;
			local vqualifiers = v.qualifiers or {}&lt;br /&gt;
			-- go through list of wanted qualifier properties&lt;br /&gt;
			for i1, v1 in ipairs(qplist) do&lt;br /&gt;
				-- check for that property ID in the statement&#039;s qualifiers&lt;br /&gt;
				local qv, qtype&lt;br /&gt;
				if vqualifiers[v1] then&lt;br /&gt;
					qtype = vqualifiers[v1][1].datatype&lt;br /&gt;
					if qtype == &amp;quot;time&amp;quot; then&lt;br /&gt;
						if vqualifiers[v1][1].snaktype == &amp;quot;value&amp;quot; then&lt;br /&gt;
							qv = mw.wikibase.renderSnak(vqualifiers[v1][1])&lt;br /&gt;
							qv = frame:expandTemplate{title=&amp;quot;dts&amp;quot;, args={qv}}&lt;br /&gt;
						else&lt;br /&gt;
							qv = &amp;quot;?&amp;quot;&lt;br /&gt;
						end&lt;br /&gt;
					elseif qtype == &amp;quot;url&amp;quot; then&lt;br /&gt;
						if vqualifiers[v1][1].snaktype == &amp;quot;value&amp;quot; then&lt;br /&gt;
							qv = mw.wikibase.renderSnak(vqualifiers[v1][1])&lt;br /&gt;
							local display = mw.ustring.match( mw.uri.decode(qv, &amp;quot;WIKI&amp;quot;), &amp;quot;([%w ]+)$&amp;quot; )&lt;br /&gt;
							if display then&lt;br /&gt;
								qv = &amp;quot;[&amp;quot; .. qv .. &amp;quot; &amp;quot; .. display .. &amp;quot;]&amp;quot;&lt;br /&gt;
							end&lt;br /&gt;
						end&lt;br /&gt;
					else&lt;br /&gt;
						qv = mw.wikibase.formatValue(vqualifiers[v1][1])&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				-- record either the value or a placeholder&lt;br /&gt;
				qval[i1] = qv or emptycell&lt;br /&gt;
			end -- of loop through list of qualifiers&lt;br /&gt;
			-- add the list of qualifier values as a &amp;quot;row&amp;quot; in the main list&lt;br /&gt;
			qvals[#qvals+1] = qval&lt;br /&gt;
		end&lt;br /&gt;
	end -- of for each value loop&lt;br /&gt;
&lt;br /&gt;
	local out = {}&lt;br /&gt;
	for i, v in ipairs(qvals) do&lt;br /&gt;
		out[i] = &amp;quot;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;quot; .. col1 .. table.concat(qvals[i], &amp;quot;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;quot;) .. &amp;quot;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	return table.concat(out, &amp;quot;\n&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getGlobe takes an optional qid of a Wikidata entity passed as |qid=&lt;br /&gt;
-- otherwise it uses the linked item for the current page.&lt;br /&gt;
-- If returns the Qid of the globe used in P625 (coordinate location),&lt;br /&gt;
-- or nil if there isn&#039;t one.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getGlobe = function(frame)&lt;br /&gt;
	local qid = frame.args.qid or frame.args[1] or &amp;quot;&amp;quot;&lt;br /&gt;
	if qid == &amp;quot;&amp;quot; then qid = mw.wikibase.getEntityIdForCurrentPage() end&lt;br /&gt;
	local coords = mw.wikibase.getBestStatements(qid, &amp;quot;P625&amp;quot;)[1]&lt;br /&gt;
	local globeid&lt;br /&gt;
	if coords and coords.mainsnak.snaktype == &amp;quot;value&amp;quot; then&lt;br /&gt;
		globeid = coords.mainsnak.datavalue.value.globe:match(&amp;quot;(Q%d+)&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	return globeid&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getCommonsLink takes an optional qid of a Wikidata entity passed as |qid=&lt;br /&gt;
-- It returns one of the following in order of preference:&lt;br /&gt;
-- the Commons sitelink of the linked Wikidata item;&lt;br /&gt;
-- the Commons sitelink of the topic&#039;s main category of the linked Wikidata item;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: _getCommonslink(); _getSitelink(); parseParam()&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getCommonsLink = function(frame)&lt;br /&gt;
	local oc = frame.args.onlycat or frame.args.onlycategories&lt;br /&gt;
	local fb = parseParam(frame.args.fallback or frame.args.fb, true)&lt;br /&gt;
	return _getCommonslink(frame.args.qid, oc, fb)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getSitelink takes the qid of a Wikidata entity passed as |qid=&lt;br /&gt;
-- It takes an optional parameter |wiki= to determine which wiki is to be checked for a sitelink&lt;br /&gt;
-- If the parameter is blank, then it uses the local wiki.&lt;br /&gt;
-- If there is a sitelink to an article available, it returns the plain text link to the article&lt;br /&gt;
-- If there is no sitelink, it returns nil.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getSiteLink = function(frame)&lt;br /&gt;
	return _getSitelink(frame.args.qid, frame.args.wiki or mw.text.trim(frame.args[1] or &amp;quot;&amp;quot;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getLink has the qid of a Wikidata entity passed as the first unnamed parameter or as |qid=&lt;br /&gt;
-- If there is a sitelink to an article on the local Wiki, it returns a link to the article&lt;br /&gt;
-- with the Wikidata label as the displayed text.&lt;br /&gt;
-- If there is no sitelink, it returns the label as plain text.&lt;br /&gt;
-- If there is no label in the local language, it displays the qid instead.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getLink = function(frame)&lt;br /&gt;
	local itemID = mw.text.trim(frame.args[1] or frame.args.qid or &amp;quot;&amp;quot;)&lt;br /&gt;
	if itemID == &amp;quot;&amp;quot; then return end&lt;br /&gt;
	local sitelink = mw.wikibase.getSitelink(itemID)&lt;br /&gt;
	local label = labelOrId(itemID)&lt;br /&gt;
	if sitelink then&lt;br /&gt;
		return &amp;quot;[[:&amp;quot; .. sitelink .. &amp;quot;|&amp;quot; .. label .. &amp;quot;]]&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		return label&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getLabel has the qid of a Wikidata entity passed as the first unnamed parameter or as |qid=&lt;br /&gt;
-- It returns the Wikidata label for the local language as plain text.&lt;br /&gt;
-- If there is no label in the local language, it displays the qid instead.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getLabel = function(frame)&lt;br /&gt;
	local itemID = mw.text.trim(frame.args[1] or frame.args.qid or &amp;quot;&amp;quot;)&lt;br /&gt;
	if itemID == &amp;quot;&amp;quot; then return end&lt;br /&gt;
	local lang = frame.args.lang or &amp;quot;&amp;quot;&lt;br /&gt;
	if lang == &amp;quot;&amp;quot; then lang = nil end&lt;br /&gt;
	local label = labelOrId(itemID, lang)&lt;br /&gt;
	return label&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- label has the qid of a Wikidata entity passed as the first unnamed parameter or as |qid=&lt;br /&gt;
-- if no qid is supplied, it uses the qid associated with the current page.&lt;br /&gt;
-- It returns the Wikidata label for the local language as plain text.&lt;br /&gt;
-- If there is no label in the local language, it returns nil.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.label = function(frame)&lt;br /&gt;
	local qid = mw.text.trim(frame.args[1] or frame.args.qid or &amp;quot;&amp;quot;)&lt;br /&gt;
	if qid == &amp;quot;&amp;quot; then qid = mw.wikibase.getEntityIdForCurrentPage() end&lt;br /&gt;
	if not qid then return end&lt;br /&gt;
	local lang = frame.args.lang or &amp;quot;&amp;quot;&lt;br /&gt;
	if lang == &amp;quot;&amp;quot; then lang = nil end&lt;br /&gt;
	local label, success = labelOrId(qid, lang)&lt;br /&gt;
	if success then return label end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getAT (Article Title)&lt;br /&gt;
-- has the qid of a Wikidata entity passed as the first unnamed parameter or as |qid=&lt;br /&gt;
-- If there is a sitelink to an article on the local Wiki, it returns the sitelink as plain text.&lt;br /&gt;
-- If there is no sitelink or qid supplied, it returns nothing.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getAT = function(frame)&lt;br /&gt;
	local itemID = mw.text.trim(frame.args[1] or frame.args.qid or &amp;quot;&amp;quot;)&lt;br /&gt;
	if itemID == &amp;quot;&amp;quot; then return end&lt;br /&gt;
	return mw.wikibase.getSitelink(itemID)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getDescription has the qid of a Wikidata entity passed as |qid=&lt;br /&gt;
-- (it defaults to the associated qid of the current article if omitted)&lt;br /&gt;
-- and a local parameter passed as the first unnamed parameter.&lt;br /&gt;
-- Any local parameter passed (other than &amp;quot;Wikidata&amp;quot; or &amp;quot;none&amp;quot;) becomes the return value.&lt;br /&gt;
-- It returns the article description for the Wikidata entity if the local parameter is &amp;quot;Wikidata&amp;quot;.&lt;br /&gt;
-- Nothing is returned if the description doesn&#039;t exist or &amp;quot;none&amp;quot; is passed as the local parameter.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getDescription = function(frame)&lt;br /&gt;
	local desc = mw.text.trim(frame.args[1] or &amp;quot;&amp;quot;)&lt;br /&gt;
	local itemID = mw.text.trim(frame.args.qid or &amp;quot;&amp;quot;)&lt;br /&gt;
	if itemID == &amp;quot;&amp;quot; then itemID = nil end&lt;br /&gt;
	if desc:lower() == &#039;wikidata&#039; then&lt;br /&gt;
		return mw.wikibase.getDescription(itemID)&lt;br /&gt;
	elseif desc:lower() == &#039;none&#039; then&lt;br /&gt;
		return nil&lt;br /&gt;
	else&lt;br /&gt;
		return desc&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getAliases has the qid of a Wikidata entity passed as |qid=&lt;br /&gt;
-- (it defaults to the associated qid of the current article if omitted)&lt;br /&gt;
-- and a local parameter passed as the first unnamed parameter.&lt;br /&gt;
-- It implements blacklisting and whitelisting with a field name of &amp;quot;alias&amp;quot; by default.&lt;br /&gt;
-- Any local parameter passed becomes the return value.&lt;br /&gt;
-- Otherwise it returns the aliases for the Wikidata entity with the usual list options.&lt;br /&gt;
-- Nothing is returned if the aliases do not exist.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: findLang(); assembleoutput()&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getAliases = function(frame)&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
&lt;br /&gt;
	local fieldname = args.name or &amp;quot;&amp;quot;&lt;br /&gt;
	if fieldname == &amp;quot;&amp;quot; then fieldname = &amp;quot;alias&amp;quot; end&lt;br /&gt;
&lt;br /&gt;
	local blacklist = args.suppressfields or args.spf or &amp;quot;&amp;quot;&lt;br /&gt;
	if blacklist:find(fieldname) then return nil end&lt;br /&gt;
&lt;br /&gt;
	local localval = mw.text.trim(args[1] or &amp;quot;&amp;quot;)&lt;br /&gt;
	if localval ~= &amp;quot;&amp;quot; then return localval end&lt;br /&gt;
&lt;br /&gt;
	local whitelist = args.fetchwikidata or args.fwd or &amp;quot;&amp;quot;&lt;br /&gt;
	if whitelist == &amp;quot;&amp;quot; then whitelist = &amp;quot;NONE&amp;quot; end&lt;br /&gt;
	if not (whitelist == &#039;ALL&#039; or whitelist:find(fieldname)) then return nil end&lt;br /&gt;
&lt;br /&gt;
	local qid = args.qid or &amp;quot;&amp;quot;&lt;br /&gt;
	if qid == &amp;quot;&amp;quot; then qid = mw.wikibase.getEntityIdForCurrentPage() end&lt;br /&gt;
	if not qid or not mw.wikibase.entityExists(qid) then return nil end&lt;br /&gt;
&lt;br /&gt;
	local aliases = mw.wikibase.getEntity(qid).aliases&lt;br /&gt;
	if not aliases then return nil end&lt;br /&gt;
&lt;br /&gt;
	args.langobj = findLang(args.lang)&lt;br /&gt;
	local langcode = args.langobj.code&lt;br /&gt;
	args.lang = langcode&lt;br /&gt;
&lt;br /&gt;
	local out = {}&lt;br /&gt;
	for k1, v1 in pairs(aliases) do&lt;br /&gt;
		if v1[1].language == langcode then&lt;br /&gt;
			for k1, v2 in ipairs(v1) do&lt;br /&gt;
				out[#out+1] = v2.value&lt;br /&gt;
			end&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return assembleoutput(out, args, qid)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- pageId returns the page id (entity ID, Qnnn) of the current page&lt;br /&gt;
-- returns nothing if the page is not connected to Wikidata&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.pageId = function(frame)&lt;br /&gt;
	return (mw.wikibase and mw.wikibase.getEntityIdForCurrentPage and mw.wikibase.getEntityIdForCurrentPage()) or nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- formatDate is a wrapper to export the private function format_Date&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: format_Date();&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.formatDate = function(frame)&lt;br /&gt;
	return format_Date(frame.args[1], frame.args.df, frame.args.bc)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- location is a wrapper to export the private function _location&lt;br /&gt;
-- it takes the entity-id as qid or the first unnamed parameter&lt;br /&gt;
-- optional boolean parameter first toggles the display of the first item&lt;br /&gt;
-- optional boolean parameter skip toggles the display to skip to the last item&lt;br /&gt;
-- parameter debug=&amp;lt;y/n&amp;gt; (default &#039;n&#039;) adds error msg if not a location&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: _location();&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.location = function(frame)&lt;br /&gt;
	local debug = (frame.args.debug or &amp;quot;&amp;quot;):sub(1, 1):lower()&lt;br /&gt;
	if debug == &amp;quot;&amp;quot; then debug = &amp;quot;n&amp;quot; end&lt;br /&gt;
	local qid = mw.text.trim(frame.args.qid or frame.args[1] or &amp;quot;&amp;quot;):upper()&lt;br /&gt;
	if qid == &amp;quot;&amp;quot; then qid=mw.wikibase.getEntityIdForCurrentPage() end&lt;br /&gt;
	if not qid then&lt;br /&gt;
		if debug ~= &amp;quot;n&amp;quot; then&lt;br /&gt;
			return i18n.errors[&amp;quot;entity-not-found&amp;quot;]&lt;br /&gt;
		else&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local first = mw.text.trim(frame.args.first or &amp;quot;&amp;quot;)&lt;br /&gt;
	local skip = mw.text.trim(frame.args.skip or &amp;quot;&amp;quot;)&lt;br /&gt;
	return table.concat( _location(qid, first, skip), &amp;quot;, &amp;quot; )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- checkBlacklist implements a test to check whether a named field is allowed&lt;br /&gt;
-- returns true if the field is not blacklisted (i.e. allowed)&lt;br /&gt;
-- returns false if the field is blacklisted (i.e. disallowed)&lt;br /&gt;
-- {{#if:{{#invoke:WikidataIB |checkBlacklist |name=Joe |suppressfields=Dave; Joe; Fred}} | not blacklisted | blacklisted}}&lt;br /&gt;
-- displays &amp;quot;blacklisted&amp;quot;&lt;br /&gt;
-- {{#if:{{#invoke:WikidataIB |checkBlacklist |name=Jim |suppressfields=Dave; Joe; Fred}} | not blacklisted | blacklisted}}&lt;br /&gt;
-- displays &amp;quot;not blacklisted&amp;quot;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.checkBlacklist = function(frame)&lt;br /&gt;
	local blacklist = frame.args.suppressfields or frame.args.spf or &amp;quot;&amp;quot;&lt;br /&gt;
	local fieldname = frame.args.name or &amp;quot;&amp;quot;&lt;br /&gt;
	if blacklist ~= &amp;quot;&amp;quot; and fieldname ~= &amp;quot;&amp;quot; then&lt;br /&gt;
		if blacklist:find(fieldname) then&lt;br /&gt;
			return false&lt;br /&gt;
		else&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		-- one of the fields is missing: let&#039;s call that &amp;quot;not on the list&amp;quot;&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- emptyor returns nil if its first unnamed argument is just punctuation, whitespace or html tags&lt;br /&gt;
-- otherwise it returns the argument unchanged (including leading/trailing space).&lt;br /&gt;
-- If the argument may contain &amp;quot;=&amp;quot;, then it must be called explicitly:&lt;br /&gt;
-- |1=arg&lt;br /&gt;
-- (In that case, leading and trailing spaces are trimmed)&lt;br /&gt;
-- It finds use in infoboxes where it can replace tests like:&lt;br /&gt;
-- {{#if: {{#invoke:WikidatIB |getvalue |P99 |fwd=ALL}} | &amp;lt;span class=&amp;quot;xxx&amp;quot;&amp;gt;{{#invoke:WikidatIB |getvalue |P99 |fwd=ALL}}&amp;lt;/span&amp;gt; | }}&lt;br /&gt;
-- with a form that uses just a single call to Wikidata:&lt;br /&gt;
-- {{#invoke |WikidataIB |emptyor |1= &amp;lt;span class=&amp;quot;xxx&amp;quot;&amp;gt;{{#invoke:WikidataIB |getvalue |P99 |fwd=ALL}}&amp;lt;/span&amp;gt; }}&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.emptyor = function(frame)&lt;br /&gt;
	local s = frame.args[1] or &amp;quot;&amp;quot;&lt;br /&gt;
	if s == &amp;quot;&amp;quot; then return nil end&lt;br /&gt;
	local sx = s:gsub(&amp;quot;%s&amp;quot;, &amp;quot;&amp;quot;):gsub(&amp;quot;&amp;lt;[^&amp;gt;]*&amp;gt;&amp;quot;, &amp;quot;&amp;quot;):gsub(&amp;quot;%p&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
	if sx == &amp;quot;&amp;quot; then&lt;br /&gt;
		return nil&lt;br /&gt;
	else&lt;br /&gt;
		return s&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- labelorid is a public function to expose the output of labelOrId()&lt;br /&gt;
-- Pass the Q-number as |qid= or as an unnamed parameter.&lt;br /&gt;
-- It returns the Wikidata label for that entity or the qid if no label exists.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: labelOrId&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.labelorid = function(frame)&lt;br /&gt;
	return (labelOrId(frame.args.qid or frame.args[1]))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getLang returns the MediaWiki language code of the current content.&lt;br /&gt;
-- If optional parameter |style=full, it returns the language name.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getLang = function(frame)&lt;br /&gt;
	local style = (frame.args.style or &amp;quot;&amp;quot;):lower()&lt;br /&gt;
	local langcode = mw.language.getContentLanguage().code&lt;br /&gt;
	if style == &amp;quot;full&amp;quot; then&lt;br /&gt;
		return mw.language.fetchLanguageName( langcode )&lt;br /&gt;
	end&lt;br /&gt;
	return langcode&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getItemLangCode takes a qid parameter (using the current page&#039;s qid if blank)&lt;br /&gt;
-- If the item for that qid has property country (P17) it looks at the first preferred value&lt;br /&gt;
-- If the country has an official language (P37), it looks at the first preferred value&lt;br /&gt;
-- If that official language has a language code (P424), it returns the first preferred value&lt;br /&gt;
-- Otherwise it returns nothing.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: _getItemLangCode()&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getItemLangCode = function(frame)&lt;br /&gt;
	return _getItemLangCode(frame.args.qid or frame.args[1])&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- findLanguage exports the local findLang() function&lt;br /&gt;
-- It takes an optional language code and returns, in order of preference:&lt;br /&gt;
-- the code if a known language;&lt;br /&gt;
-- the user&#039;s language, if set;&lt;br /&gt;
-- the server&#039;s content language.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: findLang&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.findLanguage = function(frame)&lt;br /&gt;
	return findLang(frame.args.lang or frame.args[1]).code&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getQid returns the qid, if supplied&lt;br /&gt;
-- failing that, the Wikidata entity ID of the &amp;quot;category&#039;s main topic (P301)&amp;quot;, if it exists&lt;br /&gt;
-- failing that, the Wikidata entity ID associated with the current page, if it exists&lt;br /&gt;
-- otherwise, nothing&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getQid = function(frame)&lt;br /&gt;
	local qid = (frame.args.qid or &amp;quot;&amp;quot;):upper()&lt;br /&gt;
	-- check if a qid was passed; if so, return it:&lt;br /&gt;
	if qid ~= &amp;quot;&amp;quot; then return qid end&lt;br /&gt;
	-- check if there&#039;s a &amp;quot;category&#039;s main topic (P301)&amp;quot;:&lt;br /&gt;
	qid = mw.wikibase.getEntityIdForCurrentPage()&lt;br /&gt;
	if qid then&lt;br /&gt;
		local prop301 = mw.wikibase.getBestStatements(qid, &amp;quot;P301&amp;quot;)&lt;br /&gt;
		if prop301[1] then&lt;br /&gt;
			local mctid = prop301[1].mainsnak.datavalue.value.id&lt;br /&gt;
			if mctid then return mctid end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	-- otherwise return the page qid (if any)&lt;br /&gt;
	return qid&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- followQid takes four optional parameters: qid, props, list and all.&lt;br /&gt;
-- If qid is not given, it uses the qid for the connected page&lt;br /&gt;
-- or returns nil if there isn&#039;t one.&lt;br /&gt;
-- props is a list of properties, separated by punctuation.&lt;br /&gt;
-- If props is given, the Wikidata item for the qid is examined for each property in turn.&lt;br /&gt;
-- If that property contains a value that is another Wikibase-item, that item&#039;s qid is returned,&lt;br /&gt;
-- and the search terminates, unless |all=y when all of the qids are returned, separated by spaces.&lt;br /&gt;
-- If |list= is set to a template, the qids are passed as arguments to the template.&lt;br /&gt;
-- If props is not given, the qid is returned.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: parseParam()&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p._followQid = function(args)&lt;br /&gt;
	local qid = (args.qid or &amp;quot;&amp;quot;):upper()&lt;br /&gt;
	local all = parseParam(args.all, false)&lt;br /&gt;
	local list = args.list or &amp;quot;&amp;quot;&lt;br /&gt;
	if list == &amp;quot;&amp;quot; then list = nil end&lt;br /&gt;
	if qid == &amp;quot;&amp;quot; then&lt;br /&gt;
		qid = mw.wikibase.getEntityIdForCurrentPage()&lt;br /&gt;
	end&lt;br /&gt;
	if not qid then return nil end&lt;br /&gt;
	local out = {}&lt;br /&gt;
	local props = (args.props or &amp;quot;&amp;quot;):upper()&lt;br /&gt;
	if props ~= &amp;quot;&amp;quot; then&lt;br /&gt;
		for p in mw.text.gsplit(props, &amp;quot;%p&amp;quot;) do -- split at punctuation and iterate&lt;br /&gt;
			p = mw.text.trim(p)&lt;br /&gt;
			for i, v in ipairs( mw.wikibase.getBestStatements(qid, p) ) do&lt;br /&gt;
				local linkedid = v.mainsnak.datavalue and v.mainsnak.datavalue.value.id&lt;br /&gt;
				if linkedid then&lt;br /&gt;
					if all then&lt;br /&gt;
						out[#out+1] = linkedid&lt;br /&gt;
					else&lt;br /&gt;
						return linkedid&lt;br /&gt;
					end -- test for all or just the first one found&lt;br /&gt;
				end -- test for value exists for that property&lt;br /&gt;
			end -- loop through values of property to follow&lt;br /&gt;
		end -- loop through list of properties to follow&lt;br /&gt;
	end&lt;br /&gt;
	if #out &amp;gt; 0 then&lt;br /&gt;
		local ret = &amp;quot;&amp;quot;&lt;br /&gt;
		if list then&lt;br /&gt;
			ret = mw.getCurrentFrame():expandTemplate{title = list, args = out}&lt;br /&gt;
		else&lt;br /&gt;
			ret = table.concat(out, &amp;quot; &amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
		return ret&lt;br /&gt;
	else&lt;br /&gt;
		return qid&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.followQid = function(frame)&lt;br /&gt;
	return p._followQid(frame.args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- globalSiteID returns the globalSiteID for the current wiki&lt;br /&gt;
-- e.g. returns &amp;quot;enwiki&amp;quot; for the English Wikipedia, &amp;quot;enwikisource&amp;quot; for English Wikisource, etc.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.globalSiteID = function(frame)&lt;br /&gt;
	return mw.wikibase.getGlobalSiteId()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- siteID returns the root of the globalSiteID&lt;br /&gt;
-- e.g. &amp;quot;en&amp;quot; for &amp;quot;enwiki&amp;quot;, &amp;quot;enwikisource&amp;quot;, etc.&lt;br /&gt;
-- treats &amp;quot;en-gb&amp;quot; as &amp;quot;en&amp;quot;, etc.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.siteID = function(frame)&lt;br /&gt;
	local txtlang = frame:callParserFunction(&#039;int&#039;, {&#039;lang&#039;}) or &amp;quot;&amp;quot;&lt;br /&gt;
	-- This deals with specific exceptions: be-tarask -&amp;gt; be-x-old&lt;br /&gt;
	if txtlang == &amp;quot;be-tarask&amp;quot; then&lt;br /&gt;
		return &amp;quot;be_x_old&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	local pos = txtlang:find(&amp;quot;-&amp;quot;)&lt;br /&gt;
	local ret = &amp;quot;&amp;quot;&lt;br /&gt;
	if pos then&lt;br /&gt;
		ret = txtlang:sub(1, pos-1)&lt;br /&gt;
	else&lt;br /&gt;
		ret = txtlang&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- projID returns the code used to link to the reader&#039;s language&#039;s project&lt;br /&gt;
-- e.g &amp;quot;en&amp;quot; for [[:en:WikidataIB]]&lt;br /&gt;
-- treats &amp;quot;en-gb&amp;quot; as &amp;quot;en&amp;quot;, etc.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.projID = function(frame)&lt;br /&gt;
	local txtlang = frame:callParserFunction(&#039;int&#039;, {&#039;lang&#039;}) or &amp;quot;&amp;quot;&lt;br /&gt;
	-- This deals with specific exceptions: be-tarask -&amp;gt; be-x-old&lt;br /&gt;
	if txtlang == &amp;quot;be-tarask&amp;quot; then&lt;br /&gt;
		return &amp;quot;be-x-old&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	local pos = txtlang:find(&amp;quot;-&amp;quot;)&lt;br /&gt;
	local ret = &amp;quot;&amp;quot;&lt;br /&gt;
	if pos then&lt;br /&gt;
		ret = txtlang:sub(1, pos-1)&lt;br /&gt;
	else&lt;br /&gt;
		ret = txtlang&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- formatNumber formats a number according to the the supplied language code (&amp;quot;|lang=&amp;quot;)&lt;br /&gt;
-- or the default language if not supplied.&lt;br /&gt;
-- The number is the first unnamed parameter or &amp;quot;|num=&amp;quot;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: findLang()&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.formatNumber = function(frame)&lt;br /&gt;
	local lang&lt;br /&gt;
	local num = tonumber(frame.args[1] or frame.args.num) or 0&lt;br /&gt;
	lang = findLang(frame.args.lang)&lt;br /&gt;
	return lang:formatNum( num )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- examine dumps the property (the unnamed parameter or pid)&lt;br /&gt;
-- from the item given by the parameter &#039;qid&#039; (or the other unnamed parameter)&lt;br /&gt;
-- or from the item corresponding to the current page if qid is not supplied.&lt;br /&gt;
-- e.g. {{#invoke:WikidataIB |examine |pid=P26 |qid=Q42}}&lt;br /&gt;
-- or {{#invoke:WikidataIB |examine |P26 |Q42}} or any combination of these&lt;br /&gt;
-- or {{#invoke:WikidataIB |examine |P26}} for the current page.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.examine = function( frame )&lt;br /&gt;
	local args&lt;br /&gt;
	if frame.args[1] or frame.args.pid or frame.args.qid then&lt;br /&gt;
		args = frame.args&lt;br /&gt;
	else&lt;br /&gt;
		args = frame:getParent().args&lt;br /&gt;
	end&lt;br /&gt;
	local par = {}&lt;br /&gt;
	local pid = (args.pid or &amp;quot;&amp;quot;):upper()&lt;br /&gt;
	local qid = (args.qid or &amp;quot;&amp;quot;):upper()&lt;br /&gt;
	par[1] = mw.text.trim( args[1] or &amp;quot;&amp;quot; ):upper()&lt;br /&gt;
	par[2] = mw.text.trim( args[2] or &amp;quot;&amp;quot; ):upper()&lt;br /&gt;
	table.sort(par)&lt;br /&gt;
	if par[2]:sub(1,1) == &amp;quot;P&amp;quot; then par[1], par[2] = par[2], par[1] end&lt;br /&gt;
	if pid == &amp;quot;&amp;quot; then pid = par[1] end&lt;br /&gt;
	if qid == &amp;quot;&amp;quot; then qid = par[2] end&lt;br /&gt;
	local q1 = qid:sub(1,1)&lt;br /&gt;
	if pid:sub(1,1) ~= &amp;quot;P&amp;quot; then return &amp;quot;No property supplied&amp;quot; end&lt;br /&gt;
	if q1 ~= &amp;quot;Q&amp;quot; and q1 ~= &amp;quot;M&amp;quot; then qid = mw.wikibase.getEntityIdForCurrentPage() end&lt;br /&gt;
	if not qid then return &amp;quot;No item for this page&amp;quot; end&lt;br /&gt;
	return &amp;quot;&amp;lt;pre&amp;gt;&amp;quot; .. mw.dumpObject( mw.wikibase.getAllStatements( qid, pid ) ) .. &amp;quot;&amp;lt;/pre&amp;gt;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- checkvalue looks for &#039;val&#039; as a wikibase-item value of a property (the unnamed parameter or pid)&lt;br /&gt;
-- from the item given by the parameter &#039;qid&#039;&lt;br /&gt;
-- or from the Wikidata item associated with the current page if qid is not supplied.&lt;br /&gt;
-- It only checks ranks that are requested (preferred and normal by default)&lt;br /&gt;
-- If property is not supplied, then P31 (instance of) is assumed.&lt;br /&gt;
-- It returns val if found or nothing if not found.&lt;br /&gt;
-- e.g. {{#invoke:WikidataIB |checkvalue |val=Q5 |pid=P31 |qid=Q42}}&lt;br /&gt;
-- or {{#invoke:WikidataIB |checkvalue |val=Q5 |P31 |qid=Q42}}&lt;br /&gt;
-- or {{#invoke:WikidataIB |checkvalue |val=Q5 |qid=Q42}}&lt;br /&gt;
-- or {{#invoke:WikidataIB |checkvalue |val=Q5 |P31}} for the current page.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.checkvalue = function( frame )&lt;br /&gt;
	local args&lt;br /&gt;
	if frame.args.val then&lt;br /&gt;
		args = frame.args&lt;br /&gt;
	else&lt;br /&gt;
		args = frame:getParent().args&lt;br /&gt;
	end&lt;br /&gt;
	local val = args.val&lt;br /&gt;
	if not val then return nil end&lt;br /&gt;
	local pid = mw.text.trim(args.pid or args[1] or &amp;quot;P31&amp;quot;):upper()&lt;br /&gt;
	local qid = (args.qid or &amp;quot;&amp;quot;):upper()&lt;br /&gt;
	if pid:sub(1,1) ~= &amp;quot;P&amp;quot; then return nil end&lt;br /&gt;
	if qid:sub(1,1) ~= &amp;quot;Q&amp;quot; then qid = mw.wikibase.getEntityIdForCurrentPage() end&lt;br /&gt;
	if not qid then return nil end&lt;br /&gt;
	local ranks = setRanks(args.rank)&lt;br /&gt;
	local stats = {}&lt;br /&gt;
	if ranks.b then&lt;br /&gt;
		stats = mw.wikibase.getBestStatements(qid, pid)&lt;br /&gt;
	else&lt;br /&gt;
		stats = mw.wikibase.getAllStatements( qid, pid )&lt;br /&gt;
	end&lt;br /&gt;
	if not stats[1] then return nil end&lt;br /&gt;
	if stats[1].mainsnak.datatype == &amp;quot;wikibase-item&amp;quot; then&lt;br /&gt;
		for k, v in pairs( stats ) do&lt;br /&gt;
			local ms = v.mainsnak&lt;br /&gt;
			if ranks[v.rank:sub(1,1)] and ms.snaktype == &amp;quot;value&amp;quot; and ms.datavalue.value.id == val then&lt;br /&gt;
				return val&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- url2 takes a parameter url= that is a proper url and formats it for use in an infobox.&lt;br /&gt;
-- If no parameter is supplied, it returns nothing.&lt;br /&gt;
-- This is the equivalent of Template:URL&lt;br /&gt;
-- but it keeps the &amp;quot;edit at Wikidata&amp;quot; pen icon out of the microformat.&lt;br /&gt;
-- Usually it will take its url parameter directly from a Wikidata call:&lt;br /&gt;
-- e.g. {{#invoke:WikidataIB |url2 |url={{wdib |P856 |qid=Q23317 |fwd=ALL |osd=no}} }}&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.url2 = function(frame)&lt;br /&gt;
	local txt = frame.args.url or &amp;quot;&amp;quot;&lt;br /&gt;
	if txt == &amp;quot;&amp;quot; then return nil end&lt;br /&gt;
	-- extract any icon&lt;br /&gt;
	local url, icon = txt:match(&amp;quot;(.+)&amp;amp;nbsp;(.+)&amp;quot;)&lt;br /&gt;
	-- make sure there&#039;s at least a space at the end&lt;br /&gt;
	url = (url or txt) .. &amp;quot; &amp;quot;&lt;br /&gt;
	icon = icon or &amp;quot;&amp;quot;&lt;br /&gt;
	-- extract any protocol like https://&lt;br /&gt;
	local prot = url:match(&amp;quot;(https*://).+[ \&amp;quot;\&#039;]&amp;quot;)&lt;br /&gt;
	-- extract address&lt;br /&gt;
	local addr = &amp;quot;&amp;quot;&lt;br /&gt;
	if prot then&lt;br /&gt;
		addr = url:match(&amp;quot;https*://(.+)[ \&amp;quot;\&#039;]&amp;quot;) or &amp;quot; &amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		prot = &amp;quot;//&amp;quot;&lt;br /&gt;
		addr = url:match(&amp;quot;[^%p%s]+%.(.+)[ \&amp;quot;\&#039;]&amp;quot;) or &amp;quot; &amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	-- strip trailing / from end of domain-only url and add &amp;lt;wbr/&amp;gt; before . and /&lt;br /&gt;
	local disp, n = addr:gsub( &amp;quot;^([^/]+)/$&amp;quot;, &amp;quot;%1&amp;quot; ):gsub(&amp;quot;%/&amp;quot;, &amp;quot;&amp;lt;wbr/&amp;gt;/&amp;quot;):gsub(&amp;quot;%.&amp;quot;, &amp;quot;&amp;lt;wbr/&amp;gt;.&amp;quot;)&lt;br /&gt;
	return &#039;&amp;lt;span class=&amp;quot;url&amp;quot;&amp;gt;[&#039; .. prot .. addr .. &amp;quot; &amp;quot; .. disp .. &amp;quot;]&amp;lt;/span&amp;gt;&amp;amp;nbsp;&amp;quot; .. icon&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getWebsite fetches the Official website (P856) and formats it for use in an infobox.&lt;br /&gt;
-- This is similar to Template:Official website but with a url displayed,&lt;br /&gt;
-- and it adds the &amp;quot;edit at Wikidata&amp;quot; pen icon beyond the microformat if enabled.&lt;br /&gt;
-- A local value will override the Wikidata value. &amp;quot;NONE&amp;quot; returns nothing.&lt;br /&gt;
-- e.g. {{#invoke:WikidataIB |getWebsite |qid= |noicon= |lang= |url= }}&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: findLang(); parseParam();&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getWebsite = function(frame)&lt;br /&gt;
	local url = frame.args.url or &amp;quot;&amp;quot;&lt;br /&gt;
	if url:upper() == &amp;quot;NONE&amp;quot; then return nil end&lt;br /&gt;
	local urls = {}&lt;br /&gt;
	local quals = {}&lt;br /&gt;
	local qid = frame.args.qid or &amp;quot;&amp;quot;&lt;br /&gt;
	if url and url ~= &amp;quot;&amp;quot; then&lt;br /&gt;
		urls[1] = url&lt;br /&gt;
	else&lt;br /&gt;
		if qid == &amp;quot;&amp;quot; then qid = mw.wikibase.getEntityIdForCurrentPage() end&lt;br /&gt;
		if not qid then return nil end&lt;br /&gt;
&lt;br /&gt;
		local prop856 = mw.wikibase.getBestStatements(qid, &amp;quot;P856&amp;quot;)&lt;br /&gt;
		for k, v in pairs(prop856) do&lt;br /&gt;
			if v.mainsnak.snaktype == &amp;quot;value&amp;quot; then&lt;br /&gt;
				urls[#urls+1] = v.mainsnak.datavalue.value&lt;br /&gt;
				if v.qualifiers and v.qualifiers[&amp;quot;P1065&amp;quot;] then&lt;br /&gt;
					 -- just take the first archive url (P1065)&lt;br /&gt;
					local au = v.qualifiers[&amp;quot;P1065&amp;quot;][1]&lt;br /&gt;
					if au.snaktype == &amp;quot;value&amp;quot; then&lt;br /&gt;
						quals[#urls] = au.datavalue.value&lt;br /&gt;
					end -- test for archive url having a value&lt;br /&gt;
				end -- test for qualifers&lt;br /&gt;
			end -- test for website having a value&lt;br /&gt;
		end -- loop through website(s)&lt;br /&gt;
	end&lt;br /&gt;
	if #urls == 0 then return nil end&lt;br /&gt;
&lt;br /&gt;
	local out = {}&lt;br /&gt;
	for i, u in ipairs(urls) do&lt;br /&gt;
		local link = quals[i] or u&lt;br /&gt;
		local prot, addr = u:match(&amp;quot;(http[s]*://)(.+)&amp;quot;)&lt;br /&gt;
		addr = addr or u&lt;br /&gt;
		local disp, n = addr:gsub(&amp;quot;%.&amp;quot;, &amp;quot;&amp;lt;wbr/&amp;gt;%.&amp;quot;)&lt;br /&gt;
		out[#out+1] = &#039;&amp;lt;span class=&amp;quot;url&amp;quot;&amp;gt;[&#039; .. link .. &amp;quot; &amp;quot; .. disp .. &amp;quot;]&amp;lt;/span&amp;gt;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local langcode = findLang(frame.args.lang).code&lt;br /&gt;
	local noicon = parseParam(frame.args.noicon, false)&lt;br /&gt;
	if url == &amp;quot;&amp;quot; and not noicon then&lt;br /&gt;
		out[#out] = out[#out] .. createicon(langcode, qid, &amp;quot;P856&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local ret = &amp;quot;&amp;quot;&lt;br /&gt;
	if #out &amp;gt; 1 then&lt;br /&gt;
		ret = mw.getCurrentFrame():expandTemplate{title = &amp;quot;ubl&amp;quot;, args = out}&lt;br /&gt;
	else&lt;br /&gt;
		ret = out[1]&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getAllLabels fetches the set of labels and formats it for display as wikitext.&lt;br /&gt;
-- It takes a parameter &#039;qid&#039; for arbitrary access, otherwise it uses the current page.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getAllLabels = function(frame)&lt;br /&gt;
	local args = frame.args or frame:getParent().args or {}&lt;br /&gt;
&lt;br /&gt;
	local qid = args.qid or &amp;quot;&amp;quot;&lt;br /&gt;
	if qid == &amp;quot;&amp;quot; then qid = mw.wikibase.getEntityIdForCurrentPage() end&lt;br /&gt;
	if not qid or not mw.wikibase.entityExists(qid) then return i18n[&amp;quot;entity-not-found&amp;quot;] end&lt;br /&gt;
&lt;br /&gt;
	local labels = mw.wikibase.getEntity(qid).labels&lt;br /&gt;
	if not labels then return i18n[&amp;quot;labels-not-found&amp;quot;] end&lt;br /&gt;
&lt;br /&gt;
	local out = {}&lt;br /&gt;
	for k, v in pairs(labels) do&lt;br /&gt;
		out[#out+1] = v.value .. &amp;quot; (&amp;quot; .. v.language .. &amp;quot;)&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return table.concat(out, &amp;quot;; &amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getAllDescriptions fetches the set of descriptions and formats it for display as wikitext.&lt;br /&gt;
-- It takes a parameter &#039;qid&#039; for arbitrary access, otherwise it uses the current page.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getAllDescriptions = function(frame)&lt;br /&gt;
	local args = frame.args or frame:getParent().args or {}&lt;br /&gt;
&lt;br /&gt;
	local qid = args.qid or &amp;quot;&amp;quot;&lt;br /&gt;
	if qid == &amp;quot;&amp;quot; then qid = mw.wikibase.getEntityIdForCurrentPage() end&lt;br /&gt;
	if not qid or not mw.wikibase.entityExists(qid) then return i18n[&amp;quot;entity-not-found&amp;quot;] end&lt;br /&gt;
&lt;br /&gt;
	local descriptions = mw.wikibase.getEntity(qid).descriptions&lt;br /&gt;
	if not descriptions then return i18n[&amp;quot;descriptions-not-found&amp;quot;] end&lt;br /&gt;
&lt;br /&gt;
	local out = {}&lt;br /&gt;
	for k, v in pairs(descriptions) do&lt;br /&gt;
		out[#out+1] = v.value .. &amp;quot; (&amp;quot; .. v.language .. &amp;quot;)&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return table.concat(out, &amp;quot;; &amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getAllAliases fetches the set of aliases and formats it for display as wikitext.&lt;br /&gt;
-- It takes a parameter &#039;qid&#039; for arbitrary access, otherwise it uses the current page.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.getAllAliases = function(frame)&lt;br /&gt;
	local args = frame.args or frame:getParent().args or {}&lt;br /&gt;
&lt;br /&gt;
	local qid = args.qid or &amp;quot;&amp;quot;&lt;br /&gt;
	if qid == &amp;quot;&amp;quot; then qid = mw.wikibase.getEntityIdForCurrentPage() end&lt;br /&gt;
	if not qid or not mw.wikibase.entityExists(qid) then return i18n[&amp;quot;entity-not-found&amp;quot;] end&lt;br /&gt;
&lt;br /&gt;
	local aliases = mw.wikibase.getEntity(qid).aliases&lt;br /&gt;
	if not aliases then return i18n[&amp;quot;aliases-not-found&amp;quot;] end&lt;br /&gt;
&lt;br /&gt;
	local out = {}&lt;br /&gt;
	for k1, v1 in pairs(aliases) do&lt;br /&gt;
		local lang = v1[1].language&lt;br /&gt;
		local val = {}&lt;br /&gt;
		for k1, v2 in ipairs(v1) do&lt;br /&gt;
			val[#val+1] = v2.value&lt;br /&gt;
		end&lt;br /&gt;
		out[#out+1] = table.concat(val, &amp;quot;, &amp;quot;) .. &amp;quot; (&amp;quot; .. lang .. &amp;quot;)&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return table.concat(out, &amp;quot;; &amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- showNoLinks displays the article titles that should not be linked.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
p.showNoLinks = function(frame)&lt;br /&gt;
	local out = {}&lt;br /&gt;
	for k, v in pairs(donotlink) do&lt;br /&gt;
		out[#out+1] = k&lt;br /&gt;
	end&lt;br /&gt;
	table.sort( out )&lt;br /&gt;
	return table.concat(out, &amp;quot;; &amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- checkValidity checks whether the first unnamed parameter represents a valid entity-id,&lt;br /&gt;
-- that is, something like Q1235 or P123.&lt;br /&gt;
-- It returns the strings &amp;quot;true&amp;quot; or &amp;quot;false&amp;quot;.&lt;br /&gt;
-- Change false to nil to return &amp;quot;true&amp;quot; or &amp;quot;&amp;quot; (easier to test with #if:).&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: none&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
function p.checkValidity(frame)&lt;br /&gt;
	local id = mw.text.trim(frame.args[1] or &amp;quot;&amp;quot;)&lt;br /&gt;
	if mw.wikibase.isValidEntityId(id) then&lt;br /&gt;
		return true&lt;br /&gt;
	else&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getEntityFromTitle returns the Entity-ID (Q-number) for a given title.&lt;br /&gt;
-- Modification of Module:ResolveEntityId&lt;br /&gt;
-- The title is the first unnamed parameter.&lt;br /&gt;
-- The site parameter determines the site/language for the title. Defaults to current wiki.&lt;br /&gt;
-- The showdab parameter determines whether dab pages should return the Q-number or nil. Defaults to true.&lt;br /&gt;
-- Returns the Q-number or nil if it does not exist.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: parseParam&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
function p.getEntityFromTitle(frame)&lt;br /&gt;
	local args=frame.args&lt;br /&gt;
	if not args[1] then args=frame:getParent().args end&lt;br /&gt;
	if not args[1] then return nil end&lt;br /&gt;
	local title = mw.text.trim(args[1])&lt;br /&gt;
	local site = args.site or &amp;quot;&amp;quot;&lt;br /&gt;
	local showdab = parseParam(args.showdab, true)&lt;br /&gt;
	local qid = mw.wikibase.getEntityIdForTitle(title, site)&lt;br /&gt;
	if qid then&lt;br /&gt;
		local prop31 = mw.wikibase.getBestStatements(qid, &amp;quot;P31&amp;quot;)[1]&lt;br /&gt;
		if not showdab and prop31 and prop31.mainsnak.datavalue.value.id == &amp;quot;Q4167410&amp;quot; then&lt;br /&gt;
			return nil&lt;br /&gt;
		else&lt;br /&gt;
			return qid&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- getDatePrecision returns the number representing the precision of the first best date value&lt;br /&gt;
-- for the given property.&lt;br /&gt;
-- It takes the qid and property ID&lt;br /&gt;
-- The meanings are given at https://www.mediawiki.org/wiki/Wikibase/DataModel#Dates_and_times&lt;br /&gt;
-- 0 = 1 billion years .. 6 = millennium, 7 = century, 8 = decade, 9 = year, 10 = month, 11 = day&lt;br /&gt;
-- Returns 0 (or the second unnamed parameter) if the Wikidata does not exist.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Dependencies: parseParam; sourced;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
function p.getDatePrecision(frame)&lt;br /&gt;
	local args=frame.args&lt;br /&gt;
	if not args[1] then args=frame:getParent().args end&lt;br /&gt;
	local default = tonumber(args[2] or args.default) or 0&lt;br /&gt;
	local prop = mw.text.trim(args[1] or &amp;quot;&amp;quot;)&lt;br /&gt;
	if prop == &amp;quot;&amp;quot; then return default end&lt;br /&gt;
	local qid = args.qid or &amp;quot;&amp;quot;&lt;br /&gt;
	if qid == &amp;quot;&amp;quot; then qid = mw.wikibase.getEntityIdForCurrentPage() end&lt;br /&gt;
	if not qid then return default end&lt;br /&gt;
	local onlysrc = parseParam(args.onlysourced or args.osd, true)&lt;br /&gt;
	local stat = mw.wikibase.getBestStatements(qid, prop)&lt;br /&gt;
	for i, v in ipairs(stat) do&lt;br /&gt;
		local prec = (onlysrc == false or sourced(v))&lt;br /&gt;
			and v.mainsnak.datavalue&lt;br /&gt;
			and v.mainsnak.datavalue.value&lt;br /&gt;
			and v.mainsnak.datavalue.value.precision&lt;br /&gt;
		if prec then return prec end&lt;br /&gt;
	end&lt;br /&gt;
	return default&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
return p&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- List of exported functions&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
--[[&lt;br /&gt;
_getValue&lt;br /&gt;
getValue&lt;br /&gt;
getPreferredValue&lt;br /&gt;
getCoords&lt;br /&gt;
getQualifierValue&lt;br /&gt;
getSumOfParts&lt;br /&gt;
getValueByQual&lt;br /&gt;
getValueByLang&lt;br /&gt;
getValueByRefSource&lt;br /&gt;
getPropertyIDs&lt;br /&gt;
getQualifierIDs&lt;br /&gt;
getPropOfProp&lt;br /&gt;
getAwardCat&lt;br /&gt;
getIntersectCat&lt;br /&gt;
getGlobe&lt;br /&gt;
getCommonsLink&lt;br /&gt;
getSiteLink&lt;br /&gt;
getLink&lt;br /&gt;
getLabel&lt;br /&gt;
label&lt;br /&gt;
getAT&lt;br /&gt;
getDescription&lt;br /&gt;
getAliases&lt;br /&gt;
pageId&lt;br /&gt;
formatDate&lt;br /&gt;
location&lt;br /&gt;
checkBlacklist&lt;br /&gt;
emptyor&lt;br /&gt;
labelorid&lt;br /&gt;
getLang&lt;br /&gt;
getItemLangCode&lt;br /&gt;
findLanguage&lt;br /&gt;
getQID&lt;br /&gt;
followQid&lt;br /&gt;
globalSiteID&lt;br /&gt;
siteID&lt;br /&gt;
projID&lt;br /&gt;
formatNumber&lt;br /&gt;
examine&lt;br /&gt;
checkvalue&lt;br /&gt;
url2&lt;br /&gt;
getWebsite&lt;br /&gt;
getAllLabels&lt;br /&gt;
getAllDescriptions&lt;br /&gt;
getAllAliases&lt;br /&gt;
showNoLinks&lt;br /&gt;
checkValidity&lt;br /&gt;
getEntityFromTitle&lt;br /&gt;
getDatePrecision&lt;br /&gt;
--]]&lt;br /&gt;
-------------------------------------------------------------------------------&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Module:Infobox_mapframe&amp;diff=5317</id>
		<title>Module:Infobox mapframe</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Module:Infobox_mapframe&amp;diff=5317"/>
		<updated>2026-06-15T12:50:01Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync shared ABC wiki compatibility fix from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local mf = require(&#039;Module:Mapframe&#039;)&lt;br /&gt;
local getArgs = require(&#039;Module:Arguments&#039;).getArgs&lt;br /&gt;
local yesno = require(&#039;Module:Yesno&#039;)&lt;br /&gt;
local infoboxImage = require(&#039;Module:InfoboxImage&#039;).InfoboxImage&lt;br /&gt;
&lt;br /&gt;
-- Defaults&lt;br /&gt;
local DEFAULT_FRAME_WIDTH = &amp;quot;270&amp;quot;&lt;br /&gt;
local DEFAULT_FRAME_HEIGHT = &amp;quot;200&amp;quot;&lt;br /&gt;
local DEFAULT_ZOOM = 10&lt;br /&gt;
local DEFAULT_GEOMASK_STROKE_WIDTH = &amp;quot;1&amp;quot;&lt;br /&gt;
local DEFAULT_GEOMASK_STROKE_COLOR = &amp;quot;#777777&amp;quot;&lt;br /&gt;
local DEFAULT_GEOMASK_FILL = &amp;quot;#888888&amp;quot;&lt;br /&gt;
local DEFAULT_GEOMASK_FILL_OPACITY = &amp;quot;0.25&amp;quot;&lt;br /&gt;
local DEFAULT_SHAPE_STROKE_WIDTH = &amp;quot;2&amp;quot;&lt;br /&gt;
local DEFAULT_SHAPE_STROKE_COLOR = &amp;quot;#FF0000&amp;quot;&lt;br /&gt;
local DEFAULT_SHAPE_FILL = &amp;quot;#606060&amp;quot;&lt;br /&gt;
local DEFAULT_SHAPE_FILL_OPACITY = &amp;quot;0.1&amp;quot;&lt;br /&gt;
local DEFAULT_LINE_STROKE_WIDTH = &amp;quot;5&amp;quot;&lt;br /&gt;
local DEFAULT_LINE_STROKE_COLOR = &amp;quot;#FF0000&amp;quot;&lt;br /&gt;
local DEFAULT_MARKER_COLOR = &amp;quot;#5E74F3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
local util = {}&lt;br /&gt;
&lt;br /&gt;
function util.noop(info)&lt;br /&gt;
	local DEFAULT_NOOP_OUTPUT = &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	-- uncomment this when debugging&lt;br /&gt;
	-- DEFAULT_NOOP_OUTPUT = &amp;quot;debug: mapframe no-op: &amp;quot; .. info&lt;br /&gt;
	-- mw.log(DEFAULT_NOOP_OUTPUT)&lt;br /&gt;
&lt;br /&gt;
	return DEFAULT_NOOP_OUTPUT&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Trim whitespace from args, and remove empty args&lt;br /&gt;
function util.trimArgs(argsTable)&lt;br /&gt;
	local cleanArgs = {}&lt;br /&gt;
	for key, val in pairs(argsTable) do&lt;br /&gt;
		if type(val) == &#039;string&#039; then&lt;br /&gt;
			val = val:match(&#039;^%s*(.-)%s*$&#039;)&lt;br /&gt;
			if val ~= &#039;&#039; then&lt;br /&gt;
				cleanArgs[key] = val&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			cleanArgs[key] = val&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return cleanArgs&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function util.getBestStatement(item_id, property_id)&lt;br /&gt;
	if not(item_id) or not(mw.wikibase.isValidEntityId(item_id)) or not(mw.wikibase.entityExists(item_id)) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	local statements = mw.wikibase.getBestStatements(item_id, property_id)&lt;br /&gt;
	if not statements or #statements == 0 then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	local hasNoValue = ( statements[1].mainsnak and statements[1].mainsnak.snaktype == &#039;novalue&#039; )&lt;br /&gt;
	if hasNoValue then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	return statements[1]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function util.hasWikidataProperty(item_id, property_id)&lt;br /&gt;
	return util.getBestStatement(item_id, property_id) and true or false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function util.getStatementValue(statement)&lt;br /&gt;
	return statement and statement.mainsnak and statement.mainsnak.datavalue and statement.mainsnak.datavalue.value or nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function util.relatedEntity(item_id, property_id)&lt;br /&gt;
	local value = util.getStatementValue( util.getBestStatement(item_id, property_id) )&lt;br /&gt;
	return value and value.id or false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function util.idType(id)&lt;br /&gt;
	if not id then &lt;br /&gt;
		return nil&lt;br /&gt;
	elseif mw.ustring.match(id, &amp;quot;[Pp]%d+&amp;quot;) then&lt;br /&gt;
		return &amp;quot;property&amp;quot;&lt;br /&gt;
	elseif mw.ustring.match(id, &amp;quot;[Qq]%d+&amp;quot;) then&lt;br /&gt;
		return &amp;quot;item&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function util.shouldAutoRun(frame)&lt;br /&gt;
	-- Check if should be running&lt;br /&gt;
	local pargs = frame.getParent(frame).args&lt;br /&gt;
	local explicitlyOn = yesno(mw.text.trim(pargs.mapframe or &amp;quot;&amp;quot;)) -- true of false or nil&lt;br /&gt;
	if pargs.coordinates == &amp;quot;&amp;amp;#123;&amp;amp;#123;&amp;amp;#123;coordinates&amp;amp;#125;&amp;amp;#125;&amp;amp;#125;&amp;quot; then explicitlyOn = false end&lt;br /&gt;
	local onByDefault = (explicitlyOn == nil) and yesno(mw.text.trim(frame.args.onByDefault or &amp;quot;&amp;quot;), false) -- true or false&lt;br /&gt;
	return explicitlyOn or onByDefault&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function util.argsFromAuto(frame)&lt;br /&gt;
	-- Get args from the frame (invoke call) and the parent (template call).&lt;br /&gt;
	-- Frame arguments are default values which are overridden by parent values&lt;br /&gt;
	-- when both are present&lt;br /&gt;
	local args = getArgs(frame, {parentFirst = true})&lt;br /&gt;
&lt;br /&gt;
	-- Discard args not prefixed with &amp;quot;mapframe-&amp;quot;, remove that prefix from those that remain&lt;br /&gt;
	local fixedArgs = {}&lt;br /&gt;
	for name, val in pairs(args) do&lt;br /&gt;
		local fixedName = string.match(name, &amp;quot;^mapframe%-(.+)$&amp;quot; )&lt;br /&gt;
		if fixedName then&lt;br /&gt;
			fixedArgs[fixedName] = val&lt;br /&gt;
		-- allow coord, coordinates, etc to be unprefixed&lt;br /&gt;
		elseif name == &amp;quot;coordinates&amp;quot; or name == &amp;quot;coord&amp;quot; or name == &amp;quot;coordinate&amp;quot; and not fixedArgs.coord then&lt;br /&gt;
			fixedArgs.coord = val&lt;br /&gt;
		-- allow id, qid to be unprefixed, map to id (if not already present)&lt;br /&gt;
		elseif name == &amp;quot;id&amp;quot; or name == &amp;quot;qid&amp;quot; and not fixedArgs.id then&lt;br /&gt;
			fixedArgs.id = val&lt;br /&gt;
        -- allow captionstyle to be unprefixed, for compatibility with [[Module:Infobox]]&lt;br /&gt;
        elseif name == &amp;quot;captionstyle&amp;quot; and not fixedArgs.captionstyle then&lt;br /&gt;
            fixedArgs.captionstyle = val&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return fixedArgs&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function util.parseCustomWikitext(customWikitext)&lt;br /&gt;
	-- infoboxImage will format an image if given wikitext containing an&lt;br /&gt;
	-- image, or else pass through the wikitext unmodified&lt;br /&gt;
	return infoboxImage({&lt;br /&gt;
		args = {&lt;br /&gt;
			image = customWikitext&lt;br /&gt;
		}&lt;br /&gt;
	})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function util.trackAndWarn(trackingCat, warning)&lt;br /&gt;
    local title = mw.title.getCurrentTitle()&lt;br /&gt;
    local results = title and title.namespace == 0 and trackingCat and &#039;[[Category:&#039;..trackingCat..&#039;]]&#039; or &#039;&#039;&lt;br /&gt;
    if warning then&lt;br /&gt;
        local warn = require(&#039;Module:If preview&#039;)._warning&lt;br /&gt;
        results = results..warn({warning})&lt;br /&gt;
    end&lt;br /&gt;
    return results&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function util.ternary(flag, other)&lt;br /&gt;
    other = other or &#039;other&#039;&lt;br /&gt;
    flag = flag == &#039;none&#039; and &#039;no&#039; or flag&lt;br /&gt;
    local yesNoOut = yesno(flag,other)&lt;br /&gt;
    local yes = (yesNoOut == true)&lt;br /&gt;
    local no = (yesNoOut == false)&lt;br /&gt;
    return yes, no&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
p._caption = function(args)&lt;br /&gt;
	if args.caption then&lt;br /&gt;
		return args.caption&lt;br /&gt;
	elseif args.switcher then &lt;br /&gt;
		return util.noop(&amp;quot;no caption or switcher&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	local maskItem&lt;br /&gt;
	local maskType = util.idType(args.geomask)&lt;br /&gt;
	if maskType == &#039;item&#039; then&lt;br /&gt;
		maskItem = args.geomask&lt;br /&gt;
	elseif maskType == &amp;quot;property&amp;quot; then&lt;br /&gt;
		maskItem = util.relatedEntity(args.id or mw.wikibase.getEntityIdForCurrentPage(), args.geomask)&lt;br /&gt;
	end&lt;br /&gt;
	local maskItemLabel = maskItem and mw.wikibase.getLabel( maskItem )&lt;br /&gt;
	return maskItemLabel and &amp;quot;Location in &amp;quot;..maskItemLabel&lt;br /&gt;
		or util.noop(&amp;quot;missing maskItemLabel with type &amp;quot; .. (maskType or &amp;quot;nil&amp;quot;) .. &amp;quot; and item &amp;quot; .. (maskItem or &amp;quot;nil&amp;quot;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--A list of types for objects that are too small to allow Kartographer to take over zoom&lt;br /&gt;
local tinyType = {&lt;br /&gt;
    landmark=true,&lt;br /&gt;
    railwaystation=true,&lt;br /&gt;
    edu=true,&lt;br /&gt;
    pass=true,&lt;br /&gt;
    camera=true&lt;br /&gt;
}                 &lt;br /&gt;
&lt;br /&gt;
p._main = function(_config)&lt;br /&gt;
    -- accumulate tracking cats&lt;br /&gt;
    local tracking = &#039;&#039;&lt;br /&gt;
	-- `config` is the args passed to this module&lt;br /&gt;
	local config = util.trimArgs(_config)&lt;br /&gt;
	&lt;br /&gt;
    -- allow alias for config.coord&lt;br /&gt;
    config.coord = config.coord or config.coordinates&lt;br /&gt;
&lt;br /&gt;
	-- Require wikidata item, or specified coords&lt;br /&gt;
	local wikidataId = config.id or (mw.wikibase and mw.wikibase.getEntityIdForCurrentPage and mw.wikibase.getEntityIdForCurrentPage())&lt;br /&gt;
	if not(wikidataId) and not(config.coord) then&lt;br /&gt;
		return false, util.trackAndWarn(&#039;Pages using infobox mapframe with missing coordinates&#039;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Require coords (specified or from wikidata), so that map will be centred somewhere&lt;br /&gt;
	-- (P625 = coordinate location)&lt;br /&gt;
    local wdCoordinates = wikidataId and util.getStatementValue(util.getBestStatement(wikidataId, &#039;P625&#039;)) or nil&lt;br /&gt;
    if not (config.coord or wdCoordinates) then&lt;br /&gt;
		return false, util.trackAndWarn(&#039;Pages using infobox mapframe with missing coordinates&#039;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- `args` is the arguments which will be passed to the mapframe module&lt;br /&gt;
	local args = {}&lt;br /&gt;
&lt;br /&gt;
	-- Some defaults/overrides for infobox presentation&lt;br /&gt;
	args.display = &amp;quot;inline&amp;quot;&lt;br /&gt;
	args.frame = &amp;quot;yes&amp;quot;&lt;br /&gt;
	args.plain = &amp;quot;yes&amp;quot;&lt;br /&gt;
	args[&amp;quot;frame-width&amp;quot;]  = config[&amp;quot;frame-width&amp;quot;] or config.width or DEFAULT_FRAME_WIDTH&lt;br /&gt;
	args[&amp;quot;frame-height&amp;quot;] = config[&amp;quot;frame-height&amp;quot;] or config.height or DEFAULT_FRAME_HEIGHT&lt;br /&gt;
	args[&amp;quot;frame-align&amp;quot;]  = &amp;quot;center&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	args[&amp;quot;frame-coord&amp;quot;] = config[&amp;quot;frame-coordinates&amp;quot;] or config[&amp;quot;frame-coord&amp;quot;]&lt;br /&gt;
	-- Note: config[&amp;quot;coordinates&amp;quot;] or config[&amp;quot;coord&amp;quot;] should not be used for the alignment of the frame;&lt;br /&gt;
	-- see talk page ( https://en.wikipedia.org/wiki/Special:Diff/876492931 )&lt;br /&gt;
&lt;br /&gt;
	-- deprecated lat and long parameters&lt;br /&gt;
	args[&amp;quot;frame-lat&amp;quot;]    = config[&amp;quot;frame-lat&amp;quot;] or config[&amp;quot;frame-latitude&amp;quot;]&lt;br /&gt;
	args[&amp;quot;frame-long&amp;quot;]   = config[&amp;quot;frame-long&amp;quot;] or config[&amp;quot;frame-longitude&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
    -- if zoom isn&#039;t specified from config, first check wikidata&lt;br /&gt;
    local zoom = config.zoom or util.getStatementValue(util.getBestStatement(wikidataId, &#039;P6592&#039;))&lt;br /&gt;
    if not zoom then&lt;br /&gt;
	    -- Calculate zoom from length or area (converted to km or km2)&lt;br /&gt;
	    -- Zoom so that length or area is completely included in mapframe&lt;br /&gt;
	    local getZoom = require(&#039;Module:Infobox dim&#039;)._zoom&lt;br /&gt;
	    zoom = getZoom({length_km=config.length_km, length_mi=config.length_mi,&lt;br /&gt;
                        width_km=config.width_km, width_mi=config.width_mi,&lt;br /&gt;
		                area_km2=config.area_km2, area_mi2=config.area_mi2,&lt;br /&gt;
                        area_ha=config.area_ha, area_acre=config.area_acre,&lt;br /&gt;
                        type=config.type, population=config.population,&lt;br /&gt;
		                viewport_px=math.min(args[&amp;quot;frame-width&amp;quot;],args[&amp;quot;frame-height&amp;quot;]),&lt;br /&gt;
                        latitude=wdCoordinates and wdCoordinates.latitude})&lt;br /&gt;
    end&lt;br /&gt;
    args.zoom = zoom or DEFAULT_ZOOM&lt;br /&gt;
&lt;br /&gt;
	-- Use OSM relation ID if available; otherwise use geoshape if that is available&lt;br /&gt;
	-- (geoshape is required for defunct entities, which are outside OSM&#039;s scope)&lt;br /&gt;
	local hasOsmRelationId = util.hasWikidataProperty(wikidataId, &#039;P402&#039;) -- P402 is OSM relation ID&lt;br /&gt;
	local hasGeoshape = util.hasWikidataProperty(wikidataId, &#039;P3896&#039;) -- P3896 is geoshape&lt;br /&gt;
	local wikidataProvidesGeo = hasOsmRelationId or hasGeoshape&lt;br /&gt;
&lt;br /&gt;
    -- determine marker argument value, determine whether to show marker&lt;br /&gt;
    local forcePoint, suppressPoint = util.ternary(config.point)&lt;br /&gt;
    local forceMarker, suppressMarker = util.ternary(config.marker,true)&lt;br /&gt;
&lt;br /&gt;
    forcePoint = forcePoint or forceMarker&lt;br /&gt;
    suppressPoint = suppressPoint or suppressMarker&lt;br /&gt;
&lt;br /&gt;
    local showMarker = not suppressPoint and (forcePoint or not wikidataProvidesGeo or config.coord)&lt;br /&gt;
    &lt;br /&gt;
    -- wikidata = &amp;quot;yes&amp;quot; turns on both shape and line&lt;br /&gt;
    -- wikidata = &amp;quot;no&amp;quot; turns off both shape and line&lt;br /&gt;
    -- otherwise show both if wikidata provides geo&lt;br /&gt;
    local forceWikidata, suppressWikidata = util.ternary(config.wikidata)&lt;br /&gt;
    local showShape = not suppressWikidata and (forceWikidata or wikidataProvidesGeo or not config.coord)&lt;br /&gt;
    local showLine = showShape&lt;br /&gt;
&lt;br /&gt;
    -- determine shape parameter value, determine whether to show or suppress shape&lt;br /&gt;
    -- also determine whether to invert shape&lt;br /&gt;
    local forceShape, suppressShape = util.ternary(config.shape)&lt;br /&gt;
    showShape = wikidataId and not suppressShape and (forceShape or showShape)&lt;br /&gt;
	local shapeType = config.shape == &#039;inverse&#039; and &#039;shape-inverse&#039; or &#039;shape&#039;&lt;br /&gt;
&lt;br /&gt;
    -- determine line parameter value, determine whether to show or suppress line&lt;br /&gt;
    local forceLine, suppressLine = util.ternary(config.line)&lt;br /&gt;
    showLine = wikidataId and not suppressLine and (forceLine or showLine)&lt;br /&gt;
&lt;br /&gt;
    local maskItem&lt;br /&gt;
	-- Switcher&lt;br /&gt;
	if config.switcher == &amp;quot;zooms&amp;quot; then&lt;br /&gt;
		-- switching between zoom levels&lt;br /&gt;
		local maxZoom = math.max(tonumber(args.zoom), 3) -- what zoom would have otherwise been (if 3 or more, otherwise 3)&lt;br /&gt;
		local minZoom = 1 -- completely zoomed out&lt;br /&gt;
		local midZoom = math.floor((maxZoom + minZoom)/2) -- midway between maxn and min&lt;br /&gt;
		args.switch = &amp;quot;zoomed in, zoomed midway, zoomed out&amp;quot;&lt;br /&gt;
		args.zoom = string.format(&amp;quot;SWITCH:%d,%d,%d&amp;quot;, maxZoom, midZoom, minZoom)&lt;br /&gt;
	elseif config.switcher == &amp;quot;auto&amp;quot; then&lt;br /&gt;
		-- switching between P276 and P131 areas with recursive lookup, e.g. item&#039;s city,&lt;br /&gt;
		-- that city&#039;s state, and that state&#039;s country&lt;br /&gt;
		args.zoom = nil -- let kartographer determine the zoom&lt;br /&gt;
		local maskLabels = {}&lt;br /&gt;
		local maskItems = {}&lt;br /&gt;
		local maskItemId = util.relatedEntity(wikidataId, &amp;quot;P276&amp;quot;) or  util.relatedEntity(wikidataId, &amp;quot;P131&amp;quot;) &lt;br /&gt;
		local maskLabel = mw.wikibase.getLabel(maskItemId)&lt;br /&gt;
		while maskItemId and maskLabel and mw.text.trim(maskLabel) ~= &amp;quot;&amp;quot; do&lt;br /&gt;
			table.insert(maskLabels, maskLabel)&lt;br /&gt;
			table.insert(maskItems, maskItemId)&lt;br /&gt;
			maskItemId = maskItemId and util.relatedEntity(maskItemId, &amp;quot;P131&amp;quot;)&lt;br /&gt;
			maskLabel = maskItemId and mw.wikibase.getLabel(maskItemId)&lt;br /&gt;
		end&lt;br /&gt;
		if #maskLabels &amp;gt; 1 then&lt;br /&gt;
			args.switch = table.concat(maskLabels, &amp;quot;###&amp;quot;)&lt;br /&gt;
			maskItem = &amp;quot;SWITCH:&amp;quot; .. table.concat(maskItems, &amp;quot;,&amp;quot;)&lt;br /&gt;
		elseif #maskLabels == 1 then&lt;br /&gt;
			maskItem = maskItemId[1]&lt;br /&gt;
		end&lt;br /&gt;
	elseif config.switcher == &amp;quot;geomasks&amp;quot; and config.geomask then&lt;br /&gt;
		-- switching between items in geomask parameter&lt;br /&gt;
		args.zoom = nil -- let kartographer determine the zoom&lt;br /&gt;
		local separator = (mw.ustring.find(config.geomask, &amp;quot;###&amp;quot;, 0, true ) and &amp;quot;###&amp;quot;) or&lt;br /&gt;
			(mw.ustring.find(config.geomask, &amp;quot;;&amp;quot;, 0, true ) and &amp;quot;;&amp;quot;) or &amp;quot;,&amp;quot;&lt;br /&gt;
		local pattern = &amp;quot;%s*&amp;quot;..separator..&amp;quot;%s*&amp;quot;&lt;br /&gt;
		local maskItems = mw.text.split(mw.ustring.gsub(config.geomask, &amp;quot;SWITCH:&amp;quot;, &amp;quot;&amp;quot;), pattern)&lt;br /&gt;
		local maskLabels = {}&lt;br /&gt;
		if #maskItems &amp;gt; 1 then&lt;br /&gt;
			for i, item in ipairs(maskItems) do&lt;br /&gt;
				table.insert(maskLabels, mw.wikibase.getLabel(item))&lt;br /&gt;
			end&lt;br /&gt;
			args.switch = table.concat(maskLabels, &amp;quot;###&amp;quot;)&lt;br /&gt;
			maskItem = &amp;quot;SWITCH:&amp;quot; .. table.concat(maskItems, &amp;quot;,&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- resolve geomask item id (if not using geomask switcher)&lt;br /&gt;
	if not maskItem then --  &lt;br /&gt;
		local maskType = util.idType(config.geomask)&lt;br /&gt;
		if maskType == &#039;item&#039; then&lt;br /&gt;
			maskItem = config.geomask&lt;br /&gt;
		elseif maskType == &amp;quot;property&amp;quot; then&lt;br /&gt;
			maskItem = util.relatedEntity(wikidataId, config.geomask)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
    -- if asking for shape or line from Wikidata&lt;br /&gt;
    -- and if Wikidata actually has shape/line data (wikidataProvidesGeo=true)&lt;br /&gt;
    -- and if no geomask&lt;br /&gt;
    -- and if zoom not explicitly set&lt;br /&gt;
    -- and if the object size inferred from its type is not too small&lt;br /&gt;
    -- then let Kartographer &amp;quot;take over&amp;quot; zoom&lt;br /&gt;
    if (showLine or showShape) and wikidataProvidesGeo and not maskItem&lt;br /&gt;
       and not config.zoom and not (config.type and tinyType[config.type]) then&lt;br /&gt;
	    args.zoom = nil&lt;br /&gt;
    end	&lt;br /&gt;
&lt;br /&gt;
    if not maskItem and not showShape and not showLine and not showMarker then&lt;br /&gt;
        return false, util.trackAndWarn(&#039;Pages using infobox mapframe with no geometry&#039;,&#039;No geometry specified for mapframe&#039;)&lt;br /&gt;
    end&lt;br /&gt;
	&lt;br /&gt;
	-- Keep track of arg numbering&lt;br /&gt;
	local argNumber = &#039;&#039;&lt;br /&gt;
	local function incrementArgNumber()&lt;br /&gt;
		if argNumber == &#039;&#039; then&lt;br /&gt;
			argNumber = 2&lt;br /&gt;
		else&lt;br /&gt;
			argNumber = argNumber + 1&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Geomask&lt;br /&gt;
	if maskItem then&lt;br /&gt;
		args[&amp;quot;type&amp;quot;..argNumber] = &amp;quot;shape-inverse&amp;quot;&lt;br /&gt;
		args[&amp;quot;id&amp;quot;..argNumber] = maskItem&lt;br /&gt;
		args[&amp;quot;stroke-width&amp;quot;..argNumber] = config[&amp;quot;geomask-stroke-width&amp;quot;] or DEFAULT_GEOMASK_STROKE_WIDTH&lt;br /&gt;
		args[&amp;quot;stroke-color&amp;quot;..argNumber] = config[&amp;quot;geomask-stroke-color&amp;quot;] or config[&amp;quot;geomask-stroke-colour&amp;quot;] or DEFAULT_GEOMASK_STROKE_COLOR&lt;br /&gt;
		args[&amp;quot;fill&amp;quot;..argNumber] = config[&amp;quot;geomask-fill&amp;quot;] or DEFAULT_GEOMASK_FILL&lt;br /&gt;
		args[&amp;quot;fill-opacity&amp;quot;..argNumber] = config[&amp;quot;geomask-fill-opacity&amp;quot;] or DEFAULT_SHAPE_FILL_OPACITY&lt;br /&gt;
		-- Let kartographer determine zoom and position, unless it is explicitly set in config&lt;br /&gt;
		if not config.zoom and not config.switcher then&lt;br /&gt;
			args.zoom = nil&lt;br /&gt;
			args[&amp;quot;frame-coord&amp;quot;] = nil&lt;br /&gt;
			args[&amp;quot;frame-lat&amp;quot;] = nil&lt;br /&gt;
			args[&amp;quot;frame-long&amp;quot;] = nil 	&lt;br /&gt;
			local maskArea = util.getStatementValue( util.getBestStatement(maskItem, &#039;P2046&#039;) )&lt;br /&gt;
		end&lt;br /&gt;
		incrementArgNumber()&lt;br /&gt;
		-- Hack to fix phab:T255932&lt;br /&gt;
		if not args.zoom then&lt;br /&gt;
			args[&amp;quot;type&amp;quot;..argNumber] = &amp;quot;line&amp;quot;&lt;br /&gt;
			args[&amp;quot;id&amp;quot;..argNumber] = maskItem&lt;br /&gt;
			args[&amp;quot;stroke-width&amp;quot;..argNumber] = 0&lt;br /&gt;
			incrementArgNumber()&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Shape (or shape-inverse)&lt;br /&gt;
	if showShape then&lt;br /&gt;
		args[&amp;quot;type&amp;quot;..argNumber] = shapeType&lt;br /&gt;
		if hasGeoshape and not hasOsmRelationId then&lt;br /&gt;
			args[&amp;quot;from&amp;quot;..argNumber] = string.sub( util.getStatementValue( util.getBestStatement(wikidataId, &#039;P3896&#039;) ), 6)&lt;br /&gt;
		elseif config.id then &lt;br /&gt;
			args[&amp;quot;id&amp;quot;..argNumber] = config.id&lt;br /&gt;
		end&lt;br /&gt;
		args[&amp;quot;stroke-width&amp;quot;..argNumber] = config[&amp;quot;shape-stroke-width&amp;quot;] or config[&amp;quot;stroke-width&amp;quot;] or DEFAULT_SHAPE_STROKE_WIDTH&lt;br /&gt;
		args[&amp;quot;stroke-color&amp;quot;..argNumber] = config[&amp;quot;shape-stroke-color&amp;quot;] or config[&amp;quot;shape-stroke-colour&amp;quot;] or config[&amp;quot;stroke-color&amp;quot;] or config[&amp;quot;stroke-colour&amp;quot;] or DEFAULT_SHAPE_STROKE_COLOR&lt;br /&gt;
		args[&amp;quot;fill&amp;quot;..argNumber] = config[&amp;quot;shape-fill&amp;quot;] or DEFAULT_SHAPE_FILL&lt;br /&gt;
		args[&amp;quot;fill-opacity&amp;quot;..argNumber] = config[&amp;quot;shape-fill-opacity&amp;quot;] or DEFAULT_SHAPE_FILL_OPACITY&lt;br /&gt;
		incrementArgNumber()&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Line&lt;br /&gt;
	if showLine then&lt;br /&gt;
		args[&amp;quot;type&amp;quot;..argNumber] = &amp;quot;line&amp;quot;&lt;br /&gt;
		if hasGeoshape and not hasOsmRelationId then&lt;br /&gt;
			args[&amp;quot;from&amp;quot;..argNumber] = string.sub( util.getStatementValue( util.getBestStatement(wikidataId, &#039;P3896&#039;) ), 6)&lt;br /&gt;
		elseif config.id then &lt;br /&gt;
			args[&amp;quot;id&amp;quot;..argNumber] = config.id&lt;br /&gt;
		end&lt;br /&gt;
		args[&amp;quot;stroke-width&amp;quot;..argNumber] = config[&amp;quot;line-stroke-width&amp;quot;] or config[&amp;quot;stroke-width&amp;quot;] or DEFAULT_LINE_STROKE_WIDTH&lt;br /&gt;
		args[&amp;quot;stroke-color&amp;quot;..argNumber] = config[&amp;quot;line-stroke-color&amp;quot;] or config[&amp;quot;line-stroke-colour&amp;quot;] or config[&amp;quot;stroke-color&amp;quot;] or config[&amp;quot;stroke-colour&amp;quot;] or DEFAULT_LINE_STROKE_COLOR&lt;br /&gt;
		incrementArgNumber()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Point marker&lt;br /&gt;
	if showMarker then&lt;br /&gt;
		args[&amp;quot;type&amp;quot;..argNumber] = &amp;quot;point&amp;quot;&lt;br /&gt;
		if config.id then args[&amp;quot;id&amp;quot;..argNumber] = config.id end&lt;br /&gt;
		if config.coord then args[&amp;quot;coord&amp;quot;..argNumber] = config.coord end&lt;br /&gt;
		if config.marker then args[&amp;quot;marker&amp;quot;..argNumber] = config.marker end&lt;br /&gt;
		args[&amp;quot;marker-color&amp;quot;..argNumber] = config[&amp;quot;marker-color&amp;quot;] or config[&amp;quot;marker-colour&amp;quot;] or DEFAULT_MARKER_COLOR&lt;br /&gt;
		incrementArgNumber()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
    -- if Wikidata doesn&#039;t link to OSM and the map has no mask or point,&lt;br /&gt;
    -- then center the map on the coordinates either from the infobox or from wikidata&lt;br /&gt;
    if not maskItem and not showMarker and not wikidataProvidesGeo then&lt;br /&gt;
        if config.coord then&lt;br /&gt;
            args[&amp;quot;frame-coord&amp;quot;] = args[&amp;quot;frame-coord&amp;quot;] or config.coord&lt;br /&gt;
        else&lt;br /&gt;
            args[&amp;quot;frame-lat&amp;quot;] = args[&amp;quot;frame-lat&amp;quot;] or wdCoordinates.latitude&lt;br /&gt;
            args[&amp;quot;frame-long&amp;quot;] = args[&amp;quot;frame-long&amp;quot;] or wdCoordinates.longitude&lt;br /&gt;
        end&lt;br /&gt;
        tracking = tracking..util.trackAndWarn(&#039;Pages using infobox mapframe with forced centering&#039;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- protect against nil frame arguments&lt;br /&gt;
    args[&amp;quot;frame-coord&amp;quot;] = args[&amp;quot;frame-coord&amp;quot;] or &amp;quot;&amp;quot;&lt;br /&gt;
    args[&amp;quot;frame-lat&amp;quot;] = args[&amp;quot;frame-lat&amp;quot;] or &amp;quot;&amp;quot;&lt;br /&gt;
    args[&amp;quot;frame-long&amp;quot;] = args[&amp;quot;frame-long&amp;quot;] or &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	local mapframe = args.switch and mf.multi(args) or mf._main(args)&lt;br /&gt;
	tracking = tracking..((showLine or showShape) and not wikidataProvidesGeo &lt;br /&gt;
                          and util.trackAndWarn(&#039;Pages using infobox mapframe without shape links in Wikidata&#039;)&lt;br /&gt;
                          or &#039;&#039;)&lt;br /&gt;
	return true, mapframe.. tracking&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Entry points&lt;br /&gt;
&lt;br /&gt;
p.main = function(frame)&lt;br /&gt;
	local parent = frame.getParent(frame)&lt;br /&gt;
	local parentArgs = parent.args&lt;br /&gt;
	local _, mapframe = p._main(parentArgs)&lt;br /&gt;
	return frame:preprocess(mapframe)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.auto = function(frame)&lt;br /&gt;
	if not util.shouldAutoRun(frame) then&lt;br /&gt;
		return util.noop(&amp;quot;auto should not autorun&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	local args = util.argsFromAuto(frame)&lt;br /&gt;
	if args.custom then&lt;br /&gt;
		return frame:preprocess(util.parseCustomWikitext(args.custom))&lt;br /&gt;
	end&lt;br /&gt;
	local _, mapframe = p._main(args)&lt;br /&gt;
	return frame:preprocess(mapframe)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.autocaption = function(frame)&lt;br /&gt;
	if not util.shouldAutoRun(frame) then&lt;br /&gt;
		return util.noop(&amp;quot;autocaption should not autorun&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	local args = util.argsFromAuto(frame)&lt;br /&gt;
    local caption = p._caption(args)&lt;br /&gt;
    return caption&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.autoWithCaption = function(frame)&lt;br /&gt;
	if not util.shouldAutoRun(frame) then&lt;br /&gt;
		return util.noop(&amp;quot;autoWithCaption should not autorun&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	local args = util.argsFromAuto(frame)&lt;br /&gt;
    local wikitext&lt;br /&gt;
    local caption&lt;br /&gt;
    local ok&lt;br /&gt;
    if args.custom then&lt;br /&gt;
        ok = true&lt;br /&gt;
        wikitext = util.parseCustomWikitext(args.custom)&lt;br /&gt;
    else&lt;br /&gt;
        ok, wikitext = p._main(args)&lt;br /&gt;
    end&lt;br /&gt;
    if not ok then return wikitext end&lt;br /&gt;
    wikitext = frame:preprocess(wikitext)&lt;br /&gt;
    caption = p._caption(args)&lt;br /&gt;
    local data = mw.html.create():wikitext(wikitext)&lt;br /&gt;
    data:tag(&#039;div&#039;)&lt;br /&gt;
	    :addClass(&#039;infobox-caption&#039;)&lt;br /&gt;
		:cssText(args.captionstyle)&lt;br /&gt;
		:wikitext(caption)&lt;br /&gt;
    return tostring(data)&lt;br /&gt;
end&lt;br /&gt;
    &lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Module:Jct&amp;diff=5316</id>
		<title>Module:Jct</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Module:Jct&amp;diff=5316"/>
		<updated>2026-06-15T12:42:18Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Shared ABC wiki compatibility: guard Module:Jct when route link is boolean&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
-- Change to &amp;quot;&amp;quot; upon deployment.&lt;br /&gt;
local moduleSuffix = &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
local parserModuleName = &amp;quot;Module:Road data/parser&amp;quot; .. moduleSuffix&lt;br /&gt;
local statenameModuleName = &amp;quot;Module:Jct/statename&amp;quot; .. moduleSuffix -- TODO transition&lt;br /&gt;
local cityModuleName = &amp;quot;Module:Jct/city&amp;quot; .. moduleSuffix&lt;br /&gt;
&lt;br /&gt;
local concat = table.concat&lt;br /&gt;
local insert = table.insert&lt;br /&gt;
local format = mw.ustring.format&lt;br /&gt;
local trim = mw.text.trim&lt;br /&gt;
&lt;br /&gt;
local parserModule = require(parserModuleName)&lt;br /&gt;
local parser = parserModule.parser&lt;br /&gt;
local util = require(&amp;quot;Module:Road data/util&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Shields&lt;br /&gt;
local defaultShieldSize = 24&lt;br /&gt;
&lt;br /&gt;
local function addContextBanner(route, name, suffix, bannerSpec)&lt;br /&gt;
	local bannerModule = &#039;Module:Road data/banners/&#039; .. string.upper(route.country)&lt;br /&gt;
	local shieldfield = name .. &#039;shield&#039;&lt;br /&gt;
	local shield = parser(route, shieldfield)&lt;br /&gt;
	if shield == nil then&lt;br /&gt;
		-- This route type does not define shield.&lt;br /&gt;
		-- Find shield in the default banner table.&lt;br /&gt;
		shield = parser(route, &#039;shield&#039;, name, bannerModule)&lt;br /&gt;
		if shield and shield ~= &#039;&#039; then&lt;br /&gt;
			if suffix == nil then&lt;br /&gt;
				suffix = parser(route, &#039;shield&#039;, &#039;suffix&#039;, bannerModule)&lt;br /&gt;
			end&lt;br /&gt;
			if suffix and suffix ~= &#039;&#039; then&lt;br /&gt;
				shield = shield .. &amp;quot; &amp;quot; .. suffix&lt;br /&gt;
			end&lt;br /&gt;
			shield = shield .. &amp;quot;.svg&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if shield and shield ~= &#039;&#039; then&lt;br /&gt;
		local shieldSize = defaultShieldSize&lt;br /&gt;
		-- Add banner plate.&lt;br /&gt;
		insert(bannerSpec, {shield, shieldSize})&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function bannerSpec(banner, bannerSize, bannerSuffix, route)&lt;br /&gt;
	local banners = {}&lt;br /&gt;
	if type(banner) == &amp;quot;table&amp;quot; then&lt;br /&gt;
		local bannerSizeIsNotTable = type(bannerSize) ~= &amp;quot;table&amp;quot;&lt;br /&gt;
		for i,filename in ipairs(banner) do&lt;br /&gt;
			local bannersize = bannerSizeIsNotTable and bannerSize or bannerSize[i] or defaultShieldSize&lt;br /&gt;
			insert(banners, {filename, bannersize})&lt;br /&gt;
		end&lt;br /&gt;
	elseif banner ~= &#039;&#039; then&lt;br /&gt;
		insert(banners, {banner, bannerSize})&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if route.dir then&lt;br /&gt;
		addContextBanner(route, &#039;dir&#039;, bannerSuffix, banners)&lt;br /&gt;
	end&lt;br /&gt;
	if route.to then&lt;br /&gt;
		addContextBanner(route, &#039;to&#039;, bannerSuffix, banners)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return banners&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function shieldSpec(route, mainShield, shieldList)&lt;br /&gt;
	local shieldSpec = {}&lt;br /&gt;
&lt;br /&gt;
	local shield&lt;br /&gt;
	local shieldto = parser(route, &#039;shieldto&#039;)&lt;br /&gt;
	&lt;br /&gt;
	if route.to then&lt;br /&gt;
		if not shield then shield = shieldto or parser(route, &#039;shield&#039;) or &#039;&#039; end&lt;br /&gt;
	else&lt;br /&gt;
		if not shield then shield = parser(route, &#039;shield&#039;) or &#039;&#039; end&lt;br /&gt;
	end&lt;br /&gt;
	if shield == &#039;&#039; then return shieldSpec end&lt;br /&gt;
	local orientation = parser(route, &#039;orientation&#039;)&lt;br /&gt;
&lt;br /&gt;
	local function size(route)&lt;br /&gt;
		if orientation == &amp;quot;upright&amp;quot; then&lt;br /&gt;
			return defaultShieldSize&lt;br /&gt;
			else return &amp;quot;x&amp;quot; .. defaultShieldSize&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local shieldsize = size(route)&lt;br /&gt;
	&lt;br /&gt;
	local banner = parser(route, &#039;banner&#039;) or {}&lt;br /&gt;
	local bannersize = defaultShieldSize&lt;br /&gt;
	local bannersuffix = parser(route, &#039;bannersuffix&#039;)&lt;br /&gt;
&lt;br /&gt;
	local bannerIsNotTable = type(banner) ~= &amp;quot;table&amp;quot;&lt;br /&gt;
	local bannersizeIsNotTable = type(bannersize) ~= &amp;quot;table&amp;quot;&lt;br /&gt;
	local bannersuffixIsNotTable = type(bannersuffix) ~= &amp;quot;table&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	if type(shield) == &amp;quot;table&amp;quot; then&lt;br /&gt;
		for i,filename in ipairs(shield) do&lt;br /&gt;
			local size = shieldsize or shieldsize[i]&lt;br /&gt;
			if size == &amp;quot;&amp;quot; then size = nil end&lt;br /&gt;
			-- banner.all describes banners that apply to all multiple shields.&lt;br /&gt;
			local shieldBanner = bannerIsNotTable and banner or (banner[i] or banner.all or {})&lt;br /&gt;
			-- Banner size is default if the corresponding entry&lt;br /&gt;
			-- in bannerSize table is not set.&lt;br /&gt;
			local shieldBannerSize =&lt;br /&gt;
				bannersizeIsNotTable and bannersize&lt;br /&gt;
				or (bannersize[i] or bannersize.all or defaultShieldSize)&lt;br /&gt;
			local shieldBannerSuffix = bannersuffix and (bannersuffixIsNotTable and bannersuffix or bannersuffix[i])&lt;br /&gt;
			insert(shieldSpec, {&lt;br /&gt;
				shield = {filename, size},&lt;br /&gt;
				banners = bannerSpec(shieldBanner, shieldBannerSize, shieldBannerSuffix, route)&lt;br /&gt;
			})&lt;br /&gt;
		end&lt;br /&gt;
	elseif shield ~= &#039;&#039; then&lt;br /&gt;
		if shieldsize == &amp;quot;&amp;quot; then shieldsize = nil end&lt;br /&gt;
		insert(shieldSpec, {&lt;br /&gt;
			shield = {shield, shieldsize},&lt;br /&gt;
			banners = bannerSpec(banner, bannersize,  bannersuffix, route)&lt;br /&gt;
		})&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return shieldSpec&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local missingShields&lt;br /&gt;
&lt;br /&gt;
local shieldExistsCache = {}&lt;br /&gt;
&lt;br /&gt;
local function render(shieldEntry, scale, showLink)&lt;br /&gt;
	local shield = shieldEntry.shield&lt;br /&gt;
	local banners = shieldEntry.banners&lt;br /&gt;
&lt;br /&gt;
	local size&lt;br /&gt;
	if shield[2] then&lt;br /&gt;
		local width, height = mw.ustring.match(shield[2], &amp;quot;(%d*)x?(%d*)&amp;quot;)&lt;br /&gt;
		width = tonumber(width)&lt;br /&gt;
		height = tonumber(height)&lt;br /&gt;
		local sizeparts = {}&lt;br /&gt;
		if width then&lt;br /&gt;
			insert(sizeparts, format(&amp;quot;%d&amp;quot;, width * scale))&lt;br /&gt;
		end&lt;br /&gt;
		if height then&lt;br /&gt;
			insert(sizeparts, format(&amp;quot;x%d&amp;quot;, height * scale))&lt;br /&gt;
		end&lt;br /&gt;
		size = concat(sizeparts)&lt;br /&gt;
	else&lt;br /&gt;
		size = format(&amp;quot;%s%d&amp;quot;, landscape and &amp;quot;x&amp;quot; or &amp;quot;&amp;quot;, defaultShieldSize * scale)&lt;br /&gt;
	end&lt;br /&gt;
	local shieldCode = format(&amp;quot;[[File:%s|%spx|link=|alt=]]&amp;quot;, shield[1], size)&lt;br /&gt;
	if not banners[1] then return shieldCode end&lt;br /&gt;
&lt;br /&gt;
	for _,banner in ipairs(banners) do&lt;br /&gt;
		shieldCode = format(&amp;quot;[[File:%s|%spx|link=|alt=]]&amp;lt;br&amp;gt;%s&amp;quot;,&lt;br /&gt;
			banner[1],&lt;br /&gt;
			defaultShieldSize,&lt;br /&gt;
			shieldCode)&lt;br /&gt;
	end&lt;br /&gt;
	return &#039;&amp;lt;span style=&amp;quot;display: inline-block; vertical-align: baseline; line-height: 0; text-align: center;&amp;quot;&amp;gt;&#039; .. shieldCode .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.shield(route, scale, showLink, mainShield, shieldList)&lt;br /&gt;
	missingShields = {}&lt;br /&gt;
&lt;br /&gt;
	scale = scale or 1&lt;br /&gt;
&lt;br /&gt;
	local rendered = {}&lt;br /&gt;
	for _,entry in ipairs(shieldSpec(route, mainShield, shieldList)) do&lt;br /&gt;
		insert(rendered, render(entry, scale, showLink))&lt;br /&gt;
	end&lt;br /&gt;
	return concat(rendered), missingShields&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Links/abbreviations&lt;br /&gt;
function p.link(route)&lt;br /&gt;
	local nolink = route.nolink&lt;br /&gt;
	local abbr = parser(route, &#039;abbr&#039;)&lt;br /&gt;
	if nolink then&lt;br /&gt;
		return abbr&lt;br /&gt;
	else&lt;br /&gt;
		local link = parser(route, &#039;link&#039;)&lt;br /&gt;
		if not link or link == &#039;&#039; then&lt;br /&gt;
			return abbr&lt;br /&gt;
		else&lt;br /&gt;
			return format(&amp;quot;[[%s|%s]]&amp;quot;, link, abbr)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
-------------------------------------------&lt;br /&gt;
&lt;br /&gt;
-- Links/abbreviations&lt;br /&gt;
local function routeText(route, jctname, frame)&lt;br /&gt;
	local link&lt;br /&gt;
	local type = route.type&lt;br /&gt;
	if not type or type == &#039;&#039; then&lt;br /&gt;
		link = route.route&lt;br /&gt;
	else&lt;br /&gt;
		link = p.link(route)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local dir = route.dir and &#039; &#039; .. string.lower(route.dir) or &#039;&#039;&lt;br /&gt;
	if type(link) ~= &#039;string&#039; then&lt;br /&gt;
		link = route.route or &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local routeText = link .. dir&lt;br /&gt;
&lt;br /&gt;
	local name = route.name&lt;br /&gt;
	if name and name ~= &#039;&#039; then&lt;br /&gt;
		local mainText = jctname and name or routeText&lt;br /&gt;
		local parenText = jctname and routeText or name&lt;br /&gt;
		&lt;br /&gt;
		return format(&#039;%s (%s)&#039;, mainText, parenText)&lt;br /&gt;
	else&lt;br /&gt;
		return routeText&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function extra(args)&lt;br /&gt;
	local extraTypes = mw.loadData(&#039;Module:Road data/extra&#039;)&lt;br /&gt;
	local extraIcon = extraTypes[string.lower(args.extra or &#039;&#039;)]&lt;br /&gt;
	if not extraIcon then return &#039;&#039; end&lt;br /&gt;
	local size = defaultShieldSize .. &#039;px&#039;&lt;br /&gt;
	local countryIcon = extraIcon[args.country] or extraIcon.default&lt;br /&gt;
	if type(countryIcon) == &#039;table&#039; then&lt;br /&gt;
		local localIcon = countryIcon[args.state] or countryIcon.default&lt;br /&gt;
		return string.format(&amp;quot;[[File:%s|%s|alt=|link=]]&amp;quot;, localIcon, size)&lt;br /&gt;
	else&lt;br /&gt;
		return string.format(&amp;quot;[[File:%s|%s|alt=|link=]]&amp;quot;, countryIcon, size)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function parseArgs(args)&lt;br /&gt;
	local state = args.state or args.province or &#039;&#039;&lt;br /&gt;
	args.state = state&lt;br /&gt;
	local country&lt;br /&gt;
	if args.country and args.country ~= &#039;&#039; then&lt;br /&gt;
		country = string.upper(args.country)&lt;br /&gt;
	else&lt;br /&gt;
		local countryModule = mw.loadData(&amp;quot;Module:Road data/countrymask&amp;quot;)&lt;br /&gt;
		country = countryModule[state] or &#039;UNK&#039;&lt;br /&gt;
	end&lt;br /&gt;
	args.country = country&lt;br /&gt;
&lt;br /&gt;
	local params = {&#039;denom&#039;, &#039;county&#039;, &#039;township&#039;, &#039;dab&#039;, &#039;nolink&#039;, &#039;noshield&#039;, &#039;to&#039;, &#039;dir&#039;, &#039;name&#039;}&lt;br /&gt;
	local routes = {}&lt;br /&gt;
	local routeCount = 1&lt;br /&gt;
	local seenTo = false&lt;br /&gt;
	while true do&lt;br /&gt;
		local routeType = args[routeCount * 2 - 1]&lt;br /&gt;
		if not routeType then break end&lt;br /&gt;
		local route = {type = routeType, route = args[routeCount * 2]}&lt;br /&gt;
		for _,v in pairs(params) do&lt;br /&gt;
			route[v] = args[v .. routeCount]&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if args.nolink then&lt;br /&gt;
			route.nolink = args.nolink&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		route.country = country&lt;br /&gt;
		route.state = state&lt;br /&gt;
&lt;br /&gt;
		-- Set the first .to to true.&lt;br /&gt;
		-- Set all following .to to &#039;&#039;.&lt;br /&gt;
		if seenTo then&lt;br /&gt;
			if route.to then&lt;br /&gt;
				-- Report duplicate to flag.&lt;br /&gt;
				route.toerror = true&lt;br /&gt;
			end&lt;br /&gt;
			route.to = &#039;&#039;&lt;br /&gt;
		elseif route.to then&lt;br /&gt;
			route.to = true&lt;br /&gt;
			seenTo = true&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		insert(routes, route)&lt;br /&gt;
		routeCount = routeCount + 1&lt;br /&gt;
	end&lt;br /&gt;
	return routes&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function prefix(to, num)&lt;br /&gt;
	if to and to ~= &#039;&#039; then&lt;br /&gt;
		return num == 1 and &#039;To &#039; or &#039; to &#039;&lt;br /&gt;
	end&lt;br /&gt;
	return num == 1 and &#039;&#039; or &#039;&amp;amp;nbsp;/ &#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function addErrorMsg(catCode, msg, errorMsg)&lt;br /&gt;
	errorMsg.code = errorMsg.code or catCode&lt;br /&gt;
	insert(errorMsg, format(&#039;&amp;lt;span style=&amp;quot;display: none;&amp;quot;&amp;gt;Module:Jct %s&amp;lt;/span&amp;gt;&#039;, msg))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._jct(args, frame)&lt;br /&gt;
	local routes = parseArgs(args)&lt;br /&gt;
	local shields = {}&lt;br /&gt;
	local links = {}&lt;br /&gt;
	local allMissingShields = {}&lt;br /&gt;
	local typeErr = false&lt;br /&gt;
	local toErr = false&lt;br /&gt;
	frame = frame or mw.getCurrentFrame()&lt;br /&gt;
	for num,route in ipairs(routes) do&lt;br /&gt;
		if not (args.noshield or route.noshield) then&lt;br /&gt;
			local shield, missingShields = p.shield(route)&lt;br /&gt;
			insert(shields, shield)&lt;br /&gt;
			if missingShields[1] then&lt;br /&gt;
				insert(allMissingShields, concat(missingShields, &#039; / &#039;))&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		local prefix = prefix(route.to, num)&lt;br /&gt;
		if prefix ~= &#039;&#039; then insert(links, prefix) end&lt;br /&gt;
		insert(links, routeText(route, args.jctname, frame))&lt;br /&gt;
		typeErr = typeErr or route.typeerror or false&lt;br /&gt;
		toErr = toErr or route.toerror or false&lt;br /&gt;
	end&lt;br /&gt;
	local graphics = concat(shields) .. extra(args) .. &#039; &#039;&lt;br /&gt;
	local linkText = concat(links)&lt;br /&gt;
	local cities = &#039;&#039;&lt;br /&gt;
	if args.city1 or args.location1 then&lt;br /&gt;
		local citiesPrefix&lt;br /&gt;
		if args.citiesprefix then&lt;br /&gt;
			citiesPrefix = args.citiesprefix ~= &#039;&#039; and format(&amp;quot; %s &amp;quot;, args.citiesprefix) or &#039;&#039;&lt;br /&gt;
		else&lt;br /&gt;
			citiesPrefix = &#039;&amp;amp;nbsp;&#039;&lt;br /&gt;
		end&lt;br /&gt;
		local cityModule = require(cityModuleName)&lt;br /&gt;
		cities = citiesPrefix .. cityModule.city(args)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local errorMsg = {}&lt;br /&gt;
	-- Errors must be reported by the level of severity, most severe first.&lt;br /&gt;
	if typeErr then&lt;br /&gt;
		-- Report invalid type errors.&lt;br /&gt;
		addErrorMsg(&amp;quot;§&amp;quot;, &#039;error: Invalid route type&#039;, errorMsg)&lt;br /&gt;
	end&lt;br /&gt;
	if #allMissingShields &amp;gt; 0 then&lt;br /&gt;
		-- Report missing shield error.&lt;br /&gt;
		-- shieldExists() would have populated missingShields if shields are missing.&lt;br /&gt;
		addErrorMsg(&amp;quot;¶&amp;quot;, &#039;error: Missing route marker graphics: &#039; .. concat(allMissingShields, &#039; / &#039;), errorMsg)&lt;br /&gt;
	end&lt;br /&gt;
	if toErr then&lt;br /&gt;
		-- Report invalid to errors.&lt;br /&gt;
		addErrorMsg(&amp;quot;&amp;amp;&amp;quot;, &#039;error: Invalid &amp;quot;to&amp;quot; argument&#039;, errorMsg)&lt;br /&gt;
	end&lt;br /&gt;
	if args.road then&lt;br /&gt;
		-- Report deprecated &amp;quot;road&amp;quot; warning.&lt;br /&gt;
		addErrorMsg(&amp;quot;∆&amp;quot;, &#039;warning: &amp;quot;road&amp;quot; parameter is deprecated&#039;, errorMsg)&lt;br /&gt;
	end&lt;br /&gt;
	if args.rdt then&lt;br /&gt;
		-- Report deprecated &amp;quot;rdt&amp;quot; warning.&lt;br /&gt;
		addErrorMsg(&amp;quot;£&amp;quot;, &#039;warning: &amp;quot;rdt&amp;quot; parameter is deprecated&#039;, errorMsg)&lt;br /&gt;
	end&lt;br /&gt;
	if #errorMsg &amp;gt; 0 then&lt;br /&gt;
		local page = mw.title.getCurrentTitle().prefixedText -- Get transcluding page&#039;s title&lt;br /&gt;
		-- Add a category for the first, most severe error.&lt;br /&gt;
		insert(errorMsg, format(&#039;[[Category:Jct template errors|%s %s]]&#039;, errorMsg.code, page))&lt;br /&gt;
		errorMsg = concat(errorMsg)&lt;br /&gt;
	else&lt;br /&gt;
		errorMsg = &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return graphics .. linkText .. cities .. errorMsg&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.jct(frame)&lt;br /&gt;
	-- Import module function to work with passed arguments&lt;br /&gt;
	local getArgs = require(&#039;Module:Arguments&#039;).getArgs&lt;br /&gt;
	local args = getArgs(frame, {removeBlanks = false})&lt;br /&gt;
	return p._jct(args, frame)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._roadlink(args, frame)&lt;br /&gt;
	local routes = parseArgs(args)&lt;br /&gt;
	local links = {}&lt;br /&gt;
	local typeErr = false&lt;br /&gt;
	local toErr = false&lt;br /&gt;
	frame = frame or mw.getCurrentFrame()&lt;br /&gt;
	for num,route in ipairs(routes) do&lt;br /&gt;
		local prefix = prefix(route.to, num)&lt;br /&gt;
		if prefix ~= &#039;&#039; then insert(links, prefix) end&lt;br /&gt;
		insert(links, routeText(route, args.jctname, frame))&lt;br /&gt;
		typeErr = typeErr or route.typeerror or false&lt;br /&gt;
		toErr = toErr or route.toerror or false&lt;br /&gt;
	end&lt;br /&gt;
	local linkText = concat(links)&lt;br /&gt;
	local cities = &#039;&#039;&lt;br /&gt;
	if args.city1 or args.location1 then&lt;br /&gt;
		local citiesPrefix&lt;br /&gt;
		if args.citiesprefix then&lt;br /&gt;
			citiesPrefix = args.citiesprefix ~= &#039;&#039; and format(&amp;quot; %s &amp;quot;, args.citiesprefix) or &#039;&#039;&lt;br /&gt;
		else&lt;br /&gt;
			citiesPrefix = &#039;&amp;amp;nbsp;&#039;&lt;br /&gt;
		end&lt;br /&gt;
		local cityModule = require(cityModuleName)&lt;br /&gt;
		cities = citiesPrefix .. cityModule.city(args)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local errorMsg = {}&lt;br /&gt;
	-- Errors must be reported by the level of severity, most severe first.&lt;br /&gt;
	if typeErr then&lt;br /&gt;
		-- Report invalid type errors.&lt;br /&gt;
		addErrorMsg(&amp;quot;2&amp;quot;, &#039;error: Invalid route type&#039;, errorMsg)&lt;br /&gt;
	end&lt;br /&gt;
	if toErr then&lt;br /&gt;
		-- Report invalid to errors.&lt;br /&gt;
		addErrorMsg(&amp;quot;3&amp;quot;, &#039;error: Invalid &amp;quot;to&amp;quot; argument&#039;, errorMsg)&lt;br /&gt;
	end&lt;br /&gt;
	if args.road then&lt;br /&gt;
		-- Report deprecated &amp;quot;road&amp;quot; warning.&lt;br /&gt;
		addErrorMsg(&amp;quot;W&amp;quot;, &#039;warning: &amp;quot;road&amp;quot; parameter is deprecated&#039;, errorMsg)&lt;br /&gt;
	end&lt;br /&gt;
	if #errorMsg &amp;gt; 0 then&lt;br /&gt;
		local page = mw.title.getCurrentTitle().prefixedText -- Get transcluding page&#039;s title&lt;br /&gt;
		-- Add a category for the first, most severe error.&lt;br /&gt;
		insert(errorMsg, format(&#039;[[Category:Jct template errors|%s %s]]&#039;, errorMsg.code, page))&lt;br /&gt;
		errorMsg = concat(errorMsg)&lt;br /&gt;
	else&lt;br /&gt;
		errorMsg = &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return linkText .. cities&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.roadlink(frame)&lt;br /&gt;
	-- Import module function to work with passed arguments&lt;br /&gt;
	local getArgs = require(&#039;Module:Arguments&#039;).getArgs&lt;br /&gt;
	local args = getArgs(frame, {removeBlanks = true})&lt;br /&gt;
	return p._roadlink(args, frame)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Template:Short_description&amp;diff=5314</id>
		<title>Template:Short description</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Template:Short_description&amp;diff=5314"/>
		<updated>2026-06-15T02:47:16Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Local compatibility: make Short description a no-op because SHORTDESC parser function is unavailable&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
This local wiki does not use Wikipedia&#039;s SHORTDESC parser function.&lt;br /&gt;
&lt;br /&gt;
This template is intentionally a no-op so imported Wikipedia pages do not show redlinks such as:&lt;br /&gt;
Template:SHORTDESC:Example text&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Module:Commons_link&amp;diff=5313</id>
		<title>Module:Commons link</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Module:Commons_link&amp;diff=5313"/>
		<updated>2026-06-15T02:42:22Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Shared ABC wiki patch: guard Commons link Wikibase calls when Wikibase Client is unavailable&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;require(&#039;strict&#039;)&lt;br /&gt;
&lt;br /&gt;
-- Module to find commons galleries and categories based on wikidata entries&lt;br /&gt;
local getArgs = require(&#039;Module:Arguments&#039;).getArgs&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Check if string is a valid QID&lt;br /&gt;
-- Argument: QID to check&lt;br /&gt;
-- Returns: valid (bool)&lt;br /&gt;
local function _validQID(qid)&lt;br /&gt;
	return qid and mw.ustring.find(qid,&amp;quot;^[Qq]%d+$&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Check if string is a valid wikidata property string&lt;br /&gt;
-- Argument: property string to check&lt;br /&gt;
-- Returns: valid (bool)&lt;br /&gt;
local function _validProp(prop)&lt;br /&gt;
	return prop and mw.ustring.find(prop,&amp;quot;^[Pp]%d+$&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function _lcfirst(s)&lt;br /&gt;
	return mw.ustring.lower(mw.ustring.sub(s,1,1))..mw.ustring.sub(s,2)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Format displayed linktext&lt;br /&gt;
-- Arguments:&lt;br /&gt;
--   s = string to display&lt;br /&gt;
--   formatting = formatting table:&lt;br /&gt;
--    formatting.linktext = if defined, override s&lt;br /&gt;
--    formatting.lcfirst = lower case the first letter in display&lt;br /&gt;
--    formatting.bold = whether to bold the display&lt;br /&gt;
--    formatting.italic = whether to italicize the display&lt;br /&gt;
--    formatting.nowrap = set nowrapping&lt;br /&gt;
-- Returns:&lt;br /&gt;
--   formatted string&lt;br /&gt;
local function _formatResult(s, formatting)&lt;br /&gt;
	local resultVal = formatting.linktext or s&lt;br /&gt;
	if formatting.lcfirst then&lt;br /&gt;
		resultVal = _lcfirst(resultVal)&lt;br /&gt;
	end&lt;br /&gt;
    local style = &amp;quot;&amp;quot;&lt;br /&gt;
	if formatting.italic then style = &amp;quot;font-style:italic; &amp;quot; end&lt;br /&gt;
	if formatting.bold then style = style..&amp;quot;font-weight:bold; &amp;quot; end&lt;br /&gt;
	if formatting.nowrap then style = style..&amp;quot;white-space:nowrap; &amp;quot; end&lt;br /&gt;
    if style ~= &amp;quot;&amp;quot; then&lt;br /&gt;
    	resultVal = &#039;&amp;lt;span style=&amp;quot;&#039;..mw.text.trim(style)..&#039;&amp;quot;&amp;gt;&#039;..resultVal..&#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
    end&lt;br /&gt;
	return resultVal&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Get title, namespace, and QID for current page&lt;br /&gt;
-- Arguments:&lt;br /&gt;
--   qid = testing only: get title of alternative page with QID=qid&lt;br /&gt;
--   nsQid = whether to return the ns of the qid page or current&lt;br /&gt;
-- Returns:&lt;br /&gt;
--   title, namespace (string), qid of current page (or test page)&lt;br /&gt;
local function _getTitleQID(qid,nsQid)&lt;br /&gt;
	local titleObject = mw.title.getCurrentTitle()&lt;br /&gt;
	-- look up qid for current page (if not testing)&lt;br /&gt;
	local nsText = string.gsub(titleObject.nsText,&amp;quot;_&amp;quot;,&amp;quot; &amp;quot;) -- [[phab:T369784]]&lt;br /&gt;
	if not _validQID(qid) then&lt;br /&gt;
		qid = (mw.wikibase and mw.wikibase.getEntityIdForCurrentPage and mw.wikibase.getEntityIdForCurrentPage()) or nil&lt;br /&gt;
		return titleObject.text, nsText, qid&lt;br /&gt;
	end&lt;br /&gt;
	-- testing-only path: given a qid, determine title&lt;br /&gt;
	-- always use namespace from current page (to suppress tracking cat)&lt;br /&gt;
	qid = qid:upper()&lt;br /&gt;
	local title = (mw.wikibase and mw.wikibase.getSitelink and mw.wikibase.getSitelink(qid)) or &amp;quot;&amp;quot;&lt;br /&gt;
	-- strip any namespace from sitelink&lt;br /&gt;
	local firstColon = mw.ustring.find(title,&#039;:&#039;,1,true)&lt;br /&gt;
	local qidNsText = &amp;quot;&amp;quot;&lt;br /&gt;
	if firstColon then&lt;br /&gt;
		qidNsText = mw.ustring.sub(title,1,firstColon-1)&lt;br /&gt;
		title = mw.ustring.sub(title,firstColon+1)&lt;br /&gt;
	end&lt;br /&gt;
	if nsQid then&lt;br /&gt;
		return title, qidNsText, qid&lt;br /&gt;
	end&lt;br /&gt;
	return title, nsText, qid&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Lookup Commons gallery in Wikidata&lt;br /&gt;
-- Arguments:&lt;br /&gt;
--   qid = QID of current article&lt;br /&gt;
--   fetch = whether to lookup Commons sitelink (bool)&lt;br /&gt;
--   commonsSitelink = default value for Commons sitelink&lt;br /&gt;
-- Returns:&lt;br /&gt;
--   categoryLink = name of Commons category, nil if nothing is found&lt;br /&gt;
--   consistent = multiple wikidata fields are examined: are they consistent?&lt;br /&gt;
--   commonsSitelink = commons sitelink for current article&lt;br /&gt;
local function _lookupGallery(qid,fetch,commonsSitelink)&lt;br /&gt;
	if not _validQID(qid) then&lt;br /&gt;
		return nil, true, nil&lt;br /&gt;
	end&lt;br /&gt;
	qid = qid:upper()&lt;br /&gt;
	local galleryLink = nil&lt;br /&gt;
	local consistent = true&lt;br /&gt;
	-- look up commons sitelink for article, use if not category&lt;br /&gt;
	if fetch then&lt;br /&gt;
		commonsSitelink = mw.wikibase.getSitelink(qid,&amp;quot;commonswiki&amp;quot;) or commonsSitelink&lt;br /&gt;
	end&lt;br /&gt;
	if commonsSitelink and mw.ustring.sub(commonsSitelink,1,9) ~= &amp;quot;Category:&amp;quot; then&lt;br /&gt;
		galleryLink = commonsSitelink&lt;br /&gt;
	end&lt;br /&gt;
	-- P935 is the &amp;quot;commons gallery&amp;quot; property for this article&lt;br /&gt;
	local P935 = mw.wikibase.getBestStatements(qid, &amp;quot;P935&amp;quot;)[1]&lt;br /&gt;
	if P935 and P935.mainsnak.datavalue then&lt;br /&gt;
		local gallery = P935.mainsnak.datavalue.value&lt;br /&gt;
		if galleryLink and galleryLink ~= gallery then&lt;br /&gt;
			consistent = false&lt;br /&gt;
		else&lt;br /&gt;
			galleryLink = gallery&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return galleryLink, consistent, commonsSitelink&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Find fallback category by looking up Commons sitelink of different page&lt;br /&gt;
-- Arguments:&lt;br /&gt;
--    qid = QID for current article&lt;br /&gt;
--    property = property that refers to other article whose sitelink to return&lt;br /&gt;
-- Returns: either category-stripped name of article, or nil&lt;br /&gt;
local function _lookupFallback(qid,property)&lt;br /&gt;
	if not _validQID(qid) or not _validProp(property) then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	qid = qid:upper()&lt;br /&gt;
	property = property:upper()&lt;br /&gt;
	-- If property exists on current article, get value (other article qid)&lt;br /&gt;
	local value = mw.wikibase.getBestStatements(qid, property)[1]&lt;br /&gt;
	if value and value.mainsnak.datavalue and value.mainsnak.datavalue.value.id then&lt;br /&gt;
		-- Look up Commons sitelink of other article&lt;br /&gt;
		local sitelink = mw.wikibase.getSitelink(value.mainsnak.datavalue.value.id,&amp;quot;commonswiki&amp;quot;)&lt;br /&gt;
		-- Check to see if it starts with &amp;quot;Category:&amp;quot;. If so, strip it and return&lt;br /&gt;
		if sitelink and mw.ustring.sub(sitelink,1,9) == &amp;quot;Category:&amp;quot; then&lt;br /&gt;
			return mw.ustring.sub(sitelink,10)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Find Commons category by looking in wikidata&lt;br /&gt;
-- Arguments:&lt;br /&gt;
--   qid = QID of current article&lt;br /&gt;
--   fetch = whether to lookup Commons sitelink (bool)&lt;br /&gt;
--   commonsSitelink = default value for Commons sitelink&lt;br /&gt;
-- Returns:&lt;br /&gt;
--   categoryLink = name of Commons category, nil if nothing is found&lt;br /&gt;
--   consistent = multiple wikidata fields are examined: are they consistent?&lt;br /&gt;
--   commonsSitelink = commons sitelink for current article&lt;br /&gt;
local function _lookupCategory(qid, fetch, commonsSitelink)&lt;br /&gt;
	if not _validQID(qid) then&lt;br /&gt;
		return nil, true, nil&lt;br /&gt;
	end&lt;br /&gt;
	qid = qid:upper()&lt;br /&gt;
	local categoryLink = nil&lt;br /&gt;
	local consistent = true&lt;br /&gt;
	-- look up commons sitelink for article, use if starts with &amp;quot;Category:&amp;quot;&lt;br /&gt;
	if fetch then&lt;br /&gt;
		commonsSitelink = mw.wikibase.getSitelink(qid,&amp;quot;commonswiki&amp;quot;) or commonsSitelink&lt;br /&gt;
	end&lt;br /&gt;
	if commonsSitelink and mw.ustring.sub(commonsSitelink,1,9) == &amp;quot;Category:&amp;quot; then&lt;br /&gt;
		categoryLink = mw.ustring.sub(commonsSitelink,10)&lt;br /&gt;
	end&lt;br /&gt;
	-- P910 is the &amp;quot;topic&#039;s main category&amp;quot;. Look for commons sitelink there&lt;br /&gt;
	local fallback = _lookupFallback(qid,&amp;quot;P910&amp;quot;)&lt;br /&gt;
	if fallback then&lt;br /&gt;
		if categoryLink and categoryLink ~= fallback then&lt;br /&gt;
			consistent = false&lt;br /&gt;
			qid = nil&lt;br /&gt;
		else&lt;br /&gt;
			categoryLink = fallback&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	-- P1754 is the &amp;quot;list&#039;s main category&amp;quot;. Look for commons sitelink there&lt;br /&gt;
	fallback = _lookupFallback(qid,&amp;quot;P1754&amp;quot;)&lt;br /&gt;
	if fallback then&lt;br /&gt;
		if categoryLink and categoryLink ~= fallback then&lt;br /&gt;
			consistent = false&lt;br /&gt;
			qid = nil&lt;br /&gt;
		else&lt;br /&gt;
			categoryLink = fallback&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
    -- P373 is the &amp;quot;commons category&amp;quot; property for this article. This is&lt;br /&gt;
    -- a low-quality field, so should only be used as a last resort.&lt;br /&gt;
    if categoryLink == nil and _validQID(qid) then&lt;br /&gt;
	    local P373 = mw.wikibase.getBestStatements(qid, &amp;quot;P373&amp;quot;)[1]&lt;br /&gt;
	    if P373 and P373.mainsnak.datavalue then&lt;br /&gt;
		    categoryLink = P373.mainsnak.datavalue.value&lt;br /&gt;
		    consistent = true  -- P373 is never used if anything else is available&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return categoryLink, consistent, commonsSitelink&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Does the article have a Commons gallery, and is it consistent?&lt;br /&gt;
-- Arguments:&lt;br /&gt;
--   qid = QID to lookup in wikidata (for testing only)&lt;br /&gt;
-- Returns:&lt;br /&gt;
--   filename at Commons, bool: is wikidata consistent for this article?&lt;br /&gt;
function p._hasGalleryConsistent(qid)&lt;br /&gt;
	local wp_title, wp_ns&lt;br /&gt;
	wp_title, wp_ns, qid = _getTitleQID(qid)&lt;br /&gt;
	return _lookupGallery(qid,true)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Does the article have a corresponding Commons gallery?&lt;br /&gt;
-- Arguments:&lt;br /&gt;
--   qid = QID to lookup in wikidata (for testing only)&lt;br /&gt;
-- Returns:&lt;br /&gt;
--   filename at Commons if so, false if not&lt;br /&gt;
function p._hasGallery(qid)&lt;br /&gt;
	local galleryLink, consistent = p._hasGalleryConsistent(qid)&lt;br /&gt;
	return consistent and galleryLink&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Does the article have a Commons category? Is wikidata consistent for that?&lt;br /&gt;
-- Arguments:&lt;br /&gt;
--   qid = QID to lookup in wikidata (for testing only)&lt;br /&gt;
--   prefix = whether to add &amp;quot;Category:&amp;quot; to return string (default true)&lt;br /&gt;
-- Returns:&lt;br /&gt;
--   filename at Commons, bool: consistent&lt;br /&gt;
function p._hasCategoryConsistent(qid,prefix)&lt;br /&gt;
	if prefix == nil then&lt;br /&gt;
		prefix = true&lt;br /&gt;
	end&lt;br /&gt;
	local wp_title, wp_ns&lt;br /&gt;
	wp_title, wp_ns, qid = _getTitleQID(qid)&lt;br /&gt;
	local categoryLink, consistent = _lookupCategory(qid,true)&lt;br /&gt;
	if categoryLink and prefix then&lt;br /&gt;
		categoryLink = &amp;quot;Category:&amp;quot;..categoryLink&lt;br /&gt;
	end&lt;br /&gt;
	return categoryLink, consistent&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Does the article have a corresponding Commons category?&lt;br /&gt;
-- Arguments:&lt;br /&gt;
--   qid = QID to lookup in wikidata (for testing only)&lt;br /&gt;
--   prefix = whether to add &amp;quot;Category:&amp;quot; to return string (default true)&lt;br /&gt;
-- Returns:&lt;br /&gt;
--   filename at Commons if so, blank if not&lt;br /&gt;
function p._hasCategory(qid,prefix)&lt;br /&gt;
	local categoryLink, consistent = p._hasCategoryConsistent(qid,prefix)&lt;br /&gt;
	return consistent and categoryLink&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Create Commons link corresponding to current article&lt;br /&gt;
-- Arguments:&lt;br /&gt;
--   namespace = namespace in Commons (&amp;quot;&amp;quot; for galleries)&lt;br /&gt;
--   default = use as Commons link, don&#039;t access wikidata&lt;br /&gt;
--   search = string to search for&lt;br /&gt;
--   fallback = string to search for if wikidata fails&lt;br /&gt;
--   formatting = formatting parameters&lt;br /&gt;
--   qid = QID to lookup in wikidata (for testing only)&lt;br /&gt;
-- Returns:&lt;br /&gt;
--   formatted wikilink to Commons in specified namespace&lt;br /&gt;
function p._getCommons(namespace,default,search,fallback,formatting,qid)&lt;br /&gt;
	local nsColon&lt;br /&gt;
	if not namespace or namespace == &amp;quot;&amp;quot; then&lt;br /&gt;
		nsColon = &amp;quot;&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		nsColon = namespace..&amp;quot;:&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	if default then&lt;br /&gt;
		return &amp;quot;[[Commons:&amp;quot;..nsColon..default..&amp;quot;|&amp;quot;.._formatResult(default,formatting)..&amp;quot;]]&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	if search then&lt;br /&gt;
		return &amp;quot;[[Commons:Special:Search/&amp;quot;..nsColon..search..&amp;quot;|&amp;quot;.._formatResult(search,formatting)..&amp;quot;]]&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	local wp_title, wp_ns&lt;br /&gt;
	wp_title, wp_ns, qid = _getTitleQID(qid)&lt;br /&gt;
	local commonsLink = nil&lt;br /&gt;
	local consistent = true&lt;br /&gt;
	if nsColon == &amp;quot;&amp;quot; then&lt;br /&gt;
		commonsLink, consistent = _lookupGallery(qid,true)&lt;br /&gt;
	elseif namespace:lower() == &amp;quot;category&amp;quot; then&lt;br /&gt;
		commonsLink, consistent = _lookupCategory(qid,true)&lt;br /&gt;
	end&lt;br /&gt;
	-- use wikidata if consistent&lt;br /&gt;
	if commonsLink and consistent then&lt;br /&gt;
		return &amp;quot;[[Commons:&amp;quot;..nsColon..commonsLink..&amp;quot;|&amp;quot;.._formatResult(commonsLink,formatting)..&amp;quot;]]&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	-- if not consistent, fall back to search and add to tracking cat&lt;br /&gt;
	-- construct default result (which searches for title)&lt;br /&gt;
	local searchResult = &amp;quot;[[Commons:Special:Search/&amp;quot;..nsColon..(fallback or wp_title)&lt;br /&gt;
		..&amp;quot;|&amp;quot;.._formatResult(fallback or wp_title,formatting)..&amp;quot;]]&amp;quot;&lt;br /&gt;
	if not consistent and wp_ns == &amp;quot;&amp;quot; then&lt;br /&gt;
		local friendlyNS&lt;br /&gt;
		if nsColon == &amp;quot;&amp;quot; then&lt;br /&gt;
			friendlyNS = &amp;quot;gallery&amp;quot;&lt;br /&gt;
		else&lt;br /&gt;
			friendlyNS = namespace:lower()&lt;br /&gt;
		end&lt;br /&gt;
		searchResult = searchResult..&amp;quot;[[Category:Inconsistent wikidata for Commons &amp;quot;..friendlyNS..&amp;quot;]]&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	return searchResult&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns &amp;quot;best&amp;quot; Commons link: first look for gallery, then try category&lt;br /&gt;
-- Arguments:&lt;br /&gt;
--   default = use as Commons link, don&#039;t access wikidata&lt;br /&gt;
--   search = string to search for&lt;br /&gt;
--   fallback = string to search for if wikidata lookup fails&lt;br /&gt;
--   formatting = formatting parameters&lt;br /&gt;
--   qid = QID to lookup in wikidata (for testing only)&lt;br /&gt;
-- Returns:&lt;br /&gt;
--   formatted wikilink to Commons &amp;quot;best&amp;quot; landing page&lt;br /&gt;
function p._getGalleryOrCategory(default, search, fallback, formatting, qid)&lt;br /&gt;
	if default then&lt;br /&gt;
		return &amp;quot;[[Commons:&amp;quot;..default..&amp;quot;|&amp;quot;.._formatResult(default,formatting)..&amp;quot;]]&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	if search then&lt;br /&gt;
		return &amp;quot;[[Commons:Special:Search/&amp;quot;..search..&amp;quot;|&amp;quot;.._formatResult(search,formatting)..&amp;quot;]]&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	local wp_title, wp_ns&lt;br /&gt;
	wp_title, wp_ns, qid = _getTitleQID(qid)&lt;br /&gt;
	local trackingCats = &amp;quot;&amp;quot;&lt;br /&gt;
	local galleryLink, consistent, commonsSitelink = _lookupGallery(qid,true)&lt;br /&gt;
	-- use wikidata if either sitelink or P935 exist, and they both agree&lt;br /&gt;
	if galleryLink and consistent then&lt;br /&gt;
		return &amp;quot;[[Commons:&amp;quot;..galleryLink..&amp;quot;|&amp;quot;.._formatResult(galleryLink,formatting)..&amp;quot;]]&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	if not consistent and wp_ns == &amp;quot;&amp;quot; then&lt;br /&gt;
		trackingCats = &amp;quot;[[Category:Inconsistent wikidata for Commons gallery]]&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	-- if gallery is not good, fall back looking for category&lt;br /&gt;
	local categoryLink&lt;br /&gt;
	categoryLink, consistent = _lookupCategory(qid,false,commonsSitelink)&lt;br /&gt;
	if categoryLink and consistent then&lt;br /&gt;
		return &amp;quot;[[Commons:Category:&amp;quot;..categoryLink..&amp;quot;|&amp;quot;.._formatResult(categoryLink,formatting)..&amp;quot;]]&amp;quot;..trackingCats&lt;br /&gt;
	end&lt;br /&gt;
	if not consistent and wp_ns == &amp;quot;&amp;quot; then&lt;br /&gt;
		trackingCats = trackingCats..&amp;quot;[[Category:Inconsistent wikidata for Commons category]]&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	-- return search result looking for title as last attempt&lt;br /&gt;
	return &amp;quot;[[Commons:Special:Search/&amp;quot; .. (fallback or wp_title) ..&lt;br /&gt;
		&amp;quot;|&amp;quot; .. _formatResult(fallback or wp_title,formatting) .. &amp;quot;]]&amp;quot; .. trackingCats&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Return link(s) Commons gallery, or category, or both from wikidata&lt;br /&gt;
-- Arguments:&lt;br /&gt;
--   defaultGallery = default gallery link to use, instead of wikidata&lt;br /&gt;
--   defaultCategory = default category link to use, instead of wikidata&lt;br /&gt;
--   categoryText = if both gallery and category, text to use in category link (&amp;quot;category&amp;quot; by default)&lt;br /&gt;
--   oneSearch = only emit one search result&lt;br /&gt;
--   formatting = formatting parameters&lt;br /&gt;
--   qid = qid of page to lookup in wikidata (testing only)&lt;br /&gt;
function p._getGalleryAndCategory(defaultGallery, defaultCategory, &lt;br /&gt;
	categoryText, oneSearch, formatting, qid&lt;br /&gt;
	)&lt;br /&gt;
	local wp_title, wp_ns&lt;br /&gt;
	wp_title, wp_ns, qid = _getTitleQID(qid)&lt;br /&gt;
	categoryText = categoryText or &amp;quot;category&amp;quot;&lt;br /&gt;
	local trackingCats = &amp;quot;&amp;quot;&lt;br /&gt;
	local galleryLink, galleryConsistent&lt;br /&gt;
	local commonsSitelink = nil&lt;br /&gt;
	if defaultGallery then&lt;br /&gt;
		galleryLink = defaultGallery&lt;br /&gt;
		galleryConsistent = true&lt;br /&gt;
	else&lt;br /&gt;
		galleryLink, galleryConsistent, commonsSitelink = _lookupGallery(qid,true)&lt;br /&gt;
	end&lt;br /&gt;
	local galleryGood = galleryLink and galleryConsistent&lt;br /&gt;
	if not galleryConsistent and wp_ns == &amp;quot;&amp;quot; then&lt;br /&gt;
		trackingCats = &amp;quot;[[Category:Inconsistent wikidata for Commons gallery]]&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	local categoryLink, categoryConsistent&lt;br /&gt;
	if defaultCategory then&lt;br /&gt;
		categoryLink = defaultCategory&lt;br /&gt;
		categoryConsistent = true&lt;br /&gt;
	else&lt;br /&gt;
		categoryLink, categoryConsistent = _lookupCategory(qid,defaultGallery,commonsSitelink)&lt;br /&gt;
	end&lt;br /&gt;
	local categoryGood = categoryLink and categoryConsistent&lt;br /&gt;
	if not categoryConsistent and wp_ns == &amp;quot;&amp;quot; then&lt;br /&gt;
		trackingCats = trackingCats..&amp;quot;[[Category:Inconsistent wikidata for Commons category]]&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	local firstLink&lt;br /&gt;
	-- construct default result (which searches for title)&lt;br /&gt;
	local searchResult = &amp;quot;[[Commons:Special:Search/&amp;quot;..wp_title..&amp;quot;|&amp;quot;.._formatResult(wp_title,formatting)..&amp;quot;]]&amp;quot;&lt;br /&gt;
	if not oneSearch then&lt;br /&gt;
		searchResult = searchResult..&amp;quot; ([[Commons:Special:Search/Category:&amp;quot;..wp_title..&amp;quot;|&amp;quot;..categoryText..&amp;quot;]])&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	local linkText = nil&lt;br /&gt;
	if galleryGood then&lt;br /&gt;
		firstLink = galleryLink&lt;br /&gt;
		linkText = galleryLink&lt;br /&gt;
	elseif categoryGood then&lt;br /&gt;
		firstLink = &amp;quot;Category:&amp;quot;..categoryLink&lt;br /&gt;
		linkText = categoryLink&lt;br /&gt;
	else&lt;br /&gt;
		return searchResult..trackingCats&lt;br /&gt;
	end&lt;br /&gt;
	local resultVal = &amp;quot;[[Commons:&amp;quot;..firstLink..&amp;quot;|&amp;quot;.._formatResult(linkText,formatting)..&amp;quot;]]&amp;quot;&lt;br /&gt;
	if galleryGood and categoryGood then&lt;br /&gt;
		resultVal = resultVal..&amp;quot; ([[Commons:Category:&amp;quot;..categoryLink..&amp;quot;|&amp;quot;..categoryText..&amp;quot;]])&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	return resultVal..trackingCats&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Compare two titles with their namespaces stripped&lt;br /&gt;
local function titleMatch(s1,s2)&lt;br /&gt;
	s1 = s1 or &amp;quot;&amp;quot;&lt;br /&gt;
	s2 = s2 or &amp;quot;&amp;quot;&lt;br /&gt;
    s1 = mw.ustring.gsub(s1,&amp;quot;^[^:]+:&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
    s2 = mw.ustring.gsub(s2,&amp;quot;^[^:]+:&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
    return s1 == s2&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local galleryTrackingCats = {&lt;br /&gt;
	commons_link_on_wikidata = &#039;[[Category:Commons link is on Wikidata]]&#039;,&lt;br /&gt;
	commons_link_defined_as_pagename = &#039;[[Category:Commons link is defined as the pagename]]&#039;,&lt;br /&gt;
	commons_link_locally_defined = &#039;[[Category:Commons link is locally defined]]&#039;,&lt;br /&gt;
	commons_link_from_wikidata = &#039;[[Category:Commons link from Wikidata]]&#039;,&lt;br /&gt;
	commons_link_is_pagename = &#039;[[Category:Commons link is the pagename]]&#039;,&lt;br /&gt;
	inconsistent = &#039;[[Category:Inconsistent wikidata for Commons gallery]]&#039;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local categoryTrackingCats = {&lt;br /&gt;
		commons_link_on_wikidata = &#039;[[Category:Commons category link is on Wikidata]]&#039;,&lt;br /&gt;
		commons_link_defined_as_pagename = &#039;[[Category:Commons category link is defined as the pagename]]&#039;,&lt;br /&gt;
		commons_link_locally_defined = &#039;[[Category:Commons category link is locally defined]]&#039;,&lt;br /&gt;
		commons_link_from_wikidata = &#039;[[Category:Commons category link from Wikidata]]&#039;,&lt;br /&gt;
		commons_link_is_pagename = &#039;[[Category:Commons category link is the pagename]]&#039;,&lt;br /&gt;
		inconsistent = &#039;[[Category:Inconsistent wikidata for Commons category]]&#039;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
local function selectTrackingCat(trackingCats,wikidata,consistent,default,title)&lt;br /&gt;
	if not consistent then&lt;br /&gt;
		return trackingCats.inconsistent&lt;br /&gt;
	end&lt;br /&gt;
	if default then&lt;br /&gt;
	-- construct warning message&lt;br /&gt;
		if default == wikidata then&lt;br /&gt;
			return trackingCats.commons_link_on_wikidata&lt;br /&gt;
		end&lt;br /&gt;
		local warning = &amp;quot;&amp;quot;&lt;br /&gt;
		if wikidata then&lt;br /&gt;
			local generateWarning = require(&#039;Module:If preview&#039;)._warning&lt;br /&gt;
			warning = generateWarning({&lt;br /&gt;
					&amp;quot;Commons link does not match Wikidata – [[Template:Commons_category#Resolving_discrepancies|please check]]&amp;quot;&lt;br /&gt;
				})&lt;br /&gt;
		end&lt;br /&gt;
		if titleMatch(default,title) then&lt;br /&gt;
			return trackingCats.commons_link_defined_as_pagename .. warning&lt;br /&gt;
		end&lt;br /&gt;
		return trackingCats.commons_link_locally_defined .. warning&lt;br /&gt;
	end&lt;br /&gt;
	if wikidata then&lt;br /&gt;
		return trackingCats.commons_link_from_wikidata&lt;br /&gt;
	end&lt;br /&gt;
	return trackingCats.commons_link_is_pagename&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Figure out tracking categories and editor warnings&lt;br /&gt;
-- Arguments:&lt;br /&gt;
--   default = Commons link argument passed to template&lt;br /&gt;
--   fetchGallery = whether to fetch a gallery from Wikidata&lt;br /&gt;
--   fetchCategory = whether to fetch a category from Wikidata&lt;br /&gt;
--   qid = force a qid for testing&lt;br /&gt;
-- Returns:&lt;br /&gt;
--   tracking category and possible user warning&lt;br /&gt;
--&lt;br /&gt;
-- Note: the logic for the tracking is quite different than the logic&lt;br /&gt;
-- for generating Commons links (above). Thus, it is separated into another&lt;br /&gt;
-- function for code clarity and maintainability. This should not seriously &lt;br /&gt;
-- affect performance: server time is dominated by fetching wikidata entities,&lt;br /&gt;
-- and those entities should be cached and shared between the Commons generating&lt;br /&gt;
-- code and this tracking code.&lt;br /&gt;
function p._tracking(default, fetchGallery, fetchCategory, qid)&lt;br /&gt;
	local title, wp_ns, wp_qid = _getTitleQID(qid,true)&lt;br /&gt;
	if wp_ns ~= &amp;quot;&amp;quot; then&lt;br /&gt;
		title = wp_ns..&amp;quot;:&amp;quot;..title&lt;br /&gt;
	end&lt;br /&gt;
	-- only track if test or namespace=article or namespace=category&lt;br /&gt;
	if not (qid or wp_ns == &amp;quot;&amp;quot; or wp_ns == &amp;quot;Category&amp;quot;) then&lt;br /&gt;
		return &amp;quot;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- determine title and namespace of wikidata and wp article&lt;br /&gt;
	local wikidata = nil&lt;br /&gt;
	local consistent = nil&lt;br /&gt;
	-- Tracking code works for all 4 cases of states of fetchGallery/Category&lt;br /&gt;
	-- fetchGallery takes precedence&lt;br /&gt;
	if fetchGallery then&lt;br /&gt;
		wikidata, consistent = p._hasGalleryConsistent(qid)&lt;br /&gt;
		if default or not fetchCategory or (consistent and wikidata) then&lt;br /&gt;
			return selectTrackingCat(galleryTrackingCats,wikidata,consistent,&lt;br /&gt;
				                     default,title)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
    if fetchCategory then&lt;br /&gt;
		local cat_wikidata, cat_consistent = p._hasCategoryConsistent(qid,true)&lt;br /&gt;
		if not fetchGallery or (cat_consistent and cat_wikidata) then&lt;br /&gt;
			return selectTrackingCat(categoryTrackingCats,cat_wikidata,&lt;br /&gt;
			                    	 cat_consistent,default,title)&lt;br /&gt;
		end&lt;br /&gt;
		return selectTrackingCat(galleryTrackingCats,wikidata,consistent,&lt;br /&gt;
			                     default,title)&lt;br /&gt;
    end&lt;br /&gt;
	return &amp;quot;&amp;quot; -- nothing fetched, nothing tracked&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function _createFormatting(args)&lt;br /&gt;
	local formatting = {}&lt;br /&gt;
	formatting.linktext = args.linktext&lt;br /&gt;
    local yesNo = require(&#039;Module:Yesno&#039;)&lt;br /&gt;
	formatting.lcfirst = yesNo(args.lcfirst)&lt;br /&gt;
	formatting.bold = yesNo(args.bold)&lt;br /&gt;
	formatting.italic = yesNo(args.italic)&lt;br /&gt;
	formatting.nowrap = yesNo(args.nowrap)&lt;br /&gt;
	return formatting&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Testing-only entry point for _getTitleQID&lt;br /&gt;
function p.getTitleQID(frame)&lt;br /&gt;
	local args = getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})&lt;br /&gt;
	local text, ns, qid = _getTitleQID(args[1],args[2])&lt;br /&gt;
	return text..&amp;quot;,&amp;quot;..ns..&amp;quot;,&amp;quot;..(qid or &amp;quot;nil&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Testing-only entry point for _lookupFallback&lt;br /&gt;
function p.lookupFallback(frame)&lt;br /&gt;
	local args = getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})&lt;br /&gt;
	local fallback = _lookupFallback(args[1],args[2])&lt;br /&gt;
	return fallback or &amp;quot;nil&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Find the Commons gallery page associated with article&lt;br /&gt;
function p.getGallery(frame)&lt;br /&gt;
	local args = getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})&lt;br /&gt;
	return p._getCommons(&amp;quot;&amp;quot;,args[1],args.search,args.fallback,_createFormatting(args),args.qid)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Find the Commons category page associated with article&lt;br /&gt;
function p.getCategory(frame)&lt;br /&gt;
	local args = getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})&lt;br /&gt;
	local retval = p._getCommons(&amp;quot;Category&amp;quot;, args[1], &lt;br /&gt;
		args.search, args.fallback, _createFormatting(args), args.qid&lt;br /&gt;
	)&lt;br /&gt;
	if args.tracking then&lt;br /&gt;
		local default = nil&lt;br /&gt;
		if args[1] then&lt;br /&gt;
			default = &amp;quot;Category:&amp;quot;..args[1]&lt;br /&gt;
		end&lt;br /&gt;
		retval = retval..p._tracking(default, false, true, args.qid)&lt;br /&gt;
	end&lt;br /&gt;
	return retval&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.getGalleryOrCategory(frame)&lt;br /&gt;
	local args = getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})&lt;br /&gt;
	local retval = p._getGalleryOrCategory(&lt;br /&gt;
		args[1], args.search, args.fallback, _createFormatting(args), args.qid&lt;br /&gt;
	)&lt;br /&gt;
	if args.tracking then&lt;br /&gt;
		retval = retval..p._tracking(args[1],true,true,args.qid)&lt;br /&gt;
	end&lt;br /&gt;
	return retval&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.hasGallery(frame)&lt;br /&gt;
	local args = getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})&lt;br /&gt;
	return p._hasGallery(args.qid) or &amp;quot;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.hasCategory(frame)&lt;br /&gt;
	local args = getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})&lt;br /&gt;
	return p._hasCategory(args.qid) or &amp;quot;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.hasGalleryOrCategory(frame)&lt;br /&gt;
	local args = getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})&lt;br /&gt;
	return p._hasGallery(args.qid) or p._hasCategory(args.qid) or &amp;quot;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.getGalleryAndCategory(frame)&lt;br /&gt;
	local args = getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})&lt;br /&gt;
	return p._getGalleryAndCategory(args[1], args[2], &lt;br /&gt;
		args.categoryText, args.oneSearch, _createFormatting(args), args.qid)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.tracking(frame)&lt;br /&gt;
	local args = getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})&lt;br /&gt;
	return p._tracking(args[1], args.fetchGallery, args.fetchCategory, args.qid)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Template:Country_data_Malaysia&amp;diff=5312</id>
		<title>Template:Country data Malaysia</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Template:Country_data_Malaysia&amp;diff=5312"/>
		<updated>2026-06-15T02:42:22Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync current Andaman Sea dependency from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ {{{1&amp;lt;noinclude&amp;gt;|country showdata&amp;lt;/noinclude&amp;gt;}}}&lt;br /&gt;
| alias = Malaysia&lt;br /&gt;
| flag alias = Flag of Malaysia.svg&lt;br /&gt;
| flag alias-1895 = Flag of the Federated Malay States (1895 - 1946).svg&lt;br /&gt;
| flag alias-1948 = Flag of Malaya (1950–1963).svg&lt;br /&gt;
| flag alias-naval = Naval Ensign of Malaysia.svg&lt;br /&gt;
| link alias-naval = Royal Malaysian Navy&lt;br /&gt;
| flag alias-air force = Royal Malaysian Air Force Flag.svg&lt;br /&gt;
| link alias-air force = Royal Malaysian Air Force&lt;br /&gt;
| flag alias-civil = Civil Ensign of Malaysia.svg&lt;br /&gt;
| link alias-civil = Malaysia&lt;br /&gt;
| flag alias-army = Flag of the Malaysian Army.svg&lt;br /&gt;
| link alias-army = Malaysian Army&lt;br /&gt;
| flag alias-navy = Naval Ensign of Malaysia.svg&lt;br /&gt;
| link alias-navy = Royal Malaysian Navy&lt;br /&gt;
| flag alias-military = Flag of the Malaysian Armed Forces.svg&lt;br /&gt;
| link alias-military = Malaysian Armed Forces&lt;br /&gt;
| flag alias-coast guard = Flag of the Malaysian Maritime Enforcement Agency.svg&lt;br /&gt;
| link alias-coast guard = Malaysian Maritime Enforcement Agency&lt;br /&gt;
| flag alias-23px = Flag of Malaysia 23px.svg&lt;br /&gt;
| size = {{{size|}}}&lt;br /&gt;
| name = {{{name|}}}&lt;br /&gt;
| altlink = {{{altlink|}}}&lt;br /&gt;
| variant = {{{variant|}}}&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
| var1 = 1895&lt;br /&gt;
| var2 = 1948&lt;br /&gt;
| var3 = civil&lt;br /&gt;
| redir1 = MYS&lt;br /&gt;
| redir2 = MAS&lt;br /&gt;
| related1 = Malaya&lt;br /&gt;
| related2 = Malayan Union&lt;br /&gt;
| related3 = Kingdom of Sarawak&lt;br /&gt;
| related4 = North Borneo&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Template:Country_data_Indonesia&amp;diff=5311</id>
		<title>Template:Country data Indonesia</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Template:Country_data_Indonesia&amp;diff=5311"/>
		<updated>2026-06-15T02:42:21Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync current Andaman Sea dependency from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ {{{1&amp;lt;noinclude&amp;gt;|country showdata&amp;lt;/noinclude&amp;gt;}}}&lt;br /&gt;
| alias = Indonesia&lt;br /&gt;
| flag alias = Flag of Indonesia.svg&lt;br /&gt;
| link alias-naval = Indonesian Navy&lt;br /&gt;
| flag alias-naval = Flag of Indonesia.svg&lt;br /&gt;
| link alias-navy = Indonesian Navy&lt;br /&gt;
| flag alias-navy = Flag of the Indonesian Navy.svg&lt;br /&gt;
| link alias-marines= Indonesian Marine Corps&lt;br /&gt;
| flag alias-marines = Flag of the Indonesian Marine Corps.png&lt;br /&gt;
| link alias-air force = Indonesian Air Force&lt;br /&gt;
| flag alias-air force = Flag of the Indonesian Air Force.svg&lt;br /&gt;
| link alias-army = Indonesian Army&lt;br /&gt;
| flag alias-army = Flag of the Indonesian Army.svg&lt;br /&gt;
| flag alias-military = Flag of the Indonesian National Armed Forces.svg&lt;br /&gt;
| link alias-military = Indonesian National Armed Forces&lt;br /&gt;
| flag alias-sanctionedFB = Indonesia coat of arms with name.svg &lt;br /&gt;
| size = {{{size|}}}&lt;br /&gt;
| name = {{{name|}}}&lt;br /&gt;
| altlink = {{{altlink|}}}&lt;br /&gt;
| variant = {{{variant|}}}&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
| var1 = sanctionedFB&lt;br /&gt;
| redir1 = IDN&lt;br /&gt;
| redir2 = INA&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Template:Country_data_Thailand&amp;diff=5310</id>
		<title>Template:Country data Thailand</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Template:Country_data_Thailand&amp;diff=5310"/>
		<updated>2026-06-15T02:42:20Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync current Andaman Sea dependency from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ {{{1&amp;lt;noinclude&amp;gt;|country showdata&amp;lt;/noinclude&amp;gt;}}}&lt;br /&gt;
| alias = Thailand&lt;br /&gt;
| shortname alias = {{{shortname alias|Thailand}}}&lt;br /&gt;
| flag alias = Flag of Thailand.svg&lt;br /&gt;
| flag alias-1767 = Flag of Thailand (Ayutthaya period).svg&lt;br /&gt;
| flag alias-1782 = Flag of Thailand (1782).svg&lt;br /&gt;
| flag alias-1817 = Flag of Thailand (1817).svg&lt;br /&gt;
| flag alias-1855 = Flag of Thailand 1855.svg&lt;br /&gt;
| flag alias-1893 = State Flag of Thailand (1916).svg&lt;br /&gt;
| flag alias-1916 = Flag of Siam (1916).svg&lt;br /&gt;
| flag alias-marines=Flag of the Royal Thai Marine Corps.svg&lt;br /&gt;
| link alias-marines=Royal Thai Marine Corps&lt;br /&gt;
| flag alias-naval = Naval Ensign of Thailand.svg&lt;br /&gt;
| link alias-naval = Royal Thai Navy&lt;br /&gt;
| flag alias-navy = Flag of the Royal Thai Navy.svg&lt;br /&gt;
| link alias-navy = Royal Thai Navy&lt;br /&gt;
| flag alias-military=Flag of the Royal Thai Armed Forces HQ.svg&lt;br /&gt;
| link alias-military=Royal Thai Armed Forces&lt;br /&gt;
| flag alias-air force = Flag of the Royal Thai Air Force.svg&lt;br /&gt;
| link alias-air force = Royal Thai Air Force&lt;br /&gt;
| flag alias-army= Flag of the Royal Thai Army.svg&lt;br /&gt;
| link alias-army=Royal Thai Army&lt;br /&gt;
| flag alias-sanctionedFB = THA AFF 2020.png &lt;br /&gt;
| flag alias-police=Thai National Police Flag.svg&lt;br /&gt;
| link alias-police=Royal Thai Police&lt;br /&gt;
| size = {{{size|}}}&lt;br /&gt;
| name = {{{name|}}}&lt;br /&gt;
| altlink = {{{altlink|}}}&lt;br /&gt;
| altvar = {{{altvar|}}}&lt;br /&gt;
| variant = {{{variant|}}}&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
| var1 = 1767&lt;br /&gt;
| var2 =  1782&lt;br /&gt;
| var3 = 1817&lt;br /&gt;
| var4 = 1855&lt;br /&gt;
| var5 = 1893&lt;br /&gt;
| var6 = 1916&lt;br /&gt;
| var7 = sanctionedFB&lt;br /&gt;
| var8 = police&lt;br /&gt;
| redir1 = THA&lt;br /&gt;
| related1 = Siam&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Template:Country_data_India&amp;diff=5309</id>
		<title>Template:Country data India</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Template:Country_data_India&amp;diff=5309"/>
		<updated>2026-06-15T02:42:19Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync current Andaman Sea dependency from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ {{{1&amp;lt;noinclude&amp;gt;|country showdata&amp;lt;/noinclude&amp;gt;}}}&lt;br /&gt;
| alias = India&lt;br /&gt;
| flag alias = Flag of India.svg&lt;br /&gt;
| flag alias-1880 = British Raj Red Ensign.svg&lt;br /&gt;
| flag alias-British = British Raj Red Ensign.svg&lt;br /&gt;
| flag alias-1931 = 1931 Flag of India.svg&lt;br /&gt;
| flag alias-civil = Civil Ensign of India.svg&lt;br /&gt;
| flag alias-army = Flag of Indian Army.svg&lt;br /&gt;
| link alias-army = Indian Army&lt;br /&gt;
| flag alias-naval-1879 = Flag of Imperial India.svg&lt;br /&gt;
| flag alias-naval-1884 = Flag of Imperial India.svg&lt;br /&gt;
| flag alias-naval-1928 = Naval ensign of the United Kingdom.svg&lt;br /&gt;
| flag alias-naval-1947 = Naval ensign of the United Kingdom.svg&lt;br /&gt;
| flag alias-naval-1950 = Naval Ensign of India (1950–2001).svg&lt;br /&gt;
| flag alias-naval-2001 = Naval Ensign of India (2001–2004).svg&lt;br /&gt;
| flag alias-naval-2004 = Naval Ensign of India (2004–2014).svg&lt;br /&gt;
| flag alias-naval-2014 = Naval Ensign of India (2014–2022).svg&lt;br /&gt;
| flag alias-naval-2022 = Naval Ensign of India (2022).svg&lt;br /&gt;
| flag alias-naval = Naval Ensign of India.svg&lt;br /&gt;
| flag alias-air force-1950 = Air Force Ensign of India (1950–2023).svg&lt;br /&gt;
| flag alias-air force = Air Force Ensign of India.svg&lt;br /&gt;
| flag alias-coast guard = Indian Coast Guard flag.svg&lt;br /&gt;
| link alias-coast guard = Indian Coast Guard&lt;br /&gt;
| link alias-naval = Indian Navy&lt;br /&gt;
| link alias-air force = Indian Air Force&lt;br /&gt;
| flag alias-navy = Naval Ensign of India.svg&lt;br /&gt;
| link alias-navy = Indian Navy&lt;br /&gt;
| flag alias-military = Flag of the Indian Armed Forces.svg&lt;br /&gt;
| link alias-military = Indian Armed Forces&lt;br /&gt;
| size = {{{size|}}}&lt;br /&gt;
| name = {{{name|}}}&lt;br /&gt;
| altlink = {{{altlink|}}}&lt;br /&gt;
| variant = {{{variant|}}}&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
| var1 = 1880&lt;br /&gt;
| var2 = British&lt;br /&gt;
| var3= 1931&lt;br /&gt;
| var4 = civil&lt;br /&gt;
| var5 = naval-1879&lt;br /&gt;
| var6 = naval-1884&lt;br /&gt;
| var7 = naval-1928&lt;br /&gt;
| var8 = naval-1947&lt;br /&gt;
| var9 = naval-1950&lt;br /&gt;
| var10 = naval-2001&lt;br /&gt;
| var11 = naval-2004&lt;br /&gt;
| var12 = naval-2014&lt;br /&gt;
| var13 = naval-2022&lt;br /&gt;
| var14 = air force-1950&lt;br /&gt;
| redir1 = IND&lt;br /&gt;
| related1 = British Raj&lt;br /&gt;
| related2 = Dominion of India&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Template:Country_data_Myanmar&amp;diff=5308</id>
		<title>Template:Country data Myanmar</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Template:Country_data_Myanmar&amp;diff=5308"/>
		<updated>2026-06-15T02:42:18Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync current Andaman Sea dependency from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ {{{1&amp;lt;noinclude&amp;gt;|country showdata&amp;lt;/noinclude&amp;gt;}}}&lt;br /&gt;
| alias = Myanmar&lt;br /&gt;
| shortname alias = {{{shortname alias|Myanmar}}}&lt;br /&gt;
| flag alias = Flag of Myanmar.svg&lt;br /&gt;
| flag alias-1937 = British Burma 1937 flag.svg&lt;br /&gt;
| flag alias-1943 = Flag of Burma 1943.svg&lt;br /&gt;
| flag alias-1948 = Flag of Burma (1948–1974).svg&lt;br /&gt;
| flag alias-1974 = Flag of Myanmar (1974–2010).svg&lt;br /&gt;
| flag alias-military = Flag of the Armed Forces (Tatmadaw) of Myanmar.svg&lt;br /&gt;
| link alias-military = Tatmadaw&lt;br /&gt;
| flag alias-naval = Naval Ensign of Myanmar.svg&lt;br /&gt;
| link alias-air force = Myanmar Air Force&lt;br /&gt;
| flag alias-army = Army Flag of Myanmar.svg&lt;br /&gt;
| flag alias-air force = Air Force Ensign of Myanmar.svg&lt;br /&gt;
| link alias-army = Myanmar Army&lt;br /&gt;
| link alias-naval = Myanmar Navy&lt;br /&gt;
| flag alias-navy = Naval Ensign of Myanmar.svg&lt;br /&gt;
| link alias-navy = Myanmar Navy&lt;br /&gt;
| flag alias-coast guard = Myanmar Coast Guard Ensign.svg&lt;br /&gt;
| link alias-coast guard = Myanmar Coast Guard&lt;br /&gt;
| flag alias-army 1948 = Former army flag of Myanmar.png&lt;br /&gt;
| link alias-army 1948 = Myanmar Army&lt;br /&gt;
| flag alias-navy 1948 = Naval Ensign of Burma (1948-1974).svg&lt;br /&gt;
| link alias-navy 1948 = Myanmar Navy&lt;br /&gt;
| flag alias-navy 1974 = Naval Ensign of Burma (1974–1994).svg&lt;br /&gt;
| link alias-navy 1974 = Myanmar Navy&lt;br /&gt;
| flag alias-air force 1948 = Air Force Ensign of Burma (1948-1974).svg&lt;br /&gt;
| link alias-air force 1948 = Myanmar Air Force&lt;br /&gt;
| flag alias-air force 1974 = Former Ensign of Myanmar Air Force.png&lt;br /&gt;
| link alias-air force 1974 = Myanmar Air Firce&lt;br /&gt;
| size = {{{size|}}}&lt;br /&gt;
| name = {{{name|}}}&lt;br /&gt;
| altlink = {{{altlink|}}}&lt;br /&gt;
| altvar = {{{altvar|}}}&lt;br /&gt;
| variant = {{{variant|}}}&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
| var1 = 1937&lt;br /&gt;
| var2 = 1943&lt;br /&gt;
| var3 = 1948&lt;br /&gt;
| var4 = 1974&lt;br /&gt;
| var5 = army 1948&lt;br /&gt;
| var6 = navy 1948&lt;br /&gt;
| var7 = navy 1974&lt;br /&gt;
| var8 = air force 1948&lt;br /&gt;
| var9 = air force 1974&lt;br /&gt;
| related1 = Burma&lt;br /&gt;
| related2 = British Burma&lt;br /&gt;
| related3 = Konbaung dynasty&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Module:CountryData/cacheJ&amp;diff=5307</id>
		<title>Module:CountryData/cacheJ</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Module:CountryData/cacheJ&amp;diff=5307"/>
		<updated>2026-06-15T02:42:17Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync current Andaman Sea dependency from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local CountryData = require(&#039;Module:CountryData&#039;)&lt;br /&gt;
local pages = {&#039;Bolivia&#039;, &#039;El_Salvador&#039;, &#039;Ethiopia&#039;, &#039;Guatemala&#039;, &#039;Iraq&#039;, &#039;Lebanon&#039;, &#039;Myanmar&#039;, &#039;North_Korea&#039;, &#039;Northern_Ireland&#039;, &#039;Syria&#039;, &#039;Trinidad_and_Tobago&#039;, &#039;Uganda&#039;}&lt;br /&gt;
local p = {&lt;br /&gt;
    data = {}&lt;br /&gt;
}&lt;br /&gt;
local frame = mw.getCurrentFrame()&lt;br /&gt;
&lt;br /&gt;
for _,v in ipairs(pages) do&lt;br /&gt;
    p.data[v] = CountryData.gettable(frame, v, {})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Module:CountryData&amp;diff=5306</id>
		<title>Module:CountryData</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Module:CountryData&amp;diff=5306"/>
		<updated>2026-06-15T02:42:16Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync current Andaman Sea dependency from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
local mostUsed = mw.loadData(&#039;Module:CountryData/summary&#039;)&lt;br /&gt;
&lt;br /&gt;
local function getcontents(frame,country,params)&lt;br /&gt;
  return frame:expandTemplate({title=&amp;quot;Country data &amp;quot;..country;args=params})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.getcachedtable(frame, country, params)&lt;br /&gt;
	country = mostUsed.redirects[country] or country&lt;br /&gt;
	if params and next(params) then return p.gettable(frame, country, params) end&lt;br /&gt;
	-- Uses mw.loadData to cache data for the most-used templates&lt;br /&gt;
	if mostUsed.pages[country] then&lt;br /&gt;
		local cache = mw.loadData(&#039;Module:CountryData/cache&#039; .. mostUsed.pages[country])&lt;br /&gt;
		if cache.data[country] then return cache.data[country] end&lt;br /&gt;
	end&lt;br /&gt;
	-- if not in cache&lt;br /&gt;
	return p.gettable(frame, country, params)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.gettable(frame,country,params)&lt;br /&gt;
--Returns the parameters of a country data template as a Lua table&lt;br /&gt;
  --If not a valid data template, return empty table&lt;br /&gt;
  local bool, s = pcall(getcontents,frame,country,params or {})&lt;br /&gt;
  if bool and (string.find(s,&amp;quot;^%{%{ *%{%{%{1&amp;quot;) or string.find(s,&amp;quot;^%{%{safesubst: *%{%{%{1&amp;quot;))&lt;br /&gt;
  then&lt;br /&gt;
    --Replace parameter delimiters with arbitrary control characters&lt;br /&gt;
    --to avoid clashes if param values contain equals/pipe signs&lt;br /&gt;
    s = string.gsub(s,&amp;quot;|([^|=]-)=&amp;quot;,&amp;quot;\1\1%1\2&amp;quot;)&lt;br /&gt;
    s = string.gsub(s,&amp;quot;}}%s*$&amp;quot;,&amp;quot;\1&amp;quot;)&lt;br /&gt;
    --Loop over string and add params to table&lt;br /&gt;
    local part = {}&lt;br /&gt;
    for par in string.gmatch(s,&amp;quot;\1[^\1\2]-\2[^\1\2]-\1&amp;quot;) do&lt;br /&gt;
      local k = string.match(par,&amp;quot;\1%s*(.-)%s*\2&amp;quot;)&lt;br /&gt;
      local v = string.match(par,&amp;quot;\2%s*(.-)%s*\1&amp;quot;)&lt;br /&gt;
      if v and not (v==&amp;quot;&amp;quot; and string.find(k,&amp;quot;^flag alias&amp;quot;)) then&lt;br /&gt;
        part[k] = v&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    return part&lt;br /&gt;
  else&lt;br /&gt;
  	return {}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.getalias(frame)&lt;br /&gt;
--Returns a single parameter value from a data template&lt;br /&gt;
  local part = p.gettable(frame,frame.args[1])&lt;br /&gt;
  if frame.args.variant&lt;br /&gt;
    then return tostring(part[frame.args[2]..&amp;quot;-&amp;quot;..frame.args.variant]&lt;br /&gt;
                         or part[frame.args[2]] or frame.args.def)&lt;br /&gt;
    else return tostring(part[frame.args[2]] or frame.args.def)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.gettemplate(frame)&lt;br /&gt;
--For testing, recreates the country data from the created Lua table&lt;br /&gt;
  --Get data table&lt;br /&gt;
  local data = p.gettable(frame,frame.args[1])&lt;br /&gt;
  --Concatenate fields into a template-like string&lt;br /&gt;
  local out = &amp;quot;{{ {{{1}}}&amp;quot;&lt;br /&gt;
  for k,v in pairs(data) do&lt;br /&gt;
    out = out..&amp;quot;\n| &amp;quot;..k..&amp;quot; = &amp;quot;..v&lt;br /&gt;
  end&lt;br /&gt;
  return out..&amp;quot;\n}}&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Module:Location_map/data/Indian_Ocean&amp;diff=5305</id>
		<title>Module:Location map/data/Indian Ocean</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Module:Location_map/data/Indian_Ocean&amp;diff=5305"/>
		<updated>2026-06-15T02:42:15Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync current Andaman Sea dependency from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;return {&lt;br /&gt;
	name = &#039;Indian Ocean&#039;,&lt;br /&gt;
	x = &#039;(52.4063)*( cos( $1*0.01745329252 )*sin( ($2-90)*0.01745329252 ) ) * ( ((1 + sin( $1*0.01745329252 )*sin( -20.0*0.01745329252 ) + cos( $1*0.01745329252 )*cos( -20.0*0.01745329252 )*cos( ($2-90)*0.01745329252 ) ) *0.5)^ -0.5) + 50&#039;,&lt;br /&gt;
	y = &#039;(100 -53.1221 ) - (55.4612)*( cos( -20.0*0.01745329252 )*sin( $1*0.01745329252 ) - sin( -20.0*0.01745329252 )*cos( $1*0.01745329252 )*cos( ($2-90)*0.01745329252 ) ) * ( ((1 + sin( $1*0.01745329252 )*sin( -20.0*0.01745329252 ) + cos( $1*0.01745329252 )*cos( -20.0*0.01745329252 )*cos( ($2-90)*0.01745329252 ) ) *0.5)^ -0.5)&#039;,&lt;br /&gt;
	image = &#039;Indian Ocean laea location map.svg&#039;,&lt;br /&gt;
	image1 = &#039;Indian Ocean laea relief location map.jpg&#039;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Module:Infobox_body_of_water_tracking&amp;diff=5304</id>
		<title>Module:Infobox body of water tracking</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Module:Infobox_body_of_water_tracking&amp;diff=5304"/>
		<updated>2026-06-15T02:42:14Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync current Andaman Sea dependency from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
function p.tracking(frame)&lt;br /&gt;
    local function isblank( val ) &lt;br /&gt;
        return (val == nil) or val:match(&#039;^[%s]*$&#039;)&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    local function hasnoconvert( val )&lt;br /&gt;
    	local res = nil&lt;br /&gt;
    	val = mw.text.killMarkers(val)&lt;br /&gt;
    	if val:match(&#039;[0-9]&#039;) then&lt;br /&gt;
    		res = 1&lt;br /&gt;
    		if val:match(&#039;[%(][−0-9%.]&#039;) and val:match(&#039;[%)]&#039;) then&lt;br /&gt;
    			res = nil&lt;br /&gt;
    		end&lt;br /&gt;
		end&lt;br /&gt;
		return res&lt;br /&gt;
	end&lt;br /&gt;
    &lt;br /&gt;
    local cats = &#039;&#039;&lt;br /&gt;
    local maincats = &#039;&#039;&lt;br /&gt;
    local args = frame:getParent().args&lt;br /&gt;
    local AZ = &#039;ABCDEFGHIJKLMNOPQRSTUVWXYZ&#039;&lt;br /&gt;
    local warnmsg = {}&lt;br /&gt;
    &lt;br /&gt;
    if isblank(args[&#039;image&#039;]) then&lt;br /&gt;
    	maincats = maincats .. &#039;[[Category:Articles using infobox body of water without image]]&#039;&lt;br /&gt;
    elseif isblank(args[&#039;alt&#039;]) then&lt;br /&gt;
		maincats = maincats .. &#039;[[Category:Articles using infobox body of water without alt]]&#039;&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    if isblank(args[&#039;coords&#039;]) and isblank(args[&#039;coordinates&#039;]) then &lt;br /&gt;
    	maincats = maincats .. &#039;[[Category:Articles using infobox body of water without coordinates]]&#039;&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    if (isblank(args[&#039;pushpin_map&#039;]) ) then&lt;br /&gt;
    	maincats = maincats .. &#039;[[Category:Articles using infobox body of water without pushpin_map]]&#039;&lt;br /&gt;
    elseif isblank(args[&#039;pushpin_map_alt&#039;]) then&lt;br /&gt;
		maincats = maincats .. &#039;[[Category:Articles using infobox body of water without pushpin_map_alt]]&#039;&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    if (isblank(args[&#039;image_bathymetry&#039;]) ) then&lt;br /&gt;
    	maincats = maincats .. &#039;[[Category:Articles using infobox body of water without image_bathymetry]]&#039;&lt;br /&gt;
    elseif isblank(args[&#039;alt_bathymetry&#039;]) then&lt;br /&gt;
		maincats = maincats .. &#039;[[Category:Articles using infobox body of water without alt_bathymetry]]&#039;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if args[&#039;mapframe&#039;] and mw.text.trim(args[&#039;mapframe&#039;]) == &#039;yes&#039; then&lt;br /&gt;
        maincats = maincats .. &#039;[[Category:Articles using infobox body of water with mapframe]]&#039;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local duplicate_parameters = 0&lt;br /&gt;
	local duplicate_list = {&lt;br /&gt;
		{&#039;child&#039;, &#039;embed&#039;},&lt;br /&gt;
        {&#039;name&#039;, &#039;lake_name&#039;},&lt;br /&gt;
        {&#039;image&#039;, &#039;image_lake&#039;},&lt;br /&gt;
        {&#039;alt&#039;, &#039;alt_lake&#039;},&lt;br /&gt;
        {&#039;caption&#039;, &#039;caption_lake&#039;},&lt;br /&gt;
        {&#039;coordinates&#039;, &#039;coords&#039;},&lt;br /&gt;
        {&#039;lake_type&#039;, &#039;type&#039;},&lt;br /&gt;
        {&#039;ocean_type&#039;, &#039;type&#039;},&lt;br /&gt;
        {&#039;lake_type&#039;, &#039;ocean_type&#039;},&lt;br /&gt;
        {&#039;part_of&#039;, &#039;parent&#039;},&lt;br /&gt;
        {&#039;basin_countries&#039;, &#039;countries&#039;},&lt;br /&gt;
        {&#039;catchment_km2&#039;, &#039;catchment&#039;},&lt;br /&gt;
        {&#039;length_km&#039;, &#039;length&#039;},&lt;br /&gt;
        {&#039;length_mi&#039;, &#039;length&#039;},&lt;br /&gt;
        {&#039;width_km&#039;, &#039;width&#039;},&lt;br /&gt;
        {&#039;width_mi&#039;, &#039;width&#039;},&lt;br /&gt;
        {&#039;area_km2&#039;, &#039;area&#039;},&lt;br /&gt;
        {&#039;area_mi2&#039;, &#039;area&#039;},&lt;br /&gt;
        {&#039;depth_m&#039;, &#039;depth&#039;},&lt;br /&gt;
        {&#039;max-depth_m&#039;, &#039;max-depth&#039;},&lt;br /&gt;
        {&#039;volume_km3&#039;, &#039;volume&#039;},&lt;br /&gt;
        {&#039;shore_km&#039;, &#039;shore&#039;},&lt;br /&gt;
        {&#039;elevation_m&#039;, &#039;elevation&#039;},&lt;br /&gt;
        {&#039;settlements&#039;, &#039;cities&#039;},&lt;br /&gt;
        {&#039;extra&#039;, &#039;nrhp&#039;},&lt;br /&gt;
        {&#039;extra&#039;, &#039;embedded&#039;},&lt;br /&gt;
        {&#039;embedded&#039;, &#039;nrhp&#039;}&lt;br /&gt;
    }&lt;br /&gt;
    for i, params in ipairs(duplicate_list) do&lt;br /&gt;
    	if args[params[1]] and args[params[2]] then&lt;br /&gt;
    		duplicate_parameters = duplicate_parameters + 1&lt;br /&gt;
    		table.insert(warnmsg, &#039;Cannot use &amp;lt;code&amp;gt;&#039; .. params[1] .. &#039;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&#039; .. params[2] .. &#039;&amp;lt;/code&amp;gt; at the same time.&#039;)&lt;br /&gt;
    	end&lt;br /&gt;
    end&lt;br /&gt;
    if (duplicate_parameters &amp;gt; 0) then&lt;br /&gt;
        cats = cats .. &#039;[[Category:Pages using infobox body of water with &#039; ..&lt;br /&gt;
        	&#039;duplicate parameters|&#039; .. &lt;br /&gt;
        	string.sub(AZ, duplicate_parameters, duplicate_parameters+1) .. &#039;]]&#039;&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    local no_convert_parameters = 0&lt;br /&gt;
    local dim_list = {&lt;br /&gt;
    	&#039;catchment&#039;, &#039;length&#039;, &#039;width&#039;, &#039;area&#039;, &#039;depth&#039;, &#039;max-depth&#039;, &#039;volume&#039;,&lt;br /&gt;
    	&#039;shore&#039;, &#039;elevation&#039;, &#039;temperature_low&#039;, &#039;temperature_high&#039;}&lt;br /&gt;
	for i, param in ipairs(dim_list) do&lt;br /&gt;
	   if hasnoconvert(args[param] or &#039;&#039;) then&lt;br /&gt;
	     no_convert_parameters = no_convert_parameters + 1&lt;br /&gt;
	     table.insert(warnmsg, &#039;Unconverted dimensions in &amp;lt;code&amp;gt;&#039; .. param .. &#039;&amp;lt;/code&amp;gt;&#039;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
    if (no_convert_parameters &amp;gt; 0) then&lt;br /&gt;
        maincats = maincats .. &#039;[[Category:Pages using infobox body of water with a non-automatically converted dimension|&#039; ..&lt;br /&gt;
        	string.sub(AZ,no_convert_parameters, no_convert_parameters+1) .. &#039;]]&#039;&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    if #warnmsg &amp;gt; 0 then&lt;br /&gt;
    	cats = require(&#039;Module:If preview&#039;)._warning({&lt;br /&gt;
    		table.concat(warnmsg, &#039;&amp;lt;br&amp;gt;&#039;) .. &#039;&amp;lt;br&amp;gt;(Infobox body of water).&#039;&lt;br /&gt;
    	}) .. cats&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
	if maincats ~= &#039;&#039; and mw.title.getCurrentTitle().namespace == 0 then&lt;br /&gt;
		cats = cats .. maincats&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
    return cats&lt;br /&gt;
end&lt;br /&gt;
    &lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Template:SHORTDESC&amp;diff=5303</id>
		<title>Template:SHORTDESC</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Template:SHORTDESC&amp;diff=5303"/>
		<updated>2026-06-15T02:42:13Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync current Andaman Sea dependency from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Template:Short_description&amp;diff=5302</id>
		<title>Template:Short description</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Template:Short_description&amp;diff=5302"/>
		<updated>2026-06-15T02:42:12Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync current Andaman Sea dependency from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#ifeq:{{lc:{{{1|}}}}}|none|{{SHORTDESC:|{{{2|}}}}}&amp;lt;nowiki/&amp;gt;&amp;lt;!--Prevents whitespace issues when used with adjacent newlines--&amp;gt;|&amp;lt;div class=&amp;quot;shortdescription nomobile noexcerpt noprint searchaux&amp;quot; style=&amp;quot;display:none&amp;quot;&amp;gt;{{{1|}}}{{SHORTDESC:{{{1|}}}|{{{2|}}}}}&amp;lt;/div&amp;gt;}}&amp;lt;includeonly&amp;gt;{{#ifeq:{{{pagetype}}}|Disambiguation pages||{{#ifeq:{{pagetype |defaultns = all |user=exclude}}|exclude||{{#ifeq:{{#switch: {{NAMESPACENUMBER}} | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 100 | 101 | 118 | 119 | 828 | 829 | = exclude|#default=}}|exclude||[[Category:{{{pagetype|{{pagetype |defaultns = extended |plural=y}}}}} with short description]]}}}}}}&amp;lt;/includeonly&amp;gt;&amp;lt;!-- Start tracking&lt;br /&gt;
--&amp;gt;{{#invoke:Check for unknown parameters|check|unknown={{Main other|[[Category:Pages using short description with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:Short description]] with unknown parameter &amp;quot;_VALUE_&amp;quot;|ignoreblank=y| 1 | 2 | pagetype | bot |plural }}&amp;lt;!--&lt;br /&gt;
--&amp;gt;{{#ifexpr: {{#invoke:String|len|{{{1|}}}}}&amp;gt;100 | [[Category:{{{pagetype|{{pagetype |defaultns = extended |plural=y}}}}} with long short description]]}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;&amp;lt;includeonly&amp;gt;{{#if:{{{1|}}}||[[Category:Pages with empty short description]]}}&amp;lt;/includeonly&amp;gt;&amp;lt;!--&lt;br /&gt;
--&amp;gt;{{Short description/lowercasecheck|{{{1|}}}}}&amp;lt;!-- &lt;br /&gt;
--&amp;gt;{{Main other |{{SDcat |sd={{{1|}}} }} }}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Documentation}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Template:RP&amp;diff=5301</id>
		<title>Template:RP</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Template:RP&amp;diff=5301"/>
		<updated>2026-06-15T02:42:10Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync current Andaman Sea dependency from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Template:Reference page]]&lt;br /&gt;
&lt;br /&gt;
{{Rcat shell|{{R from move}}{{R from template shortcut}}{{R from modification}}}}&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Template:R/superscript&amp;diff=5300</id>
		<title>Template:R/superscript</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Template:R/superscript&amp;diff=5300"/>
		<updated>2026-06-15T02:42:09Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync current Andaman Sea dependency from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- Only for internal use: |wrap=n[o]/y[es]/f[orced] |leadin=value |prefix=value |pp=value |where=value |sup-where=value |quote-where=value |quote=value |language=value |translation=value |suffix=value --&amp;gt;{{#if:{{{where|}}}|&amp;lt;sup class=&amp;quot;reference {{#switch:{{{wrap|}}}|f|forced=|no}}wrap&amp;quot;&amp;gt;{{#if:{{{quote|}}}|{{{prefix|}}}}}&amp;lt;span title=&amp;quot;&amp;lt;!--{{#invoke:String|replace|source={{#invoke:String|replace|source={{#invoke:String|replace|source=--&amp;gt;{{#invoke:DecodeEncode|encode|s={{#invoke:Plain text|main|1={{{leadin|}}}: {{#if:{{{quote-where|}}}|{{{quote-where|}}}|{{{where|}}}}}|encode=false}}|charset=&amp;lt;&amp;gt;&amp;quot;}}&amp;lt;!--|&amp;quot;|&amp;amp;quot;}}|&amp;lt;|&amp;amp;lt;}}|&amp;gt;|&amp;amp;gt;}}--&amp;gt;{{#if:{{{quote|}}}|&amp;amp;#10;Quotation&amp;lt;!--{{#invoke:String|replace|source={{#invoke:String|replace|source={{#invoke:String|replace|source=--&amp;gt;{{#invoke:DecodeEncode|encode|s={{#invoke:Plain text|main|1={{#if:{{{language|}}}|&amp;amp;#32;({{#ifeq:{{lang|fn=is_ietf_tag|{{{language|}}}}}|true|{{lang|fn=name_from_tag|{{{language|}}}}}|{{{language|}}}}})}}&amp;amp;#58; &amp;amp;quot;{{trim quotes|s={{{quote|}}}}}&amp;amp;quot;{{#if:{{{translation|}}}|&amp;amp;#10;Translation: &amp;amp;quot;{{trim quotes|s={{{translation}}}}}&amp;amp;quot;}}|encode=false}}|charset=&amp;lt;&amp;gt;&amp;quot;}}&amp;lt;!--|&amp;quot;|&amp;amp;quot;}}|&amp;lt;|&amp;amp;lt;}}|&amp;gt;|&amp;amp;gt;}}--&amp;gt;&amp;quot; class=&amp;quot;tooltip tooltip-dashed&amp;quot; style=&amp;quot;border-bottom: 1px dashed;}}&amp;quot;&amp;gt;{{#if:{{{quote|}}}||{{{prefix|}}}}}&amp;lt;!--DEBUG: Take care of :;*# as first character here. This also breaks plainlinks/stripmarkers/catlinks testcases {{#invoke:String|replace|source=--&amp;gt;{{{pp|}}}{{{sup-where|}}}&amp;lt;!--| |&amp;amp;thinsp;}}--&amp;gt;{{#if:{{{quote|}}}||{{{suffix|}}}}}&amp;lt;/span&amp;gt;{{#if:{{{quote|}}}|{{{suffix|}}}}}&amp;lt;/sup&amp;gt;}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Template:MMR&amp;diff=5299</id>
		<title>Template:MMR</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Template:MMR&amp;diff=5299"/>
		<updated>2026-06-15T02:42:08Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync current Andaman Sea dependency from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#invoke:flag||Myanmar}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{flag template documentation|Myanmar|MMR|MYA|MYA}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Template:List_of_seas&amp;diff=5298</id>
		<title>Template:List of seas</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Template:List_of_seas&amp;diff=5298"/>
		<updated>2026-06-15T02:42:04Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync current Andaman Sea dependency from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Navbox&lt;br /&gt;
 | name = List of seas&lt;br /&gt;
 | title = [[Earth]]&#039;s [[Borders of the oceans|oceans]] and [[List of seas on Earth|seas]]&lt;br /&gt;
 | state = {{{state&amp;lt;includeonly&amp;gt;|collapsed&amp;lt;/includeonly&amp;gt;}}}&lt;br /&gt;
 | bodyclass = hlist&lt;br /&gt;
&lt;br /&gt;
| group1 = [[Southern Ocean|Antarctic/Southern Ocean]]&lt;br /&gt;
 | list1 = &lt;br /&gt;
* [[Amundsen Sea]]&lt;br /&gt;
* [[Bellingshausen Sea]]&lt;br /&gt;
* [[Cooperation Sea]]&lt;br /&gt;
* [[Cosmonauts Sea]]&lt;br /&gt;
* [[Davis Sea]]&lt;br /&gt;
* [[D&#039;Urville Sea]]&lt;br /&gt;
* [[King Haakon VII Sea]]&lt;br /&gt;
* [[Lazarev Sea]]&lt;br /&gt;
* [[Mawson Sea]]&lt;br /&gt;
* [[Riiser-Larsen Sea]]&lt;br /&gt;
* [[Ross Sea]]&lt;br /&gt;
* [[Scotia Sea]]&lt;br /&gt;
* [[Somov Sea]]&lt;br /&gt;
* [[Weddell Sea]]&lt;br /&gt;
&lt;br /&gt;
 | group2 = [[Arctic Ocean]]&lt;br /&gt;
 | list2 = &lt;br /&gt;
* [[Amundsen Gulf]]&lt;br /&gt;
* [[Barents Sea]]&lt;br /&gt;
* [[Beaufort Sea]]&lt;br /&gt;
* [[Chukchi Sea]]&lt;br /&gt;
* [[East Siberian Sea]]&lt;br /&gt;
* [[Greenland Sea]]&lt;br /&gt;
* [[Gulf of Boothia]]&lt;br /&gt;
* [[Kara Sea]]&lt;br /&gt;
* [[Laptev Sea]]&lt;br /&gt;
* [[Lincoln Sea]]&lt;br /&gt;
* [[Pechora Sea]]&lt;br /&gt;
* [[Prince Gustaf Adolf Sea]]&lt;br /&gt;
* [[Queen Victoria Sea]]&lt;br /&gt;
* [[Wandel Sea]]&lt;br /&gt;
* [[White Sea]]&lt;br /&gt;
&lt;br /&gt;
 | group3 = [[Atlantic Ocean]]&lt;br /&gt;
 | list3 = &lt;br /&gt;
* [[Adriatic Sea]]&lt;br /&gt;
* [[Aegean Sea]]&lt;br /&gt;
* [[Alboran Sea]]&lt;br /&gt;
* [[American Mediterranean Sea]]&lt;br /&gt;
* [[Archipelago Sea]]&lt;br /&gt;
* [[Argentine Sea]]&lt;br /&gt;
* [[Baffin Bay]]&lt;br /&gt;
* [[Balearic Sea]]&lt;br /&gt;
* [[Baltic Sea]]&lt;br /&gt;
* [[Bay of Biscay]]&lt;br /&gt;
* [[Bothnian Bay|Bay of Bothnia]]&lt;br /&gt;
* [[Bay of Campeche]]&lt;br /&gt;
* [[Bay of Fundy]]&lt;br /&gt;
* [[Black Sea]]&lt;br /&gt;
* [[Bothnian Sea]]&lt;br /&gt;
* [[Caribbean Sea]]&lt;br /&gt;
* [[Celtic Sea]]&lt;br /&gt;
* [[English Channel]]&lt;br /&gt;
* [[Foxe Basin]]&lt;br /&gt;
* [[Greenland Sea]]&lt;br /&gt;
* [[Gulf of Bothnia]]&lt;br /&gt;
* [[Gulf of Finland]]&lt;br /&gt;
* [[Gulf of Guinea]]&lt;br /&gt;
* [[Gulf of Lion]]&lt;br /&gt;
* [[Gulf of Maine]]&lt;br /&gt;
* [[Gulf of Mexico]]&lt;br /&gt;
* [[Gulf of Sidra]]&lt;br /&gt;
* [[Gulf of St. Lawrence]]&lt;br /&gt;
* [[Gulf of Venezuela]]&lt;br /&gt;
* [[Hudson Bay]]&lt;br /&gt;
* [[Ionian Sea]]&lt;br /&gt;
* [[Irish Sea]]&lt;br /&gt;
* [[Irminger Sea]]&lt;br /&gt;
* [[James Bay]]&lt;br /&gt;
* [[Labrador Sea]]&lt;br /&gt;
* [[Levantine Sea]]&lt;br /&gt;
* [[Libyan Sea]]&lt;br /&gt;
* [[Ligurian Sea]]&lt;br /&gt;
* [[Mediterranean Sea]]&lt;br /&gt;
* [[Myrtoan Sea]]&lt;br /&gt;
* [[North Sea]]&lt;br /&gt;
* [[Norwegian Sea]]&lt;br /&gt;
* [[Sargasso Sea]]&lt;br /&gt;
* [[Sea of Åland]]&lt;br /&gt;
* [[Sea of Azov]]&lt;br /&gt;
* [[Sea of Crete]]&lt;br /&gt;
* [[Sea of the Hebrides]]&lt;br /&gt;
* [[Sea of Marmara]]&lt;br /&gt;
* [[Thracian Sea]]&lt;br /&gt;
* [[Tyrrhenian Sea]]&lt;br /&gt;
* [[Wadden Sea]]&lt;br /&gt;
&lt;br /&gt;
 | group4 = [[Indian Ocean]]&lt;br /&gt;
 | list4 = &lt;br /&gt;
* [[Andaman Sea]]&lt;br /&gt;
* [[Arabian Sea]]&lt;br /&gt;
* [[Bay of Bengal]]&lt;br /&gt;
* [[Flores Sea]]&lt;br /&gt;
* [[Great Australian Bight]]&lt;br /&gt;
* [[Gulf of Aden]]&lt;br /&gt;
* [[Gulf of Aqaba]]&lt;br /&gt;
* [[Gulf of Khambhat]]&lt;br /&gt;
* [[Gulf of Kutch]]&lt;br /&gt;
* [[Gulf of Oman]]&lt;br /&gt;
* [[Gulf of Suez]]&lt;br /&gt;
* [[Laccadive Sea]]&lt;br /&gt;
* [[Mozambique Channel]]&lt;br /&gt;
* [[Persian Gulf]]&lt;br /&gt;
* [[Red Sea]]&lt;br /&gt;
* [[Timor Sea]]&lt;br /&gt;
&lt;br /&gt;
 | group5 = [[Pacific Ocean]]&lt;br /&gt;
 | list5 = &lt;br /&gt;
* [[Arafura Sea]]&lt;br /&gt;
* [[Bali Sea]]&lt;br /&gt;
* [[Banda Sea]]&lt;br /&gt;
* [[Bering Sea]]&lt;br /&gt;
* [[Bismarck Sea]]&lt;br /&gt;
* [[Bohai Sea]]&lt;br /&gt;
* [[Bohol Sea]]&lt;br /&gt;
* [[Camotes Sea]]&lt;br /&gt;
* [[Celebes Sea]]&lt;br /&gt;
* [[Chilean Sea]]&lt;br /&gt;
* [[Coral Sea]]&lt;br /&gt;
* [[East China Sea]]&lt;br /&gt;
* [[Gulf of Alaska]]&lt;br /&gt;
* [[Gulf of Anadyr]]&lt;br /&gt;
* [[Gulf of California]]&lt;br /&gt;
* [[Gulf of Carpentaria]]&lt;br /&gt;
* [[Gulf of Fonseca]]&lt;br /&gt;
* [[Gulf of Panama]]&lt;br /&gt;
* [[Gulf of Thailand]]&lt;br /&gt;
* [[Gulf of Tonkin]]&lt;br /&gt;
* [[Halmahera Sea]]&lt;br /&gt;
* [[Java Sea]]&lt;br /&gt;
* [[Koro Sea]]&lt;br /&gt;
* [[Mar de Grau]]&lt;br /&gt;
* [[Molucca Sea]]&lt;br /&gt;
* [[Moro Gulf]]&lt;br /&gt;
* [[Philippine Sea]]&lt;br /&gt;
* [[Salish Sea]]&lt;br /&gt;
* [[Savu Sea]]&lt;br /&gt;
* [[Sea of Japan]]&lt;br /&gt;
* [[Sea of Okhotsk]]&lt;br /&gt;
* [[Seram Sea]]&lt;br /&gt;
* [[Seto Inland Sea]]&lt;br /&gt;
* [[Shantar Sea]]&lt;br /&gt;
* [[Sibuyan Sea]]&lt;br /&gt;
* [[Solomon Sea]]&lt;br /&gt;
* [[South China Sea]]&lt;br /&gt;
* [[Sulu Sea]]&lt;br /&gt;
* [[Tasman Sea]]&lt;br /&gt;
* [[Visayan Sea]]&lt;br /&gt;
* [[West Philippine Sea]]&lt;br /&gt;
* [[Yellow Sea]]&lt;br /&gt;
&lt;br /&gt;
 | group6 = [[Endorheic basin]]s&lt;br /&gt;
 | list6 = &lt;br /&gt;
* [[Aral Sea]]&lt;br /&gt;
* [[Caspian Sea]]&lt;br /&gt;
* [[Dead Sea]]&lt;br /&gt;
* [[Salton Sea]]&lt;br /&gt;
&lt;br /&gt;
| group7 = Others&lt;br /&gt;
| list7 = &lt;br /&gt;
*[[List of ancient oceans|Ancient oceans]]&lt;br /&gt;
*[[Ocean]]&lt;br /&gt;
*[[Sea]]&lt;br /&gt;
*[[Superocean]]&lt;br /&gt;
&lt;br /&gt;
 | below = &lt;br /&gt;
* &#039;&#039;&#039;{{portal-inline|size=small|Oceans}}&#039;&#039;&#039;&lt;br /&gt;
* {{icon|Category}} &#039;&#039;&#039;[[:Category:Seas|Category]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Documentation}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Template:List_of_Indonesian_seas&amp;diff=5297</id>
		<title>Template:List of Indonesian seas</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Template:List_of_Indonesian_seas&amp;diff=5297"/>
		<updated>2026-06-15T02:42:02Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync current Andaman Sea dependency from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Navbox&lt;br /&gt;
 | name = List of Indonesian seas&lt;br /&gt;
 | title = Indonesian seas&lt;br /&gt;
 | bodyclass = hlist&lt;br /&gt;
 | state  = {{{state&amp;lt;includeonly&amp;gt;|autocollapse&amp;lt;/includeonly&amp;gt;}}}&lt;br /&gt;
&lt;br /&gt;
 | above = &lt;br /&gt;
* [[East Indian Archipelago]]&lt;br /&gt;
&lt;br /&gt;
 | group1 = Ocean&lt;br /&gt;
 | list1 =&lt;br /&gt;
* [[Indian Ocean]]&lt;br /&gt;
* [[Pacific Ocean]]&lt;br /&gt;
&lt;br /&gt;
 | group2 = Sea&lt;br /&gt;
 | list2 =&lt;br /&gt;
* [[Andaman Sea]]&lt;br /&gt;
* [[Arafura Sea]]&lt;br /&gt;
* [[Bali Sea]]&lt;br /&gt;
* [[Banda Sea]]&lt;br /&gt;
* [[Celebes Sea]]&lt;br /&gt;
* [[Flores Sea]]&lt;br /&gt;
* [[Halmahera Sea]]&lt;br /&gt;
* [[Java Sea]]&lt;br /&gt;
* [[Molucca Sea]]&lt;br /&gt;
* [[Natuna Sea]]&lt;br /&gt;
* [[Philippine Sea]]&lt;br /&gt;
* [[Savu Sea]]&lt;br /&gt;
* [[Seram Sea]]&lt;br /&gt;
* [[South China Sea]]&lt;br /&gt;
* [[Timor Sea]]&lt;br /&gt;
&lt;br /&gt;
 | group3 = Strait&lt;br /&gt;
 | list3 =&lt;br /&gt;
* [[Alas Strait]]&lt;br /&gt;
* [[Alor Strait]]&lt;br /&gt;
* [[Badung Strait]]&lt;br /&gt;
* [[Bali Strait]]&lt;br /&gt;
* [[Bangka Strait]]&lt;br /&gt;
* [[Berhala Strait]]&lt;br /&gt;
* [[Dampier Strait (Indonesia)|Dampier Strait]]&lt;br /&gt;
* [[Gaspar Strait]]&lt;br /&gt;
* [[Karimata Strait]]&lt;br /&gt;
* [[Laut Strait]]&lt;br /&gt;
* [[Lombok Strait]]&lt;br /&gt;
* [[Madura Strait]]&lt;br /&gt;
* [[Makassar Strait]]&lt;br /&gt;
* [[Strait of Malacca|Malacca Strait]]&lt;br /&gt;
* [[Mentawai Strait]]&lt;br /&gt;
* [[Ombai Strait]]&lt;br /&gt;
* [[Pitt Strait (Indonesia)|Pitt Strait]]&lt;br /&gt;
* [[Riau Strait]]&lt;br /&gt;
* [[Rupat Strait]]&lt;br /&gt;
* [[Sape Strait]]&lt;br /&gt;
* [[Selayar Strait]]&lt;br /&gt;
* [[Singapore Strait]]&lt;br /&gt;
* [[Sumba Strait]]&lt;br /&gt;
* [[Sunda Strait]]&lt;br /&gt;
* [[Wetar Strait]]&lt;br /&gt;
&lt;br /&gt;
 | group4 = Gulf&lt;br /&gt;
 | list4 =&lt;br /&gt;
* [[Ambon Bay]]&lt;br /&gt;
* [[Balikpapan Bay]]&lt;br /&gt;
* [[Berau Gulf]]&lt;br /&gt;
* [[Bintuni Bay]]&lt;br /&gt;
* [[Gulf of Boni|Boni Gulf]]&lt;br /&gt;
* [[Cenderawasih Bay]]&lt;br /&gt;
* [[Jakarta Bay]]&lt;br /&gt;
* [[Lampung Bay]]&lt;br /&gt;
* [[Palabuhanratu Bay]]&lt;br /&gt;
* [[Saleh Bay]]&lt;br /&gt;
* [[Semangka Bay]]&lt;br /&gt;
* [[Gulf of Tolo|Tolo Gulf]]&lt;br /&gt;
* [[Gulf of Tomini|Tomini Gulf]]&lt;br /&gt;
* [[Yos Sudarso Bay]]&lt;br /&gt;
| below=&lt;br /&gt;
{{portal-inline|size=tiny|Indonesia}}&lt;br /&gt;
{{portal-inline|size=tiny|Oceans}}&lt;br /&gt;
}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{navbox documentation}}&lt;br /&gt;
[[Category:Indonesia geography navigational boxes|Seas]]&lt;br /&gt;
[[Category:Ocean and sea navigational boxes|Indonesia]]&lt;br /&gt;
[[Category:Place list templates|Indonesian seas]]&lt;br /&gt;
[[Category:List navigational boxes|Indonesian seas]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Template:Infobox_body_of_water&amp;diff=5296</id>
		<title>Template:Infobox body of water</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Template:Infobox_body_of_water&amp;diff=5296"/>
		<updated>2026-06-15T02:42:01Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync current Andaman Sea dependency from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{main other|{{#if:{{Has short description}}||&amp;lt;!--&lt;br /&gt;
  --&amp;gt;{{if first display both|{{#invoke:Type in location|main|{{if empty|{{{lake_type|}}}|{{{ocean_type|}}}|{{{type|}}}}}|&amp;lt;!--&lt;br /&gt;
      --&amp;gt;{{if empty|{{{location|}}}|{{{basin_countries|}}}|{{{countries|}}}}}|&amp;lt;!--&lt;br /&gt;
      --&amp;gt;check-patterns=basin;bay;bight;channel;estuary;gulf;lagoon;lake;loch;ocean;reservoir;river;sea;sound;strait|&amp;lt;--&lt;br /&gt;
      --&amp;gt;invalidadd={{if empty|{{#if:{{{lake_type|}}}|lake}}|{{#if:{{{ocean_type|}}}|sea}}|body of water}}}}|&amp;lt;!--&lt;br /&gt;
  --&amp;gt;[[Category:Pages using infobox body of water with auto short description]]}}}}}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;{{infobox&lt;br /&gt;
| child          = {{lc:{{if empty|{{{child|}}}|{{{embed|}}}}}}}&lt;br /&gt;
| bodyclass      = vcard&lt;br /&gt;
| bodystyle      = {{#ifeq:{{{align}}}|left|float: {{{align}}}; clear: {{{align}}}; margin-left:0; margin-right: 1em; }}&lt;br /&gt;
| headerstyle    = border-bottom: #cedeff 1px solid&lt;br /&gt;
&lt;br /&gt;
| abovestyle     = background-color: #cedeff; font-size: 125%; color:black;&lt;br /&gt;
| aboveclass     = fn org&lt;br /&gt;
| above          = {{if empty|{{{name|}}}|&amp;lt;includeonly&amp;gt;{{PAGENAMEBASE}}&amp;lt;/includeonly&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- The following is only activated when child = yes or embed = yes --&amp;gt;&lt;br /&gt;
| titleclass     = fn org&lt;br /&gt;
| title          = {{#ifeq:{{lc:{{if empty|{{{child|}}}|{{{embed|}}}}}}}|yes|{{if empty|{{{name|}}}|&amp;lt;includeonly&amp;gt;{{PAGENAMEBASE}}&amp;lt;/includeonly&amp;gt;}}}}&lt;br /&gt;
&lt;br /&gt;
| subheaderclass = nickname&lt;br /&gt;
| subheaderstyle = font-size:100%; border-bottom: 1px solid #cedeff;&lt;br /&gt;
| subheader      = {{{other_name|}}}&lt;br /&gt;
| subheader2     = {{native name checker|{{{native_name|}}}}}&lt;br /&gt;
&lt;br /&gt;
| imagestyle     = line-height: 1.2; border-bottom: 1px solid #cedeff;&lt;br /&gt;
&lt;br /&gt;
| image    = {{#invoke:InfoboxImage|InfoboxImage|image={{{image|}}}|size={{{image_size|}}}|sizedefault=264px|maxsize=296px|alt={{{alt|}}} }}&lt;br /&gt;
| caption  = {{{caption|}}}&lt;br /&gt;
&lt;br /&gt;
| image2   = {{#invoke:InfoboxImage|InfoboxImage|image={{{image_map|}}}|size={{if empty|{{{map_size|}}}|{{{image_size|}}}}}|sizedefault=256px|maxsize=296px|alt={{{alt_map|}}}}}&lt;br /&gt;
| caption2 = {{{caption_map|}}}&lt;br /&gt;
&lt;br /&gt;
| image3   = {{#if:{{both| {{{pushpin_map|}}} | {{{coordinates|}}}{{{coords|}}}{{#property:P625}} }}|&lt;br /&gt;
{{location map|{{{pushpin_map|}}}&lt;br /&gt;
|coordinates = {{if empty|{{{coordinates|}}}|{{{coords|}}}}}&lt;br /&gt;
|border = infobox&lt;br /&gt;
|alt = {{{pushpin_map_alt|}}}&lt;br /&gt;
|caption = {{{pushpin_map_caption|}}}&lt;br /&gt;
|float = center&lt;br /&gt;
|width = {{{pushpin_mapsize|}}}&lt;br /&gt;
|default_width = 256&lt;br /&gt;
|max_width = 296&lt;br /&gt;
|relief= {{yesno|{{if empty|{{{pushpin_relief|}}}|yes}}|yes=yes|no=}}&lt;br /&gt;
|AlternativeMap = {{{pushpin_image|}}}&lt;br /&gt;
 |label = {{#ifeq: {{lc: {{{pushpin_label_position|}}} }} | none | | {{if empty|{{{pushpin_label|}}}|{{{name|}}}|{{PAGENAMEBASE}} }} }}&lt;br /&gt;
 |marksize =6&lt;br /&gt;
 |position = {{{pushpin_label_position|}}}&lt;br /&gt;
}}}}&lt;br /&gt;
&lt;br /&gt;
| image4   = {{#invoke:InfoboxImage|InfoboxImage|image={{{image_bathymetry|}}}|size={{if empty|{{{bathymetry_size|}}}|{{{image_size|}}}}}|maxsize=296px|sizedefault=256px|border=yes|alt={{{alt_bathymetry|}}}}}&lt;br /&gt;
| caption4 = {{{caption_bathymetry|}}}&lt;br /&gt;
&lt;br /&gt;
| rowclass1 = adr&lt;br /&gt;
| label1 = Location&lt;br /&gt;
| class1 = region&lt;br /&gt;
| data1  = {{{location|}}}&lt;br /&gt;
&lt;br /&gt;
| label2 = Group&lt;br /&gt;
| data2  = {{{group|}}}&lt;br /&gt;
| class2 = category&lt;br /&gt;
&lt;br /&gt;
| label3 = &amp;lt;span title=&amp;quot;Geographical coordinates&amp;quot;&amp;gt;Coordinates&amp;lt;/span&amp;gt;&lt;br /&gt;
| data3  = {{#if:{{{coordinates|}}}{{{coords|}}}&lt;br /&gt;
   | {{#invoke:Coordinates|coordinsert|{{if empty|{{{coordinates|}}}|{{{coords|}}}}}|type:waterbody}}{{{coordinates_footnotes|}}}&lt;br /&gt;
   }}&lt;br /&gt;
&lt;br /&gt;
| label4 = {{if empty|{{#if:{{{lake_type|}}}|[[Lake#Types of lakes|Lake type]]}}&lt;br /&gt;
                     |{{#if:{{{ocean_type|}}}|[[Ocean#Types of oceans|Ocean type]]}}&lt;br /&gt;
                     |[[Body of water#Waterbody types|Type]]}}&lt;br /&gt;
| data4 = {{if empty|{{{lake_type|}}}|{{{ocean_type|}}}|{{{type|}}}}}&lt;br /&gt;
| class4 = category&lt;br /&gt;
&lt;br /&gt;
| label6     = Etymology&lt;br /&gt;
| data6      = {{{etymology|}}}&lt;br /&gt;
&lt;br /&gt;
| label7     = Part&amp;amp;nbsp;of&lt;br /&gt;
| data7      = {{if empty|{{{part_of|}}}|{{{parent|}}}}}&lt;br /&gt;
&lt;br /&gt;
| label8     = {{longitem|1=[[inflow (hydrology)|&amp;lt;span title=&amp;quot;Primary inflows: rivers, streams, precipitation&amp;quot;&amp;gt;Primary inflows&amp;lt;/span&amp;gt;]]}}&lt;br /&gt;
| data8      = {{{inflow|}}}&lt;br /&gt;
&lt;br /&gt;
| label9     = {{longitem|River sources}}&lt;br /&gt;
| data9      = {{{rivers|}}}&lt;br /&gt;
&lt;br /&gt;
| label10    = {{longitem|1=[[discharge (hydrology)|&amp;lt;span title=&amp;quot;Primary outflows: rivers, streams, evaporation&amp;quot;&amp;gt;Primary outflows&amp;lt;/span&amp;gt;]]}}&lt;br /&gt;
| data10     = {{{outflow|}}}&lt;br /&gt;
&lt;br /&gt;
| label11    = {{longitem|1=&amp;lt;span title=&amp;quot;Primary outflows: oceans, seas, straights&amp;quot;&amp;gt;Ocean/sea sources&amp;lt;/span&amp;gt;}}&lt;br /&gt;
| data11     = {{{oceans|}}}&lt;br /&gt;
&lt;br /&gt;
| label12    = {{longitem|[[Drainage basin|Catchment area]]}}&lt;br /&gt;
| data12     = {{{catchment|}}}&lt;br /&gt;
&lt;br /&gt;
| label13    = [[Drainage basin|Basin]]&amp;amp;nbsp;countries&lt;br /&gt;
| data13     = {{if empty|{{{basin_countries|}}}|{{{countries|}}}}}&lt;br /&gt;
&lt;br /&gt;
| label14    = {{longitem|Managing agency}}&lt;br /&gt;
| data14     = {{{agency|}}}&lt;br /&gt;
| class14    = agent&lt;br /&gt;
&lt;br /&gt;
| label15    = Designation&lt;br /&gt;
| data15     = {{{designation|}}}&lt;br /&gt;
| class15    = category&lt;br /&gt;
&lt;br /&gt;
| label16    = Built&lt;br /&gt;
| data16     = {{{date-built|}}}&lt;br /&gt;
&lt;br /&gt;
| label17    = {{longitem|Construction engineer}}&lt;br /&gt;
| data17     = {{{engineer|}}}&lt;br /&gt;
&lt;br /&gt;
| label18    = {{longitem|First flooded}}&lt;br /&gt;
| data18     = {{{date-flooded|}}}&lt;br /&gt;
&lt;br /&gt;
| header21   = {{#if:{{{length|}}}{{{width|}}}{{{area|}}}{{{depth|}}}{{{max-depth|}}}{{{volume|}}}{{{residence_time|}}}{{{salinity|}}}{{{shore|}}}{{{elevation|}}}|{{#ifeq:{{lc:{{if empty|{{{child|}}}|{{{embed|}}}}}}}|yes||&amp;lt;nowiki /&amp;gt;}}}}&lt;br /&gt;
&lt;br /&gt;
| label22    = Max.&amp;amp;nbsp;length&lt;br /&gt;
| rowclass22 = note&lt;br /&gt;
| data22     = {{{length|}}}&lt;br /&gt;
&lt;br /&gt;
| label23    = Max.&amp;amp;nbsp;width&lt;br /&gt;
| rowclass23 = note&lt;br /&gt;
| data23     = {{{width|}}}&lt;br /&gt;
&lt;br /&gt;
| label24    = Min.&amp;amp;nbsp;width&lt;br /&gt;
| rowclass24 = note&lt;br /&gt;
| data24     = {{{min_width|}}}&lt;br /&gt;
&lt;br /&gt;
| label25    = {{longitem|{{#if:{{{lake_type|}}}|[[List of lakes by area|Surface area]]|Surface area}}}}&lt;br /&gt;
| rowclass25 = note&lt;br /&gt;
| data25     = {{{area|}}}&lt;br /&gt;
&lt;br /&gt;
| label26    = {{longitem|Average depth}}&lt;br /&gt;
| rowclass26 = note&lt;br /&gt;
| data26     = {{{depth|}}}&lt;br /&gt;
&lt;br /&gt;
| label27    = Max.&amp;amp;nbsp;depth&lt;br /&gt;
| rowclass27 = note&lt;br /&gt;
| data27     = {{{max-depth|}}}&lt;br /&gt;
&lt;br /&gt;
| label28    = {{longitem|{{#if:{{{lake_type|}}}|[[List of lakes by volume|Water volume]]|Water volume}}}}&lt;br /&gt;
| rowclass28 = note&lt;br /&gt;
| data28     = {{{volume|}}}&lt;br /&gt;
&lt;br /&gt;
| label29    = {{#if:{{{lake_type|}}}&lt;br /&gt;
  | [[Lake retention time|Residence&amp;amp;nbsp;time]]&lt;br /&gt;
  | [[Water cycle#Residence times|Residence&amp;amp;nbsp;time]]&lt;br /&gt;
  }}&lt;br /&gt;
| rowclass29 = note&lt;br /&gt;
| data29     = {{#if:{{{residence_time|}}}|{{#iferror:{{#expr:{{{residence_time}}}}}&lt;br /&gt;
  |{{{residence_time}}}&lt;br /&gt;
  |{{{residence_time}}} year{{#ifeq:{{{residence_time}}}|1||s}}&lt;br /&gt;
  }}}}&lt;br /&gt;
&lt;br /&gt;
| label30    = [[Salinity]]&lt;br /&gt;
| rowclass30 = note&lt;br /&gt;
| data30     = {{{salinity|}}}&lt;br /&gt;
&lt;br /&gt;
| label31    = {{longitem|Shore length&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;}}&lt;br /&gt;
| rowclass31 = note&lt;br /&gt;
| data31     = {{{shore|}}}&lt;br /&gt;
&lt;br /&gt;
| label32    = {{longitem|Surface elevation}}&lt;br /&gt;
| rowclass32 = note&lt;br /&gt;
| data32     = {{{elevation|}}}&lt;br /&gt;
&lt;br /&gt;
| header36   = {{#if:{{{temperature_high|}}}{{{temperature_low|}}}{{{frozen|}}}{{{islands|}}}{{{sections|}}}{{{cities|}}}{{{website|}}}{{{reference|}}}|&amp;lt;nowiki /&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
| label37    = {{longitem|Max. temperature}}&lt;br /&gt;
| rowclass37 = note&lt;br /&gt;
| data37     = {{{temperature_high|}}}&lt;br /&gt;
&lt;br /&gt;
| label38    = {{longitem|Min. temperature}}&lt;br /&gt;
| rowclass38 = note&lt;br /&gt;
| data38     = {{{temperature_low|}}}&lt;br /&gt;
&lt;br /&gt;
| label39    = Frozen&lt;br /&gt;
| data39     = {{{frozen|}}}&lt;br /&gt;
&lt;br /&gt;
| label40    = Dam&lt;br /&gt;
| data40     = {{{dam_name|}}}&lt;br /&gt;
&lt;br /&gt;
| label41    = {{#if:{{{islands_category|}}}&lt;br /&gt;
  |[[:category:{{{islands_category}}}|Islands]]&lt;br /&gt;
  |{{#if:{{{lake_type|}}}&lt;br /&gt;
    | [[:category:Lake islands|Islands]]&lt;br /&gt;
    | {{#if:{{{ocean_type|}}}&lt;br /&gt;
      | [[:Category:Islands by ocean or sea|Islands]]&lt;br /&gt;
      | [[:Category:Islands by body of water|Islands]]&lt;br /&gt;
      }}&lt;br /&gt;
    }}&lt;br /&gt;
  }}&lt;br /&gt;
| data41     = {{{islands|}}}&lt;br /&gt;
&lt;br /&gt;
| label42    = {{longitem|Sections/sub-basins}}&lt;br /&gt;
| data42     = {{{sections|}}}&lt;br /&gt;
&lt;br /&gt;
| label43    = Trenches&lt;br /&gt;
| rowclass43 = note&lt;br /&gt;
| data43     = {{{trenches|}}}&lt;br /&gt;
&lt;br /&gt;
| label44    = Benches&lt;br /&gt;
| rowclass44 = note&lt;br /&gt;
| data44     = {{{benches|}}}&lt;br /&gt;
&lt;br /&gt;
| label45    = Settlements&lt;br /&gt;
| data45     = {{if empty|{{{settlements|}}}|{{{cities|}}}}}&lt;br /&gt;
&lt;br /&gt;
| label46    = Website&lt;br /&gt;
| data46     = {{{website|}}}&lt;br /&gt;
&lt;br /&gt;
| label47    = References&lt;br /&gt;
| class47    = note&lt;br /&gt;
| data47     = {{{reference|}}}&lt;br /&gt;
&lt;br /&gt;
| header48   = {{{extra|}}}{{{nrhp|}}}{{{embedded|}}}{{{module|}}}&lt;br /&gt;
&lt;br /&gt;
| header50   = {{if either | {{{mapframe|}}} | {{#if:{{{image_map|}}}{{{pushpin_map|}}}||{{{coordinates|}}}}} |&lt;br /&gt;
 Location&lt;br /&gt;
}}&lt;br /&gt;
| data51     = {{#invoke:Infobox mapframe&lt;br /&gt;
        |autoWithCaption&lt;br /&gt;
        | onByDefault={{#if:{{{image_map|}}}{{{pushpin_map|}}}|no|yes}}&lt;br /&gt;
        | mapframe-frame-width = 264&lt;br /&gt;
        | mapframe-marker = water&lt;br /&gt;
        | mapframe-type = waterbody&lt;br /&gt;
        | mapframe-stroke-color = #0000ff&lt;br /&gt;
        | mapframe-stroke-width = 2&lt;br /&gt;
        | mapframe-wikidata = yes&lt;br /&gt;
        | mapframe-caption = Interactive map of {{if empty|{{{name|}}}|{{PAGENAMEBASE}}}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
| belowstyle = border-bottom: 1px solid #cedeff; border-top: 1px solid #cedeff&lt;br /&gt;
| below      = {{#if:{{{shore|}}}|&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt; Shore length is [[Coastline paradox|not a well-defined measure]].}}&lt;br /&gt;
}}{{#invoke:Infobox body of water tracking|tracking}}{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using infobox body of water with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:Infobox body of water]] with unknown parameter &amp;quot;_VALUE_&amp;quot;|ignoreblank=y|mapframe_args=y| agency | align | alt | alt_bathymetry | alt_map | area | basin_countries | bathymetry_size | benches | caption | caption_bathymetry | caption_map | catchment | child | cities | coordinates | coordinates_footnotes | coords | countries | dam_name | date-built | date-flooded | depth | designation | elevation | embed | embedded | engineer | etymology | extra | frozen | group | image | image_bathymetry | image_map | image_size | inflow | islands | islands_category | lake_type | length | location | map_size | max-depth | min_width | module | name | native_name | nrhp | ocean_type | oceans | other_name | outflow | parent | part_of | pushpin_image | pushpin_label | pushpin_label_position | pushpin_map | pushpin_map_alt | pushpin_map_caption | pushpin_mapsize | pushpin_relief | reference | residence_time | rivers | salinity | sections | settlements | shore | temperature_high | temperature_low | trenches | type | volume | website | width }}{{#invoke:Check for conflicting parameters|check&lt;br /&gt;
| template = [[Template:Infobox body of water]]&lt;br /&gt;
| cat = {{main other|Category:Pages using infobox body of water with conflicting parameters}}&lt;br /&gt;
| lake_type; ocean_type; type &lt;br /&gt;
| child; embed &lt;br /&gt;
| coordinates; coords &lt;br /&gt;
| part_of; parent &lt;br /&gt;
| basin_countries; countries &lt;br /&gt;
| settlements; cities &lt;br /&gt;
}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Documentation}}&lt;br /&gt;
&amp;lt;!--Please add this template&#039;s categories to the /doc subpage, not here - thanks!--&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Template:Infobox_Chinese&amp;diff=5295</id>
		<title>Template:Infobox Chinese</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Template:Infobox_Chinese&amp;diff=5295"/>
		<updated>2026-06-15T02:42:00Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync current Andaman Sea dependency from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{{#invoke:infobox|infoboxTemplate&lt;br /&gt;
|above={{{title|{{PAGENAMEBASE}}}}}&lt;br /&gt;
|bodyclass={{#ifeq:{{{collapse|}}}|yes|mw-collapsible mw-collapsed}}&lt;br /&gt;
|abovestyle=color: var(--color-base,#202122);background-color: var(--background-color-interactive-subtle,{{{headercolor|#b0c4de}}});&lt;br /&gt;
|rowstyle1=display:none;&lt;br /&gt;
||child={{{child|}}}&lt;br /&gt;
|data1={{#invoke:Infobox multi-lingual name|ibox_mln}}&lt;br /&gt;
}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&amp;lt;!-- Add categories to the /doc subpage, not here!  --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Template:Infobox_sea&amp;diff=5294</id>
		<title>Template:Infobox sea</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Template:Infobox_sea&amp;diff=5294"/>
		<updated>2026-06-15T02:41:59Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync current Andaman Sea dependency from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Template:Infobox body of water]]&lt;br /&gt;
&lt;br /&gt;
{{Rcat shell|{{R from template shortcut}}}}&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Template:Infobox&amp;diff=5293</id>
		<title>Template:Infobox</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Template:Infobox&amp;diff=5293"/>
		<updated>2026-06-15T02:41:57Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync current Andaman Sea dependency from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#invoke:Infobox|infobox}}&amp;lt;includeonly&amp;gt;{{template other|{{#ifeq:{{PAGENAME}}|Infobox||{{#ifeq:{{str left|{{SUBPAGENAME}}|7}}|Infobox|[[Category:Infobox templates|{{remove first word|{{SUBPAGENAME}}}}]]}}}}|}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;!-- Categories go in the /doc subpage, and interwikis go in Wikidata. --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Template:If_either&amp;diff=5292</id>
		<title>Template:If either</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Template:If_either&amp;diff=5292"/>
		<updated>2026-06-15T02:41:56Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync current Andaman Sea dependency from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{safesubst:&amp;lt;noinclude/&amp;gt;#if:{{{1|}}}&lt;br /&gt;
 |{{{then|{{{3|}}}}}}&lt;br /&gt;
 |{{safesubst:&amp;lt;noinclude/&amp;gt;#if:{{{2|}}}&lt;br /&gt;
  |{{{then|{{{3|}}}}}}&lt;br /&gt;
  |{{{else|{{{4|}}}}}}&lt;br /&gt;
 }}&lt;br /&gt;
}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Documentation}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Template:ISSN&amp;diff=5291</id>
		<title>Template:ISSN</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Template:ISSN&amp;diff=5291"/>
		<updated>2026-06-15T02:41:55Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Sync current Andaman Sea dependency from Phuketer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{{#invoke:CS1 identifiers|main|_template=issn}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Module:Citation/CS1/COinS&amp;diff=5290</id>
		<title>Module:Citation/CS1/COinS</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Module:Citation/CS1/COinS&amp;diff=5290"/>
		<updated>2026-06-14T10:39:02Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Shared ABC wiki patch: guard CS1 COinS author metadata when citation has no author&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--[[--------------------------&amp;lt; F O R W A R D   D E C L A R A T I O N S &amp;gt;--------------------------------------&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local has_accept_as_written, is_set, in_array, remove_wiki_link, strip_apostrophe_markup;	-- functions in Module:Citation/CS1/Utilities&lt;br /&gt;
&lt;br /&gt;
local cfg;																		-- table of configuration tables that are defined in Module:Citation/CS1/Configuration&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; M A K E _ C O I N S _ T I T L E &amp;gt;----------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Makes a title for COinS from Title and / or ScriptTitle (or any other name-script pairs)&lt;br /&gt;
&lt;br /&gt;
Apostrophe markup (bold, italics) is stripped from each value so that the COinS metadata isn&#039;t corrupted with strings&lt;br /&gt;
of %27%27...&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function make_coins_title (title, script)&lt;br /&gt;
	title = has_accept_as_written (title);&lt;br /&gt;
	if is_set (title) then&lt;br /&gt;
		title = strip_apostrophe_markup (title);								-- strip any apostrophe markup&lt;br /&gt;
	else&lt;br /&gt;
		title = &#039;&#039;;																-- if not set, make sure title is an empty string&lt;br /&gt;
	end&lt;br /&gt;
	if is_set (script) then&lt;br /&gt;
		script = script:gsub (&#039;^%l%l%s*:%s*&#039;, &#039;&#039;);								-- remove language prefix if present (script value may now be empty string)&lt;br /&gt;
		script = strip_apostrophe_markup (script);								-- strip any apostrophe markup&lt;br /&gt;
	else&lt;br /&gt;
		script = &#039;&#039;;															-- if not set, make sure script is an empty string&lt;br /&gt;
	end&lt;br /&gt;
	if is_set (title) and is_set (script) then&lt;br /&gt;
		script = &#039; &#039; .. script;													-- add a space before we concatenate&lt;br /&gt;
	end&lt;br /&gt;
	return title .. script;														-- return the concatenation&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; E S C A P E _ L U A _ M A G I C _ C H A R S &amp;gt;----------------------------------&lt;br /&gt;
&lt;br /&gt;
Returns a string where all of Lua&#039;s magic characters have been escaped.  This is important because functions like&lt;br /&gt;
string.gsub() treat their pattern and replace strings as patterns, not literal strings.&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function escape_lua_magic_chars (argument)&lt;br /&gt;
	argument = argument:gsub(&amp;quot;%%&amp;quot;, &amp;quot;%%%%&amp;quot;);										-- replace % with %%&lt;br /&gt;
	argument = argument:gsub(&amp;quot;([%^%$%(%)%.%[%]%*%+%-%?])&amp;quot;, &amp;quot;%%%1&amp;quot;);				-- replace all other Lua magic pattern characters&lt;br /&gt;
	return argument;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; G E T _ C O I N S _ P A G E S &amp;gt;------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Extract page numbers from external wikilinks in any of the |page=, |pages=, or |at= parameters for use in COinS.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function get_coins_pages (pages)&lt;br /&gt;
	local pattern;&lt;br /&gt;
	if not is_set (pages) then return pages; end								-- if no page numbers then we&#039;re done&lt;br /&gt;
	&lt;br /&gt;
	while true do&lt;br /&gt;
		pattern = pages:match(&amp;quot;%[(%w*:?//[^ ]+%s+)[%w%d].*%]&amp;quot;);					-- pattern is the opening bracket, the URL and following space(s): &amp;quot;[url &amp;quot;&lt;br /&gt;
		if nil == pattern then break; end										-- no more URLs&lt;br /&gt;
		pattern = escape_lua_magic_chars (pattern);								-- pattern is not a literal string; escape Lua&#039;s magic pattern characters&lt;br /&gt;
		pages = pages:gsub(pattern, &amp;quot;&amp;quot;);										-- remove as many instances of pattern as possible&lt;br /&gt;
	end&lt;br /&gt;
	pages = pages:gsub(&amp;quot;[%[%]]&amp;quot;, &amp;quot;&amp;quot;);											-- remove the brackets&lt;br /&gt;
	pages = pages:gsub(&amp;quot;–&amp;quot;, &amp;quot;-&amp;quot; );												-- replace endashes with hyphens&lt;br /&gt;
	pages = pages:gsub(&amp;quot;&amp;amp;%w+;&amp;quot;, &amp;quot;-&amp;quot; );											-- and replace HTML entities (&amp;amp;ndash; etc.) with hyphens; do we need to replace numerical entities like &amp;amp;#32; and the like?&lt;br /&gt;
	return pages;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[=[-------------------------&amp;lt; C O I N S _ R E P L A C E _ M A T H _ S T R I P M A R K E R &amp;gt;------------------&lt;br /&gt;
&lt;br /&gt;
There are three options for math markup rendering that depend on the editor&#039;s math preference settings.  These&lt;br /&gt;
settings are at [[Special:Preferences#mw-prefsection-rendering]] and are&lt;br /&gt;
	PNG images&lt;br /&gt;
	TeX source&lt;br /&gt;
	MathML with SVG or PNG fallback&lt;br /&gt;
&lt;br /&gt;
All three are heavy with HTML and CSS which doesn&#039;t belong in the metadata.&lt;br /&gt;
&lt;br /&gt;
Without this function, the metadata saved in the raw wikitext contained the rendering determined by the settings&lt;br /&gt;
of the last editor to save the page.&lt;br /&gt;
&lt;br /&gt;
This function gets the rendered form of an equation according to the editor&#039;s preference before the page is saved.  It&lt;br /&gt;
then searches the rendering for the text equivalent of the rendered equation and replaces the rendering with that so&lt;br /&gt;
that the page is saved without extraneous HTML/CSS markup and with a reasonably readable text form of the equation.&lt;br /&gt;
&lt;br /&gt;
When a replacement is made, this function returns true and the value with replacement; otherwise false and the initial&lt;br /&gt;
value.  To replace multipe equations it is necessary to call this function from within a loop.&lt;br /&gt;
&lt;br /&gt;
]=]&lt;br /&gt;
&lt;br /&gt;
local function coins_replace_math_stripmarker (value)&lt;br /&gt;
	local stripmarker = cfg.stripmarkers[&#039;math&#039;];&lt;br /&gt;
	local rendering = value:match (stripmarker);								-- is there a math stripmarker&lt;br /&gt;
&lt;br /&gt;
	if not rendering then														-- when value doesn&#039;t have a math stripmarker, abandon this test&lt;br /&gt;
		return false, value;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	rendering = mw.text.unstripNoWiki (rendering);								-- convert stripmarker into rendered value (or nil? &#039;&#039;? when math render error)&lt;br /&gt;
	&lt;br /&gt;
	if rendering:match (&#039;alt=&amp;quot;[^&amp;quot;]+&amp;quot;&#039;) then										-- if PNG math option&lt;br /&gt;
		rendering = rendering:match (&#039;alt=&amp;quot;([^&amp;quot;]+)&amp;quot;&#039;);							-- extract just the math text&lt;br /&gt;
	elseif rendering:match (&#039;$%s+.+%s+%$&#039;) then									-- if TeX math option; $ is legit character that is escapes as \$&lt;br /&gt;
		rendering = rendering:match (&#039;$%s+(.+)%s+%$&#039;)							-- extract just the math text&lt;br /&gt;
	elseif rendering:match (&#039;&amp;lt;annotation[^&amp;gt;]+&amp;gt;.+&amp;lt;/annotation&amp;gt;&#039;) then			-- if MathML math option&lt;br /&gt;
		rendering = rendering:match (&#039;&amp;lt;annotation[^&amp;gt;]+&amp;gt;(.+)&amp;lt;/annotation&amp;gt;&#039;)		-- extract just the math text&lt;br /&gt;
	else&lt;br /&gt;
		return false, value;													-- had math stripmarker but not one of the three defined forms&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return true, value:gsub (stripmarker, rendering, 1);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; C O I N S _ C L E A N U P &amp;gt;----------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Cleanup parameter values for the metadata by removing or replacing invisible characters and certain HTML entities.&lt;br /&gt;
&lt;br /&gt;
2015-12-10: there is a bug in mw.text.unstripNoWiki ().  It replaces math stripmarkers with the appropriate content&lt;br /&gt;
when it shouldn&#039;t.  See https://phabricator.wikimedia.org/T121085 and Wikipedia_talk:Lua#stripmarkers_and_mw.text.unstripNoWiki.28.29&lt;br /&gt;
&lt;br /&gt;
TODO: move the replacement patterns and replacement values into a table in /Configuration similar to the invisible&lt;br /&gt;
characters table?&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function coins_cleanup (value)&lt;br /&gt;
	local replaced = true;														-- default state to get the do loop running&lt;br /&gt;
&lt;br /&gt;
	while replaced do															-- loop until all math stripmarkers replaced&lt;br /&gt;
		replaced, value = coins_replace_math_stripmarker (value);				-- replace math stripmarker with text representation of the equation&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	value = value:gsub (cfg.stripmarkers[&#039;math&#039;], &amp;quot;MATH RENDER ERROR&amp;quot;);			-- one or more couldn&#039;t be replaced; insert vague error message&lt;br /&gt;
	&lt;br /&gt;
	value = mw.text.unstripNoWiki (value);										-- replace nowiki stripmarkers with their content&lt;br /&gt;
	value = value:gsub (&#039;&amp;lt;span class=&amp;quot;nowrap&amp;quot; style=&amp;quot;padding%-left:0%.1em;&amp;quot;&amp;gt;&amp;amp;#39;(s?)&amp;lt;/span&amp;gt;&#039;, &amp;quot;&#039;%1&amp;quot;);	-- replace {{&#039;}} or {{&#039;s}} with simple apostrophe or apostrophe-s&lt;br /&gt;
	value = value:gsub (&#039;&amp;amp;nbsp;&#039;, &#039; &#039;);											-- replace &amp;amp;nbsp; entity with plain space&lt;br /&gt;
	value = value:gsub (&#039;\226\128\138&#039;, &#039; &#039;);									-- replace hair space with plain space&lt;br /&gt;
	if not mw.ustring.find (value, cfg.indic_script) then						-- don&#039;t remove zero-width joiner characters from indic script&lt;br /&gt;
		value = value:gsub (&#039;&amp;amp;zwj;&#039;, &#039;&#039;);										-- remove &amp;amp;zwj; entities&lt;br /&gt;
		value = mw.ustring.gsub (value, &#039;[\226\128\141\226\128\139\194\173]&#039;, &#039;&#039;);	-- remove zero-width joiner, zero-width space, soft hyphen&lt;br /&gt;
	end&lt;br /&gt;
	value = value:gsub (&#039;[\009\010\013 ]+&#039;, &#039; &#039;);								-- replace horizontal tab, line feed, carriage return with plain space&lt;br /&gt;
	return value;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; C O I N S &amp;gt;--------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
COinS metadata (see &amp;lt;http://ocoins.info/&amp;gt;) allows automated tools to parse the citation information.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function COinS(data, class)&lt;br /&gt;
	if &#039;table&#039; ~= type(data) or nil == next(data) then&lt;br /&gt;
		return &#039;&#039;;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for k, v in pairs (data) do													-- spin through all of the metadata parameter values&lt;br /&gt;
		if &#039;ID_list&#039; ~= k and &#039;Authors&#039; ~= k then								-- except the ID_list and Author tables (author nowiki stripmarker done when Author table processed)&lt;br /&gt;
			data[k] = coins_cleanup (v);&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local ctx_ver = &amp;quot;Z39.88-2004&amp;quot;;&lt;br /&gt;
	&lt;br /&gt;
	-- treat table strictly as an array with only set values.&lt;br /&gt;
	local OCinSoutput = setmetatable( {}, {&lt;br /&gt;
		__newindex = function(self, key, value)&lt;br /&gt;
			if is_set(value) then&lt;br /&gt;
				rawset( self, #self+1, table.concat{ key, &#039;=&#039;, mw.uri.encode( remove_wiki_link( value ) ) } );&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	if in_array (class, {&#039;arxiv&#039;, &#039;biorxiv&#039;, &#039;citeseerx&#039;, &#039;ssrn&#039;, &#039;journal&#039;, &#039;news&#039;, &#039;magazine&#039;}) or&lt;br /&gt;
		(in_array (class, {&#039;conference&#039;, &#039;interview&#039;, &#039;map&#039;, &#039;press release&#039;, &#039;web&#039;}) and is_set(data.Periodical)) or&lt;br /&gt;
		(&#039;citation&#039; == class and is_set(data.Periodical) and not is_set (data.Encyclopedia)) then&lt;br /&gt;
			OCinSoutput.rft_val_fmt = &amp;quot;info:ofi/fmt:kev:mtx:journal&amp;quot;;			-- journal metadata identifier&lt;br /&gt;
			if in_array (class, {&#039;arxiv&#039;, &#039;biorxiv&#039;, &#039;citeseerx&#039;, &#039;ssrn&#039;}) then	-- set genre according to the type of citation template we are rendering&lt;br /&gt;
				OCinSoutput[&amp;quot;rft.genre&amp;quot;] = &amp;quot;preprint&amp;quot;;							-- cite arxiv, cite biorxiv, cite citeseerx, cite ssrn&lt;br /&gt;
			elseif &#039;conference&#039; == class then&lt;br /&gt;
				OCinSoutput[&amp;quot;rft.genre&amp;quot;] = &amp;quot;conference&amp;quot;;						-- cite conference (when Periodical set)&lt;br /&gt;
			elseif &#039;web&#039; == class then&lt;br /&gt;
				OCinSoutput[&amp;quot;rft.genre&amp;quot;] = &amp;quot;unknown&amp;quot;;							-- cite web (when Periodical set)&lt;br /&gt;
			else&lt;br /&gt;
				OCinSoutput[&amp;quot;rft.genre&amp;quot;] = &amp;quot;article&amp;quot;;							-- journal and other &#039;periodical&#039; articles&lt;br /&gt;
			end&lt;br /&gt;
			OCinSoutput[&amp;quot;rft.jtitle&amp;quot;] = data.Periodical;						-- journal only&lt;br /&gt;
			OCinSoutput[&amp;quot;rft.atitle&amp;quot;] = data.Title;								-- &#039;periodical&#039; article titles&lt;br /&gt;
&lt;br /&gt;
																				-- these used only for periodicals&lt;br /&gt;
			OCinSoutput[&amp;quot;rft.ssn&amp;quot;] = data.Season;								-- keywords: winter, spring, summer, fall&lt;br /&gt;
			OCinSoutput[&amp;quot;rft.quarter&amp;quot;] = data.Quarter;							-- single digits 1-&amp;gt;first quarter, etc.&lt;br /&gt;
			OCinSoutput[&amp;quot;rft.chron&amp;quot;] = data.Chron;								-- free-form date components&lt;br /&gt;
			OCinSoutput[&amp;quot;rft.volume&amp;quot;] = data.Volume;							-- does not apply to books&lt;br /&gt;
			OCinSoutput[&amp;quot;rft.issue&amp;quot;] = data.Issue;&lt;br /&gt;
			OCinSoutput[&#039;rft.artnum&#039;] = data.ArticleNumber;						-- {{cite journal}} only&lt;br /&gt;
			OCinSoutput[&amp;quot;rft.pages&amp;quot;] = data.Pages;								-- also used in book metadata&lt;br /&gt;
&lt;br /&gt;
	elseif &#039;thesis&#039; ~= class then												-- all others except cite thesis are treated as &#039;book&#039; metadata; genre distinguishes&lt;br /&gt;
		OCinSoutput.rft_val_fmt = &amp;quot;info:ofi/fmt:kev:mtx:book&amp;quot;;					-- book metadata identifier&lt;br /&gt;
		if &#039;report&#039; == class or &#039;techreport&#039; == class then						-- cite report and cite techreport&lt;br /&gt;
			OCinSoutput[&amp;quot;rft.genre&amp;quot;] = &amp;quot;report&amp;quot;;&lt;br /&gt;
		elseif &#039;conference&#039; == class then										-- cite conference when Periodical not set&lt;br /&gt;
			OCinSoutput[&amp;quot;rft.genre&amp;quot;] = &amp;quot;conference&amp;quot;;&lt;br /&gt;
			OCinSoutput[&amp;quot;rft.atitle&amp;quot;] = data.Chapter;							-- conference paper as chapter in proceedings (book)&lt;br /&gt;
		elseif in_array (class, {&#039;book&#039;, &#039;citation&#039;, &#039;encyclopaedia&#039;, &#039;interview&#039;, &#039;map&#039;}) then&lt;br /&gt;
			if is_set (data.Chapter) then&lt;br /&gt;
				OCinSoutput[&amp;quot;rft.genre&amp;quot;] = &amp;quot;bookitem&amp;quot;;&lt;br /&gt;
				OCinSoutput[&amp;quot;rft.atitle&amp;quot;] = data.Chapter;						-- book chapter, encyclopedia article, interview in a book, or map title&lt;br /&gt;
			else&lt;br /&gt;
				if &#039;map&#039; == class or &#039;interview&#039; == class then&lt;br /&gt;
					OCinSoutput[&amp;quot;rft.genre&amp;quot;] = &#039;unknown&#039;;						-- standalone map or interview&lt;br /&gt;
				else&lt;br /&gt;
					OCinSoutput[&amp;quot;rft.genre&amp;quot;] = &#039;book&#039;;							-- book and encyclopedia&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		else	-- {&#039;audio-visual&#039;, &#039;AV-media-notes&#039;, &#039;DVD-notes&#039;, &#039;episode&#039;, &#039;interview&#039;, &#039;mailinglist&#039;, &#039;map&#039;, &#039;newsgroup&#039;, &#039;podcast&#039;, &#039;press release&#039;, &#039;serial&#039;, &#039;sign&#039;, &#039;speech&#039;, &#039;web&#039;}&lt;br /&gt;
			OCinSoutput[&amp;quot;rft.genre&amp;quot;] = &amp;quot;unknown&amp;quot;;&lt;br /&gt;
		end&lt;br /&gt;
		OCinSoutput[&amp;quot;rft.btitle&amp;quot;] = data.Title;									-- book only&lt;br /&gt;
		OCinSoutput[&amp;quot;rft.place&amp;quot;] = data.PublicationPlace;						-- book only&lt;br /&gt;
		OCinSoutput[&amp;quot;rft.series&amp;quot;] = data.Series;								-- book only&lt;br /&gt;
		OCinSoutput[&amp;quot;rft.pages&amp;quot;] = data.Pages;									-- book, journal&lt;br /&gt;
		OCinSoutput[&amp;quot;rft.edition&amp;quot;] = data.Edition;								-- book only&lt;br /&gt;
		OCinSoutput[&amp;quot;rft.pub&amp;quot;] = data.PublisherName;							-- book and dissertation&lt;br /&gt;
		&lt;br /&gt;
	else																		-- cite thesis&lt;br /&gt;
		OCinSoutput.rft_val_fmt = &amp;quot;info:ofi/fmt:kev:mtx:dissertation&amp;quot;;			-- dissertation metadata identifier&lt;br /&gt;
		OCinSoutput[&amp;quot;rft.title&amp;quot;] = data.Title;									-- dissertation (also patent but that is not yet supported)&lt;br /&gt;
		OCinSoutput[&amp;quot;rft.degree&amp;quot;] = data.Degree;								-- dissertation only&lt;br /&gt;
		OCinSoutput[&#039;rft.inst&#039;] = data.PublisherName;							-- book and dissertation&lt;br /&gt;
	end&lt;br /&gt;
	-- NB. Not currently supported are &amp;quot;info:ofi/fmt:kev:mtx:patent&amp;quot;, &amp;quot;info:ofi/fmt:kev:mtx:dc&amp;quot;, &amp;quot;info:ofi/fmt:kev:mtx:sch_svc&amp;quot;, &amp;quot;info:ofi/fmt:kev:mtx:ctx&amp;quot;&lt;br /&gt;
																				-- and now common parameters (as much as possible)&lt;br /&gt;
	OCinSoutput[&amp;quot;rft.date&amp;quot;] = data.Date;										-- book, journal, dissertation&lt;br /&gt;
&lt;br /&gt;
	for k, v in pairs( data.ID_list ) do										-- what to do about these? For now assume that they are common to all?&lt;br /&gt;
		if k == &#039;ISBN&#039; then v = v:gsub( &amp;quot;[^-0-9X]&amp;quot;, &amp;quot;&amp;quot; ); end&lt;br /&gt;
		local id = cfg.id_handlers[k].COinS;&lt;br /&gt;
		if string.sub( id or &amp;quot;&amp;quot;, 1, 4 ) == &#039;info&#039; then							-- for ids that are in the info:registry&lt;br /&gt;
			OCinSoutput[&amp;quot;rft_id&amp;quot;] = table.concat{ id, &amp;quot;/&amp;quot;, v };&lt;br /&gt;
		elseif string.sub (id or &amp;quot;&amp;quot;, 1, 3 ) == &#039;rft&#039; then						-- for isbn, issn, eissn, etc. that have defined COinS keywords&lt;br /&gt;
			OCinSoutput[ id ] = v;&lt;br /&gt;
		elseif &#039;url&#039; == id then													-- for urls that are assembled in ~/Identifiers; |asin= and |ol=&lt;br /&gt;
			OCinSoutput[&amp;quot;rft_id&amp;quot;] = table.concat ({data.ID_list[k], &amp;quot;#id-name=&amp;quot;, cfg.id_handlers[k].label});&lt;br /&gt;
		elseif id then															-- when cfg.id_handlers[k].COinS is not nil so urls created here&lt;br /&gt;
			OCinSoutput[&amp;quot;rft_id&amp;quot;] = table.concat{ cfg.id_handlers[k].prefix, v, cfg.id_handlers[k].suffix or &#039;&#039;, &amp;quot;#id-name=&amp;quot;, cfg.id_handlers[k].label };	-- others; provide a URL and indicate identifier name as #fragment (human-readable, but transparent to browsers)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local last, first;&lt;br /&gt;
	for k, v in ipairs( data.Authors or {} ) do&lt;br /&gt;
		last, first = coins_cleanup (v.last), coins_cleanup (v.first or &#039;&#039;);	-- replace any nowiki stripmarkers, non-printing or invisible characters&lt;br /&gt;
		if k == 1 then															-- for the first author name only&lt;br /&gt;
			if is_set(last) and is_set(first) then								-- set these COinS values if |first= and |last= specify the first author name&lt;br /&gt;
				OCinSoutput[&amp;quot;rft.aulast&amp;quot;] = last;								-- book, journal, dissertation&lt;br /&gt;
				OCinSoutput[&amp;quot;rft.aufirst&amp;quot;] = first;								-- book, journal, dissertation&lt;br /&gt;
			elseif is_set(last) then &lt;br /&gt;
				OCinSoutput[&amp;quot;rft.au&amp;quot;] = last;									-- book, journal, dissertation -- otherwise use this form for the first name&lt;br /&gt;
			end&lt;br /&gt;
		else																	-- for all other authors&lt;br /&gt;
			if is_set(last) and is_set(first) then&lt;br /&gt;
				OCinSoutput[&amp;quot;rft.au&amp;quot;] = table.concat{ last, &amp;quot;, &amp;quot;, first };		-- book, journal, dissertation&lt;br /&gt;
			elseif is_set(last) then&lt;br /&gt;
				OCinSoutput[&amp;quot;rft.au&amp;quot;] = last;									-- book, journal, dissertation&lt;br /&gt;
			end&lt;br /&gt;
			-- TODO: At present we do not report &amp;quot;et al.&amp;quot;. Add anything special if this condition applies?&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	OCinSoutput.rft_id = data.URL;&lt;br /&gt;
	OCinSoutput.rfr_id = table.concat{ &amp;quot;info:sid/&amp;quot;, mw.site.server:match( &amp;quot;[^/]*$&amp;quot; ), &amp;quot;:&amp;quot;, data.RawPage };&lt;br /&gt;
&lt;br /&gt;
	-- TODO: Add optional extra info:&lt;br /&gt;
	-- rfr_dat=#REVISION&amp;lt;version&amp;gt; (referrer private data)&lt;br /&gt;
	-- ctx_id=&amp;lt;data.RawPage&amp;gt;#&amp;lt;ref&amp;gt; (identifier for the context object)&lt;br /&gt;
	-- ctx_tim=&amp;lt;ts&amp;gt; (timestamp in format yyyy-mm-ddThh:mm:ssTZD or yyyy-mm-dd)&lt;br /&gt;
	-- ctx_enc=info:ofi/enc:UTF-8 (character encoding)&lt;br /&gt;
	&lt;br /&gt;
	OCinSoutput = setmetatable( OCinSoutput, nil );&lt;br /&gt;
&lt;br /&gt;
	-- sort with version string always first, and combine.&lt;br /&gt;
	-- table.sort( OCinSoutput );&lt;br /&gt;
	table.insert( OCinSoutput, 1, &amp;quot;ctx_ver=&amp;quot; .. ctx_ver ); -- such as &amp;quot;Z39.88-2004&amp;quot;&lt;br /&gt;
	return table.concat(OCinSoutput, &amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; S E T _ S E L E C T E D _ M O D U L E S &amp;gt;--------------------------------------&lt;br /&gt;
&lt;br /&gt;
Sets local cfg table and imported functions table to same (live or sandbox) as that used by the other modules.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function set_selected_modules (cfg_table_ptr, utilities_page_ptr)&lt;br /&gt;
	cfg = cfg_table_ptr;&lt;br /&gt;
&lt;br /&gt;
	has_accept_as_written = utilities_page_ptr.has_accept_as_written;			-- import functions from selected Module:Citation/CS1/Utilities module&lt;br /&gt;
	is_set = utilities_page_ptr.is_set;&lt;br /&gt;
	in_array = utilities_page_ptr.in_array;&lt;br /&gt;
	remove_wiki_link = utilities_page_ptr.remove_wiki_link;&lt;br /&gt;
	strip_apostrophe_markup = utilities_page_ptr.strip_apostrophe_markup;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; E X P O R T E D   F U N C T I O N S &amp;gt;------------------------------------------&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
return {&lt;br /&gt;
	make_coins_title = make_coins_title,&lt;br /&gt;
	get_coins_pages = get_coins_pages,&lt;br /&gt;
	COinS = COinS,&lt;br /&gt;
	set_selected_modules = set_selected_modules,&lt;br /&gt;
	}&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://montepedia.com/w/index.php?title=Module:Coordinates&amp;diff=5289</id>
		<title>Module:Coordinates</title>
		<link rel="alternate" type="text/html" href="https://montepedia.com/w/index.php?title=Module:Coordinates&amp;diff=5289"/>
		<updated>2026-06-14T08:32:25Z</updated>

		<summary type="html">&lt;p&gt;Maintenance script: Shared ABC wiki patch: make Module:Coordinates work without Wikibase Client&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--[[&lt;br /&gt;
This module is intended to replace the functionality of {{Coord}} and related&lt;br /&gt;
templates.  It provides several methods, including&lt;br /&gt;
&lt;br /&gt;
{{#invoke:Coordinates | coord }} : General function formatting and displaying&lt;br /&gt;
coordinate values.&lt;br /&gt;
&lt;br /&gt;
{{#invoke:Coordinates | dec2dms }} : Simple function for converting decimal&lt;br /&gt;
degree values to DMS format.&lt;br /&gt;
&lt;br /&gt;
{{#invoke:Coordinates | dms2dec }} : Simple function for converting DMS format&lt;br /&gt;
to decimal degree format.&lt;br /&gt;
&lt;br /&gt;
{{#invoke:Coordinates | link }} : Export the link used to reach the tools&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
require(&#039;strict&#039;)&lt;br /&gt;
&lt;br /&gt;
local math_mod = require(&amp;quot;Module:Math&amp;quot;)&lt;br /&gt;
local coordinates = {};&lt;br /&gt;
local isSandbox = mw.getCurrentFrame():getTitle():find(&#039;sandbox&#039;, 1, true);&lt;br /&gt;
&lt;br /&gt;
local current_page = mw.title.getCurrentTitle()&lt;br /&gt;
local page_name = mw.uri.encode( current_page.prefixedText, &#039;WIKI&#039; );&lt;br /&gt;
local coord_link = &#039;https://geohack.toolforge.org/geohack.php?pagename=&#039; .. page_name .. &#039;&amp;amp;params=&#039;&lt;br /&gt;
&lt;br /&gt;
--[[ Helper function, replacement for {{coord/display/title}} ]]&lt;br /&gt;
local function displaytitle(coords)&lt;br /&gt;
	return mw.getCurrentFrame():extensionTag{&lt;br /&gt;
		name = &#039;indicator&#039;,&lt;br /&gt;
		args = { name = &#039;coordinates&#039; },&lt;br /&gt;
		content = &#039;&amp;lt;span id=&amp;quot;coordinates&amp;quot;&amp;gt;[[Geographic coordinate system|Coordinates]]: &#039; .. coords .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[ Helper function, used in detecting DMS formatting ]]&lt;br /&gt;
local function dmsTest(first, second)&lt;br /&gt;
	if type(first) ~= &#039;string&#039; or type(second) ~= &#039;string&#039; then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	local s = (first .. second):upper()&lt;br /&gt;
	return s:find(&#039;^[NS][EW]$&#039;) or s:find(&#039;^[EW][NS]$&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[ Wrapper function to grab args, see Module:Arguments for this function&#039;s documentation. ]]&lt;br /&gt;
local function makeInvokeFunc(funcName)&lt;br /&gt;
	return function (frame)&lt;br /&gt;
		local args = require(&#039;Module:Arguments&#039;).getArgs(frame, {&lt;br /&gt;
			wrappers = &#039;Template:Coord&#039;&lt;br /&gt;
		})&lt;br /&gt;
		return coordinates[funcName](args, frame)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[ Helper function, handle optional args. ]]&lt;br /&gt;
local function optionalArg(arg, supplement)&lt;br /&gt;
	return arg and arg .. supplement or &#039;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Formats any error messages generated for display&lt;br /&gt;
]]&lt;br /&gt;
local function errorPrinter(errors)&lt;br /&gt;
	local result = &amp;quot;&amp;quot;&lt;br /&gt;
	for i,v in ipairs(errors) do&lt;br /&gt;
		result = result .. &#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;Coordinates: &#039; .. v[2] .. &#039;&amp;lt;/strong&amp;gt;&amp;lt;br /&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Determine the required CSS class to display coordinates&lt;br /&gt;
&lt;br /&gt;
Usually geo-nondefault is hidden by CSS, unless a user has overridden this for himself&lt;br /&gt;
default is the mode as specificied by the user when calling the {{coord}} template&lt;br /&gt;
mode is the display mode (dec or dms) that we will need to determine the css class for&lt;br /&gt;
]]&lt;br /&gt;
local function displayDefault(default, mode)&lt;br /&gt;
	if default == &amp;quot;&amp;quot; then&lt;br /&gt;
		default = &amp;quot;dec&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if default == mode then&lt;br /&gt;
		return &amp;quot;geo-default&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		return &amp;quot;geo-nondefault&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
specPrinter&lt;br /&gt;
&lt;br /&gt;
Output formatter.  Takes the structure generated by either parseDec&lt;br /&gt;
or parseDMS and formats it for inclusion on Wikipedia.&lt;br /&gt;
]]&lt;br /&gt;
local function specPrinter(args, coordinateSpec)&lt;br /&gt;
	local uriComponents = coordinateSpec[&amp;quot;param&amp;quot;]&lt;br /&gt;
	if uriComponents == &amp;quot;&amp;quot; then&lt;br /&gt;
		-- RETURN error, should never be empty or nil&lt;br /&gt;
		return &amp;quot;ERROR param was empty&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	if args[&amp;quot;name&amp;quot;] then&lt;br /&gt;
		uriComponents = uriComponents .. &amp;quot;&amp;amp;title=&amp;quot; .. mw.uri.encode(coordinateSpec[&amp;quot;name&amp;quot;])&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local geodmshtml = &#039;&amp;lt;span class=&amp;quot;geo-dms&amp;quot; title=&amp;quot;Maps, aerial photos, and other data for this location&amp;quot;&amp;gt;&#039;&lt;br /&gt;
			.. &#039;&amp;lt;span class=&amp;quot;latitude&amp;quot;&amp;gt;&#039; .. coordinateSpec[&amp;quot;dms-lat&amp;quot;] .. &#039;&amp;lt;/span&amp;gt; &#039;&lt;br /&gt;
			.. &#039;&amp;lt;span class=&amp;quot;longitude&amp;quot;&amp;gt;&#039; ..coordinateSpec[&amp;quot;dms-long&amp;quot;] .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
			.. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	local lat = tonumber( coordinateSpec[&amp;quot;dec-lat&amp;quot;] ) or 0&lt;br /&gt;
	local geodeclat&lt;br /&gt;
	if lat &amp;lt; 0 then&lt;br /&gt;
		-- FIXME this breaks the pre-existing precision&lt;br /&gt;
		geodeclat = tostring(coordinateSpec[&amp;quot;dec-lat&amp;quot;]):sub(2) .. &amp;quot;°S&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		geodeclat = (coordinateSpec[&amp;quot;dec-lat&amp;quot;] or 0) .. &amp;quot;°N&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local long = tonumber( coordinateSpec[&amp;quot;dec-long&amp;quot;] ) or 0&lt;br /&gt;
	local geodeclong&lt;br /&gt;
	if long &amp;lt; 0 then&lt;br /&gt;
		-- FIXME does not handle unicode minus&lt;br /&gt;
		geodeclong = tostring(coordinateSpec[&amp;quot;dec-long&amp;quot;]):sub(2) .. &amp;quot;°W&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		geodeclong = (coordinateSpec[&amp;quot;dec-long&amp;quot;] or 0) .. &amp;quot;°E&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local geodechtml = &#039;&amp;lt;span class=&amp;quot;geo-dec&amp;quot; title=&amp;quot;Maps, aerial photos, and other data for this location&amp;quot;&amp;gt;&#039;&lt;br /&gt;
			.. geodeclat .. &#039; &#039;&lt;br /&gt;
			.. geodeclong&lt;br /&gt;
			.. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	local geonumhtml = &#039;&amp;lt;span class=&amp;quot;geo&amp;quot;&amp;gt;&#039;&lt;br /&gt;
			.. coordinateSpec[&amp;quot;dec-lat&amp;quot;] .. &#039;; &#039;&lt;br /&gt;
			.. coordinateSpec[&amp;quot;dec-long&amp;quot;]&lt;br /&gt;
			.. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	local inner = &#039;&amp;lt;span class=&amp;quot;&#039; .. displayDefault(coordinateSpec[&amp;quot;default&amp;quot;], &amp;quot;dms&amp;quot; ) .. &#039;&amp;quot;&amp;gt;&#039; .. geodmshtml .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
				.. &#039;&amp;lt;span class=&amp;quot;geo-multi-punct&amp;quot;&amp;gt;&amp;amp;#xfeff; / &amp;amp;#xfeff;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
				.. &#039;&amp;lt;span class=&amp;quot;&#039; .. displayDefault(coordinateSpec[&amp;quot;default&amp;quot;], &amp;quot;dec&amp;quot; ) .. &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
	if not args[&amp;quot;name&amp;quot;] then&lt;br /&gt;
		inner = inner .. geodechtml&lt;br /&gt;
				.. &#039;&amp;lt;span style=&amp;quot;display:none&amp;quot;&amp;gt;&amp;amp;#xfeff; / &#039; .. geonumhtml .. &#039;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	else&lt;br /&gt;
		inner = inner .. &#039;&amp;lt;span class=&amp;quot;vcard&amp;quot;&amp;gt;&#039; .. geodechtml&lt;br /&gt;
				.. &#039;&amp;lt;span style=&amp;quot;display:none&amp;quot;&amp;gt;&amp;amp;#xfeff; / &#039; .. geonumhtml .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
				.. &#039;&amp;lt;span style=&amp;quot;display:none&amp;quot;&amp;gt;&amp;amp;#xfeff; (&amp;lt;span class=&amp;quot;fn org&amp;quot;&amp;gt;&#039;&lt;br /&gt;
				.. args[&amp;quot;name&amp;quot;] .. &#039;&amp;lt;/span&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
    local stylesheetLink = &#039;Module:Coordinates&#039; .. ( isSandbox and &#039;/sandbox&#039; or &#039;&#039; ) .. &#039;/styles.css&#039;&lt;br /&gt;
	return mw.getCurrentFrame():extensionTag{&lt;br /&gt;
		name = &#039;templatestyles&#039;, args = { src = stylesheetLink }&lt;br /&gt;
	} .. &#039;&amp;lt;span class=&amp;quot;plainlinks nourlexpansion&amp;quot;&amp;gt;[&#039; .. coord_link .. uriComponents ..&lt;br /&gt;
	&#039; &#039; .. inner .. &#039;]&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[ Helper function, convert decimal to degrees ]]&lt;br /&gt;
local function convert_dec2dms_d(coordinate)&lt;br /&gt;
	local d = math_mod._round( coordinate, 0 ) .. &amp;quot;°&amp;quot;&lt;br /&gt;
	return d .. &amp;quot;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[ Helper function, convert decimal to degrees and minutes ]]&lt;br /&gt;
local function convert_dec2dms_dm(coordinate)&lt;br /&gt;
	coordinate = math_mod._round( coordinate * 60, 0 );&lt;br /&gt;
	local m = coordinate % 60;&lt;br /&gt;
	coordinate = math.floor( (coordinate - m) / 60 );&lt;br /&gt;
	local d = coordinate % 360 ..&amp;quot;°&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	return d .. string.format( &amp;quot;%02d′&amp;quot;, m )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[ Helper function, convert decimal to degrees, minutes, and seconds ]]&lt;br /&gt;
local function convert_dec2dms_dms(coordinate)&lt;br /&gt;
	coordinate = math_mod._round( coordinate * 60 * 60, 0 );&lt;br /&gt;
	local s = coordinate % 60&lt;br /&gt;
	coordinate = math.floor( (coordinate - s) / 60 );&lt;br /&gt;
	local m = coordinate % 60&lt;br /&gt;
	coordinate = math.floor( (coordinate - m) / 60 );&lt;br /&gt;
	local d = coordinate % 360 ..&amp;quot;°&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	return d .. string.format( &amp;quot;%02d′&amp;quot;, m ) .. string.format( &amp;quot;%02d″&amp;quot;, s )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Helper function, convert decimal latitude or longitude to&lt;br /&gt;
degrees, minutes, and seconds format based on the specified precision.&lt;br /&gt;
]]&lt;br /&gt;
local function convert_dec2dms(coordinate, firstPostfix, secondPostfix, precision)&lt;br /&gt;
	local coord = tonumber(coordinate)&lt;br /&gt;
	local postfix&lt;br /&gt;
	if coord &amp;gt;= 0 then&lt;br /&gt;
		postfix = firstPostfix&lt;br /&gt;
	else&lt;br /&gt;
		postfix = secondPostfix&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	precision = precision:lower();&lt;br /&gt;
	if precision == &amp;quot;dms&amp;quot; then&lt;br /&gt;
		return convert_dec2dms_dms( math.abs( coord ) ) .. postfix;&lt;br /&gt;
	elseif precision == &amp;quot;dm&amp;quot; then&lt;br /&gt;
		return convert_dec2dms_dm( math.abs( coord ) ) .. postfix;&lt;br /&gt;
	elseif precision == &amp;quot;d&amp;quot; then&lt;br /&gt;
		return convert_dec2dms_d( math.abs( coord ) ) .. postfix;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Convert DMS format into a N or E decimal coordinate&lt;br /&gt;
]]&lt;br /&gt;
local function convert_dms2dec(direction, degrees_str, minutes_str, seconds_str)&lt;br /&gt;
	local degrees = tonumber(degrees_str)&lt;br /&gt;
	local minutes = tonumber(minutes_str) or 0&lt;br /&gt;
	local seconds = tonumber(seconds_str) or 0&lt;br /&gt;
&lt;br /&gt;
	local factor = 1&lt;br /&gt;
	if direction == &amp;quot;S&amp;quot; or direction == &amp;quot;W&amp;quot; then&lt;br /&gt;
		factor = -1&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local precision = 0&lt;br /&gt;
	if seconds_str then&lt;br /&gt;
		precision = 5 + math.max( math_mod._precision(seconds_str), 0 );&lt;br /&gt;
	elseif minutes_str and minutes_str ~= &#039;&#039; then&lt;br /&gt;
		precision = 3 + math.max( math_mod._precision(minutes_str), 0 );&lt;br /&gt;
	else&lt;br /&gt;
		precision = math.max( math_mod._precision(degrees_str), 0 );&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local decimal = factor * (degrees+(minutes+seconds/60)/60)&lt;br /&gt;
	return string.format( &amp;quot;%.&amp;quot; .. precision .. &amp;quot;f&amp;quot;, decimal ) -- not tonumber since this whole thing is string based.&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Checks input values to for out of range errors.&lt;br /&gt;
]]&lt;br /&gt;
local function validate( lat_d, lat_m, lat_s, long_d, long_m, long_s, source, strong )&lt;br /&gt;
	local errors = {};&lt;br /&gt;
	lat_d = tonumber( lat_d ) or 0;&lt;br /&gt;
	lat_m = tonumber( lat_m ) or 0;&lt;br /&gt;
	lat_s = tonumber( lat_s ) or 0;&lt;br /&gt;
	long_d = tonumber( long_d ) or 0;&lt;br /&gt;
	long_m = tonumber( long_m ) or 0;&lt;br /&gt;
	long_s = tonumber( long_s ) or 0;&lt;br /&gt;
&lt;br /&gt;
	if strong then&lt;br /&gt;
		if lat_d &amp;lt; 0 then&lt;br /&gt;
			table.insert(errors, {source, &amp;quot;latitude degrees &amp;lt; 0 with hemisphere flag&amp;quot;})&lt;br /&gt;
		end&lt;br /&gt;
		if long_d &amp;lt; 0 then&lt;br /&gt;
			table.insert(errors, {source, &amp;quot;longitude degrees &amp;lt; 0 with hemisphere flag&amp;quot;})&lt;br /&gt;
		end&lt;br /&gt;
		--[[&lt;br /&gt;
		#coordinates is inconsistent about whether this is an error.  If globe: is&lt;br /&gt;
		specified, it won&#039;t error on this condition, but otherwise it will.&lt;br /&gt;
&lt;br /&gt;
		For not simply disable this check.&lt;br /&gt;
&lt;br /&gt;
		if long_d &amp;gt; 180 then&lt;br /&gt;
			table.insert(errors, {source, &amp;quot;longitude degrees &amp;gt; 180 with hemisphere flag&amp;quot;})&lt;br /&gt;
		end&lt;br /&gt;
		]]&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if lat_d &amp;gt; 90 then&lt;br /&gt;
		table.insert(errors, {source, &amp;quot;latitude degrees &amp;gt; 90&amp;quot;})&lt;br /&gt;
	end&lt;br /&gt;
	if lat_d &amp;lt; -90 then&lt;br /&gt;
		table.insert(errors, {source, &amp;quot;latitude degrees &amp;lt; -90&amp;quot;})&lt;br /&gt;
	end&lt;br /&gt;
	if lat_m &amp;gt;= 60 then&lt;br /&gt;
		table.insert(errors, {source, &amp;quot;latitude minutes &amp;gt;= 60&amp;quot;})&lt;br /&gt;
	end&lt;br /&gt;
	if lat_m &amp;lt; 0 then&lt;br /&gt;
		table.insert(errors, {source, &amp;quot;latitude minutes &amp;lt; 0&amp;quot;})&lt;br /&gt;
	end&lt;br /&gt;
	if lat_s &amp;gt;= 60 then&lt;br /&gt;
		table.insert(errors, {source, &amp;quot;latitude seconds &amp;gt;= 60&amp;quot;})&lt;br /&gt;
	end&lt;br /&gt;
	if lat_s &amp;lt; 0 then&lt;br /&gt;
		table.insert(errors, {source, &amp;quot;latitude seconds &amp;lt; 0&amp;quot;})&lt;br /&gt;
	end&lt;br /&gt;
	if long_d &amp;gt;= 360 then&lt;br /&gt;
		table.insert(errors, {source, &amp;quot;longitude degrees &amp;gt;= 360&amp;quot;})&lt;br /&gt;
	end&lt;br /&gt;
	if long_d &amp;lt;= -360 then&lt;br /&gt;
		table.insert(errors, {source, &amp;quot;longitude degrees &amp;lt;= -360&amp;quot;})&lt;br /&gt;
	end&lt;br /&gt;
	if long_m &amp;gt;= 60 then&lt;br /&gt;
		table.insert(errors, {source, &amp;quot;longitude minutes &amp;gt;= 60&amp;quot;})&lt;br /&gt;
	end&lt;br /&gt;
	if long_m &amp;lt; 0 then&lt;br /&gt;
		table.insert(errors, {source, &amp;quot;longitude minutes &amp;lt; 0&amp;quot;})&lt;br /&gt;
	end&lt;br /&gt;
	if long_s &amp;gt;= 60 then&lt;br /&gt;
		table.insert(errors, {source, &amp;quot;longitude seconds &amp;gt;= 60&amp;quot;})&lt;br /&gt;
	end&lt;br /&gt;
	if long_s &amp;lt; 0 then&lt;br /&gt;
		table.insert(errors, {source, &amp;quot;longitude seconds &amp;lt; 0&amp;quot;})&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return errors;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
parseDec&lt;br /&gt;
&lt;br /&gt;
Transforms decimal format latitude and longitude into the&lt;br /&gt;
structure to be used in displaying coordinates&lt;br /&gt;
]]&lt;br /&gt;
local function parseDec( lat, long, format )&lt;br /&gt;
	local coordinateSpec = {}&lt;br /&gt;
	local errors = {}&lt;br /&gt;
&lt;br /&gt;
	if not long then&lt;br /&gt;
		return nil, {{&amp;quot;parseDec&amp;quot;, &amp;quot;Missing longitude&amp;quot;}}&lt;br /&gt;
	elseif not tonumber(long) then&lt;br /&gt;
		return nil, {{&amp;quot;parseDec&amp;quot;, &amp;quot;Longitude could not be parsed as a number: &amp;quot; .. long}}&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	errors = validate( lat, nil, nil, long, nil, nil, &#039;parseDec&#039;, false );&lt;br /&gt;
	coordinateSpec[&amp;quot;dec-lat&amp;quot;]  = lat;&lt;br /&gt;
	coordinateSpec[&amp;quot;dec-long&amp;quot;] = long;&lt;br /&gt;
&lt;br /&gt;
	local mode = coordinates.determineMode( lat, long );&lt;br /&gt;
	coordinateSpec[&amp;quot;dms-lat&amp;quot;]  = convert_dec2dms( lat, &amp;quot;N&amp;quot;, &amp;quot;S&amp;quot;, mode)  -- {{coord/dec2dms|{{{1}}}|N|S|{{coord/prec dec|{{{1}}}|{{{2}}}}}}}&lt;br /&gt;
	coordinateSpec[&amp;quot;dms-long&amp;quot;] = convert_dec2dms( long, &amp;quot;E&amp;quot;, &amp;quot;W&amp;quot;, mode)  -- {{coord/dec2dms|{{{2}}}|E|W|{{coord/prec dec|{{{1}}}|{{{2}}}}}}}&lt;br /&gt;
&lt;br /&gt;
	if format then&lt;br /&gt;
		coordinateSpec.default = format&lt;br /&gt;
	else&lt;br /&gt;
		coordinateSpec.default = &amp;quot;dec&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return coordinateSpec, errors&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
parseDMS&lt;br /&gt;
&lt;br /&gt;
Transforms degrees, minutes, seconds format latitude and longitude&lt;br /&gt;
into the a structure to be used in displaying coordinates&lt;br /&gt;
]]&lt;br /&gt;
local function parseDMS( lat_d, lat_m, lat_s, lat_f, long_d, long_m, long_s, long_f, format )&lt;br /&gt;
	local coordinateSpec, errors, backward = {}, {}&lt;br /&gt;
&lt;br /&gt;
	lat_f = lat_f:upper();&lt;br /&gt;
	long_f = long_f:upper();&lt;br /&gt;
&lt;br /&gt;
	-- Check if specified backward&lt;br /&gt;
	if lat_f == &#039;E&#039; or lat_f == &#039;W&#039; then&lt;br /&gt;
		lat_d, long_d, lat_m, long_m, lat_s, long_s, lat_f, long_f, backward = long_d, lat_d, long_m, lat_m, long_s, lat_s, long_f, lat_f, true;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	errors = validate( lat_d, lat_m, lat_s, long_d, long_m, long_s, &#039;parseDMS&#039;, true );&lt;br /&gt;
	if not long_d then&lt;br /&gt;
		return nil, {{&amp;quot;parseDMS&amp;quot;, &amp;quot;Missing longitude&amp;quot; }}&lt;br /&gt;
	elseif not tonumber(long_d) then&lt;br /&gt;
		return nil, {{&amp;quot;parseDMS&amp;quot;, &amp;quot;Longitude could not be parsed as a number:&amp;quot; .. long_d }}&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if not lat_m and not lat_s and not long_m and not long_s and #errors == 0 then&lt;br /&gt;
		if math_mod._precision( lat_d ) &amp;gt; 0 or math_mod._precision( long_d ) &amp;gt; 0 then&lt;br /&gt;
			if lat_f:upper() == &#039;S&#039; then&lt;br /&gt;
				lat_d = &#039;-&#039; .. lat_d;&lt;br /&gt;
			end&lt;br /&gt;
			if long_f:upper() == &#039;W&#039; then&lt;br /&gt;
				long_d = &#039;-&#039; .. long_d;&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			return parseDec( lat_d, long_d, format );&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	coordinateSpec[&amp;quot;dms-lat&amp;quot;]  = lat_d..&amp;quot;°&amp;quot;..optionalArg(lat_m,&amp;quot;′&amp;quot;) .. optionalArg(lat_s,&amp;quot;″&amp;quot;) .. lat_f&lt;br /&gt;
	coordinateSpec[&amp;quot;dms-long&amp;quot;] = long_d..&amp;quot;°&amp;quot;..optionalArg(long_m,&amp;quot;′&amp;quot;) .. optionalArg(long_s,&amp;quot;″&amp;quot;) .. long_f&lt;br /&gt;
	coordinateSpec[&amp;quot;dec-lat&amp;quot;]  = convert_dms2dec(lat_f, lat_d, lat_m, lat_s) -- {{coord/dms2dec|{{{4}}}|{{{1}}}|0{{{2}}}|0{{{3}}}}}&lt;br /&gt;
	coordinateSpec[&amp;quot;dec-long&amp;quot;] = convert_dms2dec(long_f, long_d, long_m, long_s) -- {{coord/dms2dec|{{{8}}}|{{{5}}}|0{{{6}}}|0{{{7}}}}}&lt;br /&gt;
&lt;br /&gt;
	if format then&lt;br /&gt;
		coordinateSpec.default = format&lt;br /&gt;
	else&lt;br /&gt;
		coordinateSpec.default = &amp;quot;dms&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return coordinateSpec, errors, backward&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Check the input arguments for coord to determine the kind of data being provided&lt;br /&gt;
and then make the necessary processing.&lt;br /&gt;
]]&lt;br /&gt;
local function formatTest(args)&lt;br /&gt;
	local result, errors&lt;br /&gt;
	local backward, primary = false, false&lt;br /&gt;
&lt;br /&gt;
	local function getParam(args, lim)&lt;br /&gt;
		local ret = {}&lt;br /&gt;
		for i = 1, lim do&lt;br /&gt;
			ret[i] = args[i] or &#039;&#039;&lt;br /&gt;
		end&lt;br /&gt;
		return table.concat(ret, &#039;_&#039;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if not args[1] then&lt;br /&gt;
		-- no lat logic&lt;br /&gt;
		return errorPrinter( {{&amp;quot;formatTest&amp;quot;, &amp;quot;Missing latitude&amp;quot;}} )&lt;br /&gt;
	elseif not tonumber(args[1]) then&lt;br /&gt;
		-- bad lat logic&lt;br /&gt;
		return errorPrinter( {{&amp;quot;formatTest&amp;quot;, &amp;quot;Unable to parse latitude as a number:&amp;quot; .. args[1]}} )&lt;br /&gt;
	elseif not args[4] and not args[5] and not args[6] then&lt;br /&gt;
		-- dec logic&lt;br /&gt;
		result, errors = parseDec(args[1], args[2], args.format)&lt;br /&gt;
		if not result then&lt;br /&gt;
			return errorPrinter(errors);&lt;br /&gt;
		end&lt;br /&gt;
		-- formatting for geohack: geohack expects D_N_D_E notation or D;D notation&lt;br /&gt;
		-- wikiminiatlas doesn&#039;t support D;D notation&lt;br /&gt;
		-- #coordinates parserfunction doesn&#039;t support negative decimals with NSWE&lt;br /&gt;
		result.param = table.concat({&lt;br /&gt;
			math.abs(tonumber(args[1])),&lt;br /&gt;
			((tonumber(args[1]) or 0) &amp;lt; 0) and &#039;S&#039; or &#039;N&#039;,&lt;br /&gt;
			math.abs(tonumber(args[2])),&lt;br /&gt;
			((tonumber(args[2]) or 0) &amp;lt; 0) and &#039;W&#039; or &#039;E&#039;,&lt;br /&gt;
			args[3] or &#039;&#039;}, &#039;_&#039;)&lt;br /&gt;
	elseif dmsTest(args[4], args[8]) then&lt;br /&gt;
		-- dms logic&lt;br /&gt;
		result, errors, backward = parseDMS(args[1], args[2], args[3], args[4],&lt;br /&gt;
			args[5], args[6], args[7], args[8], args.format)&lt;br /&gt;
		if args[10] then&lt;br /&gt;
			table.insert(errors, {&#039;formatTest&#039;, &#039;Extra unexpected parameters&#039;})&lt;br /&gt;
		end&lt;br /&gt;
		if not result then&lt;br /&gt;
			return errorPrinter(errors)&lt;br /&gt;
		end&lt;br /&gt;
		result.param = getParam(args, 9)&lt;br /&gt;
	elseif dmsTest(args[3], args[6]) then&lt;br /&gt;
		-- dm logic&lt;br /&gt;
		result, errors, backward = parseDMS(args[1], args[2], nil, args[3],&lt;br /&gt;
			args[4], args[5], nil, args[6], args[&#039;format&#039;])&lt;br /&gt;
		if args[8] then&lt;br /&gt;
			table.insert(errors, {&#039;formatTest&#039;, &#039;Extra unexpected parameters&#039;})&lt;br /&gt;
		end&lt;br /&gt;
		if not result then&lt;br /&gt;
			return errorPrinter(errors)&lt;br /&gt;
		end&lt;br /&gt;
		result.param = getParam(args, 7)&lt;br /&gt;
	elseif dmsTest(args[2], args[4]) then&lt;br /&gt;
		-- d logic&lt;br /&gt;
		result, errors, backward = parseDMS(args[1], nil, nil, args[2],&lt;br /&gt;
			args[3], nil, nil, args[4], args.format)&lt;br /&gt;
		if args[6] then&lt;br /&gt;
			table.insert(errors, {&#039;formatTest&#039;, &#039;Extra unexpected parameters&#039;})&lt;br /&gt;
		end&lt;br /&gt;
		if not result then&lt;br /&gt;
			return errorPrinter(errors)&lt;br /&gt;
		end&lt;br /&gt;
		result.param = getParam(args, 5)&lt;br /&gt;
	else&lt;br /&gt;
		-- Error&lt;br /&gt;
		return errorPrinter({{&amp;quot;formatTest&amp;quot;, &amp;quot;Unknown argument format&amp;quot;}}) .. &#039;[[Category:Pages with malformed coordinate tags]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	result.name = args.name&lt;br /&gt;
&lt;br /&gt;
	local extra_param = {&#039;dim&#039;, &#039;globe&#039;, &#039;scale&#039;, &#039;region&#039;, &#039;source&#039;, &#039;type&#039;}&lt;br /&gt;
	for _, v in ipairs(extra_param) do&lt;br /&gt;
		if args[v] then&lt;br /&gt;
			table.insert(errors, {&#039;formatTest&#039;, &#039;Parameter: &amp;quot;&#039; .. v .. &#039;=&amp;quot; should be &amp;quot;&#039; .. v .. &#039;:&amp;quot;&#039; })&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local ret = specPrinter(args, result)&lt;br /&gt;
	if #errors &amp;gt; 0 then&lt;br /&gt;
		ret = ret .. &#039; &#039; .. errorPrinter(errors) .. &#039;[[Category:Pages with malformed coordinate tags]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	return ret, backward&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Generate Wikidata tracking categories.&lt;br /&gt;
]]&lt;br /&gt;
local function makeWikidataCategories(qid)&lt;br /&gt;
	local ret&lt;br /&gt;
	local qid = qid or (mw.wikibase and mw.wikibase.getEntityIdForCurrentPage and mw.wikibase.getEntityIdForCurrentPage())&lt;br /&gt;
	if mw.wikibase and current_page.namespace == 0 then&lt;br /&gt;
		if qid and mw.wikibase.entityExists(qid) and mw.wikibase.getBestStatements(qid, &amp;quot;P625&amp;quot;) and mw.wikibase.getBestStatements(qid, &amp;quot;P625&amp;quot;)[1] then&lt;br /&gt;
			local snaktype = mw.wikibase.getBestStatements(qid, &amp;quot;P625&amp;quot;)[1].mainsnak.snaktype&lt;br /&gt;
			if snaktype == &#039;value&#039; then&lt;br /&gt;
				-- coordinates exist both here and on Wikidata, and can be compared.&lt;br /&gt;
				ret = &#039;Coordinates on Wikidata&#039;&lt;br /&gt;
			elseif snaktype == &#039;somevalue&#039; then&lt;br /&gt;
				ret = &#039;Coordinates on Wikidata set to unknown value&#039;&lt;br /&gt;
			elseif snaktype == &#039;novalue&#039; then&lt;br /&gt;
				ret = &#039;Coordinates on Wikidata set to no value&#039;&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			-- We have to either import the coordinates to Wikidata or remove them here.&lt;br /&gt;
			ret = &#039;Coordinates not on Wikidata&#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if ret then&lt;br /&gt;
		return string.format(&#039;[[Category:%s]]&#039;, ret)&lt;br /&gt;
	else&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
link&lt;br /&gt;
&lt;br /&gt;
Simple function to export the coordinates link for other uses.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
	{{#invoke:Coordinates | link }}&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
function coordinates.link(frame)&lt;br /&gt;
	return coord_link;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
dec2dms&lt;br /&gt;
&lt;br /&gt;
Wrapper to allow templates to call dec2dms directly.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
	{{#invoke:Coordinates | dec2dms | decimal_coordinate | positive_suffix |&lt;br /&gt;
		negative_suffix | precision }}&lt;br /&gt;
&lt;br /&gt;
decimal_coordinate is converted to DMS format.  If positive, the positive_suffix&lt;br /&gt;
is appended (typical N or E), if negative, the negative suffix is appended.  The&lt;br /&gt;
specified precision is one of &#039;D&#039;, &#039;DM&#039;, or &#039;DMS&#039; to specify the level of detail&lt;br /&gt;
to use.&lt;br /&gt;
]]&lt;br /&gt;
coordinates.dec2dms = makeInvokeFunc(&#039;_dec2dms&#039;)&lt;br /&gt;
function coordinates._dec2dms(args)&lt;br /&gt;
	local coordinate = args[1]&lt;br /&gt;
	local firstPostfix = args[2] or &#039;&#039;&lt;br /&gt;
	local secondPostfix = args[3] or &#039;&#039;&lt;br /&gt;
	local precision = args[4] or &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
	return convert_dec2dms(coordinate, firstPostfix, secondPostfix, precision)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Helper function to determine whether to use D, DM, or DMS&lt;br /&gt;
format depending on the precision of the decimal input.&lt;br /&gt;
]]&lt;br /&gt;
function coordinates.determineMode( value1, value2 )&lt;br /&gt;
	local precision = math.max( math_mod._precision( value1 ), math_mod._precision( value2 ) );&lt;br /&gt;
	if precision &amp;lt;= 0 then&lt;br /&gt;
		return &#039;d&#039;&lt;br /&gt;
	elseif precision &amp;lt;= 2 then&lt;br /&gt;
		return &#039;dm&#039;;&lt;br /&gt;
	else&lt;br /&gt;
		return &#039;dms&#039;;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
dms2dec&lt;br /&gt;
&lt;br /&gt;
Wrapper to allow templates to call dms2dec directly.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
	{{#invoke:Coordinates | dms2dec | direction_flag | degrees |&lt;br /&gt;
		minutes | seconds }}&lt;br /&gt;
&lt;br /&gt;
Converts DMS values specified as degrees, minutes, seconds too decimal format.&lt;br /&gt;
direction_flag is one of N, S, E, W, and determines whether the output is&lt;br /&gt;
positive (i.e. N and E) or negative (i.e. S and W).&lt;br /&gt;
]]&lt;br /&gt;
coordinates.dms2dec = makeInvokeFunc(&#039;_dms2dec&#039;)&lt;br /&gt;
function coordinates._dms2dec(args)&lt;br /&gt;
	local direction = args[1]&lt;br /&gt;
	local degrees = args[2]&lt;br /&gt;
	local minutes = args[3]&lt;br /&gt;
	local seconds = args[4]&lt;br /&gt;
&lt;br /&gt;
	return convert_dms2dec(direction, degrees, minutes, seconds)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
coord&lt;br /&gt;
&lt;br /&gt;
Main entry point for Lua function to replace {{coord}}&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
	{{#invoke:Coordinates | coord }}&lt;br /&gt;
	{{#invoke:Coordinates | coord | lat | long }}&lt;br /&gt;
	{{#invoke:Coordinates | coord | lat | lat_flag | long | long_flag }}&lt;br /&gt;
	...&lt;br /&gt;
&lt;br /&gt;
	Refer to {{coord}} documentation page for many additional parameters and&lt;br /&gt;
	configuration options.&lt;br /&gt;
&lt;br /&gt;
Note: This function provides the visual display elements of {{coord}}.  In&lt;br /&gt;
order to load coordinates into the database, the {{#coordinates:}} parser&lt;br /&gt;
function must also be called, this is done automatically in the Lua&lt;br /&gt;
version of {{coord}}.&lt;br /&gt;
]]&lt;br /&gt;
coordinates.coord = makeInvokeFunc(&#039;_coord&#039;)&lt;br /&gt;
function coordinates._coord(args)&lt;br /&gt;
	if not tonumber(args[1]) and not args[2] then&lt;br /&gt;
		args[3] = args[1]; args[1] = nil&lt;br /&gt;
		local entity = mw.wikibase and mw.wikibase.getEntityObject and mw.wikibase.getEntityObject(args.qid)&lt;br /&gt;
		if entity&lt;br /&gt;
			and entity.claims&lt;br /&gt;
			and entity.claims.P625&lt;br /&gt;
			and entity.claims.P625[1].mainsnak.snaktype == &#039;value&#039;&lt;br /&gt;
		then&lt;br /&gt;
			local precision = entity.claims.P625[1].mainsnak.datavalue.value.precision&lt;br /&gt;
			args[1] = entity.claims.P625[1].mainsnak.datavalue.value.latitude&lt;br /&gt;
			args[2] = entity.claims.P625[1].mainsnak.datavalue.value.longitude&lt;br /&gt;
			if precision then&lt;br /&gt;
				precision = -math_mod._round(math.log(precision)/math.log(10),0)&lt;br /&gt;
				args[1] = math_mod._round(args[1],precision)&lt;br /&gt;
				args[2] = math_mod._round(args[2],precision)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local contents, backward = formatTest(args)&lt;br /&gt;
	local Notes = args.notes or &#039;&#039;&lt;br /&gt;
	local Display = args.display and args.display:lower() or &#039;inline&#039;&lt;br /&gt;
&lt;br /&gt;
	-- it and ti are short for inline,title and title,inline&lt;br /&gt;
	local function isInline(s)&lt;br /&gt;
		-- Finds whether coordinates are displayed inline.&lt;br /&gt;
		return s:find(&#039;inline&#039;) ~= nil or s == &#039;i&#039; or s == &#039;it&#039; or s == &#039;ti&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local function isInTitle(s)&lt;br /&gt;
		-- Finds whether coordinates are displayed in the title.&lt;br /&gt;
		return s:find(&#039;title&#039;) ~= nil or s == &#039;t&#039; or s == &#039;it&#039; or s == &#039;ti&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local function coord_wrapper(in_args)&lt;br /&gt;
		-- Calls the parser function {{#coordinates:}}.&lt;br /&gt;
		return mw.getCurrentFrame():callParserFunction(&#039;#coordinates&#039;, in_args) or &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local text = &#039;&#039;&lt;br /&gt;
	if isInline(Display) then&lt;br /&gt;
		text = text .. &#039;&amp;lt;span class=&amp;quot;geo-inline&amp;quot;&amp;gt;&#039; .. contents .. Notes .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	if isInTitle(Display) then&lt;br /&gt;
		-- Add to output since indicator content is invisible to Lua later on&lt;br /&gt;
		if not isInline(Display) then&lt;br /&gt;
			text = text .. &#039;&amp;lt;span class=&amp;quot;geo-inline-hidden noexcerpt&amp;quot;&amp;gt;&#039; .. contents .. Notes .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
		end&lt;br /&gt;
		text = text .. displaytitle(contents .. Notes) .. makeWikidataCategories(args.qid)&lt;br /&gt;
	end&lt;br /&gt;
	if not args.nosave then&lt;br /&gt;
		local page_title, count = mw.title.getCurrentTitle(), 1&lt;br /&gt;
		if backward then&lt;br /&gt;
			local tmp = {}&lt;br /&gt;
			while not string.find((args[count-1] or &#039;&#039;), &#039;[EW]&#039;) do tmp[count] = (args[count] or &#039;&#039;); count = count+1 end&lt;br /&gt;
			tmp.count = count; count = 2*(count-1)&lt;br /&gt;
			while count &amp;gt;= tmp.count do table.insert(tmp, 1, (args[count] or &#039;&#039;)); count = count-1 end&lt;br /&gt;
			for i, v in ipairs(tmp) do args[i] = v end&lt;br /&gt;
		else&lt;br /&gt;
			while count &amp;lt;= 9 do args[count] = (args[count] or &#039;&#039;); count = count+1 end&lt;br /&gt;
		end&lt;br /&gt;
		if isInTitle(Display) and not page_title.isTalkPage and page_title.subpageText ~= &#039;doc&#039; and page_title.subpageText ~= &#039;testcases&#039; then args[10] = &#039;primary&#039; end&lt;br /&gt;
		args.notes, args.format, args.display = nil&lt;br /&gt;
		text = text .. coord_wrapper(args)&lt;br /&gt;
	end&lt;br /&gt;
	return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
coord2text&lt;br /&gt;
&lt;br /&gt;
Extracts a single value from a transclusion of {{Coord}}.&lt;br /&gt;
IF THE GEOHACK LINK SYNTAX CHANGES THIS FUNCTION MUST BE MODIFIED.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&lt;br /&gt;
    {{#invoke:Coordinates | coord2text | {{Coord}} | parameter }}&lt;br /&gt;
&lt;br /&gt;
Valid values for the second parameter are: lat (signed integer), long (signed integer), type, scale, dim, region, globe, source&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
function coordinates._coord2text(coord,type)&lt;br /&gt;
	if coord == &#039;&#039; or type == &#039;&#039; or not type then return nil end&lt;br /&gt;
	type = mw.text.trim(type)&lt;br /&gt;
	if type == &#039;lat&#039; or type == &#039;long&#039; then&lt;br /&gt;
		local result, negative = mw.text.split((mw.ustring.match(coord,&#039;[%.%d]+°[NS] [%.%d]+°[EW]&#039;) or &#039;&#039;), &#039; &#039;)&lt;br /&gt;
		if type == &#039;lat&#039; then&lt;br /&gt;
			result, negative = result[1], &#039;S&#039;&lt;br /&gt;
		else&lt;br /&gt;
			result, negative = result[2], &#039;W&#039;&lt;br /&gt;
		end&lt;br /&gt;
		result = mw.text.split(result, &#039;°&#039;)&lt;br /&gt;
		if result[2] == negative then result[1] = &#039;-&#039;..result[1] end&lt;br /&gt;
		return result[1]&lt;br /&gt;
	else&lt;br /&gt;
		return mw.ustring.match(coord, &#039;params=.-_&#039; .. type .. &#039;:(.-)[ _]&#039;)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function coordinates.coord2text(frame)&lt;br /&gt;
	return coordinates._coord2text(frame.args[1],frame.args[2])&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
coordinsert&lt;br /&gt;
&lt;br /&gt;
Injects some text into the Geohack link of a transclusion of {{Coord}} (if that text isn&#039;t already in the transclusion). Outputs the modified transclusion of {{Coord}}.&lt;br /&gt;
IF THE GEOHACK LINK SYNTAX CHANGES THIS FUNCTION MUST BE MODIFIED.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&lt;br /&gt;
    {{#invoke:Coordinates | coordinsert | {{Coord}} | parameter:value | parameter:value | … }}&lt;br /&gt;
&lt;br /&gt;
Do not make Geohack unhappy by inserting something which isn&#039;t mentioned in the {{Coord}} documentation.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
function coordinates.coordinsert(frame)&lt;br /&gt;
	-- for the 2nd or later integer parameter (the first is the coord template, as above)&lt;br /&gt;
	for i, v in ipairs(frame.args) do&lt;br /&gt;
		if i ~= 1 then&lt;br /&gt;
			-- if we cannot find in the coord_template the i_th coordinsert parameter e.g. region&lt;br /&gt;
			if not mw.ustring.find(frame.args[1], (mw.ustring.match(frame.args[i], &#039;^(.-:)&#039;) or &#039;&#039;)) then&lt;br /&gt;
				-- find from the params= up to the first possibly-present underscore&lt;br /&gt;
				-- and append the i_th coordinsert parameter and a space&lt;br /&gt;
				-- IDK why we&#039;re adding a space but it does seem somewhat convenient&lt;br /&gt;
				frame.args[1] = mw.ustring.gsub(frame.args[1], &#039;(params=.-)_? &#039;, &#039;%1_&#039;..frame.args[i]..&#039; &#039;)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if frame.args.name then&lt;br /&gt;
		-- if we can&#039;t find the vcard class&lt;br /&gt;
		if not mw.ustring.find(frame.args[1], &#039;&amp;lt;span class=&amp;quot;vcard&amp;quot;&amp;gt;&#039;) then&lt;br /&gt;
			-- take something that looks like a coord template and add the vcard span with class and fn org class&lt;br /&gt;
			local namestr = frame.args.name&lt;br /&gt;
			frame.args[1] = mw.ustring.gsub(&lt;br /&gt;
				frame.args[1],&lt;br /&gt;
				&#039;(&amp;lt;span class=&amp;quot;geo%-default&amp;quot;&amp;gt;)(&amp;lt;span[^&amp;lt;&amp;gt;]*&amp;gt;[^&amp;lt;&amp;gt;]*&amp;lt;/span&amp;gt;&amp;lt;span[^&amp;lt;&amp;gt;]*&amp;gt;[^&amp;lt;&amp;gt;]*&amp;lt;span[^&amp;lt;&amp;gt;]*&amp;gt;[^&amp;lt;&amp;gt;]*&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;)(&amp;lt;/span&amp;gt;)&#039;,&lt;br /&gt;
				&#039;%1&amp;lt;span class=&amp;quot;vcard&amp;quot;&amp;gt;%2&amp;lt;span style=&amp;quot;display:none&amp;quot;&amp;gt;&amp;amp;#xfeff; (&amp;lt;span class=&amp;quot;fn org&amp;quot;&amp;gt;&#039; .. namestr .. &#039;&amp;lt;/span&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;%3&#039;&lt;br /&gt;
			)&lt;br /&gt;
			-- then find anything from coordinates parameters to the &#039;end&#039; and attach the title parameter&lt;br /&gt;
			frame.args[1] = mw.ustring.gsub(&lt;br /&gt;
				frame.args[1],&lt;br /&gt;
				&#039;(&amp;amp;params=[^&amp;amp;&amp;quot;&amp;lt;&amp;gt;%[%] ]*) &#039;,&lt;br /&gt;
				&#039;%1&amp;amp;title=&#039; .. mw.uri.encode(namestr) .. &#039; &#039;&lt;br /&gt;
			)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- replace the existing indicator with a new indicator using the modified content&lt;br /&gt;
	frame.args[1] = mw.ustring.gsub(&lt;br /&gt;
		frame.args[1],&lt;br /&gt;
		&#039;(&amp;lt;span class=&amp;quot;geo%-inline[^&amp;quot;]*&amp;quot;&amp;gt;(.+)&amp;lt;/span&amp;gt;)\127[^\127]*UNIQ%-%-indicator%-%x+%-%-?QINU[^\127]*\127&#039;,&lt;br /&gt;
		function (inline, coord) return inline .. displaytitle(coord) end&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
	return frame.args[1]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return coordinates&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
</feed>