<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="rue">
	<id>https://wiki.kocky.cc/w/index.php?action=history&amp;feed=atom&amp;title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C%3AInfoboxNeue</id>
	<title>Модуль:InfoboxNeue - Історія едітовань</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.kocky.cc/w/index.php?action=history&amp;feed=atom&amp;title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C%3AInfoboxNeue"/>
	<link rel="alternate" type="text/html" href="https://wiki.kocky.cc/w/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:InfoboxNeue&amp;action=history"/>
	<updated>2026-04-04T04:40:03Z</updated>
	<subtitle>Історія едітовань той сторінкы на вікі</subtitle>
	<generator>MediaWiki 1.40.1</generator>
	<entry>
		<id>https://wiki.kocky.cc/w/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:InfoboxNeue&amp;diff=52&amp;oldid=prev</id>
		<title>Бетярь: 1 ревізія: InfoboxNeue from StarCitizenTools</title>
		<link rel="alternate" type="text/html" href="https://wiki.kocky.cc/w/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:InfoboxNeue&amp;diff=52&amp;oldid=prev"/>
		<updated>2023-10-17T23:55:13Z</updated>

		<summary type="html">&lt;p&gt;1 ревізія: InfoboxNeue from StarCitizenTools&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;rue&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Старша верзія&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Ревізія 01:55, 18 октовбра 2023&lt;/td&gt;
				&lt;/tr&gt;
&lt;!-- diff cache key wiki:diff::1.12:old-51:rev-52 --&gt;
&lt;/table&gt;</summary>
		<author><name>Бетярь</name></author>
	</entry>
	<entry>
		<id>https://wiki.kocky.cc/w/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:InfoboxNeue&amp;diff=51&amp;oldid=prev</id>
		<title>starcitizen&gt;Alistair3149 в 22:27, 28 юлія 2023</title>
		<link rel="alternate" type="text/html" href="https://wiki.kocky.cc/w/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:InfoboxNeue&amp;diff=51&amp;oldid=prev"/>
		<updated>2023-07-28T22:27:42Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Нова сторінка&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local InfoboxNeue = {}&lt;br /&gt;
&lt;br /&gt;
local metatable = {}&lt;br /&gt;
local methodtable = {}&lt;br /&gt;
&lt;br /&gt;
local libraryUtil = require( &amp;#039;libraryUtil&amp;#039; )&lt;br /&gt;
local checkType = libraryUtil.checkType&lt;br /&gt;
local checkTypeMulti = libraryUtil.checkTypeMulti&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
metatable.__index = methodtable&lt;br /&gt;
&lt;br /&gt;
metatable.__tostring = function( self )&lt;br /&gt;
	return tostring( self:renderInfobox() )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- FIXME: This should go to somewhere else, like Module:Common&lt;br /&gt;
--- Calls TNT with the given key&lt;br /&gt;
---&lt;br /&gt;
--- @param key string The translation key&lt;br /&gt;
--- @return string If the key was not found in the .tab page, the key is returned&lt;br /&gt;
local function translate( key, ... )&lt;br /&gt;
	local TNT = require( &amp;#039;Module:Translate&amp;#039; ):new()&lt;br /&gt;
	local success, translation = pcall( TNT.format, &amp;#039;Module:InfoboxNeue/i18n.json&amp;#039;, key or &amp;#039;&amp;#039;, ... )&lt;br /&gt;
&lt;br /&gt;
	if not success or translation == nil then&lt;br /&gt;
		return key&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return translation&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Helper function to restore underscore from space&lt;br /&gt;
--- so that it does not screw up the external link wikitext syntax&lt;br /&gt;
--- For some reason SMW property converts underscore into space&lt;br /&gt;
--- mw.uri.encode can&amp;#039;t be used on full URL&lt;br /&gt;
local function restoreUnderscore( s )&lt;br /&gt;
	return s:gsub( &amp;#039; &amp;#039;, &amp;#039;%%5F&amp;#039; )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--- Helper function to format string to number with separators&lt;br /&gt;
--- It is usually use to re-format raw number from SMW into more readable format&lt;br /&gt;
local function formatNumber( s )&lt;br /&gt;
	local lang = mw.getContentLanguage()&lt;br /&gt;
	if s == nil then&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if type( s ) ~= &amp;#039;number&amp;#039; then&lt;br /&gt;
		s = tonumber( s )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if type( s ) == &amp;#039;number&amp;#039; then&lt;br /&gt;
		return lang:formatNum( s )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return s&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Put table values into a comma-separated list&lt;br /&gt;
---&lt;br /&gt;
--- @param data table&lt;br /&gt;
--- @return string&lt;br /&gt;
function methodtable.tableToCommaList( data )&lt;br /&gt;
	if type( data ) == &amp;#039;table&amp;#039; then&lt;br /&gt;
		return table.concat( data, &amp;#039;, &amp;#039; )&lt;br /&gt;
	else&lt;br /&gt;
		return data&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--- Show range if value1 and value2 are different&lt;br /&gt;
---&lt;br /&gt;
--- @param string s1&lt;br /&gt;
--- @param string s2&lt;br /&gt;
--- @return string or nil&lt;br /&gt;
function methodtable.formatRange( s1, s2, formatNum )&lt;br /&gt;
	if s1 == nil and s2 == nil then&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	formatNum = formatNum or false;&lt;br /&gt;
&lt;br /&gt;
	if formatNum then&lt;br /&gt;
		if s1 then&lt;br /&gt;
			s1 = formatNumber( s1 )&lt;br /&gt;
		end&lt;br /&gt;
		if s2 then&lt;br /&gt;
			s2 = formatNumber( s2 )&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if s1 and s2 and s1 ~= s2 then&lt;br /&gt;
		return s1 .. &amp;#039; – &amp;#039; .. s2&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return s1 or s2&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--- Append unit to the value if exists&lt;br /&gt;
---&lt;br /&gt;
--- @param string s&lt;br /&gt;
--- @param string unit&lt;br /&gt;
--- @return string or nil&lt;br /&gt;
function methodtable.addUnitIfExists( s, unit )&lt;br /&gt;
	if s == nil then&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return s .. &amp;#039; &amp;#039; .. unit&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Shortcut to return the HTML of the infobox message component as string&lt;br /&gt;
---&lt;br /&gt;
--- @param data table {title, desc)&lt;br /&gt;
--- @return string html&lt;br /&gt;
function methodtable.renderMessage( self, data, noInsert )&lt;br /&gt;
	checkType( &amp;#039;Module:InfoboxNeue.renderMessage&amp;#039;, 1, self, &amp;#039;table&amp;#039; )&lt;br /&gt;
	checkType( &amp;#039;Module:InfoboxNeue.renderMessage&amp;#039;, 2, data, &amp;#039;table&amp;#039; )&lt;br /&gt;
	checkType( &amp;#039;Module:InfoboxNeue.renderMessage&amp;#039;, 3, noInsert, &amp;#039;boolean&amp;#039;, true )&lt;br /&gt;
&lt;br /&gt;
	noInsert = noInsert or false&lt;br /&gt;
&lt;br /&gt;
	local item = self:renderSection( { content = self:renderItem( { data = data.title, desc = data.desc } ) }, noInsert )&lt;br /&gt;
&lt;br /&gt;
	if not noInsert then&lt;br /&gt;
		table.insert( self.entries, item )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return item&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Return the HTML of the infobox image component as string&lt;br /&gt;
---&lt;br /&gt;
--- @param filename string&lt;br /&gt;
--- @return string html&lt;br /&gt;
function methodtable.renderImage( self, filename )&lt;br /&gt;
	checkType( &amp;#039;Module:InfoboxNeue.renderImage&amp;#039;, 1, self, &amp;#039;table&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
	if type( filename ) ~= &amp;#039;string&amp;#039; and self.config.displayPlaceholder == true then&lt;br /&gt;
		filename = self.config.placeholderImage&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if type( filename ) ~= &amp;#039;string&amp;#039; then&lt;br /&gt;
		return &amp;#039;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local parts = mw.text.split( filename, &amp;#039;:&amp;#039;, true )&lt;br /&gt;
	if #parts &amp;gt; 1 then&lt;br /&gt;
		table.remove( parts, 1 )&lt;br /&gt;
		filename = table.concat( parts, &amp;#039;:&amp;#039; )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local html = mw.html.create( &amp;#039;div&amp;#039; )&lt;br /&gt;
		:addClass( &amp;#039;infobox__image&amp;#039; )&lt;br /&gt;
		:wikitext( string.format( &amp;#039;[[File:%s|400px]]&amp;#039;, filename ) )&lt;br /&gt;
&lt;br /&gt;
	local item = tostring( html )&lt;br /&gt;
&lt;br /&gt;
	table.insert( self.entries, item )&lt;br /&gt;
&lt;br /&gt;
	return item&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Return the HTML of the infobox indicator component as string&lt;br /&gt;
---&lt;br /&gt;
--- @param data table {data, desc, class)&lt;br /&gt;
--- @return string html&lt;br /&gt;
function methodtable.renderIndicator( self, data )&lt;br /&gt;
	checkType( &amp;#039;Module:InfoboxNeue.renderIndicator&amp;#039;, 1, self, &amp;#039;table&amp;#039; )&lt;br /&gt;
	checkType( &amp;#039;Module:InfoboxNeue.renderIndicator&amp;#039;, 2, data, &amp;#039;table&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
	if data == nil or data[ &amp;#039;data&amp;#039; ] == nil or data[ &amp;#039;data&amp;#039; ] == &amp;#039;&amp;#039; then return &amp;#039;&amp;#039; end&lt;br /&gt;
&lt;br /&gt;
	local html = mw.html.create( &amp;#039;div&amp;#039; ):addClass( &amp;#039;infobox__indicator&amp;#039; )&lt;br /&gt;
	html:wikitext(&lt;br /&gt;
		self:renderItem(&lt;br /&gt;
			{&lt;br /&gt;
				[ &amp;#039;data&amp;#039; ] = data[ &amp;#039;data&amp;#039; ],&lt;br /&gt;
				[ &amp;#039;desc&amp;#039; ] = data[ &amp;#039;desc&amp;#039; ] or nil,&lt;br /&gt;
				row = true,&lt;br /&gt;
				spacebetween = true&lt;br /&gt;
			}&lt;br /&gt;
		)&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
	if data[ &amp;#039;class&amp;#039; ] then html:addClass( data[ &amp;#039;class&amp;#039; ] ) end&lt;br /&gt;
&lt;br /&gt;
	local item = tostring( html )&lt;br /&gt;
&lt;br /&gt;
	table.insert( self.entries, item )&lt;br /&gt;
&lt;br /&gt;
	return item&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Return the HTML of the infobox header component as string&lt;br /&gt;
---&lt;br /&gt;
--- @param data table {title, subtitle, badge)&lt;br /&gt;
--- @return string html&lt;br /&gt;
function methodtable.renderHeader( self, data )&lt;br /&gt;
	checkType( &amp;#039;Module:InfoboxNeue.renderHeader&amp;#039;, 1, self, &amp;#039;table&amp;#039; )&lt;br /&gt;
	checkTypeMulti( &amp;#039;Module:InfoboxNeue.renderHeader&amp;#039;, 2, data, { &amp;#039;table&amp;#039;, &amp;#039;string&amp;#039; } )&lt;br /&gt;
&lt;br /&gt;
	if type( data ) == &amp;#039;string&amp;#039; then&lt;br /&gt;
		data = {&lt;br /&gt;
			title = data&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if data == nil or data[ &amp;#039;title&amp;#039; ] == nil then return &amp;#039;&amp;#039; end&lt;br /&gt;
&lt;br /&gt;
	local html = mw.html.create( &amp;#039;div&amp;#039; ):addClass( &amp;#039;infobox__header&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
	if data[ &amp;#039;badge&amp;#039; ] then&lt;br /&gt;
		html:tag( &amp;#039;div&amp;#039; )&lt;br /&gt;
			:addClass( &amp;#039;infobox__item infobox__badge&amp;#039; )&lt;br /&gt;
			:wikitext( data[ &amp;#039;badge&amp;#039; ] )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local titleItem = mw.html.create( &amp;#039;div&amp;#039; ):addClass( &amp;#039;infobox__item&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
	titleItem:tag( &amp;#039;div&amp;#039; )&lt;br /&gt;
		:addClass( &amp;#039;infobox__title&amp;#039; )&lt;br /&gt;
		:wikitext( data[ &amp;#039;title&amp;#039; ] )&lt;br /&gt;
&lt;br /&gt;
	if data[ &amp;#039;subtitle&amp;#039; ] then&lt;br /&gt;
		titleItem:tag( &amp;#039;div&amp;#039; )&lt;br /&gt;
			-- Subtitle is always data&lt;br /&gt;
			:addClass( &amp;#039;infobox__subtitle infobox__data&amp;#039; )&lt;br /&gt;
			:wikitext( data[ &amp;#039;subtitle&amp;#039; ] )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	html:node( titleItem )&lt;br /&gt;
&lt;br /&gt;
	local item = tostring( html )&lt;br /&gt;
&lt;br /&gt;
	table.insert( self.entries, item )&lt;br /&gt;
&lt;br /&gt;
	return item&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Wrap the HTML into an infobox section&lt;br /&gt;
---&lt;br /&gt;
--- @param data table {title, subtitle, content, border, col, class}&lt;br /&gt;
--- @param noInsert boolean whether to insert this section into the internal table table&lt;br /&gt;
--- @return string html&lt;br /&gt;
function methodtable.renderSection( self, data, noInsert )&lt;br /&gt;
	checkType( &amp;#039;Module:InfoboxNeue.renderSection&amp;#039;, 1, self, &amp;#039;table&amp;#039; )&lt;br /&gt;
	checkType( &amp;#039;Module:InfoboxNeue.renderSection&amp;#039;, 2, data, &amp;#039;table&amp;#039; )&lt;br /&gt;
	checkType( &amp;#039;Module:InfoboxNeue.renderSection&amp;#039;, 3, noInsert, &amp;#039;boolean&amp;#039;, true )&lt;br /&gt;
&lt;br /&gt;
	noInsert = noInsert or false&lt;br /&gt;
&lt;br /&gt;
	if type( data.content ) == &amp;#039;table&amp;#039; then&lt;br /&gt;
		data.content = table.concat( data.content )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if data == nil or data[ &amp;#039;content&amp;#039; ] == nil or data[ &amp;#039;content&amp;#039; ] == &amp;#039;&amp;#039; then return &amp;#039;&amp;#039; end&lt;br /&gt;
&lt;br /&gt;
	local html = mw.html.create( &amp;#039;div&amp;#039; ):addClass( &amp;#039;infobox__section&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
	if data[ &amp;#039;title&amp;#039; ] then&lt;br /&gt;
		local header = html:tag( &amp;#039;div&amp;#039; ):addClass( &amp;#039;infobox__sectionHeader&amp;#039; )&lt;br /&gt;
		header:tag( &amp;#039;div&amp;#039; )&lt;br /&gt;
				:addClass( &amp;#039;infobox__sectionTitle&amp;#039; )&lt;br /&gt;
				:wikitext( data[ &amp;#039;title&amp;#039; ] )&lt;br /&gt;
		if data[ &amp;#039;subtitle&amp;#039; ] then&lt;br /&gt;
			header:tag( &amp;#039;div&amp;#039; )&lt;br /&gt;
				:addClass( &amp;#039;infobox__sectionSubtitle&amp;#039; )&lt;br /&gt;
				:wikitext( data[ &amp;#039;subtitle&amp;#039; ] )&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local content = html:tag( &amp;#039;div&amp;#039; )&lt;br /&gt;
	content:addClass( &amp;#039;infobox__sectionContent&amp;#039;)&lt;br /&gt;
			:wikitext( data[ &amp;#039;content&amp;#039; ] )&lt;br /&gt;
&lt;br /&gt;
	if data[ &amp;#039;border&amp;#039; ] == false then html:addClass( &amp;#039;infobox__section--noborder&amp;#039; ) end&lt;br /&gt;
	if data[ &amp;#039;col&amp;#039; ] then content:addClass( &amp;#039;infobox__grid--cols-&amp;#039; .. data[ &amp;#039;col&amp;#039; ] ) end&lt;br /&gt;
	if data[ &amp;#039;class&amp;#039; ] then html:addClass( data[ &amp;#039;class&amp;#039; ] ) end&lt;br /&gt;
&lt;br /&gt;
	local item = tostring( html )&lt;br /&gt;
&lt;br /&gt;
	if not noInsert then&lt;br /&gt;
		table.insert( self.entries, item )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return item&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Return the HTML of the infobox link button component as string&lt;br /&gt;
---&lt;br /&gt;
--- @param data table {label, link, page}&lt;br /&gt;
--- @return string html&lt;br /&gt;
function methodtable.renderLinkButton( self, data )&lt;br /&gt;
	checkType( &amp;#039;Module:InfoboxNeue.renderLinkButton&amp;#039;, 1, self, &amp;#039;table&amp;#039; )&lt;br /&gt;
	checkType( &amp;#039;Module:InfoboxNeue.renderLinkButton&amp;#039;, 2, data, &amp;#039;table&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
	if data == nil or data[ &amp;#039;label&amp;#039; ] == nil or ( data[ &amp;#039;link&amp;#039; ] == nil and data[ &amp;#039;page&amp;#039; ] == nil ) then return &amp;#039;&amp;#039; end&lt;br /&gt;
&lt;br /&gt;
	--- Render multiple linkButton when link is a table&lt;br /&gt;
	if type( data[ &amp;#039;link&amp;#039; ] ) == &amp;#039;table&amp;#039; then&lt;br /&gt;
		local htmls = {}&lt;br /&gt;
&lt;br /&gt;
		for i, url in ipairs( data[ &amp;#039;link&amp;#039; ] ) do&lt;br /&gt;
			table.insert( htmls,&lt;br /&gt;
				self:renderLinkButton( {&lt;br /&gt;
					label = string.format( &amp;#039;%s %d&amp;#039;, data[ &amp;#039;label&amp;#039; ], i ),&lt;br /&gt;
					link = url&lt;br /&gt;
				} )&lt;br /&gt;
			)&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		return table.concat( htmls )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local html = mw.html.create( &amp;#039;div&amp;#039; ):addClass( &amp;#039;infobox__linkButton&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
	if data[ &amp;#039;link&amp;#039; ] then&lt;br /&gt;
		html:wikitext( string.format( &amp;#039;[%s %s]&amp;#039;, restoreUnderscore( data[ &amp;#039;link&amp;#039; ] ), data[ &amp;#039;label&amp;#039; ] ) )&lt;br /&gt;
	elseif data[ &amp;#039;page&amp;#039; ] then&lt;br /&gt;
		html:wikitext( string.format( &amp;#039;[[%s|%s]]&amp;#039;, data[ &amp;#039;page&amp;#039; ], data[ &amp;#039;label&amp;#039; ] ) )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return tostring( html )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--- Return the HTML of the infobox footer component as string&lt;br /&gt;
---&lt;br /&gt;
--- @param data table {content, button}&lt;br /&gt;
--- @return string html&lt;br /&gt;
function methodtable.renderFooter( self, data )&lt;br /&gt;
	checkType( &amp;#039;Module:InfoboxNeue.renderFooter&amp;#039;, 1, self, &amp;#039;table&amp;#039; )&lt;br /&gt;
	checkType( &amp;#039;Module:InfoboxNeue.renderFooter&amp;#039;, 2, data, &amp;#039;table&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
	if data == nil then return &amp;#039;&amp;#039; end&lt;br /&gt;
&lt;br /&gt;
    -- Checks if an input is of type &amp;#039;table&amp;#039; or &amp;#039;string&amp;#039; and if it is not empty&lt;br /&gt;
    local function isNonEmpty( input )&lt;br /&gt;
		if input == nil or input == &amp;#039;&amp;#039; then return false end&lt;br /&gt;
        return ( type( input ) == &amp;#039;table&amp;#039; and next( input ) ~= nil ) or ( type( input ) == &amp;#039;string&amp;#039; and #input &amp;gt; 0 )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
	local hasContent = isNonEmpty( data[ &amp;#039;content&amp;#039; ] )&lt;br /&gt;
	local hasButton = isNonEmpty( data[ &amp;#039;button&amp;#039; ] ) and isNonEmpty( data[ &amp;#039;button&amp;#039; ][ &amp;#039;content&amp;#039; ] ) and isNonEmpty( data[ &amp;#039;button&amp;#039; ][ &amp;#039;label&amp;#039; ] )&lt;br /&gt;
&lt;br /&gt;
	if not hasContent and not hasButton then return &amp;#039;&amp;#039; end&lt;br /&gt;
&lt;br /&gt;
	local html = mw.html.create( &amp;#039;div&amp;#039; ):addClass( &amp;#039;infobox__footer&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
	if hasContent then&lt;br /&gt;
		local content = data[ &amp;#039;content&amp;#039; ]&lt;br /&gt;
		if type( content ) == &amp;#039;table&amp;#039; then content = table.concat( content ) end&lt;br /&gt;
&lt;br /&gt;
        html:addClass( &amp;#039;infobox__footer--has-content&amp;#039;)&lt;br /&gt;
        html:tag( &amp;#039;div&amp;#039; )&lt;br /&gt;
            :addClass( &amp;#039;infobox__section&amp;#039; )&lt;br /&gt;
            :wikitext( content )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if hasButton then&lt;br /&gt;
	    html:addClass( &amp;#039;infobox__footer--has-button&amp;#039;)&lt;br /&gt;
		local buttonData = data[ &amp;#039;button&amp;#039; ];&lt;br /&gt;
		local button = html:tag( &amp;#039;div&amp;#039; ):addClass( &amp;#039;infobox__button&amp;#039; )&lt;br /&gt;
		local label = button:tag( &amp;#039;div&amp;#039; ):addClass( &amp;#039;infobox__buttonLabel&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
		if buttonData[ &amp;#039;icon&amp;#039; ] ~= nil then&lt;br /&gt;
			label:wikitext( string.format( &amp;#039;[[File:%s|16px|link=]]%s&amp;#039;, buttonData[ &amp;#039;icon&amp;#039; ], buttonData[ &amp;#039;label&amp;#039; ] ) )&lt;br /&gt;
		else&lt;br /&gt;
			label:wikitext( buttonData[ &amp;#039;label&amp;#039; ] )&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if buttonData[ &amp;#039;type&amp;#039; ] == &amp;#039;link&amp;#039; then&lt;br /&gt;
			button:tag( &amp;#039;div&amp;#039; )&lt;br /&gt;
				:addClass( &amp;#039;infobox__buttonLink&amp;#039; )&lt;br /&gt;
				:wikitext( buttonData[ &amp;#039;content&amp;#039; ] )&lt;br /&gt;
		elseif buttonData[ &amp;#039;type&amp;#039; ] == &amp;#039;popup&amp;#039; then&lt;br /&gt;
			button:tag( &amp;#039;div&amp;#039; )&lt;br /&gt;
				:addClass( &amp;#039;infobox__buttonCard&amp;#039; )&lt;br /&gt;
				:wikitext( buttonData[ &amp;#039;content&amp;#039; ] )&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local item = tostring( html )&lt;br /&gt;
&lt;br /&gt;
	table.insert( self.entries, item )&lt;br /&gt;
&lt;br /&gt;
	return item&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Return the HTML of the infobox footer button component as string&lt;br /&gt;
---&lt;br /&gt;
--- @param data table {icon, label, type, content}&lt;br /&gt;
--- @return string html&lt;br /&gt;
function methodtable.renderFooterButton( self, data )&lt;br /&gt;
	checkType( &amp;#039;Module:InfoboxNeue.renderFooterButton&amp;#039;, 1, self, &amp;#039;table&amp;#039; )&lt;br /&gt;
	checkType( &amp;#039;Module:InfoboxNeue.renderFooterButton&amp;#039;, 2, data, &amp;#039;table&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
	if data == nil then return &amp;#039;&amp;#039; end&lt;br /&gt;
&lt;br /&gt;
	return self:renderFooter( { button = data } )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Return the HTML of the infobox item component as string&lt;br /&gt;
---&lt;br /&gt;
--- @param data table {label, data, desc, row, spacebetween, colspan)&lt;br /&gt;
--- @param content string|number optional&lt;br /&gt;
--- @return string html&lt;br /&gt;
function methodtable.renderItem( self, data, content )&lt;br /&gt;
	checkType( &amp;#039;Module:InfoboxNeue.renderItem&amp;#039;, 1, self, &amp;#039;table&amp;#039; )&lt;br /&gt;
	checkTypeMulti( &amp;#039;Module:InfoboxNeue.renderItem&amp;#039;, 2, data, { &amp;#039;table&amp;#039;, &amp;#039;string&amp;#039; } )&lt;br /&gt;
	checkTypeMulti( &amp;#039;Module:InfoboxNeue.renderItem&amp;#039;, 3, content, { &amp;#039;string&amp;#039;, &amp;#039;number&amp;#039;, &amp;#039;nil&amp;#039; } )&lt;br /&gt;
&lt;br /&gt;
	-- The arguments are not passed as a table&lt;br /&gt;
	-- Allows to call this as box:renderItem( &amp;#039;Label&amp;#039;, &amp;#039;Data&amp;#039; )&lt;br /&gt;
	if content ~= nil then&lt;br /&gt;
		data = {&lt;br /&gt;
			label = data,&lt;br /&gt;
			data = content&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if data == nil or data[ &amp;#039;data&amp;#039; ] == nil or data[ &amp;#039;data&amp;#039; ] == &amp;#039;&amp;#039; then return &amp;#039;&amp;#039; end&lt;br /&gt;
&lt;br /&gt;
	if self.config.removeEmpty == true and data[ &amp;#039;data&amp;#039; ] == self.config.emptyString then&lt;br /&gt;
		return &amp;#039;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local html = mw.html.create( &amp;#039;div&amp;#039; ):addClass( &amp;#039;infobox__item&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
	if data[ &amp;#039;row&amp;#039; ] == true then html:addClass( &amp;#039;infobox__grid--row&amp;#039; ) end&lt;br /&gt;
	if data[ &amp;#039;spacebetween&amp;#039; ] == true then html:addClass( &amp;#039;infobox__grid--space-between&amp;#039; ) end&lt;br /&gt;
	if data[ &amp;#039;colspan&amp;#039; ] then html:addClass( &amp;#039;infobox__grid--col-span-&amp;#039; .. data[ &amp;#039;colspan&amp;#039; ] ) end&lt;br /&gt;
&lt;br /&gt;
	local dataOrder = { &amp;#039;label&amp;#039;, &amp;#039;data&amp;#039;, &amp;#039;desc&amp;#039; }&lt;br /&gt;
&lt;br /&gt;
	for _, key in ipairs( dataOrder ) do&lt;br /&gt;
		if data[ key ] then&lt;br /&gt;
			if type( data[ key ] ) == &amp;#039;table&amp;#039; then&lt;br /&gt;
				data[ key ] = table.concat( data[ key ], &amp;#039;, &amp;#039; )&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			html:tag( &amp;#039;div&amp;#039; )&lt;br /&gt;
				:addClass( &amp;#039;infobox__&amp;#039; .. key )&lt;br /&gt;
				:wikitext( data[ key ] )&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return tostring( html )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Wrap the infobox HTML&lt;br /&gt;
---&lt;br /&gt;
--- @param innerHtml string inner html of the infobox&lt;br /&gt;
--- @param snippetText string text used in snippet in mobile view&lt;br /&gt;
--- @return string html infobox html with templatestyles&lt;br /&gt;
function methodtable.renderInfobox( self, innerHtml, snippetText )&lt;br /&gt;
	checkType( &amp;#039;Module:InfoboxNeue.renderInfobox&amp;#039;, 1, self, &amp;#039;table&amp;#039; )&lt;br /&gt;
	checkTypeMulti( &amp;#039;Module:InfoboxNeue.renderInfobox&amp;#039;, 2, innerHtml, { &amp;#039;table&amp;#039;, &amp;#039;string&amp;#039;, &amp;#039;nil&amp;#039; } )&lt;br /&gt;
	checkType( &amp;#039;Module:InfoboxNeue.renderInfobox&amp;#039;, 3, snippetText, &amp;#039;string&amp;#039;, true )&lt;br /&gt;
&lt;br /&gt;
	innerHtml = innerHtml or self.entries&lt;br /&gt;
	if type( innerHtml ) == &amp;#039;table&amp;#039; then&lt;br /&gt;
		innerHtml = table.concat( self.entries )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local function renderSnippet()&lt;br /&gt;
		if snippetText == nil then snippetText = mw.title.getCurrentTitle().rootText end&lt;br /&gt;
&lt;br /&gt;
		local html = mw.html.create( &amp;#039;div&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
		html&lt;br /&gt;
			:addClass( &amp;#039;infobox__snippet mw-collapsible-toggle&amp;#039; )&lt;br /&gt;
			:tag( &amp;#039;div&amp;#039; )&lt;br /&gt;
				:addClass( &amp;#039;citizen-ui-icon mw-ui-icon-wikimedia-collapse&amp;#039; )&lt;br /&gt;
				:done()&lt;br /&gt;
			:tag( &amp;#039;div&amp;#039; )&lt;br /&gt;
				:addClass( &amp;#039;infobox__data&amp;#039; )&lt;br /&gt;
				:wikitext( string.format( &amp;#039;%s:&amp;#039;, translate( &amp;#039;LBL_quick_facts&amp;#039; ) ) )&lt;br /&gt;
				:done()&lt;br /&gt;
			:tag( &amp;#039;div&amp;#039; )&lt;br /&gt;
				:addClass( &amp;#039;infobox__desc&amp;#039; )&lt;br /&gt;
				:wikitext( snippetText )&lt;br /&gt;
&lt;br /&gt;
		return tostring( html )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local html = mw.html.create( &amp;#039;div&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
	html&lt;br /&gt;
		:addClass( &amp;#039;infobox floatright mw-collapsible&amp;#039; )&lt;br /&gt;
		:wikitext( renderSnippet() )&lt;br /&gt;
		:tag( &amp;#039;div&amp;#039; )&lt;br /&gt;
			:addClass( &amp;#039;infobox__content mw-collapsible-content&amp;#039; )&lt;br /&gt;
			:wikitext( innerHtml )&lt;br /&gt;
&lt;br /&gt;
	return tostring( html ) .. mw.getCurrentFrame():extensionTag{&lt;br /&gt;
		name = &amp;#039;templatestyles&amp;#039;, args = { src = &amp;#039;Module:InfoboxNeue/styles.css&amp;#039; }&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Just an accessor for the class method&lt;br /&gt;
function methodtable.showDescIfDiff( s1, s2 )&lt;br /&gt;
	return InfoboxNeue.showDescIfDiff( s1, s2 )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Format text to show comparison as desc text if two strings are different&lt;br /&gt;
---&lt;br /&gt;
--- @param s1 string base&lt;br /&gt;
--- @param s2 string comparsion&lt;br /&gt;
--- @return string html&lt;br /&gt;
function InfoboxNeue.showDescIfDiff( s1, s2 )&lt;br /&gt;
    if s1 == nil or s2 == nil or s1 == s2 then return s1 end&lt;br /&gt;
    return string.format( &amp;#039;%s &amp;lt;span class=&amp;quot;infobox__desc&amp;quot;&amp;gt;(%s)&amp;lt;/span&amp;gt;&amp;#039;, s1, s2 )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- New Instance&lt;br /&gt;
---&lt;br /&gt;
--- @return table InfoboxNeue&lt;br /&gt;
function InfoboxNeue.new( self, config )&lt;br /&gt;
	local baseConfig = {&lt;br /&gt;
		-- Flag to discard empty rows&lt;br /&gt;
		removeEmpty = false,&lt;br /&gt;
		-- Optional string which is valued as empty&lt;br /&gt;
		emptyString = nil,&lt;br /&gt;
		-- Display a placeholder image if addImage does not find an image&lt;br /&gt;
		displayPlaceholder = true,&lt;br /&gt;
		-- Placeholder Image&lt;br /&gt;
		placeholderImage = &amp;#039;Platzhalter.webp&amp;#039;,&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for k, v in pairs( config or {} ) do&lt;br /&gt;
		baseConfig[ k ] = v&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
    local instance = {&lt;br /&gt;
		config = baseConfig,&lt;br /&gt;
		entries = {}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
    setmetatable( instance, metatable )&lt;br /&gt;
&lt;br /&gt;
    return instance&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Create an Infobox from args&lt;br /&gt;
---&lt;br /&gt;
--- @param frame table&lt;br /&gt;
--- @return string&lt;br /&gt;
function InfoboxNeue.fromArgs( frame )&lt;br /&gt;
	local instance = InfoboxNeue:new()&lt;br /&gt;
	local args = require( &amp;#039;Module:Arguments&amp;#039; ).getArgs( frame )&lt;br /&gt;
&lt;br /&gt;
	local sections = {&lt;br /&gt;
		{ content = {}, col = args[ &amp;#039;col&amp;#039; ] or 2 }&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	local sectionMap = { default = 1 }&lt;br /&gt;
&lt;br /&gt;
	local currentSection&lt;br /&gt;
&lt;br /&gt;
	if args[ &amp;#039;image&amp;#039; ] then&lt;br /&gt;
		instance:renderImage( args[ &amp;#039;image&amp;#039; ] )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if args[ &amp;#039;title&amp;#039; ] then&lt;br /&gt;
		instance:renderHeader( {&lt;br /&gt;
			title = args[ &amp;#039;title&amp;#039; ],&lt;br /&gt;
			subtitle = args[ &amp;#039;subtitle&amp;#039; ],&lt;br /&gt;
		} )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for i = 1, 50, 1 do&lt;br /&gt;
		if args[ &amp;#039;section&amp;#039; .. i ] then&lt;br /&gt;
			currentSection = args[ &amp;#039;section&amp;#039; .. i ]&lt;br /&gt;
&lt;br /&gt;
			table.insert( sections, {&lt;br /&gt;
				title = currentSection,&lt;br /&gt;
				subtitle = args[ &amp;#039;section-subtitle&amp;#039; .. i ],&lt;br /&gt;
				col = args[ &amp;#039;section-col&amp;#039; .. i ] or args[ &amp;#039;col&amp;#039; ] or 2,&lt;br /&gt;
				content = {}&lt;br /&gt;
			} )&lt;br /&gt;
&lt;br /&gt;
			sectionMap[ currentSection ] = #sections&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if args[ &amp;#039;label&amp;#039; .. i ] and args[ &amp;#039;content&amp;#039; .. i ] then&lt;br /&gt;
			table.insert( sections[ sectionMap[ ( currentSection or &amp;#039;default&amp;#039; ) ] ].content, instance:renderItem( args[ &amp;#039;label&amp;#039; .. i ], args[ &amp;#039;content&amp;#039; .. i ] ) )&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for _, section in ipairs( sections ) do&lt;br /&gt;
		instance:renderSection( {&lt;br /&gt;
			title = section.title,&lt;br /&gt;
			subtitle = section.subtitle,&lt;br /&gt;
			col = section.col,&lt;br /&gt;
			content = section.content,&lt;br /&gt;
		} )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return instance:renderInfobox( nil, args[ &amp;#039;snippet&amp;#039; ] )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
return InfoboxNeue&lt;/div&gt;</summary>
		<author><name>starcitizen&gt;Alistair3149</name></author>
	</entry>
</feed>