<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://help.gulfstatesflood.com/mediawiki/index.php?action=history&amp;feed=atom&amp;title=Module%3ANavbox</id>
	<title>Module:Navbox - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://help.gulfstatesflood.com/mediawiki/index.php?action=history&amp;feed=atom&amp;title=Module%3ANavbox"/>
	<link rel="alternate" type="text/html" href="https://help.gulfstatesflood.com/mediawiki/index.php?title=Module:Navbox&amp;action=history"/>
	<updated>2026-04-06T01:05:53Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.42.0</generator>
	<entry>
		<id>https://help.gulfstatesflood.com/mediawiki/index.php?title=Module:Navbox&amp;diff=6792&amp;oldid=prev</id>
		<title>WikiAdmin: Created page with &quot;require(&#039;strict&#039;) local p = {} local cfg = mw.loadData(&#039;Module:Navbox/configuration&#039;) local inArray = require(&quot;Module:TableTools&quot;).inArray local getArgs -- lazily initialized local format = string.format  function p._navbox(args) 	local function striped(wikitext, border) 		-- Return wikitext with markers replaced for odd/even striping. 		-- Child (subgroup) navboxes are flagged with a category that is removed 		-- by parent navboxes. The result is that the category shows...&quot;</title>
		<link rel="alternate" type="text/html" href="https://help.gulfstatesflood.com/mediawiki/index.php?title=Module:Navbox&amp;diff=6792&amp;oldid=prev"/>
		<updated>2024-12-30T21:52:49Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;require(&amp;#039;strict&amp;#039;) local p = {} local cfg = mw.loadData(&amp;#039;Module:Navbox/configuration&amp;#039;) local inArray = require(&amp;quot;Module:TableTools&amp;quot;).inArray local getArgs -- lazily initialized local format = string.format  function p._navbox(args) 	local function striped(wikitext, border) 		-- Return wikitext with markers replaced for odd/even striping. 		-- Child (subgroup) navboxes are flagged with a category that is removed 		-- by parent navboxes. The result is that the category shows...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;require(&amp;#039;strict&amp;#039;)&lt;br /&gt;
local p = {}&lt;br /&gt;
local cfg = mw.loadData(&amp;#039;Module:Navbox/configuration&amp;#039;)&lt;br /&gt;
local inArray = require(&amp;quot;Module:TableTools&amp;quot;).inArray&lt;br /&gt;
local getArgs -- lazily initialized&lt;br /&gt;
local format = string.format&lt;br /&gt;
&lt;br /&gt;
function p._navbox(args)&lt;br /&gt;
	local function striped(wikitext, border)&lt;br /&gt;
		-- Return wikitext with markers replaced for odd/even striping.&lt;br /&gt;
		-- Child (subgroup) navboxes are flagged with a category that is removed&lt;br /&gt;
		-- by parent navboxes. The result is that the category shows all pages&lt;br /&gt;
		-- where a child navbox is not contained in a parent navbox.&lt;br /&gt;
		local orphanCat = cfg.category.orphan&lt;br /&gt;
		if border == cfg.keyword.border_subgroup and args[cfg.arg.orphan] ~= cfg.keyword.orphan_yes then&lt;br /&gt;
			-- No change; striping occurs in outermost navbox.&lt;br /&gt;
			return wikitext .. orphanCat&lt;br /&gt;
		end&lt;br /&gt;
		local first, second = cfg.class.navbox_odd_part, cfg.class.navbox_even_part&lt;br /&gt;
		if args[cfg.arg.evenodd] then&lt;br /&gt;
			if args[cfg.arg.evenodd] == cfg.keyword.evenodd_swap then&lt;br /&gt;
				first, second = second, first&lt;br /&gt;
			else&lt;br /&gt;
				first = args[cfg.arg.evenodd]&lt;br /&gt;
				second = first&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		local changer&lt;br /&gt;
		if first == second then&lt;br /&gt;
			changer = first&lt;br /&gt;
		else&lt;br /&gt;
			local index = 0&lt;br /&gt;
			changer = function (code)&lt;br /&gt;
				if code == &amp;#039;0&amp;#039; then&lt;br /&gt;
					-- Current occurrence is for a group before a nested table.&lt;br /&gt;
					-- Set it to first as a valid although pointless class.&lt;br /&gt;
					-- The next occurrence will be the first row after a title&lt;br /&gt;
					-- in a subgroup and will also be first.&lt;br /&gt;
					index = 0&lt;br /&gt;
					return first&lt;br /&gt;
				end&lt;br /&gt;
				index = index + 1&lt;br /&gt;
				return index % 2 == 1 and first or second&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		local regex = orphanCat:gsub(&amp;#039;([%[%]])&amp;#039;, &amp;#039;%%%1&amp;#039;)&lt;br /&gt;
		return (wikitext:gsub(regex, &amp;#039;&amp;#039;):gsub(cfg.marker.regex, changer)) -- () omits gsub count&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function processItem(item, nowrapitems)&lt;br /&gt;
		if item:sub(1, 2) == &amp;#039;{|&amp;#039; then&lt;br /&gt;
			-- Applying nowrap to lines in a table does not make sense.&lt;br /&gt;
			-- Add newlines to compensate for trim of x in |parm=x in a template.&lt;br /&gt;
			return &amp;#039;\n&amp;#039; .. item ..&amp;#039;\n&amp;#039;&lt;br /&gt;
		end&lt;br /&gt;
		if nowrapitems == cfg.keyword.nowrapitems_yes then&lt;br /&gt;
			local lines = {}&lt;br /&gt;
			for line in (item .. &amp;#039;\n&amp;#039;):gmatch(&amp;#039;([^\n]*)\n&amp;#039;) do&lt;br /&gt;
				local prefix, content = line:match(&amp;#039;^([*:;#]+)%s*(.*)&amp;#039;)&lt;br /&gt;
				if prefix and not content:match(cfg.pattern.nowrap) then&lt;br /&gt;
					line = format(cfg.nowrap_item, prefix, content)&lt;br /&gt;
				end&lt;br /&gt;
				table.insert(lines, line)&lt;br /&gt;
			end&lt;br /&gt;
			item = table.concat(lines, &amp;#039;\n&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
		if item:match(&amp;#039;^[*:;#]&amp;#039;) then&lt;br /&gt;
			return &amp;#039;\n&amp;#039; .. item ..&amp;#039;\n&amp;#039;&lt;br /&gt;
		end&lt;br /&gt;
		return item&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function has_navbar()&lt;br /&gt;
		return args[cfg.arg.navbar] ~= cfg.keyword.navbar_off&lt;br /&gt;
			and args[cfg.arg.navbar] ~= cfg.keyword.navbar_plain&lt;br /&gt;
			and (&lt;br /&gt;
				args[cfg.arg.name]&lt;br /&gt;
				or mw.getCurrentFrame():getParent():getTitle():gsub(cfg.pattern.sandbox, &amp;#039;&amp;#039;)&lt;br /&gt;
					~= cfg.pattern.navbox&lt;br /&gt;
			)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- extract text color from css, which is the only permitted inline CSS for the navbar&lt;br /&gt;
	local function extract_color(css_str)&lt;br /&gt;
		-- return nil because navbar takes its argument into mw.html which handles&lt;br /&gt;
		-- nil gracefully, removing the associated style attribute&lt;br /&gt;
		return mw.ustring.match(&amp;#039;;&amp;#039; .. css_str .. &amp;#039;;&amp;#039;, &amp;#039;.*;%s*([Cc][Oo][Ll][Oo][Rr]%s*:%s*.-)%s*;&amp;#039;) or nil&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function renderNavBar(titleCell)&lt;br /&gt;
		if has_navbar() then&lt;br /&gt;
			local navbar = require(&amp;#039;Module:Navbar&amp;#039;)._navbar&lt;br /&gt;
			titleCell:wikitext(navbar{&lt;br /&gt;
				[cfg.navbar.name] = args[cfg.arg.name],&lt;br /&gt;
				[cfg.navbar.mini] = 1,&lt;br /&gt;
				[cfg.navbar.fontstyle] = extract_color(&lt;br /&gt;
					(args[cfg.arg.basestyle] or &amp;#039;&amp;#039;) .. &amp;#039;;&amp;#039; .. (args[cfg.arg.titlestyle] or &amp;#039;&amp;#039;)&lt;br /&gt;
				)&lt;br /&gt;
			})&lt;br /&gt;
		end&lt;br /&gt;
	&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function renderTitleRow(tbl)&lt;br /&gt;
		if not args[cfg.arg.title] then return end&lt;br /&gt;
	&lt;br /&gt;
		local titleRow = tbl:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
	&lt;br /&gt;
		local titleCell = titleRow:tag(&amp;#039;th&amp;#039;):attr(&amp;#039;scope&amp;#039;, &amp;#039;col&amp;#039;)&lt;br /&gt;
	&lt;br /&gt;
		local titleColspan = 2&lt;br /&gt;
		if args[cfg.arg.imageleft] then titleColspan = titleColspan + 1 end&lt;br /&gt;
		if args[cfg.arg.image] then titleColspan = titleColspan + 1 end&lt;br /&gt;
	&lt;br /&gt;
		titleCell&lt;br /&gt;
			:cssText(args[cfg.arg.basestyle])&lt;br /&gt;
			:cssText(args[cfg.arg.titlestyle])&lt;br /&gt;
			:addClass(cfg.class.navbox_title)&lt;br /&gt;
			:attr(&amp;#039;colspan&amp;#039;, titleColspan)&lt;br /&gt;
	&lt;br /&gt;
		renderNavBar(titleCell)&lt;br /&gt;
	&lt;br /&gt;
		titleCell&lt;br /&gt;
			:tag(&amp;#039;div&amp;#039;)&lt;br /&gt;
				-- id for aria-labelledby attribute&lt;br /&gt;
				:attr(&amp;#039;id&amp;#039;, mw.uri.anchorEncode(args[cfg.arg.title]))&lt;br /&gt;
				:addClass(args[cfg.arg.titleclass])&lt;br /&gt;
				:css(&amp;#039;font-size&amp;#039;, &amp;#039;114%&amp;#039;)&lt;br /&gt;
				:css(&amp;#039;margin&amp;#039;, &amp;#039;0 4em&amp;#039;)&lt;br /&gt;
				:wikitext(processItem(args[cfg.arg.title]))&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function getAboveBelowColspan()&lt;br /&gt;
		local ret = 2&lt;br /&gt;
		if args[cfg.arg.imageleft] then ret = ret + 1 end&lt;br /&gt;
		if args[cfg.arg.image] then ret = ret + 1 end&lt;br /&gt;
		return ret&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function renderAboveRow(tbl)&lt;br /&gt;
		if not args[cfg.arg.above] then return end&lt;br /&gt;
	&lt;br /&gt;
		tbl:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
			:tag(&amp;#039;td&amp;#039;)&lt;br /&gt;
				:addClass(cfg.class.navbox_abovebelow)&lt;br /&gt;
				:addClass(args[cfg.arg.aboveclass])&lt;br /&gt;
				:cssText(args[cfg.arg.basestyle])&lt;br /&gt;
				:cssText(args[cfg.arg.abovestyle])&lt;br /&gt;
				:attr(&amp;#039;colspan&amp;#039;, getAboveBelowColspan())&lt;br /&gt;
				:tag(&amp;#039;div&amp;#039;)&lt;br /&gt;
					-- id for aria-labelledby attribute, if no title&lt;br /&gt;
					:attr(&amp;#039;id&amp;#039;, (not args[cfg.arg.title]) and mw.uri.anchorEncode(args[cfg.arg.above]) or nil)&lt;br /&gt;
					:wikitext(processItem(args[cfg.arg.above], args[cfg.arg.nowrapitems]))&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function renderBelowRow(tbl)&lt;br /&gt;
		if not args[cfg.arg.below] then return end&lt;br /&gt;
	&lt;br /&gt;
		tbl:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
			:tag(&amp;#039;td&amp;#039;)&lt;br /&gt;
				:addClass(cfg.class.navbox_abovebelow)&lt;br /&gt;
				:addClass(args[cfg.arg.belowclass])&lt;br /&gt;
				:cssText(args[cfg.arg.basestyle])&lt;br /&gt;
				:cssText(args[cfg.arg.belowstyle])&lt;br /&gt;
				:attr(&amp;#039;colspan&amp;#039;, getAboveBelowColspan())&lt;br /&gt;
				:tag(&amp;#039;div&amp;#039;)&lt;br /&gt;
					:wikitext(processItem(args[cfg.arg.below], args[cfg.arg.nowrapitems]))&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function renderListRow(tbl, index, listnum, listnums_size)&lt;br /&gt;
		local row = tbl:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
	&lt;br /&gt;
		if index == 1 and args[cfg.arg.imageleft] then&lt;br /&gt;
			row&lt;br /&gt;
				:tag(&amp;#039;td&amp;#039;)&lt;br /&gt;
					:addClass(cfg.class.noviewer)&lt;br /&gt;
					:addClass(cfg.class.navbox_image)&lt;br /&gt;
					:addClass(args[cfg.arg.imageclass])&lt;br /&gt;
					:css(&amp;#039;width&amp;#039;, &amp;#039;1px&amp;#039;)               -- Minimize width&lt;br /&gt;
					:css(&amp;#039;padding&amp;#039;, &amp;#039;0 2px 0 0&amp;#039;)&lt;br /&gt;
					:cssText(args[cfg.arg.imageleftstyle])&lt;br /&gt;
					:attr(&amp;#039;rowspan&amp;#039;, listnums_size)&lt;br /&gt;
					:tag(&amp;#039;div&amp;#039;)&lt;br /&gt;
						:wikitext(processItem(args[cfg.arg.imageleft]))&lt;br /&gt;
		end&lt;br /&gt;
	&lt;br /&gt;
		local group_and_num = format(cfg.arg.group_and_num, listnum)&lt;br /&gt;
		local groupstyle_and_num = format(cfg.arg.groupstyle_and_num, listnum)&lt;br /&gt;
		if args[group_and_num] then&lt;br /&gt;
			local groupCell = row:tag(&amp;#039;th&amp;#039;)&lt;br /&gt;
	&lt;br /&gt;
			-- id for aria-labelledby attribute, if lone group with no title or above&lt;br /&gt;
			if listnum == 1 and not (args[cfg.arg.title] or args[cfg.arg.above] or args[cfg.arg.group2]) then&lt;br /&gt;
				groupCell&lt;br /&gt;
					:attr(&amp;#039;id&amp;#039;, mw.uri.anchorEncode(args[cfg.arg.group1]))&lt;br /&gt;
			end&lt;br /&gt;
	&lt;br /&gt;
			groupCell&lt;br /&gt;
				:attr(&amp;#039;scope&amp;#039;, &amp;#039;row&amp;#039;)&lt;br /&gt;
				:addClass(cfg.class.navbox_group)&lt;br /&gt;
				:addClass(args[cfg.arg.groupclass])&lt;br /&gt;
				:cssText(args[cfg.arg.basestyle])&lt;br /&gt;
				-- If groupwidth not specified, minimize width&lt;br /&gt;
				:css(&amp;#039;width&amp;#039;, args[cfg.arg.groupwidth] or &amp;#039;1%&amp;#039;)&lt;br /&gt;
	&lt;br /&gt;
			groupCell&lt;br /&gt;
				:cssText(args[cfg.arg.groupstyle])&lt;br /&gt;
				:cssText(args[groupstyle_and_num])&lt;br /&gt;
				:wikitext(args[group_and_num])&lt;br /&gt;
		end&lt;br /&gt;
	&lt;br /&gt;
		local listCell = row:tag(&amp;#039;td&amp;#039;)&lt;br /&gt;
	&lt;br /&gt;
		if args[group_and_num] then&lt;br /&gt;
			listCell&lt;br /&gt;
				:addClass(cfg.class.navbox_list_with_group)&lt;br /&gt;
		else&lt;br /&gt;
			listCell:attr(&amp;#039;colspan&amp;#039;, 2)&lt;br /&gt;
		end&lt;br /&gt;
	&lt;br /&gt;
		if not args[cfg.arg.groupwidth] then&lt;br /&gt;
			listCell:css(&amp;#039;width&amp;#039;, &amp;#039;100%&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
	&lt;br /&gt;
		local rowstyle  -- usually nil so cssText(rowstyle) usually adds nothing&lt;br /&gt;
		if index % 2 == 1 then&lt;br /&gt;
			rowstyle = args[cfg.arg.oddstyle]&lt;br /&gt;
		else&lt;br /&gt;
			rowstyle = args[cfg.arg.evenstyle]&lt;br /&gt;
		end&lt;br /&gt;
	&lt;br /&gt;
		local list_and_num = format(cfg.arg.list_and_num, listnum)&lt;br /&gt;
		local listText = args[list_and_num]&lt;br /&gt;
		&lt;br /&gt;
		if inArray(cfg.keyword.subgroups, listText) then&lt;br /&gt;
			local childArgs = {&lt;br /&gt;
				[cfg.arg.border] = cfg.keyword.border_subgroup,&lt;br /&gt;
				[cfg.arg.navbar] = cfg.keyword.navbar_plain&lt;br /&gt;
			}&lt;br /&gt;
			local hasChildArgs = false&lt;br /&gt;
			for k, v in pairs(args) do&lt;br /&gt;
				k = tostring(k)&lt;br /&gt;
				for _, w in ipairs(cfg.keyword.subgroups) do&lt;br /&gt;
					w = w .. listnum .. &amp;quot;_&amp;quot;&lt;br /&gt;
					if (#k &amp;gt; #w) and (k:sub(1, #w) == w) then&lt;br /&gt;
						childArgs[k:sub(#w + 1)] = v&lt;br /&gt;
						hasChildArgs = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			listText = hasChildArgs and p._navbox(childArgs) or listText&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		local oddEven = cfg.marker.oddeven&lt;br /&gt;
		if listText:sub(1, 12) == &amp;#039;&amp;lt;/div&amp;gt;&amp;lt;table&amp;#039; then&lt;br /&gt;
			-- Assume list text is for a subgroup navbox so no automatic striping for this row.&lt;br /&gt;
			oddEven = listText:find(cfg.pattern.navbox_title) and cfg.marker.restart or cfg.class.navbox_odd_part&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		local liststyle_and_num = format(cfg.arg.liststyle_and_num, listnum)&lt;br /&gt;
		local listclass_and_num = format(cfg.arg.listclass_and_num, listnum)&lt;br /&gt;
		listCell&lt;br /&gt;
			:css(&amp;#039;padding&amp;#039;, &amp;#039;0&amp;#039;)&lt;br /&gt;
			:cssText(args[cfg.arg.liststyle])&lt;br /&gt;
			:cssText(rowstyle)&lt;br /&gt;
			:cssText(args[liststyle_and_num])&lt;br /&gt;
			:addClass(cfg.class.navbox_list)&lt;br /&gt;
			:addClass(cfg.class.navbox_part .. oddEven)&lt;br /&gt;
			:addClass(args[cfg.arg.listclass])&lt;br /&gt;
			:addClass(args[listclass_and_num])&lt;br /&gt;
			:tag(&amp;#039;div&amp;#039;)&lt;br /&gt;
				:css(&amp;#039;padding&amp;#039;,&lt;br /&gt;
					(index == 1 and args[cfg.arg.list1padding]) or args[cfg.arg.listpadding] or &amp;#039;0 0.25em&amp;#039;&lt;br /&gt;
				)&lt;br /&gt;
				:wikitext(processItem(listText, args[cfg.arg.nowrapitems]))&lt;br /&gt;
	&lt;br /&gt;
		if index == 1 and args[cfg.arg.image] then&lt;br /&gt;
			row&lt;br /&gt;
				:tag(&amp;#039;td&amp;#039;)&lt;br /&gt;
					:addClass(cfg.class.noviewer)&lt;br /&gt;
					:addClass(cfg.class.navbox_image)&lt;br /&gt;
					:addClass(args[cfg.arg.imageclass])&lt;br /&gt;
					:css(&amp;#039;width&amp;#039;, &amp;#039;1px&amp;#039;)               -- Minimize width&lt;br /&gt;
					:css(&amp;#039;padding&amp;#039;, &amp;#039;0 0 0 2px&amp;#039;)&lt;br /&gt;
					:cssText(args[cfg.arg.imagestyle])&lt;br /&gt;
					:attr(&amp;#039;rowspan&amp;#039;, listnums_size)&lt;br /&gt;
					:tag(&amp;#039;div&amp;#039;)&lt;br /&gt;
						:wikitext(processItem(args[cfg.arg.image]))&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function has_list_class(htmlclass)&lt;br /&gt;
		local patterns = {&lt;br /&gt;
			&amp;#039;^&amp;#039; .. htmlclass .. &amp;#039;$&amp;#039;,&lt;br /&gt;
			&amp;#039;%s&amp;#039; .. htmlclass .. &amp;#039;$&amp;#039;,&lt;br /&gt;
			&amp;#039;^&amp;#039; .. htmlclass .. &amp;#039;%s&amp;#039;,&lt;br /&gt;
			&amp;#039;%s&amp;#039; .. htmlclass .. &amp;#039;%s&amp;#039;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		for arg, _ in pairs(args) do&lt;br /&gt;
			if type(arg) == &amp;#039;string&amp;#039; and mw.ustring.find(arg, cfg.pattern.class) then&lt;br /&gt;
				for _, pattern in ipairs(patterns) do&lt;br /&gt;
					if mw.ustring.find(args[arg] or &amp;#039;&amp;#039;, pattern) 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;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- there are a lot of list classes in the wild, so we add their TemplateStyles&lt;br /&gt;
	local function add_list_styles()&lt;br /&gt;
		local frame = mw.getCurrentFrame()&lt;br /&gt;
		local function add_list_templatestyles(htmlclass, templatestyles)&lt;br /&gt;
			if has_list_class(htmlclass) then&lt;br /&gt;
				return frame:extensionTag{&lt;br /&gt;
					name = &amp;#039;templatestyles&amp;#039;, args = { src = templatestyles }&lt;br /&gt;
				}&lt;br /&gt;
			else&lt;br /&gt;
				return &amp;#039;&amp;#039;&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		local hlist_styles = add_list_templatestyles(&amp;#039;hlist&amp;#039;, cfg.hlist_templatestyles)&lt;br /&gt;
		local plainlist_styles = add_list_templatestyles(&amp;#039;plainlist&amp;#039;, cfg.plainlist_templatestyles)&lt;br /&gt;
		&lt;br /&gt;
		-- a second workaround for [[phab:T303378]]&lt;br /&gt;
		-- when that issue is fixed, we can actually use has_navbar not to emit the&lt;br /&gt;
		-- tag here if we want&lt;br /&gt;
		if has_navbar() and hlist_styles == &amp;#039;&amp;#039; then&lt;br /&gt;
			hlist_styles = frame:extensionTag{&lt;br /&gt;
				name = &amp;#039;templatestyles&amp;#039;, args = { src = cfg.hlist_templatestyles }&lt;br /&gt;
			}&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		-- hlist -&amp;gt; plainlist is best-effort to preserve old Common.css ordering.&lt;br /&gt;
		-- this ordering is not a guarantee because most navboxes will emit only&lt;br /&gt;
		-- one of these classes [hlist_note]&lt;br /&gt;
		return hlist_styles .. plainlist_styles&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function needsHorizontalLists(border)&lt;br /&gt;
		if border == cfg.keyword.border_subgroup or args[cfg.arg.tracking] == cfg.keyword.tracking_no then&lt;br /&gt;
			return false&lt;br /&gt;
		end&lt;br /&gt;
		return not has_list_class(cfg.pattern.hlist) and not has_list_class(cfg.pattern.plainlist)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function hasBackgroundColors()&lt;br /&gt;
		for _, key in ipairs({cfg.arg.titlestyle, cfg.arg.groupstyle,&lt;br /&gt;
			cfg.arg.basestyle, cfg.arg.abovestyle, cfg.arg.belowstyle}) do&lt;br /&gt;
			if tostring(args[key]):find(&amp;#039;background&amp;#039;, 1, true) then&lt;br /&gt;
				return true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function hasBorders()&lt;br /&gt;
		for _, key in ipairs({cfg.arg.groupstyle, cfg.arg.basestyle,&lt;br /&gt;
			cfg.arg.abovestyle, cfg.arg.belowstyle}) do&lt;br /&gt;
			if tostring(args[key]):find(&amp;#039;border&amp;#039;, 1, true) then&lt;br /&gt;
				return true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function isIllegible()&lt;br /&gt;
		local styleratio = require(&amp;#039;Module:Color contrast&amp;#039;)._styleratio&lt;br /&gt;
		for key, style in pairs(args) do&lt;br /&gt;
			if tostring(key):match(cfg.pattern.style) then&lt;br /&gt;
				if styleratio{mw.text.unstripNoWiki(style)} &amp;lt; 4.5 then&lt;br /&gt;
					return true&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function getTrackingCategories(border)&lt;br /&gt;
		local cats = {}&lt;br /&gt;
		if needsHorizontalLists(border) then table.insert(cats, cfg.category.horizontal_lists) end&lt;br /&gt;
		if hasBackgroundColors() then table.insert(cats, cfg.category.background_colors) end&lt;br /&gt;
		if isIllegible() then table.insert(cats, cfg.category.illegible) end&lt;br /&gt;
		if hasBorders() then table.insert(cats, cfg.category.borders) end&lt;br /&gt;
		return cats&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function renderTrackingCategories(builder, border)&lt;br /&gt;
		local title = mw.title.getCurrentTitle()&lt;br /&gt;
		if title.namespace ~= 10 then return end -- not in template space&lt;br /&gt;
		local subpage = title.subpageText&lt;br /&gt;
		if subpage == cfg.keyword.subpage_doc or subpage == cfg.keyword.subpage_sandbox&lt;br /&gt;
			or subpage == cfg.keyword.subpage_testcases then return end&lt;br /&gt;
	&lt;br /&gt;
		for _, cat in ipairs(getTrackingCategories(border)) do&lt;br /&gt;
			builder:wikitext(&amp;#039;[[Category:&amp;#039; .. cat .. &amp;#039;]]&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function renderMainTable(border, listnums)&lt;br /&gt;
		local tbl = mw.html.create(&amp;#039;table&amp;#039;)&lt;br /&gt;
			:addClass(cfg.class.nowraplinks)&lt;br /&gt;
			:addClass(args[cfg.arg.bodyclass])&lt;br /&gt;
	&lt;br /&gt;
		local state = args[cfg.arg.state]&lt;br /&gt;
		if args[cfg.arg.title] and state ~= cfg.keyword.state_plain and state ~= cfg.keyword.state_off then&lt;br /&gt;
			if state == cfg.keyword.state_collapsed then&lt;br /&gt;
				state = cfg.class.collapsed&lt;br /&gt;
			end&lt;br /&gt;
			tbl&lt;br /&gt;
				:addClass(cfg.class.collapsible)&lt;br /&gt;
				:addClass(state or cfg.class.autocollapse)&lt;br /&gt;
		end&lt;br /&gt;
	&lt;br /&gt;
		tbl:css(&amp;#039;border-spacing&amp;#039;, 0)&lt;br /&gt;
		if border == cfg.keyword.border_subgroup or border == cfg.keyword.border_none then&lt;br /&gt;
			tbl&lt;br /&gt;
				:addClass(cfg.class.navbox_subgroup)&lt;br /&gt;
				:cssText(args[cfg.arg.bodystyle])&lt;br /&gt;
				:cssText(args[cfg.arg.style])&lt;br /&gt;
		else  -- regular navbox - bodystyle and style will be applied to the wrapper table&lt;br /&gt;
			tbl&lt;br /&gt;
				:addClass(cfg.class.navbox_inner)&lt;br /&gt;
				:css(&amp;#039;background&amp;#039;, &amp;#039;transparent&amp;#039;)&lt;br /&gt;
				:css(&amp;#039;color&amp;#039;, &amp;#039;inherit&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
		tbl:cssText(args[cfg.arg.innerstyle])&lt;br /&gt;
	&lt;br /&gt;
		renderTitleRow(tbl)&lt;br /&gt;
		renderAboveRow(tbl)&lt;br /&gt;
		local listnums_size = #listnums&lt;br /&gt;
		for i, listnum in ipairs(listnums) do&lt;br /&gt;
			renderListRow(tbl, i, listnum, listnums_size)&lt;br /&gt;
		end&lt;br /&gt;
		renderBelowRow(tbl)&lt;br /&gt;
	&lt;br /&gt;
		return tbl&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function add_navbox_styles(hiding_templatestyles)&lt;br /&gt;
		local frame = mw.getCurrentFrame()&lt;br /&gt;
		-- This is a lambda so that it doesn&amp;#039;t need the frame as a parameter&lt;br /&gt;
		local function add_user_styles(templatestyles)&lt;br /&gt;
			if templatestyles and templatestyles ~= &amp;#039;&amp;#039; then&lt;br /&gt;
				return frame:extensionTag{&lt;br /&gt;
					name = &amp;#039;templatestyles&amp;#039;, args = { src = templatestyles }&lt;br /&gt;
				}&lt;br /&gt;
			end&lt;br /&gt;
			return &amp;#039;&amp;#039;&lt;br /&gt;
		end&lt;br /&gt;
	&lt;br /&gt;
		-- get templatestyles. load base from config so that Lua only needs to do&lt;br /&gt;
		-- the work once of parser tag expansion&lt;br /&gt;
		local base_templatestyles = cfg.templatestyles&lt;br /&gt;
		local templatestyles = add_user_styles(args[cfg.arg.templatestyles])&lt;br /&gt;
		local child_templatestyles = add_user_styles(args[cfg.arg.child_templatestyles])&lt;br /&gt;
	&lt;br /&gt;
		-- The &amp;#039;navbox-styles&amp;#039; div exists to wrap the styles to work around T200206&lt;br /&gt;
		-- more elegantly. Instead of combinatorial rules, this ends up being linear&lt;br /&gt;
		-- number of CSS rules.&lt;br /&gt;
		return mw.html.create(&amp;#039;div&amp;#039;)&lt;br /&gt;
			:addClass(cfg.class.navbox_styles)&lt;br /&gt;
			:wikitext(&lt;br /&gt;
				add_list_styles() .. -- see [hlist_note] applied to &amp;#039;before base_templatestyles&amp;#039;&lt;br /&gt;
				base_templatestyles ..&lt;br /&gt;
				templatestyles ..&lt;br /&gt;
				child_templatestyles ..&lt;br /&gt;
				table.concat(hiding_templatestyles)&lt;br /&gt;
			)&lt;br /&gt;
			:done()&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- work around [[phab:T303378]]&lt;br /&gt;
	-- for each arg: find all the templatestyles strip markers, insert them into a&lt;br /&gt;
	-- table. then remove all templatestyles markers from the arg&lt;br /&gt;
	local function move_hiding_templatestyles(args)&lt;br /&gt;
		local gfind = string.gfind&lt;br /&gt;
		local gsub = string.gsub&lt;br /&gt;
		local templatestyles_markers = {}&lt;br /&gt;
		local strip_marker_pattern = &amp;#039;(\127[^\127]*UNIQ%-%-templatestyles%-%x+%-QINU[^\127]*\127)&amp;#039;&lt;br /&gt;
		for k, arg in pairs(args) do&lt;br /&gt;
			for marker in gfind(arg, strip_marker_pattern) do&lt;br /&gt;
				table.insert(templatestyles_markers, marker)&lt;br /&gt;
			end&lt;br /&gt;
			args[k] = gsub(arg, strip_marker_pattern, &amp;#039;&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
		return templatestyles_markers&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local hiding_templatestyles = move_hiding_templatestyles(args)&lt;br /&gt;
	local listnums = {}&lt;br /&gt;
	&lt;br /&gt;
	for k, _ in pairs(args) do&lt;br /&gt;
		if type(k) == &amp;#039;string&amp;#039; then&lt;br /&gt;
			local listnum = k:match(cfg.pattern.listnum)&lt;br /&gt;
			if listnum then table.insert(listnums, tonumber(listnum)) end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(listnums)&lt;br /&gt;
&lt;br /&gt;
	local border = mw.text.trim(args[cfg.arg.border] or args[1] or &amp;#039;&amp;#039;)&lt;br /&gt;
	if border == cfg.keyword.border_child then&lt;br /&gt;
		border = cfg.keyword.border_subgroup&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- render the main body of the navbox&lt;br /&gt;
	local tbl = renderMainTable(border, listnums)&lt;br /&gt;
&lt;br /&gt;
	local res = mw.html.create()&lt;br /&gt;
	-- render the appropriate wrapper for the navbox, based on the border param&lt;br /&gt;
&lt;br /&gt;
	if border == cfg.keyword.border_none then&lt;br /&gt;
		res:node(add_navbox_styles(hiding_templatestyles))&lt;br /&gt;
		local nav = res:tag(&amp;#039;div&amp;#039;)&lt;br /&gt;
			:attr(&amp;#039;role&amp;#039;, &amp;#039;navigation&amp;#039;)&lt;br /&gt;
			:node(tbl)&lt;br /&gt;
		-- aria-labelledby title, otherwise above, otherwise lone group&lt;br /&gt;
		if args[cfg.arg.title] or args[cfg.arg.above] or (args[cfg.arg.group1]&lt;br /&gt;
			and not args[cfg.arg.group2]) then&lt;br /&gt;
			nav:attr(&lt;br /&gt;
				&amp;#039;aria-labelledby&amp;#039;,&lt;br /&gt;
				mw.uri.anchorEncode(&lt;br /&gt;
					args[cfg.arg.title] or args[cfg.arg.above] or args[cfg.arg.group1]&lt;br /&gt;
				)&lt;br /&gt;
			)&lt;br /&gt;
		else&lt;br /&gt;
			nav:attr(&amp;#039;aria-label&amp;#039;, cfg.aria_label)&lt;br /&gt;
		end&lt;br /&gt;
	elseif border == cfg.keyword.border_subgroup then&lt;br /&gt;
		-- We assume that this navbox is being rendered in a list cell of a&lt;br /&gt;
		-- parent navbox, and is therefore inside a div with padding:0em 0.25em.&lt;br /&gt;
		-- We start with a &amp;lt;/div&amp;gt; to avoid the padding being applied, and at the&lt;br /&gt;
		-- end add a &amp;lt;div&amp;gt; to balance out the parent&amp;#039;s &amp;lt;/div&amp;gt;&lt;br /&gt;
		res&lt;br /&gt;
			:wikitext(&amp;#039;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
			:node(tbl)&lt;br /&gt;
			:wikitext(&amp;#039;&amp;lt;div&amp;gt;&amp;#039;)&lt;br /&gt;
	else&lt;br /&gt;
		res:node(add_navbox_styles(hiding_templatestyles))&lt;br /&gt;
		local nav = res:tag(&amp;#039;div&amp;#039;)&lt;br /&gt;
			:attr(&amp;#039;role&amp;#039;, &amp;#039;navigation&amp;#039;)&lt;br /&gt;
			:addClass(cfg.class.navbox)&lt;br /&gt;
			:addClass(args[cfg.arg.navboxclass])&lt;br /&gt;
			:cssText(args[cfg.arg.bodystyle])&lt;br /&gt;
			:cssText(args[cfg.arg.style])&lt;br /&gt;
			:css(&amp;#039;padding&amp;#039;, &amp;#039;3px&amp;#039;)&lt;br /&gt;
			:node(tbl)&lt;br /&gt;
		-- aria-labelledby title, otherwise above, otherwise lone group&lt;br /&gt;
		if args[cfg.arg.title] or args[cfg.arg.above]&lt;br /&gt;
			or (args[cfg.arg.group1] and not args[cfg.arg.group2]) then&lt;br /&gt;
			nav:attr(&lt;br /&gt;
				&amp;#039;aria-labelledby&amp;#039;,&lt;br /&gt;
				mw.uri.anchorEncode(args[cfg.arg.title] or args[cfg.arg.above] or args[cfg.arg.group1])&lt;br /&gt;
			)&lt;br /&gt;
		else&lt;br /&gt;
			nav:attr(&amp;#039;aria-label&amp;#039;, cfg.aria_label)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (args[cfg.arg.nocat] or cfg.keyword.nocat_false):lower() == cfg.keyword.nocat_false then&lt;br /&gt;
		renderTrackingCategories(res, border)&lt;br /&gt;
	end&lt;br /&gt;
	return striped(tostring(res), border)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.navbox(frame)&lt;br /&gt;
	local function readArgs(args, prefix)&lt;br /&gt;
		-- Read the arguments in the order they&amp;#039;ll be output in, to make references&lt;br /&gt;
		-- number in the right order.&lt;br /&gt;
		local _&lt;br /&gt;
		_ = args[prefix .. cfg.arg.title]&lt;br /&gt;
		_ = args[prefix .. cfg.arg.above]&lt;br /&gt;
		-- Limit this to 20 as covering &amp;#039;most&amp;#039; cases (that&amp;#039;s a SWAG) and because&lt;br /&gt;
		-- iterator approach won&amp;#039;t work here&lt;br /&gt;
		for i = 1, 20 do&lt;br /&gt;
			_ = args[prefix .. format(cfg.arg.group_and_num, i)]&lt;br /&gt;
			if inArray(cfg.keyword.subgroups, args[prefix .. format(cfg.arg.list_and_num, i)]) then&lt;br /&gt;
				for _, v in ipairs(cfg.keyword.subgroups) do&lt;br /&gt;
					readArgs(args, prefix .. v .. i .. &amp;quot;_&amp;quot;)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		_ = args[prefix .. cfg.arg.below]&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if not getArgs then&lt;br /&gt;
		getArgs = require(&amp;#039;Module:Arguments&amp;#039;).getArgs&lt;br /&gt;
	end&lt;br /&gt;
	local args = getArgs(frame, {wrappers = {cfg.pattern.navbox}})&lt;br /&gt;
	readArgs(args, &amp;quot;&amp;quot;)&lt;br /&gt;
	return p._navbox(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>WikiAdmin</name></author>
	</entry>
</feed>