<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.jadetimber.com/index.php?action=history&amp;feed=atom&amp;title=Module%3ALanguages</id>
	<title>Module:Languages - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.jadetimber.com/index.php?action=history&amp;feed=atom&amp;title=Module%3ALanguages"/>
	<link rel="alternate" type="text/html" href="https://wiki.jadetimber.com/index.php?title=Module:Languages&amp;action=history"/>
	<updated>2026-04-17T18:19:12Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.44.1</generator>
	<entry>
		<id>https://wiki.jadetimber.com/index.php?title=Module:Languages&amp;diff=751&amp;oldid=prev</id>
		<title>Aki: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://wiki.jadetimber.com/index.php?title=Module:Languages&amp;diff=751&amp;oldid=prev"/>
		<updated>2025-10-10T05:05:53Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 23:05, 9 October 2025&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Aki</name></author>
	</entry>
	<entry>
		<id>https://wiki.jadetimber.com/index.php?title=Module:Languages&amp;diff=750&amp;oldid=prev</id>
		<title>Fandom&gt;Winston Sung at 10:48, 26 December 2023</title>
		<link rel="alternate" type="text/html" href="https://wiki.jadetimber.com/index.php?title=Module:Languages&amp;diff=750&amp;oldid=prev"/>
		<updated>2023-12-26T10:48:37Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- &amp;lt;nowiki&amp;gt;&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Lua templating and link generation for language subpages.&lt;br /&gt;
--&lt;br /&gt;
-- @module languages&lt;br /&gt;
-- @alias l&lt;br /&gt;
-- @release stable&lt;br /&gt;
-- @require [[w:c:dev:Global Lua Modules/Arguments|Module:Arguments]]&lt;br /&gt;
-- @require [[w:c:dev:Global Lua Modules/I18n|Module:I18n]]&lt;br /&gt;
-- @require [[w:c:dev:Module:Fallbacklist|Module:Fallbacklist]]&lt;br /&gt;
-- @require [[w:c:dev:Module:Common/i18n|Module:Common/i18n]]&lt;br /&gt;
-- @author [[User:Nanaki|Nanaki]] - original version&lt;br /&gt;
-- @author [[User:KockaAdmiralac|KockaAdmiralac]]&lt;br /&gt;
-- @author [[User:MACH-59330|MACH-59330]]&lt;br /&gt;
-- @see [[project:Internationalization]]&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
local l = {}&lt;br /&gt;
local getArgs = require(&amp;#039;Dev:Arguments&amp;#039;).getArgs&lt;br /&gt;
local fallbacks = mw.loadData(&amp;#039;Dev:Fallbacklist&amp;#039;)&lt;br /&gt;
local i18n = require(&amp;#039;Dev:I18n&amp;#039;).loadMessages(&amp;#039;Common&amp;#039;)&lt;br /&gt;
local contentLang = mw.getContentLanguage():getCode()&lt;br /&gt;
local title = mw.title.getCurrentTitle()&lt;br /&gt;
l.langMessage = &amp;#039;lang&amp;#039;&lt;br /&gt;
&lt;br /&gt;
-- Module constants&lt;br /&gt;
l.TRANSLATE_DISABLED_TARGET_LANGUAGES = {&lt;br /&gt;
	[&amp;quot;zh&amp;quot;] = &amp;quot;zh-hans&amp;quot;,&lt;br /&gt;
	[&amp;quot;zh-cn&amp;quot;] = &amp;quot;zh-hans&amp;quot;,&lt;br /&gt;
	[&amp;quot;zh-mo&amp;quot;] = &amp;quot;zh-hk&amp;quot;,&lt;br /&gt;
	[&amp;quot;zh-my&amp;quot;] = &amp;quot;zh-hans&amp;quot;,&lt;br /&gt;
	[&amp;quot;zh-sg&amp;quot;] = &amp;quot;zh-hans&amp;quot;,&lt;br /&gt;
	[&amp;quot;zh-tw&amp;quot;] = &amp;quot;zh-hant&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function intOrI18n(msg, ...)&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
	if not frame then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local hasArgs = false&lt;br /&gt;
	local args = {}&lt;br /&gt;
	for i = 1, select(&amp;#039;#&amp;#039;, ...) do&lt;br /&gt;
		hasArgs = true&lt;br /&gt;
		local val = select(i, ...)&lt;br /&gt;
		val = val == nil and &amp;#039;&amp;#039; or tostring(val)&lt;br /&gt;
		args[i] = val&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local text = frame:preprocess(&amp;#039;{{int:&amp;#039; .. msg .. (hasArgs and &amp;#039;|&amp;#039; .. table.concat(args, &amp;#039;|&amp;#039;)) .. &amp;#039;}}&amp;#039;)&lt;br /&gt;
	if text == &amp;#039;&amp;lt;&amp;#039; .. msg .. &amp;#039;&amp;gt;&amp;#039; or text == &amp;#039;⧼&amp;#039; .. msg .. &amp;#039;⧽&amp;#039; then&lt;br /&gt;
		text = frame:preprocess(i18n:msg{&lt;br /&gt;
			key = msg,&lt;br /&gt;
			args = args,&lt;br /&gt;
		})&lt;br /&gt;
	end&lt;br /&gt;
	return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function escRx(text, spaces)&lt;br /&gt;
	text = text:gsub(&amp;#039;[\\().+*?^$-/=!:]&amp;#039;, &amp;#039;\\%0&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	if spaces then&lt;br /&gt;
		text = text:gsub(&amp;#039; &amp;#039;, &amp;#039;_&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function makeRedLink(page, text, query)&lt;br /&gt;
	page = mw.ustring.gsub(tostring(page), &amp;#039;^:*&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
	local title = frame&lt;br /&gt;
		and frame:preprocess(&amp;#039;{{int:red-link-title|{{ucfirst:&amp;#039; .. page .. &amp;#039;}}}}&amp;#039;)&lt;br /&gt;
		or &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
	query = query or {}&lt;br /&gt;
	query.action = &amp;#039;edit&amp;#039;&lt;br /&gt;
	query.redlink = 1&lt;br /&gt;
&lt;br /&gt;
	return mw.html.create(&amp;#039;span&amp;#039;)&lt;br /&gt;
		:addClass(&amp;#039;redlink&amp;#039;)&lt;br /&gt;
		:attr(&amp;#039;title&amp;#039;, title)&lt;br /&gt;
		:wikitext(&amp;#039;[&amp;#039; .. tostring(mw.uri.fullUrl(page, query)) .. &amp;#039; &amp;#039; .. text .. &amp;#039;]&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function makeBlueLink(page, text)&lt;br /&gt;
	page = mw.ustring.gsub(tostring(page), &amp;#039;^:*&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	return mw.html.create(&amp;#039;&amp;#039;)&lt;br /&gt;
		:wikitext(&amp;#039;[[:&amp;#039; .. page .. &amp;#039;|&amp;#039; .. text .. &amp;#039;]]&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getAttr(t, name)&lt;br /&gt;
	for i, attr in ipairs(t.attributes) do&lt;br /&gt;
		if attr.name == name then&lt;br /&gt;
			return attr.val&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- @type Links&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- @property {table} Links.list&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- @property {table} Links.keys&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- @function prepLinks&lt;br /&gt;
-- @param {string} root&lt;br /&gt;
-- @param {table} list&lt;br /&gt;
-- @param {table} order&lt;br /&gt;
-- @param[opt] {string} editintro&lt;br /&gt;
-- @return {Links}&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
local function prepLinks(root, list, order, editintro)&lt;br /&gt;
	local links = {&lt;br /&gt;
		list = {},&lt;br /&gt;
		keys = {}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	editintro = editintro or &amp;#039;Template:I18ndoc/editintro&amp;#039;&lt;br /&gt;
&lt;br /&gt;
	for _, k in ipairs(order) do&lt;br /&gt;
		local lang = mw.language.fetchLanguageName(k)&lt;br /&gt;
&lt;br /&gt;
		if lang ~= &amp;#039;&amp;#039; then&lt;br /&gt;
			local obj = {&lt;br /&gt;
				lang = k&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if list[k] then&lt;br /&gt;
				if type(list[k]) == &amp;#039;string&amp;#039; then&lt;br /&gt;
					obj.link = makeBlueLink(list[k], lang)&lt;br /&gt;
					obj.page = list[k]&lt;br /&gt;
				elseif k == contentLang then&lt;br /&gt;
					obj.link = makeBlueLink(root, lang)&lt;br /&gt;
					obj.page = root&lt;br /&gt;
				else&lt;br /&gt;
					obj.link = makeBlueLink(root .. &amp;#039;/&amp;#039; .. k, lang)&lt;br /&gt;
					obj.page = root .. &amp;#039;/&amp;#039; .. k&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				local options = {&lt;br /&gt;
					editintro = editintro,&lt;br /&gt;
					preload = &amp;#039;Template:I18ndoc&amp;#039;,&lt;br /&gt;
					summary = &amp;#039;Automatic generation of i18n documentation&amp;#039;&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
				obj.link = makeRedLink(root .. &amp;#039;/&amp;#039; .. k, lang, options)&lt;br /&gt;
				obj.page = root .. &amp;#039;/&amp;#039; .. k&lt;br /&gt;
				obj.new = true&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			table.insert(links.list, obj)&lt;br /&gt;
&lt;br /&gt;
			links.keys[k] = obj&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return links&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- @function l.userLang&lt;br /&gt;
-- @return {Lang}&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function l.userLang()&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
	local lang&lt;br /&gt;
&lt;br /&gt;
	if frame == nil then&lt;br /&gt;
		mw.log(&amp;#039;userLang(): can\&amp;#039;t get user\&amp;#039;s language without frame object, returning content language for now (&amp;#039; .. mw.language.fetchLanguageName(contentLang) .. &amp;#039;)&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
		return mw.getContentLanguage()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local code = frame:preprocess(&amp;#039;{{int:&amp;#039; .. l.langMessage .. &amp;#039;}}&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	if mw.language.fetchLanguageName(code) == &amp;#039;&amp;#039; then&lt;br /&gt;
		mw.log(&amp;#039;userLang(): unrecognised language code, returning content language (&amp;#039; .. mw.language.fetchLanguageName(contentLang) .. &amp;#039;)&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
		return mw.getContentLanguage()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return mw.language.new(code)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- @function l.pageLink&lt;br /&gt;
-- @param {Links} links&lt;br /&gt;
-- @param {table} args1&lt;br /&gt;
-- @param {table} args2&lt;br /&gt;
-- @return {table}&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function l.pageLink(links, args1, args2)&lt;br /&gt;
	local keys = links.keys&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
	local link = {}&lt;br /&gt;
&lt;br /&gt;
	local pageLang = #mw.language.fetchLanguageName(title.subpageText) ~= 0&lt;br /&gt;
		and title.subpageText&lt;br /&gt;
		or contentLang&lt;br /&gt;
	local userLang = frame&lt;br /&gt;
		and l.userLang():getCode()&lt;br /&gt;
		or &amp;#039;szl&amp;#039;&lt;br /&gt;
&lt;br /&gt;
	if l.TRANSLATE_DISABLED_TARGET_LANGUAGES[userLang] ~= nil then&lt;br /&gt;
		userLang = l.TRANSLATE_DISABLED_TARGET_LANGUAGES[userLang]&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if pageLang == contentLang then&lt;br /&gt;
		link = keys[userLang]&lt;br /&gt;
&lt;br /&gt;
		for i, l in ipairs(fallbacks[userLang] or {}) do&lt;br /&gt;
			if not link and keys[l] and not keys[l].new then&lt;br /&gt;
				link = keys[l]&lt;br /&gt;
&lt;br /&gt;
				break&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	link = (link and not link.new)&lt;br /&gt;
		and link&lt;br /&gt;
		or keys[pageLang]&lt;br /&gt;
&lt;br /&gt;
	if link.new then&lt;br /&gt;
		local langs = {}&lt;br /&gt;
&lt;br /&gt;
		for l, _ in pairs(keys) do&lt;br /&gt;
			table.insert(langs, l)&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		table.sort(langs)&lt;br /&gt;
&lt;br /&gt;
		link = keys[langs[1]]&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	do&lt;br /&gt;
		local lastPart = (link.page or &amp;#039;&amp;#039;):match(&amp;#039;[^/]+$&amp;#039;) or &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
		link.lang = mw.language.fetchLanguageName(lastPart) ~= &amp;#039;&amp;#039;&lt;br /&gt;
			and lastPart&lt;br /&gt;
			or contentLang&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return link&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- @function l.editData&lt;br /&gt;
-- @param {Links} links&lt;br /&gt;
-- @param {table} args1&lt;br /&gt;
-- @param {table} args2&lt;br /&gt;
-- @return {table}&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function l.editData(links, args1, args2)&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
	local userLang = frame:preprocess(&amp;#039;{{int:&amp;#039; .. l.langMessage .. &amp;#039;}}&amp;#039;)&lt;br /&gt;
	local pageLang = #mw.language.fetchLanguageName(title.subpageText) ~= 0&lt;br /&gt;
		and title.subpageText&lt;br /&gt;
		or l.pageLink(links, args1, args2).lang&lt;br /&gt;
&lt;br /&gt;
	if l.TRANSLATE_DISABLED_TARGET_LANGUAGES[userLang] ~= nil then&lt;br /&gt;
		userLang = l.TRANSLATE_DISABLED_TARGET_LANGUAGES[userLang]&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return tostring(mw.html.create(&amp;#039;span&amp;#039;)&lt;br /&gt;
		:attr(&amp;#039;class&amp;#039;, &amp;#039;lang-select-data wds-is-hidden&amp;#039;)&lt;br /&gt;
		-- Start LangSelect.js attributes.&lt;br /&gt;
		:attr(&amp;#039;data-lang&amp;#039;, pageLang)&lt;br /&gt;
		:attr(&amp;#039;data-lang-name&amp;#039;, mw.language.fetchLanguageName(pageLang))&lt;br /&gt;
		:attr(&amp;#039;data-userlang-translatable&amp;#039;, userLang)&lt;br /&gt;
		:attr(&amp;#039;data-userlang-name&amp;#039;, mw.language.fetchLanguageName(userLang))&lt;br /&gt;
		:attr(&amp;#039;data-userlang-exists&amp;#039;, tostring((links.keys[userLang] and not links.keys[userLang].new) or false))&lt;br /&gt;
		-- End LangSelect.js attributes.&lt;br /&gt;
	)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
l.formats = {}&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- @function l.formats.default&lt;br /&gt;
-- @param {Links} links&lt;br /&gt;
-- @param {table} args1&lt;br /&gt;
-- @param {table} args2&lt;br /&gt;
-- @param {string} root&lt;br /&gt;
-- @return {table}&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function l.formats.default(links, args1, args2, uselangs)&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
&lt;br /&gt;
	local div = mw.html.create(&amp;#039;div&amp;#039;)&lt;br /&gt;
		:addClass(args1.class)&lt;br /&gt;
&lt;br /&gt;
	if frame and l.userLang():isRTL() then&lt;br /&gt;
		div:attr(&amp;#039;dir&amp;#039;, &amp;#039;rtl&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	div&lt;br /&gt;
		:tag(&amp;#039;strong&amp;#039;)&lt;br /&gt;
			:wikitext(frame and frame:preprocess(&amp;#039;[[w:c:dev:Languages|{{int:interlang-section-header-desktop}}]]&amp;#039;) or &amp;#039;Languages:&amp;#039;)&lt;br /&gt;
			:done()&lt;br /&gt;
		:wikitext(&amp;#039; &amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	local separator = frame&lt;br /&gt;
		and frame:preprocess(&amp;#039;{{int:pipe-separator}}&amp;#039;)&lt;br /&gt;
		or &amp;#039;|&amp;#039;&lt;br /&gt;
	local highlight = mw.ustring.lower(args1.highlight or &amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	for i, v in ipairs(links.list) do&lt;br /&gt;
		if i &amp;gt; 1 then&lt;br /&gt;
			div:wikitext(&amp;#039; &amp;#039; .. separator .. &amp;#039; &amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local link = v.link&lt;br /&gt;
&lt;br /&gt;
		link.tagName = &amp;#039;span&amp;#039;&lt;br /&gt;
		link:attr(&amp;#039;data-lang&amp;#039;, v.lang)&lt;br /&gt;
&lt;br /&gt;
		if highlight == v.lang then&lt;br /&gt;
			link:addClass(&amp;#039;highlight&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		div:node(link)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local selected = mw.ustring.lower(args1.select or &amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	if selected ~= &amp;#039;&amp;#039; then&lt;br /&gt;
		local flag = false&lt;br /&gt;
&lt;br /&gt;
		if links.keys[selected] and not links.keys[selected].new then&lt;br /&gt;
			links.keys[selected].link:addClass(&amp;#039;selected&amp;#039;)&lt;br /&gt;
			flag = true&lt;br /&gt;
		else&lt;br /&gt;
			for i, v in ipairs(fallbacks[selected] or {}) do&lt;br /&gt;
				if links.keys[v] and not links.keys[v].new then&lt;br /&gt;
					links.keys[v].link:addClass(&amp;#039;selected&amp;#039;)&lt;br /&gt;
					flag = true&lt;br /&gt;
&lt;br /&gt;
					break&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if not flag then&lt;br /&gt;
			links.keys.en.link:addClass(&amp;#039;selected&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if not uselangs then&lt;br /&gt;
		div = tostring(div) .. l.editData(links, args1, args2)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return div&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- @function l.formats.uselangs&lt;br /&gt;
-- @param {Links} links&lt;br /&gt;
-- @param {table} args1&lt;br /&gt;
-- @param {table} args2&lt;br /&gt;
-- @param {string} root&lt;br /&gt;
-- @return {table}&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function l.formats.uselangs(links, args1, args2, root)&lt;br /&gt;
	local div = l.formats.default(links, args1, args2, root, true)&lt;br /&gt;
&lt;br /&gt;
	for i, v in ipairs(div.nodes) do&lt;br /&gt;
		local node = div.nodes[i]&lt;br /&gt;
&lt;br /&gt;
		if node.tagName ~= nil and getAttr(node, &amp;#039;data-lang&amp;#039;) then&lt;br /&gt;
			local lang = getAttr(node, &amp;#039;data-lang&amp;#039;)&lt;br /&gt;
			local langName = mw.language.fetchLanguageName(lang)&lt;br /&gt;
&lt;br /&gt;
			if langName ~= &amp;#039;&amp;#039; then&lt;br /&gt;
				node.nodes = {}&lt;br /&gt;
				node:wikitext(&amp;#039;[&amp;#039; .. tostring(mw.uri.fullUrl(root, {uselang = lang})) .. &amp;#039; &amp;#039; .. langName .. &amp;#039;]&amp;#039;)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	div = tostring(div) .. l.editData(links, args1, args2)&lt;br /&gt;
&lt;br /&gt;
	return div&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- @function l.formats.list&lt;br /&gt;
-- @param {Links} links&lt;br /&gt;
-- @param {table} args1&lt;br /&gt;
-- @param {table} args2&lt;br /&gt;
-- @return {table}&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function l.formats.list(links, args1, args2)&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
&lt;br /&gt;
	local ul = mw.html.create(&amp;#039;ul&amp;#039;)&lt;br /&gt;
		:addClass(args1.class)&lt;br /&gt;
&lt;br /&gt;
	if frame and l.userLang():isRTL() then&lt;br /&gt;
		ul:attr(&amp;#039;dir&amp;#039;, &amp;#039;rtl&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local highlight = mw.ustring.lower(args1.highlight or &amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	for i, v in ipairs(links.list) do&lt;br /&gt;
		local link = v.link&lt;br /&gt;
&lt;br /&gt;
		link.tagName = &amp;#039;li&amp;#039;&lt;br /&gt;
		link:attr(&amp;#039;data-lang&amp;#039;, v.lang)&lt;br /&gt;
&lt;br /&gt;
		if highlight == v.lang then&lt;br /&gt;
			link:addClass(&amp;#039;highlight&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		ul:node(link):newline()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local selected = mw.ustring.lower(args1.select or &amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	if selected ~= &amp;#039;&amp;#039; then&lt;br /&gt;
		local flag = false&lt;br /&gt;
&lt;br /&gt;
		if links.keys[selected] and not links.keys[selected].new then&lt;br /&gt;
			links.keys[selected].link:addClass(&amp;#039;selected&amp;#039;)&lt;br /&gt;
			flag = true&lt;br /&gt;
		else&lt;br /&gt;
			for i, v in ipairs(fallbacks[selected] or {}) do&lt;br /&gt;
				if links.keys[v] and not links.keys[v].new then&lt;br /&gt;
					links.keys[v].link:addClass(&amp;#039;selected&amp;#039;)&lt;br /&gt;
					flag = true&lt;br /&gt;
&lt;br /&gt;
					break&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if not flag then&lt;br /&gt;
			links.keys.en.link:addClass(&amp;#039;selected&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return ul&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- @function l.formats.transclude&lt;br /&gt;
-- @param {Links} links&lt;br /&gt;
-- @param {table} args1&lt;br /&gt;
-- @param {table} args2&lt;br /&gt;
-- @return {table}&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function l.formats.transclude(links, args1, args2)&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
	local lang = frame&lt;br /&gt;
		and l.userLang():getCode()&lt;br /&gt;
		or &amp;#039;szl&amp;#039;&lt;br /&gt;
	local link = l.pageLink(links, args1, args2)&lt;br /&gt;
	local res = mw.html.create(&amp;#039;&amp;#039;)&lt;br /&gt;
	local notice = mw.ustring.lower(args1.notice or &amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	if notice == &amp;#039;top&amp;#039; or notice == &amp;#039;both&amp;#039; then&lt;br /&gt;
		res&lt;br /&gt;
			:tag(&amp;#039;div&amp;#039;)&lt;br /&gt;
				:addClass(&amp;#039;transclude-notice transclude-notice-top&amp;#039;)&lt;br /&gt;
				:wikitext(intOrI18n(&amp;#039;custom-languages-notice&amp;#039;, link.page, tostring(mw.uri.fullUrl(link.page, &amp;#039;action=edit&amp;#039;)), &amp;#039;&amp;#039;) or &amp;#039;Here goes the notice&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
		if frame and l.userLang():isRTL() then&lt;br /&gt;
			res:attr(&amp;#039;dir&amp;#039;, &amp;#039;rtl&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		res:done():newline()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if frame then&lt;br /&gt;
		if not pcall(function ()&lt;br /&gt;
			res:wikitext(frame:expandTemplate{&lt;br /&gt;
				title = mw.ustring.gsub(link.page, &amp;#039;^:*&amp;#039;, &amp;#039;:&amp;#039;)&lt;br /&gt;
			})&lt;br /&gt;
		end) then&lt;br /&gt;
			return args1.missing or &amp;#039;[[:&amp;#039; .. link.page .. &amp;#039;]]&amp;#039;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
	else&lt;br /&gt;
		res:wikitext(&amp;#039;Here goes the transcluded page: &amp;#039; .. mw.ustring.gsub(link.page, &amp;#039;^:*&amp;#039;, &amp;#039;:&amp;#039;))&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if notice == &amp;#039;bottom&amp;#039; or notice == &amp;#039;both&amp;#039; then&lt;br /&gt;
		res&lt;br /&gt;
			:newline()&lt;br /&gt;
			:tag(&amp;#039;div&amp;#039;)&lt;br /&gt;
				:addClass(&amp;#039;transclude-notice transclude-notice-bottom&amp;#039;)&lt;br /&gt;
				:wikitext(intOrI18n(&amp;#039;custom-languages-notice&amp;#039;, link.page, tostring(mw.uri.fullUrl(link.page, &amp;#039;action=edit&amp;#039;)), &amp;#039;*&amp;#039;) or &amp;#039;Here goes the notice&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
		if frame and l.userLang():isRTL() then&lt;br /&gt;
			res:attr(&amp;#039;dir&amp;#039;, &amp;#039;rtl&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return res&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- @function l.formats.interwiki&lt;br /&gt;
-- @param {Links} links&lt;br /&gt;
-- @param {table} args1&lt;br /&gt;
-- @param {table} args2&lt;br /&gt;
-- @param {string} prefixedRoot&lt;br /&gt;
-- @return {table}&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function l.formats.interwiki(links, args1, args2, prefixedRoot)&lt;br /&gt;
	local str = &amp;#039;&amp;#039;&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
&lt;br /&gt;
	for k, v in ipairs(links.list) do&lt;br /&gt;
		if not v.new and v.lang ~= contentLang then&lt;br /&gt;
			str = str .. &amp;#039;[[&amp;#039; .. v.lang .. &amp;#039;:&amp;#039; .. prefixedRoot .. &amp;#039;/&amp;#039; .. v.lang .. &amp;#039;]]&amp;#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	str = str .. l.editData(links, args1, args2)&lt;br /&gt;
&lt;br /&gt;
	return frame&lt;br /&gt;
		and frame:preprocess(str)&lt;br /&gt;
		or mw.text.nowiki(str)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- @function l.subpages&lt;br /&gt;
-- @param {string} page&lt;br /&gt;
-- @param[opt] {string} namespace&lt;br /&gt;
-- @param[opt] {string} redirects nil|exclude|include|only&lt;br /&gt;
-- @return {table}&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function l.subpages(page, namespace, redirects)&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
	if redirects == &amp;#039;exclude&amp;#039; then&lt;br /&gt;
		redirects = &amp;#039;exclude&amp;#039;&lt;br /&gt;
	elseif redirects == &amp;#039;only&amp;#039; then&lt;br /&gt;
		redirects = &amp;#039;only&amp;#039;&lt;br /&gt;
	else&lt;br /&gt;
		redirects = &amp;#039;include&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if frame == nil then&lt;br /&gt;
		return {&amp;#039;en&amp;#039;, &amp;#039;fr&amp;#039;, &amp;#039;pl&amp;#039;, &amp;#039;es&amp;#039;, &amp;#039;de&amp;#039;, &amp;#039;bad-code&amp;#039;}&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local existing = mw.ustring.lower(frame:preprocess(&amp;#039;{{#dpl:namespace=&amp;#039; .. (namespace or &amp;#039;&amp;#039;) .. &amp;#039;|titleregexp=^&amp;#039; .. escRx(page, true) .. &amp;#039;\\/[a-z-]+$|replaceintitle=/^&amp;#039; .. escRx(page, false) .. &amp;#039;\\//,|redirects=&amp;#039; .. redirects  .. &amp;#039;|skipthispage=no|format=¦,%TITLE%¦|noresultsheader=¦¦}}&amp;#039;))&lt;br /&gt;
&lt;br /&gt;
	existing = select(3, mw.ustring.find(existing, &amp;#039;^%s*%|([%|a-z-]*)%|%s*$&amp;#039;))&lt;br /&gt;
&lt;br /&gt;
	if existing then&lt;br /&gt;
		return mw.text.split(existing, &amp;#039;%s*|%s*&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- @function l.langs&lt;br /&gt;
-- @param {Frame} frame&lt;br /&gt;
-- @return {string}&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function l.langs(frame)&lt;br /&gt;
	-- Invoke-only parameters&lt;br /&gt;
	local args1 = getArgs(frame, {&lt;br /&gt;
		trim = true,&lt;br /&gt;
		removeBlanks = true,&lt;br /&gt;
		frameOnly = true,&lt;br /&gt;
		readOnly = true&lt;br /&gt;
	})&lt;br /&gt;
&lt;br /&gt;
	-- Overwritable parameters&lt;br /&gt;
	local args2 = getArgs(frame, {&lt;br /&gt;
		trim = true,&lt;br /&gt;
		removeBlanks = true,&lt;br /&gt;
		parentFirst = true,&lt;br /&gt;
		readOnly = true&lt;br /&gt;
	})&lt;br /&gt;
&lt;br /&gt;
	-- Pass to format function&lt;br /&gt;
	local format = mw.ustring.lower(args1.format or &amp;#039;interwiki&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	local redirect = &amp;#039;&amp;#039;&lt;br /&gt;
	if format == &amp;#039;interwiki&amp;#039; then&lt;br /&gt;
		redirect = &amp;#039;exclude&amp;#039;&lt;br /&gt;
	else&lt;br /&gt;
		redirect = &amp;#039;include&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Get the root page name&lt;br /&gt;
	local root&lt;br /&gt;
	local rootTitle = args1.page&lt;br /&gt;
		and mw.title.new(args1.page)&lt;br /&gt;
		or mw.title.getCurrentTitle()&lt;br /&gt;
&lt;br /&gt;
	if&lt;br /&gt;
		mw.ustring.find(rootTitle.subpageText, &amp;#039;[a-z-]+&amp;#039;) and&lt;br /&gt;
		mw.language.fetchLanguageName(rootTitle.subpageText) ~= &amp;#039;&amp;#039;&lt;br /&gt;
	then&lt;br /&gt;
		root = rootTitle.baseText&lt;br /&gt;
	else&lt;br /&gt;
		root = rootTitle.text&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local prefixedRoot = rootTitle.nsText&lt;br /&gt;
&lt;br /&gt;
	prefixedRoot = mw.ustring.gsub(prefixedRoot .. &amp;#039;:&amp;#039; .. root, &amp;#039;^:*&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	-- Must-have languages&lt;br /&gt;
	local langs = {}&lt;br /&gt;
&lt;br /&gt;
	for i, v in ipairs(args1 or {}) do&lt;br /&gt;
		v = mw.ustring.lower(mw.text.trim(v or &amp;#039;&amp;#039;))&lt;br /&gt;
&lt;br /&gt;
		if v ~= &amp;#039;&amp;#039; then&lt;br /&gt;
			langs[v] = false&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	langs[contentLang] = true&lt;br /&gt;
&lt;br /&gt;
	-- Go over subpages of root&lt;br /&gt;
	local existing = l.subpages(root, rootTitle.nsText, redirect) or {}&lt;br /&gt;
&lt;br /&gt;
	for i, v in ipairs(existing) do&lt;br /&gt;
		if v ~= &amp;#039;&amp;#039; then&lt;br /&gt;
			if v == contentLang then -- English has a separate subpage&lt;br /&gt;
				langs[contentLang] = mw.ustring.gsub(rootTitle.nsText .. &amp;#039;:&amp;#039; .. root, &amp;#039;^:&amp;#039;, &amp;#039;&amp;#039;) .. &amp;#039;/&amp;#039; .. contentLang&lt;br /&gt;
			else&lt;br /&gt;
				langs[v] = true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Look for parameters overriding language pages&lt;br /&gt;
	for k, v in pairs(args2) do&lt;br /&gt;
		if type(k) == &amp;#039;string&amp;#039; and mw.language.fetchLanguageName(k) ~= &amp;#039;&amp;#039; then&lt;br /&gt;
			langs[k] = v&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Get a list of langs sorted by code&lt;br /&gt;
	local ordered = {}&lt;br /&gt;
&lt;br /&gt;
	for k, v in pairs(langs) do&lt;br /&gt;
		if k ~= contentLang then&lt;br /&gt;
			ordered[#ordered + 1] = k&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	table.sort(ordered)&lt;br /&gt;
	table.insert(ordered, 1, contentLang) -- with English being first&lt;br /&gt;
&lt;br /&gt;
	-- Get list of links&lt;br /&gt;
	local links = prepLinks(prefixedRoot, langs, ordered, args1.editintro)&lt;br /&gt;
&lt;br /&gt;
	return l.formats[format](links, args1, args2, prefixedRoot)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Preload function for i18n documentation&lt;br /&gt;
--&lt;br /&gt;
-- @function l.preload&lt;br /&gt;
-- @param {Frame} frame&lt;br /&gt;
-- @return {string}&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function l.preload(frame)&lt;br /&gt;
	-- Fetch page&lt;br /&gt;
	local page = frame.args[1]&lt;br /&gt;
	local namespace = frame.args[2]&lt;br /&gt;
	if namespace ~= &amp;#039;&amp;#039; then&lt;br /&gt;
		page = namespace .. &amp;#039;:&amp;#039; .. page&lt;br /&gt;
	end&lt;br /&gt;
	local txt = mw.title.new(page):getContent():gsub(&amp;#039;&amp;lt;!%-(.-)%-&amp;gt;&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	-- Generate untranslated doc&lt;br /&gt;
	local ret = &amp;#039;{{Untranslated}}\n&amp;#039;&lt;br /&gt;
	local tbl, i18n&lt;br /&gt;
&lt;br /&gt;
	-- Temporary parsing of legacy i18n&lt;br /&gt;
	local LANGSELECT = &amp;#039;{{LangSelect}}&amp;#039;&lt;br /&gt;
	local LANGUAGES = &amp;#039;{{Languages}}&amp;#039;&lt;br /&gt;
	local txtInline = mw.text.trim((txt:gsub(&amp;#039;\n&amp;#039;, &amp;#039;&amp;#039;)))&lt;br /&gt;
&lt;br /&gt;
	if&lt;br /&gt;
		txtInline == LANGSELECT or&lt;br /&gt;
		txtInline == LANGSELECT .. LANGUAGES or&lt;br /&gt;
		txtInline == LANGUAGES .. LANGSELECT&lt;br /&gt;
	then&lt;br /&gt;
		ret = ret .. mw.title.new(page .. &amp;#039;/en&amp;#039;):getContent():gsub(&amp;#039;&amp;lt;!%-(.-)%-&amp;gt;&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	elseif not txt:find(&amp;#039;{{{&amp;#039;) then&lt;br /&gt;
		ret = ret .. frame:preprocess(txt)&lt;br /&gt;
&lt;br /&gt;
	-- Parsing parameter defaults in base page&lt;br /&gt;
   else&lt;br /&gt;
		ret = ret .. &amp;#039;{{:&amp;#039; .. page&lt;br /&gt;
&lt;br /&gt;
		for en in txt:gmatch(&amp;#039;{{%b{}}}&amp;#039;) do&lt;br /&gt;
			en = en:match(&amp;#039;^{{{(.-)}}}$&amp;#039;)&lt;br /&gt;
			tbl = mw.text.split(en, &amp;#039;|&amp;#039;)&lt;br /&gt;
			i18n = {&lt;br /&gt;
				key = en:match(&amp;#039;^([^|]+)&amp;#039;) or &amp;#039;&amp;#039;,&lt;br /&gt;
				val = en:match(&amp;#039;^[^|]+|*(.*)$&amp;#039;) or &amp;#039;&amp;#039;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if not ret:find(&amp;#039;| &amp;#039; .. (i18n.key:gsub(&amp;#039;%-&amp;#039;, &amp;#039;%%-&amp;#039;)) .. &amp;#039; = &amp;#039;) then&lt;br /&gt;
				ret = ret .. &amp;#039;\n| &amp;#039; .. i18n.key .. &amp;#039; = &amp;#039; .. i18n.val&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		ret = ret .. &amp;#039;\n}}&amp;#039;&lt;br /&gt;
&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return ret&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return l&lt;/div&gt;</summary>
		<author><name>Fandom&gt;Winston Sung</name></author>
	</entry>
</feed>