<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://dukesyndicate.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Illegitimate-egg</id>
	<title>Duke Syndicate - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://dukesyndicate.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Illegitimate-egg"/>
	<link rel="alternate" type="text/html" href="https://dukesyndicate.org/wiki/Special:Contributions/Illegitimate-egg"/>
	<updated>2026-06-06T00:19:29Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Incident_Log&amp;diff=41</id>
		<title>Incident Log</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Incident_Log&amp;diff=41"/>
		<updated>2026-02-20T02:31:40Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a log for all Incidents relating the the Duke Syndicate&#039;s server operation, starting 2026-02-19.&lt;br /&gt;
&lt;br /&gt;
=== 2026-02-19T22:17:11Z/2026-02-20T02:00:29Z (3 hours 43 minutes elapsed) ===&lt;br /&gt;
A router was rebooted, for some fucking reason (the reason being the router was a SHITTY residential ISP issued router (I mean a proper pile of shit)), this caused the router to change it&#039;s policy for IPv6 communication. I ([[Illegitimate-egg]]) slaved away for a long time, resolving local link issues (there is an odd setup with direct connections that made the issue deceptive, and also because outright filtering all IPv6 is FUCKING stupid, I dismissed the idea) until I finally caved and realised that the stupidity of my router was very real, and my pain and time were very exhausted.&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Incident_Log&amp;diff=40</id>
		<title>Incident Log</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Incident_Log&amp;diff=40"/>
		<updated>2026-02-20T02:27:54Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a log for all Incidents relating the the Duke Syndicate&#039;s server operation, starting 2026-02-19.&lt;br /&gt;
&lt;br /&gt;
=== 2026-02-19T22:17:11Z/2026-02-20T02:00:29Z (3 hours 43 minutes elapsed) ===&lt;br /&gt;
A router was rebooted, for some fucking reason (the reason being the router was a SHITTY ISP issued router (I mean a proper pile of shit)), this caused the router to change it&#039;s policy for IPv6 communication. I ([[Illegitimate-egg]]) slaved away for a long time, resolving local link issues (there is an odd setup with direct connections that made the issue deceptive, and also because outright filtering all IPv6 is FUCKING stupid, I dismissed the idea) until I finally caved and realised that the stupidity of my router was very real, and my pain and time were very exhausted.&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=MediaWiki:Sidebar&amp;diff=39</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=MediaWiki:Sidebar&amp;diff=39"/>
		<updated>2026-02-20T02:25:22Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** sitemap|Complete Sitemap&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
** Special:AllPages|Page List&lt;br /&gt;
** specialpages-url|specialpages&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Incident_Log&amp;diff=38</id>
		<title>Incident Log</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Incident_Log&amp;diff=38"/>
		<updated>2026-02-20T02:23:52Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;This is a log for all Incidents relating the the Duke Syndicate&amp;#039;s server operation, starting 2026-02-19.  === 2026-02-19T22:17:11Z TO 2026-02-20T02:00:29Z (3 hours 43 minutes elapsed) === A router was rebooted, for some fucking reason (the reason being the router was a SHITTY ISP issued router (I mean a proper pile of shit)), this caused the router to change it&amp;#039;s policy for IPv6 communication. I (Illegitimate-egg) slaved away for a long time, resolving local link iss...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a log for all Incidents relating the the Duke Syndicate&#039;s server operation, starting 2026-02-19.&lt;br /&gt;
&lt;br /&gt;
=== 2026-02-19T22:17:11Z TO 2026-02-20T02:00:29Z (3 hours 43 minutes elapsed) ===&lt;br /&gt;
A router was rebooted, for some fucking reason (the reason being the router was a SHITTY ISP issued router (I mean a proper pile of shit)), this caused the router to change it&#039;s policy for IPv6 communication. I ([[Illegitimate-egg]]) slaved away for a long time, resolving local link issues (there is an odd setup with direct connections that made the issue deceptive, and also because outright filtering all IPv6 is FUCKING stupid, I dismissed the idea) until I finally caved and realised that the stupidity of my router was very real, and my pain and time were very exhausted.&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Sitemap&amp;diff=36</id>
		<title>Sitemap</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Sitemap&amp;diff=36"/>
		<updated>2026-02-09T22:57:14Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;This page is a total list of every page on the Duke Syndicate server in case I develop amnesia and become unable to read nginx config files.  = Über Public = * https://dukesyndicate.org/ - The Duke Syndicate home page. * https://dukesyndicate.org/wiki - The Duke Syndicate wiki. * https://git.dukesyndicate.org/ - The Duke Syndicate git.  = Semi-public (Unlisted/Not Advertised) = * https://dukesyndicate.org/pictures - A small collection of illegitimate-egg&amp;#039;s p...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is a total list of every page on the Duke Syndicate server in case I develop amnesia and become unable to read nginx config files.&lt;br /&gt;
&lt;br /&gt;
= Über Public =&lt;br /&gt;
* https://dukesyndicate.org/ - The [[Duke Syndicate]] home page.&lt;br /&gt;
* https://dukesyndicate.org/wiki - The [[Duke Syndicate]] wiki.&lt;br /&gt;
* https://git.dukesyndicate.org/ - The [[Duke Syndicate]] git.&lt;br /&gt;
&lt;br /&gt;
= Semi-public (Unlisted/Not Advertised) =&lt;br /&gt;
* https://dukesyndicate.org/pictures - A small collection of illegitimate-egg&#039;s pictures.&lt;br /&gt;
* https://dukesyndicate.org/audio - A small collection of audio uploaded by illegitimate-egg.&lt;br /&gt;
&lt;br /&gt;
= Private (Password Protected) =&lt;br /&gt;
* https://dukesyndicate.org/vault - A private file collection.&lt;br /&gt;
* https://grafana.dukesyndicate.org/ - Monitoring for the [[Duke Syndicate]] server.&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=MediaWiki:Sidebar&amp;diff=35</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=MediaWiki:Sidebar&amp;diff=35"/>
		<updated>2026-02-09T22:51:22Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot; * navigation ** mainpage|mainpage-description ** sitemap|Complete Sitemap ** recentchanges-url|recentchanges ** randompage-url|randompage ** helppage|help-mediawiki ** specialpages-url|specialpages * SEARCH * TOOLBOX * LANGUAGES&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** sitemap|Complete Sitemap&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
** specialpages-url|specialpages&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Duke_Syndicate&amp;diff=34</id>
		<title>Duke Syndicate</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Duke_Syndicate&amp;diff=34"/>
		<updated>2025-12-24T17:09:22Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Duke Syndicate is a foundation that operates in favour of [[Duke]], the mascot of [[Java]].&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Illegitimate-egg&amp;diff=33</id>
		<title>Illegitimate-egg</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Illegitimate-egg&amp;diff=33"/>
		<updated>2025-12-24T17:08:49Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;The operator of the Duke Syndicate server and current system administrator. One of the two founders. Responsible for the Duke-bot, git, discord and more.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The operator of the [[Duke Syndicate]] server and current system administrator. One of the two founders. Responsible for the [[Duke-bot]], git, discord and more.&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Williamist&amp;diff=32</id>
		<title>Williamist</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Williamist&amp;diff=32"/>
		<updated>2025-12-24T17:08:48Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;Co-founder of the Duke Syndicate. Responsible for preventing [https://en.wikipedia.org/wiki/Omega_Point Omega Point].&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Co-founder of the [[Duke Syndicate]]. Responsible for preventing [https://en.wikipedia.org/wiki/Omega_Point Omega Point].&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Duke&amp;diff=31</id>
		<title>Duke</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Duke&amp;diff=31"/>
		<updated>2025-12-24T17:08:08Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Duke-little.png|frame|alt=Duke&#039;s Instantiation|Duke at the moment of his creation, his genesis]]&lt;br /&gt;
&lt;br /&gt;
Duke is God.&lt;br /&gt;
&lt;br /&gt;
Little is known about his creation at Sun Microsystems by Joe Palrang, but his status is known.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Text found on tablet&lt;br /&gt;
|-&lt;br /&gt;
! Original Text !! Translation&lt;br /&gt;
|-&lt;br /&gt;
| Duke est Deus, omnia perfecta. Ille est omnia et omnia dirigit. Pax sit super eum et creationes eius, omnibus in suo dominio. || Duke is God, the complete everything. He is all and guides all. Peace be upon him and his creations, all in their dominion.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=File:Duke-little.png&amp;diff=30</id>
		<title>File:Duke-little.png</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=File:Duke-little.png&amp;diff=30"/>
		<updated>2025-12-24T17:07:07Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Duke creation&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Duke&amp;diff=29</id>
		<title>Duke</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Duke&amp;diff=29"/>
		<updated>2025-12-24T17:06:19Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;Duke is God.  Little is known about his creation at Sun Microsystems by Joe Palrang, but his status is known.  {| class=&amp;quot;wikitable&amp;quot; |+ Text found on tablet |- ! Original Text !! Translation |- | Duke est Deus, omnia perfecta. Ille est omnia et omnia dirigit. Pax sit super eum et creationes eius, omnibus in suo dominio. || Duke is God, the complete everything. He is all and guides all. Peace be upon him and his creations, all in their dominion. |}&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Duke is God.&lt;br /&gt;
&lt;br /&gt;
Little is known about his creation at Sun Microsystems by Joe Palrang, but his status is known.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Text found on tablet&lt;br /&gt;
|-&lt;br /&gt;
! Original Text !! Translation&lt;br /&gt;
|-&lt;br /&gt;
| Duke est Deus, omnia perfecta. Ille est omnia et omnia dirigit. Pax sit super eum et creationes eius, omnibus in suo dominio. || Duke is God, the complete everything. He is all and guides all. Peace be upon him and his creations, all in their dominion.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Duke_Syndicate&amp;diff=28</id>
		<title>Duke Syndicate</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Duke_Syndicate&amp;diff=28"/>
		<updated>2025-12-24T17:02:46Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;The Duke Syndicate is a foundation that operates in favour of Duke the mascot of Java.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Duke Syndicate is a foundation that operates in favour of [[Duke]] the mascot of [[Java]].&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Java&amp;diff=27</id>
		<title>Java</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Java&amp;diff=27"/>
		<updated>2025-12-24T17:02:10Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;Java is God&amp;#039;s language, his native tongue. It was foretold in the dead sea scrolls.  The passage from the Dead Sea Scrolls that foretells java.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Java is God&#039;s language, his native tongue. It was foretold in the dead sea scrolls.&lt;br /&gt;
&lt;br /&gt;
[[File:Dead Sea Scrolls.png|frame|alt=Yellowed scrolls, text reads: &amp;quot;Java Will be Great&amp;quot;|The passage from the Dead Sea Scrolls that foretells java.]]&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=File:Dead_Sea_Scrolls.png&amp;diff=26</id>
		<title>File:Dead Sea Scrolls.png</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=File:Dead_Sea_Scrolls.png&amp;diff=26"/>
		<updated>2025-12-24T17:01:25Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The passage from which the mother tongue comes.&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Duke-bot&amp;diff=25</id>
		<title>Duke-bot</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Duke-bot&amp;diff=25"/>
		<updated>2025-12-24T16:57:16Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;{{Infobox | title    = Duke-bot  | image    = alt:The duke-bot&amp;#039;s git repo stats | caption1 = The duke-bot&amp;#039;s git repo stats  | label1   = Description |  data1   = A discord bot written in Java that governs the Duke Syndicate discord. | label2   = Language |  data2   = Java  | header3  = Repository | label4   = Host |  data4   = https://git.dukesyndicate.org/ | label5   = Url |  data5   = https://git.dukesyndicate.org/Duke-Syndi...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox&lt;br /&gt;
| title    = Duke-bot&lt;br /&gt;
&lt;br /&gt;
| image    = [[File:Duke-bot onefetch.png|400px|alt:The duke-bot&#039;s git repo stats]]&lt;br /&gt;
| caption1 = The duke-bot&#039;s git repo stats&lt;br /&gt;
&lt;br /&gt;
| label1   = Description&lt;br /&gt;
|  data1   = A discord bot written in [[Java]] that governs the Duke Syndicate discord.&lt;br /&gt;
| label2   = Language&lt;br /&gt;
|  data2   = [[Java]]&lt;br /&gt;
&lt;br /&gt;
| header3  = Repository&lt;br /&gt;
| label4   = Host&lt;br /&gt;
|  data4   = https://git.dukesyndicate.org/&lt;br /&gt;
| label5   = Url&lt;br /&gt;
|  data5   = https://git.dukesyndicate.org/Duke-Syndicate/duke-bot&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Duke-bot is a creation of the [[Duke Syndicate]]. Written by [[illegitimate-egg]] under observation by [[williamist]] it performs actions on the discord server. &lt;br /&gt;
&lt;br /&gt;
== Jobs ==&lt;br /&gt;
=== He&#039;s so Talented ===&lt;br /&gt;
The bot ensures that nothing other than praise is permitted in the #hes-so-talented channel.&lt;br /&gt;
&lt;br /&gt;
== Trivia ==&lt;br /&gt;
* The list of accepted phrases is very short&lt;br /&gt;
* People have tried to &amp;quot;beat the bot&amp;quot;&lt;br /&gt;
* It is the superior droid in the discord and sits at the top of the members ranking, separate from the other bots filed under &amp;quot;Droid inferior to Duke&amp;quot;&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=File:Duke-bot_onefetch.png&amp;diff=24</id>
		<title>File:Duke-bot onefetch.png</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=File:Duke-bot_onefetch.png&amp;diff=24"/>
		<updated>2025-12-24T16:27:15Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A onefetch description of the Duke-bot repo&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=MediaWiki:Common.css&amp;diff=23</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=MediaWiki:Common.css&amp;diff=23"/>
		<updated>2025-12-24T16:02:52Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;/* Reset italic styling set by user agent */ cite, dfn { 	font-style: inherit; }  /* Straight quote marks for &amp;lt;q&amp;gt; */ q { 	quotes: &amp;#039;&amp;quot;&amp;#039; &amp;#039;&amp;quot;&amp;#039; &amp;quot;&amp;#039;&amp;quot; &amp;quot;&amp;#039;&amp;quot;; }  /* Avoid collision of blockquote with floating elements by swapping margin and padding */ blockquote { 	overflow: hidden; 	margin: 1em 0; 	padding: 0 40px; }  /* Consistent size for &amp;lt;small&amp;gt;, &amp;lt;sub&amp;gt; and &amp;lt;sup&amp;gt; */ small { 	font-size: 85%; }  .mw-body-content sub, .mw-body-content sup, span.reference /* for Parsoid */ { 	font-si...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Reset italic styling set by user agent */&lt;br /&gt;
cite,&lt;br /&gt;
dfn {&lt;br /&gt;
	font-style: inherit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Straight quote marks for &amp;lt;q&amp;gt; */&lt;br /&gt;
q {&lt;br /&gt;
	quotes: &#039;&amp;quot;&#039; &#039;&amp;quot;&#039; &amp;quot;&#039;&amp;quot; &amp;quot;&#039;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Avoid collision of blockquote with floating elements by swapping margin and padding */&lt;br /&gt;
blockquote {&lt;br /&gt;
	overflow: hidden;&lt;br /&gt;
	margin: 1em 0;&lt;br /&gt;
	padding: 0 40px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Consistent size for &amp;lt;small&amp;gt;, &amp;lt;sub&amp;gt; and &amp;lt;sup&amp;gt; */&lt;br /&gt;
small {&lt;br /&gt;
	font-size: 85%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-body-content sub,&lt;br /&gt;
.mw-body-content sup,&lt;br /&gt;
span.reference /* for Parsoid */ {&lt;br /&gt;
	font-size: 80%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Same spacing for indented and unindented paragraphs on talk pages */&lt;br /&gt;
.ns-talk .mw-body-content dd {&lt;br /&gt;
	margin-top: 0.4em;&lt;br /&gt;
	margin-bottom: 0.4em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Reduce page jumps by hiding collapsed/dismissed content */&lt;br /&gt;
.client-js .mw-special-Watchlist #watchlist-message,&lt;br /&gt;
.client-js .collapsible:not( .mw-made-collapsible).collapsed &amp;gt; tbody &amp;gt; tr:not(:first-child),&lt;br /&gt;
&lt;br /&gt;
/* Hide charinsert base for those not using the gadget */&lt;br /&gt;
#editpage-specialchars {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Adds padding above Watchlist announcements where new recentchanges/watchlist filters are enabled */&lt;br /&gt;
.mw-rcfilters-enabled .mw-specialpage-summary {&lt;br /&gt;
	margin-top: 1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Make the list of references smaller&lt;br /&gt;
 * Keep in sync with Template:Refbegin/styles.css&lt;br /&gt;
 * And Template:Reflist/styles.css&lt;br /&gt;
 */&lt;br /&gt;
ol.references {&lt;br /&gt;
	font-size: 90%;&lt;br /&gt;
	margin-bottom: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style for horizontal lists (separator following item).&lt;br /&gt;
   @source mediawiki.org/wiki/Snippets/Horizontal_lists&lt;br /&gt;
   @revision 8 (2016-05-21)&lt;br /&gt;
   @author [[User:Edokter]]&lt;br /&gt;
 */&lt;br /&gt;
.hlist dl,&lt;br /&gt;
.hlist ol,&lt;br /&gt;
.hlist ul {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Display list items inline */&lt;br /&gt;
.hlist dd,&lt;br /&gt;
.hlist dt,&lt;br /&gt;
.hlist li {&lt;br /&gt;
	margin: 0; /* don&#039;t trust the note that says margin doesn&#039;t work with inline&lt;br /&gt;
				* removing margin: 0 makes dds have margins again */&lt;br /&gt;
	display: inline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Display nested lists inline */&lt;br /&gt;
.hlist.inline,&lt;br /&gt;
.hlist.inline dl,&lt;br /&gt;
.hlist.inline ol,&lt;br /&gt;
.hlist.inline ul,&lt;br /&gt;
.hlist dl dl,&lt;br /&gt;
.hlist dl ol,&lt;br /&gt;
.hlist dl ul,&lt;br /&gt;
.hlist ol dl,&lt;br /&gt;
.hlist ol ol,&lt;br /&gt;
.hlist ol ul,&lt;br /&gt;
.hlist ul dl,&lt;br /&gt;
.hlist ul ol,&lt;br /&gt;
.hlist ul ul {&lt;br /&gt;
	display: inline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide empty list items */&lt;br /&gt;
.hlist .mw-empty-li {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Generate interpuncts */&lt;br /&gt;
.hlist dt:after {&lt;br /&gt;
	content: &amp;quot;: &amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Note hlist style usage differs in Minerva and is defined in core as well!&lt;br /&gt;
 * Please check Minerva desktop (and Minerva.css) when changing&lt;br /&gt;
 * See https://phabricator.wikimedia.org/T213239&lt;br /&gt;
 */&lt;br /&gt;
.hlist dd:after,&lt;br /&gt;
.hlist li:after {&lt;br /&gt;
	content: &amp;quot; · &amp;quot;;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hlist dd:last-child:after,&lt;br /&gt;
.hlist dt:last-child:after,&lt;br /&gt;
.hlist li:last-child:after {&lt;br /&gt;
	content: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Add parentheses around nested lists */&lt;br /&gt;
.hlist dd dd:first-child:before,&lt;br /&gt;
.hlist dd dt:first-child:before,&lt;br /&gt;
.hlist dd li:first-child:before,&lt;br /&gt;
.hlist dt dd:first-child:before,&lt;br /&gt;
.hlist dt dt:first-child:before,&lt;br /&gt;
.hlist dt li:first-child:before,&lt;br /&gt;
.hlist li dd:first-child:before,&lt;br /&gt;
.hlist li dt:first-child:before,&lt;br /&gt;
.hlist li li:first-child:before {&lt;br /&gt;
	content: &amp;quot; (&amp;quot;;&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hlist dd dd:last-child:after,&lt;br /&gt;
.hlist dd dt:last-child:after,&lt;br /&gt;
.hlist dd li:last-child:after,&lt;br /&gt;
.hlist dt dd:last-child:after,&lt;br /&gt;
.hlist dt dt:last-child:after,&lt;br /&gt;
.hlist dt li:last-child:after,&lt;br /&gt;
.hlist li dd:last-child:after,&lt;br /&gt;
.hlist li dt:last-child:after,&lt;br /&gt;
.hlist li li:last-child:after {&lt;br /&gt;
	content: &amp;quot;)&amp;quot;;&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Put ordinals in front of ordered list items */&lt;br /&gt;
.hlist ol {&lt;br /&gt;
	counter-reset: listitem;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hlist ol &amp;gt; li {&lt;br /&gt;
	counter-increment: listitem;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hlist ol &amp;gt; li:before {&lt;br /&gt;
	content: &amp;quot; &amp;quot; counter(listitem) &amp;quot;\a0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hlist dd ol &amp;gt; li:first-child:before,&lt;br /&gt;
.hlist dt ol &amp;gt; li:first-child:before,&lt;br /&gt;
.hlist li ol &amp;gt; li:first-child:before {&lt;br /&gt;
	content: &amp;quot; (&amp;quot; counter(listitem) &amp;quot;\a0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Unbulleted lists */&lt;br /&gt;
.plainlist ol,&lt;br /&gt;
.plainlist ul {&lt;br /&gt;
	line-height: inherit;&lt;br /&gt;
	list-style: none none;&lt;br /&gt;
	margin: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.plainlist ol li,&lt;br /&gt;
.plainlist ul li {&lt;br /&gt;
	margin-bottom: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Styling for JQuery makeCollapsible, matching that of collapseButton */&lt;br /&gt;
.mw-parser-output .mw-collapsible-toggle {&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: right;&lt;br /&gt;
	padding-right: 0.2em;&lt;br /&gt;
	padding-left: 0.2em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-collapsible-leftside-toggle .mw-collapsible-toggle {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: left;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Infobox template style */&lt;br /&gt;
.infobox {&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	border-spacing: 3px;&lt;br /&gt;
	background-color: #f8f9fa;&lt;br /&gt;
	color: black;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 0.5em 0 0.5em 1em;&lt;br /&gt;
	padding: 0.2em;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: right;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	clear: right;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	line-height: 1.5em;&lt;br /&gt;
	width: 22em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox-header,&lt;br /&gt;
.infobox-label,&lt;br /&gt;
.infobox-above,&lt;br /&gt;
.infobox-full-data,&lt;br /&gt;
.infobox-data,&lt;br /&gt;
.infobox-below,&lt;br /&gt;
.infobox-subheader,&lt;br /&gt;
.infobox-image,&lt;br /&gt;
.infobox-navbar,&lt;br /&gt;
/* Remove element selector when every .infobox thing is using the standard module/templates  */&lt;br /&gt;
.infobox th,&lt;br /&gt;
.infobox td {&lt;br /&gt;
	vertical-align: top;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox-label,&lt;br /&gt;
.infobox-data,&lt;br /&gt;
/* Remove element selector when every .infobox thing is using the standard module/templates  */&lt;br /&gt;
.infobox th,&lt;br /&gt;
.infobox td {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Remove .infobox when element selectors above are removed */&lt;br /&gt;
.infobox .infobox-above,&lt;br /&gt;
.infobox .infobox-title,&lt;br /&gt;
/* Remove element selector when every .infobox thing is using the standard module/templates  */&lt;br /&gt;
.infobox caption {&lt;br /&gt;
	font-size: 125%;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox-title,&lt;br /&gt;
/* Remove element selector when every .infobox thing is using the standard module/templates  */&lt;br /&gt;
.infobox caption {&lt;br /&gt;
	padding: 0.2em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Remove .infobox when element selectors above are removed */&lt;br /&gt;
.infobox .infobox-header,&lt;br /&gt;
.infobox .infobox-subheader,&lt;br /&gt;
.infobox .infobox-image,&lt;br /&gt;
.infobox .infobox-full-data,&lt;br /&gt;
.infobox .infobox-below {&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Remove .infobox when element selectors above are removed */&lt;br /&gt;
.infobox .infobox-navbar {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: right;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Normal font styling for wikitable row headers with scope=&amp;quot;row&amp;quot; tag */&lt;br /&gt;
.wikitable.plainrowheaders th[scope=row] {&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Lists in wikitable data cells are always left-aligned */&lt;br /&gt;
.wikitable td ul,&lt;br /&gt;
.wikitable td ol,&lt;br /&gt;
.wikitable td dl {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Fix for hieroglyphs specificity issue in infoboxes ([[phab:T43869]]) */&lt;br /&gt;
table.mw-hiero-table td {&lt;br /&gt;
	vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Change the external link icon to an Adobe icon for all PDF files */&lt;br /&gt;
.mw-parser-output a[href$=&amp;quot;.pdf&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href*=&amp;quot;.pdf?&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href*=&amp;quot;.pdf#&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href$=&amp;quot;.PDF&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href*=&amp;quot;.PDF?&amp;quot;].external,&lt;br /&gt;
.mw-parser-output a[href*=&amp;quot;.PDF#&amp;quot;].external {&lt;br /&gt;
	background: url(&amp;quot;//upload.wikimedia.org/wikipedia/commons/4/4d/Icon_pdf_file.png&amp;quot;) no-repeat right;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding-right: 18px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Messagebox templates */&lt;br /&gt;
.messagebox {&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	background-color: #f8f9fa;&lt;br /&gt;
	width: 80%;&lt;br /&gt;
	margin: 0 auto 1em auto;&lt;br /&gt;
	padding: .2em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.messagebox.standard-talk {&lt;br /&gt;
	border: 1px solid #c0c090;&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
	margin: 4px auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* For old WikiProject banners inside banner shells. */&lt;br /&gt;
.mbox-inside .standard-talk {&lt;br /&gt;
	border: 1px solid #c0c090;&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	margin: 2px 0;&lt;br /&gt;
	padding: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.messagebox.small {&lt;br /&gt;
	width: 238px;&lt;br /&gt;
	font-size: 85%;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: right;&lt;br /&gt;
	clear: both;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 0 0 1em 1em;&lt;br /&gt;
	line-height: 1.25em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.messagebox.small-talk {&lt;br /&gt;
	width: 238px;&lt;br /&gt;
	font-size: 85%;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: right;&lt;br /&gt;
	clear: both;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 0 0 1em 1em;&lt;br /&gt;
	line-height: 1.25em;&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Cell sizes for ambox/tmbox/imbox/cmbox/ombox/fmbox/dmbox message boxes */&lt;br /&gt;
th.mbox-text, td.mbox-text {   /* The message body cell(s) */&lt;br /&gt;
	border: none;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 0.25em 0.9em;     /* 0.9em left/right */&lt;br /&gt;
	width: 100%;               /* Make all mboxes the same width regardless of text length */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
td.mbox-image {                /* The left image cell */&lt;br /&gt;
	border: none;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 2px 0 2px 0.9em;  /* 0.9em left, 0px right */&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
td.mbox-imageright {           /* The right image cell */&lt;br /&gt;
	border: none;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 2px 0.9em 2px 0;  /* 0px left, 0.9em right */&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
td.mbox-empty-cell {           /* An empty narrow cell */&lt;br /&gt;
	border: none;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
	width: 1px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Article message box styles */&lt;br /&gt;
table.ambox {&lt;br /&gt;
	margin: 0 10%;                  /* 10% = Will not overlap with other elements */&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #36c;  /* Default &amp;quot;notice&amp;quot; blue */&lt;br /&gt;
	background-color: #fbfbfb;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Single border between stacked boxes. */&lt;br /&gt;
table.ambox + table.ambox,&lt;br /&gt;
table.ambox + .mw-empty-elt + table.ambox {&lt;br /&gt;
	margin-top: -1px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ambox th.mbox-text,&lt;br /&gt;
.ambox td.mbox-text {            /* The message body cell(s) */&lt;br /&gt;
	padding: 0.25em 0.5em;       /* 0.5em left/right */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ambox td.mbox-image {           /* The left image cell */&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 2px 0 2px 0.5em;    /* 0.5em left, 0px right */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ambox td.mbox-imageright {      /* The right image cell */&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 2px 0.5em 2px 0;    /* 0px left, 0.5em right */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.ambox-notice {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #36c;       /* Blue */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.ambox-speedy {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #fee7e6;          /* Pink */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.ambox-delete {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #b32424;    /* Red */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.ambox-content {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #f28500;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.ambox-style {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #fc3;       /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.ambox-move {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #9932cc;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.ambox-protection {&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	border-left: 10px solid #a2a9b1;    /* Gray-gold */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Image message box styles */&lt;br /&gt;
table.imbox {&lt;br /&gt;
	margin: 4px 10%;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	border: 3px solid #36c;    /* Default &amp;quot;notice&amp;quot; blue */&lt;br /&gt;
	background-color: #fbfbfb;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.imbox .mbox-text .imbox {  /* For imboxes inside imbox-text cells. */&lt;br /&gt;
	margin: 0 -0.5em;       /* 0.9 - 0.5 = 0.4em left/right.        */&lt;br /&gt;
	display: block;         /* Fix for webkit to force 100% width.  */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mbox-inside .imbox {       /* For imboxes inside other templates.  */&lt;br /&gt;
	margin: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.imbox-notice {&lt;br /&gt;
	border: 3px solid #36c;       /* Blue */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.imbox-speedy {&lt;br /&gt;
	border: 3px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #fee7e6;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.imbox-delete {&lt;br /&gt;
	border: 3px solid #b32424;    /* Red */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.imbox-content {&lt;br /&gt;
	border: 3px solid #f28500;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.imbox-style {&lt;br /&gt;
	border: 3px solid #fc3;       /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.imbox-move {&lt;br /&gt;
	border: 3px solid #9932cc;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.imbox-protection {&lt;br /&gt;
	border: 3px solid #a2a9b1;    /* Gray-gold */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.imbox-license {&lt;br /&gt;
	border: 3px solid #88a;       /* Dark gray */&lt;br /&gt;
	background-color: #f7f8ff;    /* Light gray */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.imbox-featured {&lt;br /&gt;
	border: 3px solid #cba135;    /* Brown-gold */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Category message box styles */&lt;br /&gt;
table.cmbox {&lt;br /&gt;
	margin: 3px 10%;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	background-color: #dfe8ff;    /* Default &amp;quot;notice&amp;quot; blue */&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.cmbox-notice {&lt;br /&gt;
	background-color: #d8e8ff;    /* Blue */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.cmbox-speedy {&lt;br /&gt;
	margin-top: 4px;&lt;br /&gt;
	margin-bottom: 4px;&lt;br /&gt;
	border: 4px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #ffdbdb;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.cmbox-delete {&lt;br /&gt;
	background-color: #ffdbdb;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.cmbox-content {&lt;br /&gt;
	background-color: #ffe7ce;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.cmbox-style {&lt;br /&gt;
	background-color: #fff9db;    /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.cmbox-move {&lt;br /&gt;
	background-color: #e4d8ff;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.cmbox-protection {&lt;br /&gt;
	background-color: #efefe1;    /* Gray-gold */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Other pages message box styles */&lt;br /&gt;
table.ombox {&lt;br /&gt;
	margin: 4px 10%;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	border: 1px solid #a2a9b1;    /* Default &amp;quot;notice&amp;quot; gray */&lt;br /&gt;
	background-color: #f8f9fa;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.ombox-notice {&lt;br /&gt;
	border: 1px solid #a2a9b1;    /* Gray */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.ombox-speedy {&lt;br /&gt;
	border: 2px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #fee7e6;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.ombox-delete {&lt;br /&gt;
	border: 2px solid #b32424;    /* Red */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.ombox-content {&lt;br /&gt;
	border: 1px solid #f28500;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.ombox-style {&lt;br /&gt;
	border: 1px solid #fc3;       /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.ombox-move {&lt;br /&gt;
	border: 1px solid #9932cc;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.ombox-protection {&lt;br /&gt;
	border: 2px solid #a2a9b1;    /* Gray-gold */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Talk page message box styles */&lt;br /&gt;
table.tmbox {&lt;br /&gt;
	margin: 4px 10%;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	border: 1px solid #c0c090;    /* Default &amp;quot;notice&amp;quot; gray-brown */&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
	min-width: 80%;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tmbox.mbox-small {&lt;br /&gt;
	min-width: 0;                /* reset the min-width of tmbox above        */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mediawiki .mbox-inside .tmbox { /* For tmboxes inside other templates. The &amp;quot;mediawiki&amp;quot; class ensures that */&lt;br /&gt;
	margin: 2px 0;               /* this declaration overrides other styles (including mbox-small above)   */&lt;br /&gt;
	width: 100%;                 /* For Safari and Opera */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mbox-inside .tmbox.mbox-small { /* &amp;quot;small&amp;quot; tmboxes should not be small when  */&lt;br /&gt;
	line-height: 1.5em;          /* also &amp;quot;nested&amp;quot;, so reset styles that are   */&lt;br /&gt;
	font-size: 100%;             /* set in &amp;quot;mbox-small&amp;quot; above.                */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.tmbox-speedy {&lt;br /&gt;
	border: 2px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #fee7e6;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.tmbox-delete {&lt;br /&gt;
	border: 2px solid #b32424;    /* Red */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.tmbox-content {&lt;br /&gt;
	border: 2px solid #f28500;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.tmbox-style {&lt;br /&gt;
	border: 2px solid #fc3;       /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.tmbox-move {&lt;br /&gt;
	border: 2px solid #9932cc;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.tmbox-protection,&lt;br /&gt;
table.tmbox-notice {&lt;br /&gt;
	border: 1px solid #c0c090;    /* Gray-brown */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Footer and header message box styles */&lt;br /&gt;
table.fmbox {&lt;br /&gt;
	clear: both;&lt;br /&gt;
	margin: 0.2em 0;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	border: 1px solid #a2a9b1;&lt;br /&gt;
	background-color: #f8f9fa;     /* Default &amp;quot;system&amp;quot; gray */&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.fmbox-system {&lt;br /&gt;
	background-color: #f8f9fa;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.fmbox-warning {&lt;br /&gt;
	border: 1px solid #bb7070;  /* Dark pink */&lt;br /&gt;
	background-color: #ffdbdb;  /* Pink */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
table.fmbox-editnotice {&lt;br /&gt;
	background-color: transparent;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Div based &amp;quot;warning&amp;quot; style fmbox messages. */&lt;br /&gt;
div.mw-warning-with-logexcerpt,&lt;br /&gt;
div.mw-lag-warn-high,&lt;br /&gt;
div.mw-cascadeprotectedwarning,&lt;br /&gt;
div#mw-protect-cascadeon,&lt;br /&gt;
div.titleblacklist-warning {&lt;br /&gt;
	clear: both;&lt;br /&gt;
	margin: 0.2em 0;&lt;br /&gt;
	border: 1px solid #bb7070;&lt;br /&gt;
	background-color: #ffdbdb;&lt;br /&gt;
	padding: 0.25em 0.9em;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Use default color for partial block fmbox banner per [[Special:PermaLink/1028105567#pblock-style]] */&lt;br /&gt;
.mw-contributions-blocked-notice-partial .mw-warning-with-logexcerpt {&lt;br /&gt;
	border-color: #fc3;&lt;br /&gt;
	background-color: #fef6e7;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* These mbox-small classes must be placed after all other&lt;br /&gt;
   ambox/tmbox/ombox etc classes. &amp;quot;html body.mediawiki&amp;quot; is so&lt;br /&gt;
   they override &amp;quot;table.ambox + table.ambox&amp;quot; above. */&lt;br /&gt;
html body.mediawiki .mbox-small {   /* For the &amp;quot;small=yes&amp;quot; option. */&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	clear: right;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	float: right;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 4px 0 4px 1em;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
	width: 238px;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	line-height: 1.25em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
html body.mediawiki .mbox-small-left {   /* For the &amp;quot;small=left&amp;quot; option. */&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	margin: 4px 1em 4px 0;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
	overflow: hidden;&lt;br /&gt;
	width: 238px;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	line-height: 1.25em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style for compact ambox */&lt;br /&gt;
/* Hide the images */&lt;br /&gt;
.compact-ambox table .mbox-image,&lt;br /&gt;
.compact-ambox table .mbox-imageright,&lt;br /&gt;
.compact-ambox table .mbox-empty-cell {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Remove borders, backgrounds, padding, etc. */&lt;br /&gt;
.compact-ambox table.ambox {&lt;br /&gt;
	border: none;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	background-color: transparent;&lt;br /&gt;
	margin: 0 0 0 1.6em !important;&lt;br /&gt;
	padding: 0 !important;&lt;br /&gt;
	width: auto;&lt;br /&gt;
	display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.mediawiki .compact-ambox table.mbox-small-left {&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
	width: auto;&lt;br /&gt;
	margin: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style the text cell as a list item and remove its padding */&lt;br /&gt;
.compact-ambox table .mbox-text {&lt;br /&gt;
	padding: 0 !important;&lt;br /&gt;
	margin: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.compact-ambox table .mbox-text-span {&lt;br /&gt;
	display: list-item;&lt;br /&gt;
	line-height: 1.5em;&lt;br /&gt;
	list-style-type: square;&lt;br /&gt;
	list-style-image: url(/w/skins/MonoBook/resources/images/bullet.svg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Allow for hiding text in compact form */&lt;br /&gt;
.compact-ambox .hide-when-compact {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Remove underlines from certain links */&lt;br /&gt;
.nounderlines a,&lt;br /&gt;
.IPA a:link,&lt;br /&gt;
.IPA a:visited {&lt;br /&gt;
	text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Prevent line breaks in silly places where desired (nowrap)&lt;br /&gt;
   and links when we don&#039;t want them to (nowraplinks a) */&lt;br /&gt;
.nowrap,&lt;br /&gt;
.nowraplinks a {&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* But allow wrapping where desired: */&lt;br /&gt;
.wrap,&lt;br /&gt;
.wraplinks a {&lt;br /&gt;
	white-space: normal;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Increase the height of the image upload box */&lt;br /&gt;
#wpUploadDescription {&lt;br /&gt;
	height: 13em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Minimum thumb width */&lt;br /&gt;
.thumbinner {&lt;br /&gt;
	min-width: 100px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Prevent floating boxes from overlapping any category listings,&lt;br /&gt;
   file histories, edit previews, and edit [Show changes] views. */&lt;br /&gt;
#mw-subcategories,&lt;br /&gt;
#mw-pages,&lt;br /&gt;
#mw-category-media,&lt;br /&gt;
#filehistory,&lt;br /&gt;
#wikiPreview,&lt;br /&gt;
#wikiDiff {&lt;br /&gt;
	clear: both;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Selectively hide headers in WikiProject banners */&lt;br /&gt;
/* TemplateStyles */&lt;br /&gt;
.wpb .wpb-header {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wpbs-inner .wpb .wpb-header {&lt;br /&gt;
	display: table-row;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wpbs-inner .wpb-outside {&lt;br /&gt;
	display: none;             /* hide things that should only display outside shells */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Styling for Abuse Filter tags */&lt;br /&gt;
.mw-tag-markers {&lt;br /&gt;
	font-style: italic;&lt;br /&gt;
	font-size: 90%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide stuff meant for accounts with special permissions. Made visible again in&lt;br /&gt;
   [[MediaWiki:Group-checkuser.css]], [[MediaWiki:Group-sysop.css]], [[MediaWiki:Group-abusefilter.css]],&lt;br /&gt;
   [[MediaWiki:Group-abusefilter-helper.css]], [[MediaWiki:Group-patroller.css]],&lt;br /&gt;
   [[MediaWiki:Group-templateeditor.css]], [[MediaWiki:Group-extendedmover.css]],&lt;br /&gt;
   [[MediaWiki:Group-extendedconfirmed.css]], and [[Mediawiki:Group-autoconfirmed.css]]. */&lt;br /&gt;
.checkuser-show,&lt;br /&gt;
.sysop-show,&lt;br /&gt;
.abusefilter-show,&lt;br /&gt;
.abusefilter-helper-show,&lt;br /&gt;
.patroller-show,&lt;br /&gt;
.templateeditor-show,&lt;br /&gt;
.extendedmover-show,&lt;br /&gt;
.extendedconfirmed-show,&lt;br /&gt;
.autoconfirmed-show,&lt;br /&gt;
.user-show {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide the redlink generated by {{Editnotice}},&lt;br /&gt;
   this overrides the &amp;quot;.sysop-show { display: none; }&amp;quot; above that applies&lt;br /&gt;
   to the same link as well. See [[phab:T45013]]&lt;br /&gt;
&lt;br /&gt;
   Hide the images in editnotices to keep them readable in VE view.&lt;br /&gt;
   Long term, editnotices should become a core feature so that they can be designed responsive. */&lt;br /&gt;
.ve-ui-mwNoticesPopupTool-item .editnotice-redlink,&lt;br /&gt;
.ve-ui-mwNoticesPopupTool-item .mbox-image,&lt;br /&gt;
.ve-ui-mwNoticesPopupTool-item .mbox-imageright {&lt;br /&gt;
	display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Remove bullets when there are multiple edit page warnings */&lt;br /&gt;
ul.permissions-errors &amp;gt; li {&lt;br /&gt;
	list-style: none none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ul.permissions-errors {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* texhtml class for inline math (based on generic times-serif class) */&lt;br /&gt;
span.texhtml {&lt;br /&gt;
	font-family: &amp;quot;Nimbus Roman No9 L&amp;quot;, &amp;quot;Times New Roman&amp;quot;, Times, serif;&lt;br /&gt;
	font-size: 118%;&lt;br /&gt;
	line-height: 1;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	/* Force tabular and lining display for texhtml */&lt;br /&gt;
	-moz-font-feature-settings: &amp;quot;lnum&amp;quot;, &amp;quot;tnum&amp;quot;, &amp;quot;kern&amp;quot; 0;&lt;br /&gt;
	-webkit-font-feature-settings: &amp;quot;lnum&amp;quot;, &amp;quot;tnum&amp;quot;, &amp;quot;kern&amp;quot; 0;&lt;br /&gt;
	font-feature-settings: &amp;quot;lnum&amp;quot;, &amp;quot;tnum&amp;quot;, &amp;quot;kern&amp;quot; 0;&lt;br /&gt;
	font-variant-numeric: lining-nums tabular-nums;&lt;br /&gt;
	font-kerning: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
span.texhtml span.texhtml {&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
span.mwe-math-mathml-inline {&lt;br /&gt;
	font-size: 118%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Make &amp;lt;math display=&amp;quot;block&amp;quot;&amp;gt; be left aligned with one space indent for &lt;br /&gt;
 * compatibility with style conventions&lt;br /&gt;
 */&lt;br /&gt;
.mwe-math-fallback-image-display,&lt;br /&gt;
.mwe-math-mathml-display {&lt;br /&gt;
	margin-left: 1.6em !important;&lt;br /&gt;
	margin-top: 0.6em;&lt;br /&gt;
	margin-bottom: 0.6em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mwe-math-mathml-display math {&lt;br /&gt;
	display: inline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Work-around for [[phab:T25965]] / [[phab:T100106]] (Kaltura advertisement) */&lt;br /&gt;
.k-player .k-attribution {&lt;br /&gt;
	visibility: hidden;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Move &#039;play&#039; button of video player to bottom left corner */&lt;br /&gt;
.PopUpMediaTransform a .play-btn-large {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	top: auto;&lt;br /&gt;
	right: auto;&lt;br /&gt;
	bottom: 0;&lt;br /&gt;
	left: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen {&lt;br /&gt;
	/* Gallery styles background changes are restricted to screen view.&lt;br /&gt;
	   In printing we should avoid applying backgrounds. */&lt;br /&gt;
	/* The backgrounds for galleries. */&lt;br /&gt;
	#content .gallerybox div.thumb {&lt;br /&gt;
		/* Light gray padding */&lt;br /&gt;
		background-color: #f8f9fa;&lt;br /&gt;
	}&lt;br /&gt;
	/* Put a chequered background behind images, only visible if they have transparency.&lt;br /&gt;
	   &#039;.filehistory a img&#039; and &#039;#file img:hover&#039; are handled by MediaWiki core (as of 1.19) */&lt;br /&gt;
	.gallerybox .thumb img {&lt;br /&gt;
		background: #fff url(//upload.wikimedia.org/wikipedia/commons/5/5d/Checker-16x16.png) repeat;&lt;br /&gt;
	}&lt;br /&gt;
	/* But not on articles, user pages, portals or with opt-out. */&lt;br /&gt;
	.ns-0 .gallerybox .thumb img,&lt;br /&gt;
	.ns-2 .gallerybox .thumb img,&lt;br /&gt;
	.ns-100 .gallerybox .thumb img,&lt;br /&gt;
	.nochecker .gallerybox .thumb img {&lt;br /&gt;
		background-image: none;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Display &amp;quot;From Wikipedia, the free encyclopedia&amp;quot; in skins that support it,&lt;br /&gt;
	   do not apply to print mode */&lt;br /&gt;
	#siteSub {&lt;br /&gt;
		display: block;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide FlaggedRevs notice UI when there are no pending changes */&lt;br /&gt;
.flaggedrevs_draft_synced,&lt;br /&gt;
.flaggedrevs_stable_synced,&lt;br /&gt;
/* &amp;quot;Temporary&amp;quot; to remove links in sidebar T255381 */&lt;br /&gt;
#t-upload,&lt;br /&gt;
/* Hide broken download box on Special:Book pending T285400 */&lt;br /&gt;
.mw-special-Book #coll-downloadbox {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Module:String&amp;diff=22</id>
		<title>Module:String</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Module:String&amp;diff=22"/>
		<updated>2025-12-24T15:17:15Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;--[[  This module is intended to provide access to basic string functions.  Most of the functions provided here can be invoked with named parameters, unnamed parameters, or a mixture.  If named parameters are used, Mediawiki will automatically remove any leading or trailing whitespace from the parameter. Depending on the intended use, it may be advantageous to either preserve or remove such whitespace.  Global options     ignore_errors: If set to &amp;#039;true&amp;#039; or 1, any error c...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--[[&lt;br /&gt;
&lt;br /&gt;
This module is intended to provide access to basic string functions.&lt;br /&gt;
&lt;br /&gt;
Most of the functions provided here can be invoked with named parameters,&lt;br /&gt;
unnamed parameters, or a mixture.  If named parameters are used, Mediawiki will&lt;br /&gt;
automatically remove any leading or trailing whitespace from the parameter.&lt;br /&gt;
Depending on the intended use, it may be advantageous to either preserve or&lt;br /&gt;
remove such whitespace.&lt;br /&gt;
&lt;br /&gt;
Global options&lt;br /&gt;
    ignore_errors: If set to &#039;true&#039; or 1, any error condition will result in&lt;br /&gt;
        an empty string being returned rather than an error message.&lt;br /&gt;
&lt;br /&gt;
    error_category: If an error occurs, specifies the name of a category to&lt;br /&gt;
        include with the error message.  The default category is&lt;br /&gt;
        [Category:Errors reported by Module String].&lt;br /&gt;
&lt;br /&gt;
    no_category: If set to &#039;true&#039; or 1, no category will be added if an error&lt;br /&gt;
        is generated.&lt;br /&gt;
&lt;br /&gt;
Unit tests for this module are available at Module:String/tests.&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local str = {}&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
len&lt;br /&gt;
&lt;br /&gt;
This function returns the length of the target string.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:String|len|target_string|}}&lt;br /&gt;
OR&lt;br /&gt;
{{#invoke:String|len|s=target_string}}&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
    s: The string whose length to report&lt;br /&gt;
&lt;br /&gt;
If invoked using named parameters, Mediawiki will automatically remove any leading or&lt;br /&gt;
trailing whitespace from the target string.&lt;br /&gt;
]]&lt;br /&gt;
function str.len( frame )&lt;br /&gt;
	local new_args = str._getParameters( frame.args, {&#039;s&#039;} )&lt;br /&gt;
	local s = new_args[&#039;s&#039;] or &#039;&#039;&lt;br /&gt;
	return mw.ustring.len( s )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
sub&lt;br /&gt;
&lt;br /&gt;
This function returns a substring of the target string at specified indices.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:String|sub|target_string|start_index|end_index}}&lt;br /&gt;
OR&lt;br /&gt;
{{#invoke:String|sub|s=target_string|i=start_index|j=end_index}}&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
    s: The string to return a subset of&lt;br /&gt;
    i: The first index of the substring to return, defaults to 1.&lt;br /&gt;
    j: The last index of the string to return, defaults to the last character.&lt;br /&gt;
&lt;br /&gt;
The first character of the string is assigned an index of 1.  If either i or j&lt;br /&gt;
is a negative value, it is interpreted the same as selecting a character by&lt;br /&gt;
counting from the end of the string.  Hence, a value of -1 is the same as&lt;br /&gt;
selecting the last character of the string.&lt;br /&gt;
&lt;br /&gt;
If the requested indices are out of range for the given string, an error is&lt;br /&gt;
reported.&lt;br /&gt;
]]&lt;br /&gt;
function str.sub( frame )&lt;br /&gt;
	local new_args = str._getParameters( frame.args, { &#039;s&#039;, &#039;i&#039;, &#039;j&#039; } )&lt;br /&gt;
	local s = new_args[&#039;s&#039;] or &#039;&#039;&lt;br /&gt;
	local i = tonumber( new_args[&#039;i&#039;] ) or 1&lt;br /&gt;
	local j = tonumber( new_args[&#039;j&#039;] ) or -1&lt;br /&gt;
&lt;br /&gt;
	local len = mw.ustring.len( s )&lt;br /&gt;
&lt;br /&gt;
	-- Convert negatives for range checking&lt;br /&gt;
	if i &amp;lt; 0 then&lt;br /&gt;
		i = len + i + 1&lt;br /&gt;
	end&lt;br /&gt;
	if j &amp;lt; 0 then&lt;br /&gt;
		j = len + j + 1&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if i &amp;gt; len or j &amp;gt; len or i &amp;lt; 1 or j &amp;lt; 1 then&lt;br /&gt;
		return str._error( &#039;String subset index out of range&#039; )&lt;br /&gt;
	end&lt;br /&gt;
	if j &amp;lt; i then&lt;br /&gt;
		return str._error( &#039;String subset indices out of order&#039; )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return mw.ustring.sub( s, i, j )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
This function implements that features of {{str sub old}} and is kept in order&lt;br /&gt;
to maintain these older templates.&lt;br /&gt;
]]&lt;br /&gt;
function str.sublength( frame )&lt;br /&gt;
	local i = tonumber( frame.args.i ) or 0&lt;br /&gt;
	local len = tonumber( frame.args.len )&lt;br /&gt;
	return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
_match&lt;br /&gt;
&lt;br /&gt;
This function returns a substring from the source string that matches a&lt;br /&gt;
specified pattern. It is exported for use in other modules&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
strmatch = require(&amp;quot;Module:String&amp;quot;)._match&lt;br /&gt;
sresult = strmatch( s, pattern, start, match, plain, nomatch )&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
    s: The string to search&lt;br /&gt;
    pattern: The pattern or string to find within the string&lt;br /&gt;
    start: The index within the source string to start the search.  The first&lt;br /&gt;
        character of the string has index 1.  Defaults to 1.&lt;br /&gt;
    match: In some cases it may be possible to make multiple matches on a single&lt;br /&gt;
        string.  This specifies which match to return, where the first match is&lt;br /&gt;
        match= 1.  If a negative number is specified then a match is returned&lt;br /&gt;
        counting from the last match.  Hence match = -1 is the same as requesting&lt;br /&gt;
        the last match.  Defaults to 1.&lt;br /&gt;
    plain: A flag indicating that the pattern should be understood as plain&lt;br /&gt;
        text.  Defaults to false.&lt;br /&gt;
    nomatch: If no match is found, output the &amp;quot;nomatch&amp;quot; value rather than an error.&lt;br /&gt;
&lt;br /&gt;
For information on constructing Lua patterns, a form of [regular expression], see:&lt;br /&gt;
&lt;br /&gt;
* http://www.lua.org/manual/5.1/manual.html#5.4.1&lt;br /&gt;
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns&lt;br /&gt;
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
-- This sub-routine is exported for use in other modules&lt;br /&gt;
function str._match( s, pattern, start, match_index, plain_flag, nomatch )&lt;br /&gt;
	if s == &#039;&#039; then&lt;br /&gt;
		return str._error( &#039;Target string is empty&#039; )&lt;br /&gt;
	end&lt;br /&gt;
	if pattern == &#039;&#039; then&lt;br /&gt;
		return str._error( &#039;Pattern string is empty&#039; )&lt;br /&gt;
	end&lt;br /&gt;
	start = tonumber(start) or 1&lt;br /&gt;
	if math.abs(start) &amp;lt; 1 or math.abs(start) &amp;gt; mw.ustring.len( s ) then&lt;br /&gt;
		return str._error( &#039;Requested start is out of range&#039; )&lt;br /&gt;
	end&lt;br /&gt;
	if match_index == 0 then&lt;br /&gt;
		return str._error( &#039;Match index is out of range&#039; )&lt;br /&gt;
	end&lt;br /&gt;
	if plain_flag then&lt;br /&gt;
		pattern = str._escapePattern( pattern )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local result&lt;br /&gt;
	if match_index == 1 then&lt;br /&gt;
		-- Find first match is simple case&lt;br /&gt;
		result = mw.ustring.match( s, pattern, start )&lt;br /&gt;
	else&lt;br /&gt;
		if start &amp;gt; 1 then&lt;br /&gt;
			s = mw.ustring.sub( s, start )&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local iterator = mw.ustring.gmatch(s, pattern)&lt;br /&gt;
		if match_index &amp;gt; 0 then&lt;br /&gt;
			-- Forward search&lt;br /&gt;
			for w in iterator do&lt;br /&gt;
				match_index = match_index - 1&lt;br /&gt;
				if match_index == 0 then&lt;br /&gt;
					result = w&lt;br /&gt;
					break&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			-- Reverse search&lt;br /&gt;
			local result_table = {}&lt;br /&gt;
			local count = 1&lt;br /&gt;
			for w in iterator do&lt;br /&gt;
				result_table[count] = w&lt;br /&gt;
				count = count + 1&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			result = result_table[ count + match_index ]&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if result == nil then&lt;br /&gt;
		if nomatch == nil then&lt;br /&gt;
			return str._error( &#039;Match not found&#039; )&lt;br /&gt;
		else&lt;br /&gt;
			return nomatch&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		return result&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
match&lt;br /&gt;
&lt;br /&gt;
This function returns a substring from the source string that matches a&lt;br /&gt;
specified pattern.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:String|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}}&lt;br /&gt;
OR&lt;br /&gt;
{{#invoke:String|match|s=source_string|pattern=pattern_string|start=start_index&lt;br /&gt;
    |match=match_number|plain=plain_flag|nomatch=nomatch_output}}&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
    s: The string to search&lt;br /&gt;
    pattern: The pattern or string to find within the string&lt;br /&gt;
    start: The index within the source string to start the search.  The first&lt;br /&gt;
        character of the string has index 1.  Defaults to 1.&lt;br /&gt;
    match: In some cases it may be possible to make multiple matches on a single&lt;br /&gt;
        string.  This specifies which match to return, where the first match is&lt;br /&gt;
        match= 1.  If a negative number is specified then a match is returned&lt;br /&gt;
        counting from the last match.  Hence match = -1 is the same as requesting&lt;br /&gt;
        the last match.  Defaults to 1.&lt;br /&gt;
    plain: A flag indicating that the pattern should be understood as plain&lt;br /&gt;
        text.  Defaults to false.&lt;br /&gt;
    nomatch: If no match is found, output the &amp;quot;nomatch&amp;quot; value rather than an error.&lt;br /&gt;
&lt;br /&gt;
If invoked using named parameters, Mediawiki will automatically remove any leading or&lt;br /&gt;
trailing whitespace from each string.  In some circumstances this is desirable, in&lt;br /&gt;
other cases one may want to preserve the whitespace.&lt;br /&gt;
&lt;br /&gt;
If the match_number or start_index are out of range for the string being queried, then&lt;br /&gt;
this function generates an error.  An error is also generated if no match is found.&lt;br /&gt;
If one adds the parameter ignore_errors=true, then the error will be suppressed and&lt;br /&gt;
an empty string will be returned on any failure.&lt;br /&gt;
&lt;br /&gt;
For information on constructing Lua patterns, a form of [regular expression], see:&lt;br /&gt;
&lt;br /&gt;
* http://www.lua.org/manual/5.1/manual.html#5.4.1&lt;br /&gt;
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns&lt;br /&gt;
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
-- This is the entry point for #invoke:String|match&lt;br /&gt;
function str.match( frame )&lt;br /&gt;
	local new_args = str._getParameters( frame.args, {&#039;s&#039;, &#039;pattern&#039;, &#039;start&#039;, &#039;match&#039;, &#039;plain&#039;, &#039;nomatch&#039;} )&lt;br /&gt;
	local s = new_args[&#039;s&#039;] or &#039;&#039;&lt;br /&gt;
	local start = tonumber( new_args[&#039;start&#039;] ) or 1&lt;br /&gt;
	local plain_flag = str._getBoolean( new_args[&#039;plain&#039;] or false )&lt;br /&gt;
	local pattern = new_args[&#039;pattern&#039;] or &#039;&#039;&lt;br /&gt;
	local match_index = math.floor( tonumber(new_args[&#039;match&#039;]) or 1 )&lt;br /&gt;
	local nomatch = new_args[&#039;nomatch&#039;]&lt;br /&gt;
&lt;br /&gt;
	return str._match( s, pattern, start, match_index, plain_flag, nomatch )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
pos&lt;br /&gt;
&lt;br /&gt;
This function returns a single character from the target string at position pos.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:String|pos|target_string|index_value}}&lt;br /&gt;
OR&lt;br /&gt;
{{#invoke:String|pos|target=target_string|pos=index_value}}&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
    target: The string to search&lt;br /&gt;
    pos: The index for the character to return&lt;br /&gt;
&lt;br /&gt;
If invoked using named parameters, Mediawiki will automatically remove any leading or&lt;br /&gt;
trailing whitespace from the target string.  In some circumstances this is desirable, in&lt;br /&gt;
other cases one may want to preserve the whitespace.&lt;br /&gt;
&lt;br /&gt;
The first character has an index value of 1.&lt;br /&gt;
&lt;br /&gt;
If one requests a negative value, this function will select a character by counting backwards&lt;br /&gt;
from the end of the string.  In other words pos = -1 is the same as asking for the last character.&lt;br /&gt;
&lt;br /&gt;
A requested value of zero, or a value greater than the length of the string returns an error.&lt;br /&gt;
]]&lt;br /&gt;
function str.pos( frame )&lt;br /&gt;
	local new_args = str._getParameters( frame.args, {&#039;target&#039;, &#039;pos&#039;} )&lt;br /&gt;
	local target_str = new_args[&#039;target&#039;] or &#039;&#039;&lt;br /&gt;
	local pos = tonumber( new_args[&#039;pos&#039;] ) or 0&lt;br /&gt;
&lt;br /&gt;
	if pos == 0 or math.abs(pos) &amp;gt; mw.ustring.len( target_str ) then&lt;br /&gt;
		return str._error( &#039;String index out of range&#039; )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return mw.ustring.sub( target_str, pos, pos )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
str_find&lt;br /&gt;
&lt;br /&gt;
This function duplicates the behavior of {{str_find}}, including all of its quirks.&lt;br /&gt;
This is provided in order to support existing templates, but is NOT RECOMMENDED for&lt;br /&gt;
new code and templates.  New code is recommended to use the &amp;quot;find&amp;quot; function instead.&lt;br /&gt;
&lt;br /&gt;
Returns the first index in &amp;quot;source&amp;quot; that is a match to &amp;quot;target&amp;quot;.  Indexing is 1-based,&lt;br /&gt;
and the function returns -1 if the &amp;quot;target&amp;quot; string is not present in &amp;quot;source&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Important Note: If the &amp;quot;target&amp;quot; string is empty / missing, this function returns a&lt;br /&gt;
value of &amp;quot;1&amp;quot;, which is generally unexpected behavior, and must be accounted for&lt;br /&gt;
separatetly.&lt;br /&gt;
]]&lt;br /&gt;
function str.str_find( frame )&lt;br /&gt;
	local new_args = str._getParameters( frame.args, {&#039;source&#039;, &#039;target&#039;} )&lt;br /&gt;
	local source_str = new_args[&#039;source&#039;] or &#039;&#039;&lt;br /&gt;
	local target_str = new_args[&#039;target&#039;] or &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
	if target_str == &#039;&#039; then&lt;br /&gt;
		return 1&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local start = mw.ustring.find( source_str, target_str, 1, true )&lt;br /&gt;
	if start == nil then&lt;br /&gt;
		start = -1&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return start&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
find&lt;br /&gt;
&lt;br /&gt;
This function allows one to search for a target string or pattern within another&lt;br /&gt;
string.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:String|find|source_str|target_string|start_index|plain_flag}}&lt;br /&gt;
OR&lt;br /&gt;
{{#invoke:String|find|source=source_str|target=target_str|start=start_index|plain=plain_flag}}&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
    source: The string to search&lt;br /&gt;
    target: The string or pattern to find within source&lt;br /&gt;
    start: The index within the source string to start the search, defaults to 1&lt;br /&gt;
    plain: Boolean flag indicating that target should be understood as plain&lt;br /&gt;
        text and not as a Lua style regular expression, defaults to true&lt;br /&gt;
&lt;br /&gt;
If invoked using named parameters, Mediawiki will automatically remove any leading or&lt;br /&gt;
trailing whitespace from the parameter.  In some circumstances this is desirable, in&lt;br /&gt;
other cases one may want to preserve the whitespace.&lt;br /&gt;
&lt;br /&gt;
This function returns the first index &amp;gt;= &amp;quot;start&amp;quot; where &amp;quot;target&amp;quot; can be found&lt;br /&gt;
within &amp;quot;source&amp;quot;.  Indices are 1-based.  If &amp;quot;target&amp;quot; is not found, then this&lt;br /&gt;
function returns 0.  If either &amp;quot;source&amp;quot; or &amp;quot;target&amp;quot; are missing / empty, this&lt;br /&gt;
function also returns 0.&lt;br /&gt;
&lt;br /&gt;
This function should be safe for UTF-8 strings.&lt;br /&gt;
]]&lt;br /&gt;
function str.find( frame )&lt;br /&gt;
	local new_args = str._getParameters( frame.args, {&#039;source&#039;, &#039;target&#039;, &#039;start&#039;, &#039;plain&#039; } )&lt;br /&gt;
	local source_str = new_args[&#039;source&#039;] or &#039;&#039;&lt;br /&gt;
	local pattern = new_args[&#039;target&#039;] or &#039;&#039;&lt;br /&gt;
	local start_pos = tonumber(new_args[&#039;start&#039;]) or 1&lt;br /&gt;
	local plain = new_args[&#039;plain&#039;] or true&lt;br /&gt;
&lt;br /&gt;
	if source_str == &#039;&#039; or pattern == &#039;&#039; then&lt;br /&gt;
		return 0&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	plain = str._getBoolean( plain )&lt;br /&gt;
&lt;br /&gt;
	local start = mw.ustring.find( source_str, pattern, start_pos, plain )&lt;br /&gt;
	if start == nil then&lt;br /&gt;
		start = 0&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return start&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
replace&lt;br /&gt;
&lt;br /&gt;
This function allows one to replace a target string or pattern within another&lt;br /&gt;
string.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:String|replace|source_str|pattern_string|replace_string|replacement_count|plain_flag}}&lt;br /&gt;
OR&lt;br /&gt;
{{#invoke:String|replace|source=source_string|pattern=pattern_string|replace=replace_string|&lt;br /&gt;
   count=replacement_count|plain=plain_flag}}&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
    source: The string to search&lt;br /&gt;
    pattern: The string or pattern to find within source&lt;br /&gt;
    replace: The replacement text&lt;br /&gt;
    count: The number of occurences to replace, defaults to all.&lt;br /&gt;
    plain: Boolean flag indicating that pattern should be understood as plain&lt;br /&gt;
        text and not as a Lua style regular expression, defaults to true&lt;br /&gt;
]]&lt;br /&gt;
function str.replace( frame )&lt;br /&gt;
	local new_args = str._getParameters( frame.args, {&#039;source&#039;, &#039;pattern&#039;, &#039;replace&#039;, &#039;count&#039;, &#039;plain&#039; } )&lt;br /&gt;
	local source_str = new_args[&#039;source&#039;] or &#039;&#039;&lt;br /&gt;
	local pattern = new_args[&#039;pattern&#039;] or &#039;&#039;&lt;br /&gt;
	local replace = new_args[&#039;replace&#039;] or &#039;&#039;&lt;br /&gt;
	local count = tonumber( new_args[&#039;count&#039;] )&lt;br /&gt;
	local plain = new_args[&#039;plain&#039;] or true&lt;br /&gt;
&lt;br /&gt;
	if source_str == &#039;&#039; or pattern == &#039;&#039; then&lt;br /&gt;
		return source_str&lt;br /&gt;
	end&lt;br /&gt;
	plain = str._getBoolean( plain )&lt;br /&gt;
&lt;br /&gt;
	if plain then&lt;br /&gt;
		pattern = str._escapePattern( pattern )&lt;br /&gt;
		replace = string.gsub( replace, &amp;quot;%%&amp;quot;, &amp;quot;%%%%&amp;quot; ) --Only need to escape replacement sequences.&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local result&lt;br /&gt;
&lt;br /&gt;
	if count ~= nil then&lt;br /&gt;
		result = mw.ustring.gsub( source_str, pattern, replace, count )&lt;br /&gt;
	else&lt;br /&gt;
		result = mw.ustring.gsub( source_str, pattern, replace )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
    simple function to pipe string.rep to templates.&lt;br /&gt;
]]&lt;br /&gt;
function str.rep( frame )&lt;br /&gt;
	local repetitions = tonumber( frame.args[2] )&lt;br /&gt;
	if not repetitions then&lt;br /&gt;
		return str._error( &#039;function rep expects a number as second parameter, received &amp;quot;&#039; .. ( frame.args[2] or &#039;&#039; ) .. &#039;&amp;quot;&#039; )&lt;br /&gt;
	end&lt;br /&gt;
	return string.rep( frame.args[1] or &#039;&#039;, repetitions )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
escapePattern&lt;br /&gt;
&lt;br /&gt;
This function escapes special characters from a Lua string pattern. See [1]&lt;br /&gt;
for details on how patterns work.&lt;br /&gt;
&lt;br /&gt;
[1] https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:String|escapePattern|pattern_string}}&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
    pattern_string: The pattern string to escape.&lt;br /&gt;
]]&lt;br /&gt;
function str.escapePattern( frame )&lt;br /&gt;
	local pattern_str = frame.args[1]&lt;br /&gt;
	if not pattern_str then&lt;br /&gt;
		return str._error( &#039;No pattern string specified&#039; )&lt;br /&gt;
	end&lt;br /&gt;
	local result = str._escapePattern( pattern_str )&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
count&lt;br /&gt;
This function counts the number of occurrences of one string in another.&lt;br /&gt;
]]&lt;br /&gt;
function str.count(frame)&lt;br /&gt;
	local args = str._getParameters(frame.args, {&#039;source&#039;, &#039;pattern&#039;, &#039;plain&#039;})&lt;br /&gt;
	local source = args.source or &#039;&#039;&lt;br /&gt;
	local pattern = args.pattern or &#039;&#039;&lt;br /&gt;
	local plain = str._getBoolean(args.plain or true)&lt;br /&gt;
	if plain then&lt;br /&gt;
		pattern = str._escapePattern(pattern)&lt;br /&gt;
	end&lt;br /&gt;
	local _, count = mw.ustring.gsub(source, pattern, &#039;&#039;)&lt;br /&gt;
	return count&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
endswith&lt;br /&gt;
This function determines whether a string ends with another string.&lt;br /&gt;
]]&lt;br /&gt;
function str.endswith(frame)&lt;br /&gt;
	local args = str._getParameters(frame.args, {&#039;source&#039;, &#039;pattern&#039;})&lt;br /&gt;
	local source = args.source or &#039;&#039;&lt;br /&gt;
	local pattern = args.pattern or &#039;&#039;&lt;br /&gt;
	if pattern == &#039;&#039; then&lt;br /&gt;
		-- All strings end with the empty string.&lt;br /&gt;
		return &amp;quot;yes&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	if mw.ustring.sub(source, -mw.ustring.len(pattern), -1) == pattern then&lt;br /&gt;
		return &amp;quot;yes&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		return &amp;quot;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
join&lt;br /&gt;
&lt;br /&gt;
Join all non empty arguments together; the first argument is the separator.&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:String|join|sep|one|two|three}}&lt;br /&gt;
]]&lt;br /&gt;
function str.join(frame)&lt;br /&gt;
	local args = {}&lt;br /&gt;
	local sep&lt;br /&gt;
	for _, v in ipairs( frame.args ) do&lt;br /&gt;
		if sep then&lt;br /&gt;
			if v ~= &#039;&#039; then&lt;br /&gt;
				table.insert(args, v)&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			sep = v&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return table.concat( args, sep or &#039;&#039; )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- findpagetext returns the position of a piece of text in a page&lt;br /&gt;
-- First positional parameter or |text is the search text&lt;br /&gt;
-- Optional parameter |title is the page title, defaults to current page&lt;br /&gt;
-- Optional parameter |plain is either true for plain search (default) or false for Lua pattern search&lt;br /&gt;
-- Optional parameter |nomatch is the return value when no match is found; default is nil&lt;br /&gt;
function str._findpagetext(args)&lt;br /&gt;
	-- process parameters&lt;br /&gt;
	local nomatch = args.nomatch or &amp;quot;&amp;quot;&lt;br /&gt;
	if nomatch == &amp;quot;&amp;quot; then nomatch = nil end&lt;br /&gt;
	--&lt;br /&gt;
	local text = mw.text.trim(args[1] or args.text or &amp;quot;&amp;quot;)&lt;br /&gt;
	if text == &amp;quot;&amp;quot; then return nil end&lt;br /&gt;
	--&lt;br /&gt;
	local title = args.title or &amp;quot;&amp;quot;&lt;br /&gt;
	local titleobj&lt;br /&gt;
	if title == &amp;quot;&amp;quot; then&lt;br /&gt;
		titleobj = mw.title.getCurrentTitle()&lt;br /&gt;
	else&lt;br /&gt;
		titleobj = mw.title.new(title)&lt;br /&gt;
	end&lt;br /&gt;
	--&lt;br /&gt;
	local plain = args.plain or &amp;quot;&amp;quot;&lt;br /&gt;
	if plain:sub(1, 1) == &amp;quot;f&amp;quot; then plain = false else plain = true end&lt;br /&gt;
	-- get the page content and look for &#039;text&#039; - return position or nomatch&lt;br /&gt;
	local content = titleobj and titleobj:getContent()&lt;br /&gt;
	return content and mw.ustring.find(content, text, 1, plain) or nomatch&lt;br /&gt;
end&lt;br /&gt;
function str.findpagetext(frame)&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
	local pargs = frame:getParent().args&lt;br /&gt;
	for k, v in pairs(pargs) do&lt;br /&gt;
		args[k] = v&lt;br /&gt;
	end&lt;br /&gt;
	if not (args[1] or args.text) then return nil end&lt;br /&gt;
	-- just the first value&lt;br /&gt;
	return (str._findpagetext(args))&lt;br /&gt;
end&lt;br /&gt;
--[[&lt;br /&gt;
Helper function that populates the argument list given that user may need to use a mix of&lt;br /&gt;
named and unnamed parameters.  This is relevant because named parameters are not&lt;br /&gt;
identical to unnamed parameters due to string trimming, and when dealing with strings&lt;br /&gt;
we sometimes want to either preserve or remove that whitespace depending on the application.&lt;br /&gt;
]]&lt;br /&gt;
function str._getParameters( frame_args, arg_list )&lt;br /&gt;
	local new_args = {}&lt;br /&gt;
	local index = 1&lt;br /&gt;
	local value&lt;br /&gt;
&lt;br /&gt;
	for _, arg in ipairs( arg_list ) do&lt;br /&gt;
		value = frame_args[arg]&lt;br /&gt;
		if value == nil then&lt;br /&gt;
			value = frame_args[index]&lt;br /&gt;
			index = index + 1&lt;br /&gt;
		end&lt;br /&gt;
		new_args[arg] = value&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return new_args&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Helper function to handle error messages.&lt;br /&gt;
]]&lt;br /&gt;
function str._error( error_str )&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
	local error_category = frame.args.error_category or &#039;Errors reported by Module String&#039;&lt;br /&gt;
	local ignore_errors = frame.args.ignore_errors or false&lt;br /&gt;
	local no_category = frame.args.no_category or false&lt;br /&gt;
&lt;br /&gt;
	if str._getBoolean(ignore_errors) then&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local error_str = &#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;String Module Error: &#039; .. error_str .. &#039;&amp;lt;/strong&amp;gt;&#039;&lt;br /&gt;
	if error_category ~= &#039;&#039; and not str._getBoolean( no_category ) then&lt;br /&gt;
		error_str = &#039;[[Category:&#039; .. error_category .. &#039;]]&#039; .. error_str&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return error_str&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Helper Function to interpret boolean strings&lt;br /&gt;
]]&lt;br /&gt;
function str._getBoolean( boolean_str )&lt;br /&gt;
	local boolean_value&lt;br /&gt;
&lt;br /&gt;
	if type( boolean_str ) == &#039;string&#039; then&lt;br /&gt;
		boolean_str = boolean_str:lower()&lt;br /&gt;
		if boolean_str == &#039;false&#039; or boolean_str == &#039;no&#039; or boolean_str == &#039;0&#039;&lt;br /&gt;
				or boolean_str == &#039;&#039; then&lt;br /&gt;
			boolean_value = false&lt;br /&gt;
		else&lt;br /&gt;
			boolean_value = true&lt;br /&gt;
		end&lt;br /&gt;
	elseif type( boolean_str ) == &#039;boolean&#039; then&lt;br /&gt;
		boolean_value = boolean_str&lt;br /&gt;
	else&lt;br /&gt;
		error( &#039;No boolean value found&#039; )&lt;br /&gt;
	end&lt;br /&gt;
	return boolean_value&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Helper function that escapes all pattern characters so that they will be treated&lt;br /&gt;
as plain text.&lt;br /&gt;
]]&lt;br /&gt;
function str._escapePattern( pattern_str )&lt;br /&gt;
	return ( string.gsub( pattern_str, &amp;quot;[%(%)%.%%%+%-%*%?%[%^%$%]]&amp;quot;, &amp;quot;%%%0&amp;quot; ) )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return str&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Template:Remove_first_word&amp;diff=21</id>
		<title>Template:Remove first word</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Template:Remove_first_word&amp;diff=21"/>
		<updated>2025-12-24T15:16:45Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;{{&amp;lt;includeonly&amp;gt;safesubst:&amp;lt;/includeonly&amp;gt;#invoke:String|replace|source={{{1}}}|pattern=^[^{{{sep|%s}}}]*{{{sep|%s}}}*|replace=|plain=false}}&amp;lt;noinclude&amp;gt;{{Documentation}}&amp;lt;/noinclude&amp;gt;&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{&amp;lt;includeonly&amp;gt;safesubst:&amp;lt;/includeonly&amp;gt;#invoke:String|replace|source={{{1}}}|pattern=^[^{{{sep|%s}}}]*{{{sep|%s}}}*|replace=|plain=false}}&amp;lt;noinclude&amp;gt;{{Documentation}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Template:Str_left&amp;diff=20</id>
		<title>Template:Str left</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Template:Str_left&amp;diff=20"/>
		<updated>2025-12-24T15:16:25Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;&amp;lt;includeonly&amp;gt;{{safesubst:padleft:|{{{2|1}}}|{{{1}}}}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt; {{documentation}} &amp;lt;!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --&amp;gt; &amp;lt;/noinclude&amp;gt;&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{{safesubst:padleft:|{{{2|1}}}|{{{1}}}}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Template:Template_other&amp;diff=19</id>
		<title>Template:Template other</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Template:Template_other&amp;diff=19"/>
		<updated>2025-12-24T15:03:07Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;{{#switch:   &amp;lt;!--If no or empty &amp;quot;demospace&amp;quot; parameter then detect namespace--&amp;gt;   {{#if:{{{demospace|}}}   | {{lc: {{{demospace}}} }}    &amp;lt;!--Use lower case &amp;quot;demospace&amp;quot;--&amp;gt;   | {{#ifeq:{{NAMESPACE}}|{{ns:Template}}     | template     | other     }}   }} | template = {{{1|}}} | other | #default = {{{2|}}} }}&amp;lt;!--End switch--&amp;gt;&amp;lt;noinclude&amp;gt;  {{documentation}} &amp;lt;!-- Add categories and interwikis to the /doc subpage, not here! --&amp;gt; &amp;lt;/noinclude&amp;gt;&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#switch:&lt;br /&gt;
  &amp;lt;!--If no or empty &amp;quot;demospace&amp;quot; parameter then detect namespace--&amp;gt;&lt;br /&gt;
  {{#if:{{{demospace|}}}&lt;br /&gt;
  | {{lc: {{{demospace}}} }}    &amp;lt;!--Use lower case &amp;quot;demospace&amp;quot;--&amp;gt;&lt;br /&gt;
  | {{#ifeq:{{NAMESPACE}}|{{ns:Template}}&lt;br /&gt;
    | template&lt;br /&gt;
    | other&lt;br /&gt;
    }}&lt;br /&gt;
  }}&lt;br /&gt;
| template = {{{1|}}}&lt;br /&gt;
| other&lt;br /&gt;
| #default = {{{2|}}}&lt;br /&gt;
}}&amp;lt;!--End switch--&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;!-- Add categories and interwikis to the /doc subpage, not here! --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Module:TableTools&amp;diff=18</id>
		<title>Module:TableTools</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Module:TableTools&amp;diff=18"/>
		<updated>2025-12-24T15:00:34Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;------------------------------------------------------------------------------------ --                                   TableTools                                   -- --                                                                                -- -- This module includes a number of functions for dealing with Lua tables.        -- -- It is a meta-module, meant to be called from other Lua modules, and should not -- -- be called directly from #invoke....&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;------------------------------------------------------------------------------------&lt;br /&gt;
--                                   TableTools                                   --&lt;br /&gt;
--                                                                                --&lt;br /&gt;
-- This module includes a number of functions for dealing with Lua tables.        --&lt;br /&gt;
-- It is a meta-module, meant to be called from other Lua modules, and should not --&lt;br /&gt;
-- be called directly from #invoke.                                               --&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local libraryUtil = require(&#039;libraryUtil&#039;)&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Define often-used variables and functions.&lt;br /&gt;
local floor = math.floor&lt;br /&gt;
local infinity = math.huge&lt;br /&gt;
local checkType = libraryUtil.checkType&lt;br /&gt;
local checkTypeMulti = libraryUtil.checkTypeMulti&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- isPositiveInteger&lt;br /&gt;
--&lt;br /&gt;
-- This function returns true if the given value is a positive integer, and false&lt;br /&gt;
-- if not. Although it doesn&#039;t operate on tables, it is included here as it is&lt;br /&gt;
-- useful for determining whether a given table key is in the array part or the&lt;br /&gt;
-- hash part of a table.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
function p.isPositiveInteger(v)&lt;br /&gt;
	return type(v) == &#039;number&#039; and v &amp;gt;= 1 and floor(v) == v and v &amp;lt; infinity&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- isNan&lt;br /&gt;
--&lt;br /&gt;
-- This function returns true if the given number is a NaN value, and false if&lt;br /&gt;
-- not. Although it doesn&#039;t operate on tables, it is included here as it is useful&lt;br /&gt;
-- for determining whether a value can be a valid table key. Lua will generate an&lt;br /&gt;
-- error if a NaN is used as a table key.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
function p.isNan(v)&lt;br /&gt;
	return type(v) == &#039;number&#039; and v ~= v&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- shallowClone&lt;br /&gt;
--&lt;br /&gt;
-- This returns a clone of a table. The value returned is a new table, but all&lt;br /&gt;
-- subtables and functions are shared. Metamethods are respected, but the returned&lt;br /&gt;
-- table will have no metatable of its own.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
function p.shallowClone(t)&lt;br /&gt;
	checkType(&#039;shallowClone&#039;, 1, t, &#039;table&#039;)&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	for k, v in pairs(t) do&lt;br /&gt;
		ret[k] = v&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- removeDuplicates&lt;br /&gt;
--&lt;br /&gt;
-- This removes duplicate values from an array. Non-positive-integer keys are&lt;br /&gt;
-- ignored. The earliest value is kept, and all subsequent duplicate values are&lt;br /&gt;
-- removed, but otherwise the array order is unchanged.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
function p.removeDuplicates(arr)&lt;br /&gt;
	checkType(&#039;removeDuplicates&#039;, 1, arr, &#039;table&#039;)&lt;br /&gt;
	local isNan = p.isNan&lt;br /&gt;
	local ret, exists = {}, {}&lt;br /&gt;
	for _, v in ipairs(arr) do&lt;br /&gt;
		if isNan(v) then&lt;br /&gt;
			-- NaNs can&#039;t be table keys, and they are also unique, so we don&#039;t need to check existence.&lt;br /&gt;
			ret[#ret + 1] = v&lt;br /&gt;
		elseif not exists[v] then&lt;br /&gt;
			ret[#ret + 1] = v&lt;br /&gt;
			exists[v] = true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- numKeys&lt;br /&gt;
--&lt;br /&gt;
-- This takes a table and returns an array containing the numbers of any numerical&lt;br /&gt;
-- keys that have non-nil values, sorted in numerical order.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
function p.numKeys(t)&lt;br /&gt;
	checkType(&#039;numKeys&#039;, 1, t, &#039;table&#039;)&lt;br /&gt;
	local isPositiveInteger = p.isPositiveInteger&lt;br /&gt;
	local nums = {}&lt;br /&gt;
	for k in pairs(t) do&lt;br /&gt;
		if isPositiveInteger(k) then&lt;br /&gt;
			nums[#nums + 1] = k&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(nums)&lt;br /&gt;
	return nums&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- affixNums&lt;br /&gt;
--&lt;br /&gt;
-- This takes a table and returns an array containing the numbers of keys with the&lt;br /&gt;
-- specified prefix and suffix. For example, for the table&lt;br /&gt;
-- {a1 = &#039;foo&#039;, a3 = &#039;bar&#039;, a6 = &#039;baz&#039;} and the prefix &amp;quot;a&amp;quot;, affixNums will return&lt;br /&gt;
-- {1, 3, 6}.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
function p.affixNums(t, prefix, suffix)&lt;br /&gt;
	checkType(&#039;affixNums&#039;, 1, t, &#039;table&#039;)&lt;br /&gt;
	checkType(&#039;affixNums&#039;, 2, prefix, &#039;string&#039;, true)&lt;br /&gt;
	checkType(&#039;affixNums&#039;, 3, suffix, &#039;string&#039;, true)&lt;br /&gt;
&lt;br /&gt;
	local function cleanPattern(s)&lt;br /&gt;
		-- Cleans a pattern so that the magic characters ()%.[]*+-?^$ are interpreted literally.&lt;br /&gt;
		return s:gsub(&#039;([%(%)%%%.%[%]%*%+%-%?%^%$])&#039;, &#039;%%%1&#039;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	prefix = prefix or &#039;&#039;&lt;br /&gt;
	suffix = suffix or &#039;&#039;&lt;br /&gt;
	prefix = cleanPattern(prefix)&lt;br /&gt;
	suffix = cleanPattern(suffix)&lt;br /&gt;
	local pattern = &#039;^&#039; .. prefix .. &#039;([1-9]%d*)&#039; .. suffix .. &#039;$&#039;&lt;br /&gt;
&lt;br /&gt;
	local nums = {}&lt;br /&gt;
	for k in pairs(t) do&lt;br /&gt;
		if type(k) == &#039;string&#039; then&lt;br /&gt;
			local num = mw.ustring.match(k, pattern)&lt;br /&gt;
			if num then&lt;br /&gt;
				nums[#nums + 1] = tonumber(num)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(nums)&lt;br /&gt;
	return nums&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- numData&lt;br /&gt;
--&lt;br /&gt;
-- Given a table with keys like {&amp;quot;foo1&amp;quot;, &amp;quot;bar1&amp;quot;, &amp;quot;foo2&amp;quot;, &amp;quot;baz2&amp;quot;}, returns a table&lt;br /&gt;
-- of subtables in the format&lt;br /&gt;
-- {[1] = {foo = &#039;text&#039;, bar = &#039;text&#039;}, [2] = {foo = &#039;text&#039;, baz = &#039;text&#039;}}.&lt;br /&gt;
-- Keys that don&#039;t end with an integer are stored in a subtable named &amp;quot;other&amp;quot;. The&lt;br /&gt;
-- compress option compresses the table so that it can be iterated over with&lt;br /&gt;
-- ipairs.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
function p.numData(t, compress)&lt;br /&gt;
	checkType(&#039;numData&#039;, 1, t, &#039;table&#039;)&lt;br /&gt;
	checkType(&#039;numData&#039;, 2, compress, &#039;boolean&#039;, true)&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	for k, v in pairs(t) do&lt;br /&gt;
		local prefix, num = mw.ustring.match(tostring(k), &#039;^([^0-9]*)([1-9][0-9]*)$&#039;)&lt;br /&gt;
		if num then&lt;br /&gt;
			num = tonumber(num)&lt;br /&gt;
			local subtable = ret[num] or {}&lt;br /&gt;
			if prefix == &#039;&#039; then&lt;br /&gt;
				-- Positional parameters match the blank string; put them at the start of the subtable instead.&lt;br /&gt;
				prefix = 1&lt;br /&gt;
			end&lt;br /&gt;
			subtable[prefix] = v&lt;br /&gt;
			ret[num] = subtable&lt;br /&gt;
		else&lt;br /&gt;
			local subtable = ret.other or {}&lt;br /&gt;
			subtable[k] = v&lt;br /&gt;
			ret.other = subtable&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if compress then&lt;br /&gt;
		local other = ret.other&lt;br /&gt;
		ret = p.compressSparseArray(ret)&lt;br /&gt;
		ret.other = other&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- compressSparseArray&lt;br /&gt;
--&lt;br /&gt;
-- This takes an array with one or more nil values, and removes the nil values&lt;br /&gt;
-- while preserving the order, so that the array can be safely traversed with&lt;br /&gt;
-- ipairs.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
function p.compressSparseArray(t)&lt;br /&gt;
	checkType(&#039;compressSparseArray&#039;, 1, t, &#039;table&#039;)&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	local nums = p.numKeys(t)&lt;br /&gt;
	for _, num in ipairs(nums) do&lt;br /&gt;
		ret[#ret + 1] = t[num]&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- sparseIpairs&lt;br /&gt;
--&lt;br /&gt;
-- This is an iterator for sparse arrays. It can be used like ipairs, but can&lt;br /&gt;
-- handle nil values.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
function p.sparseIpairs(t)&lt;br /&gt;
	checkType(&#039;sparseIpairs&#039;, 1, t, &#039;table&#039;)&lt;br /&gt;
	local nums = p.numKeys(t)&lt;br /&gt;
	local i = 0&lt;br /&gt;
	local lim = #nums&lt;br /&gt;
	return function ()&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		if i &amp;lt;= lim then&lt;br /&gt;
			local key = nums[i]&lt;br /&gt;
			return key, t[key]&lt;br /&gt;
		else&lt;br /&gt;
			return nil, nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- size&lt;br /&gt;
--&lt;br /&gt;
-- This returns the size of a key/value pair table. It will also work on arrays,&lt;br /&gt;
-- but for arrays it is more efficient to use the # operator.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
function p.size(t)&lt;br /&gt;
	checkType(&#039;size&#039;, 1, t, &#039;table&#039;)&lt;br /&gt;
	local i = 0&lt;br /&gt;
	for _ in pairs(t) do&lt;br /&gt;
		i = i + 1&lt;br /&gt;
	end&lt;br /&gt;
	return i&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function defaultKeySort(item1, item2)&lt;br /&gt;
	-- &amp;quot;number&amp;quot; &amp;lt; &amp;quot;string&amp;quot;, so numbers will be sorted before strings.&lt;br /&gt;
	local type1, type2 = type(item1), type(item2)&lt;br /&gt;
	if type1 ~= type2 then&lt;br /&gt;
		return type1 &amp;lt; type2&lt;br /&gt;
	elseif type1 == &#039;table&#039; or type1 == &#039;boolean&#039; or type1 == &#039;function&#039; then&lt;br /&gt;
		return tostring(item1) &amp;lt; tostring(item2)&lt;br /&gt;
	else&lt;br /&gt;
		return item1 &amp;lt; item2&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- keysToList&lt;br /&gt;
--&lt;br /&gt;
-- Returns an array of the keys in a table, sorted using either a default&lt;br /&gt;
-- comparison function or a custom keySort function.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
function p.keysToList(t, keySort, checked)&lt;br /&gt;
	if not checked then&lt;br /&gt;
		checkType(&#039;keysToList&#039;, 1, t, &#039;table&#039;)&lt;br /&gt;
		checkTypeMulti(&#039;keysToList&#039;, 2, keySort, {&#039;function&#039;, &#039;boolean&#039;, &#039;nil&#039;})&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local arr = {}&lt;br /&gt;
	local index = 1&lt;br /&gt;
	for k in pairs(t) do&lt;br /&gt;
		arr[index] = k&lt;br /&gt;
		index = index + 1&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if keySort ~= false then&lt;br /&gt;
		keySort = type(keySort) == &#039;function&#039; and keySort or defaultKeySort&lt;br /&gt;
		table.sort(arr, keySort)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return arr&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- sortedPairs&lt;br /&gt;
--&lt;br /&gt;
-- Iterates through a table, with the keys sorted using the keysToList function.&lt;br /&gt;
-- If there are only numerical keys, sparseIpairs is probably more efficient.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
function p.sortedPairs(t, keySort)&lt;br /&gt;
	checkType(&#039;sortedPairs&#039;, 1, t, &#039;table&#039;)&lt;br /&gt;
	checkType(&#039;sortedPairs&#039;, 2, keySort, &#039;function&#039;, true)&lt;br /&gt;
&lt;br /&gt;
	local arr = p.keysToList(t, keySort, true)&lt;br /&gt;
&lt;br /&gt;
	local i = 0&lt;br /&gt;
	return function ()&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		local key = arr[i]&lt;br /&gt;
		if key ~= nil then&lt;br /&gt;
			return key, t[key]&lt;br /&gt;
		else&lt;br /&gt;
			return nil, nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- isArray&lt;br /&gt;
--&lt;br /&gt;
-- Returns true if the given value is a table and all keys are consecutive&lt;br /&gt;
-- integers starting at 1.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
function p.isArray(v)&lt;br /&gt;
	if type(v) ~= &#039;table&#039; then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	local i = 0&lt;br /&gt;
	for _ in pairs(v) do&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		if v[i] == nil then&lt;br /&gt;
			return false&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- isArrayLike&lt;br /&gt;
--&lt;br /&gt;
-- Returns true if the given value is iterable and all keys are consecutive&lt;br /&gt;
-- integers starting at 1.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
function p.isArrayLike(v)&lt;br /&gt;
	if not pcall(pairs, v) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	local i = 0&lt;br /&gt;
	for _ in pairs(v) do&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		if v[i] == nil then&lt;br /&gt;
			return false&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- invert&lt;br /&gt;
--&lt;br /&gt;
-- Transposes the keys and values in an array. For example, {&amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;c&amp;quot;} -&amp;gt;&lt;br /&gt;
-- {a = 1, b = 2, c = 3}. Duplicates are not supported (result values refer to&lt;br /&gt;
-- the index of the last duplicate) and NaN values are ignored.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
function p.invert(arr)&lt;br /&gt;
	checkType(&amp;quot;invert&amp;quot;, 1, arr, &amp;quot;table&amp;quot;)&lt;br /&gt;
	local isNan = p.isNan&lt;br /&gt;
	local map = {}&lt;br /&gt;
	for i, v in ipairs(arr) do&lt;br /&gt;
		if not isNan(v) then&lt;br /&gt;
			map[v] = i&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return map&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- listToSet&lt;br /&gt;
--&lt;br /&gt;
-- Creates a set from the array part of the table. Indexing the set by any of the&lt;br /&gt;
-- values of the array returns true. For example, {&amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;c&amp;quot;} -&amp;gt;&lt;br /&gt;
-- {a = true, b = true, c = true}. NaN values are ignored as Lua considers them&lt;br /&gt;
-- never equal to any value (including other NaNs or even themselves).&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
function p.listToSet(arr)&lt;br /&gt;
	checkType(&amp;quot;listToSet&amp;quot;, 1, arr, &amp;quot;table&amp;quot;)&lt;br /&gt;
	local isNan = p.isNan&lt;br /&gt;
	local set = {}&lt;br /&gt;
	for _, v in ipairs(arr) do&lt;br /&gt;
		if not isNan(v) then&lt;br /&gt;
			set[v] = true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return set&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- deepCopy&lt;br /&gt;
--&lt;br /&gt;
-- Recursive deep copy function. Preserves identities of subtables.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
local function _deepCopy(orig, includeMetatable, already_seen)&lt;br /&gt;
	if type(orig) ~= &amp;quot;table&amp;quot; then&lt;br /&gt;
		return orig&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- already_seen stores copies of tables indexed by the original table.&lt;br /&gt;
	local copy = already_seen[orig]&lt;br /&gt;
	if copy ~= nil then&lt;br /&gt;
		return copy&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	copy = {}&lt;br /&gt;
	already_seen[orig] = copy -- memoize before any recursion, to avoid infinite loops&lt;br /&gt;
	&lt;br /&gt;
	for orig_key, orig_value in pairs(orig) do&lt;br /&gt;
		copy[_deepCopy(orig_key, includeMetatable, already_seen)] = _deepCopy(orig_value, includeMetatable, already_seen)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if includeMetatable then&lt;br /&gt;
		local mt = getmetatable(orig)&lt;br /&gt;
		if mt ~= nil then&lt;br /&gt;
			setmetatable(copy, _deepCopy(mt, true, already_seen))&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return copy&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.deepCopy(orig, noMetatable, already_seen)&lt;br /&gt;
	checkType(&amp;quot;deepCopy&amp;quot;, 3, already_seen, &amp;quot;table&amp;quot;, true)&lt;br /&gt;
	return _deepCopy(orig, not noMetatable, already_seen or {})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- sparseConcat&lt;br /&gt;
--&lt;br /&gt;
-- Concatenates all values in the table that are indexed by a number, in order.&lt;br /&gt;
-- sparseConcat{a, nil, c, d}  =&amp;gt;  &amp;quot;acd&amp;quot;&lt;br /&gt;
-- sparseConcat{nil, b, c, d}  =&amp;gt;  &amp;quot;bcd&amp;quot;&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
function p.sparseConcat(t, sep, i, j)&lt;br /&gt;
	local arr = {}&lt;br /&gt;
&lt;br /&gt;
	local arr_i = 0&lt;br /&gt;
	for _, v in p.sparseIpairs(t) do&lt;br /&gt;
		arr_i = arr_i + 1&lt;br /&gt;
		arr[arr_i] = v&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return table.concat(arr, sep, i, j)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- length&lt;br /&gt;
--&lt;br /&gt;
-- Finds the length of an array, or of a quasi-array with keys such as &amp;quot;data1&amp;quot;,&lt;br /&gt;
-- &amp;quot;data2&amp;quot;, etc., using an exponential search algorithm. It is similar to the&lt;br /&gt;
-- operator #, but may return a different value when there are gaps in the array&lt;br /&gt;
-- portion of the table. Intended to be used on data loaded with mw.loadData. For&lt;br /&gt;
-- other tables, use #.&lt;br /&gt;
-- Note: #frame.args in frame object always be set to 0, regardless of  the number&lt;br /&gt;
-- of unnamed template parameters, so use this function for frame.args.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
function p.length(t, prefix)&lt;br /&gt;
	-- requiring module inline so that [[Module:Exponential search]] which is&lt;br /&gt;
	-- only needed by this one function doesn&#039;t get millions of transclusions&lt;br /&gt;
	local expSearch = require(&amp;quot;Module:Exponential search&amp;quot;)&lt;br /&gt;
	checkType(&#039;length&#039;, 1, t, &#039;table&#039;)&lt;br /&gt;
	checkType(&#039;length&#039;, 2, prefix, &#039;string&#039;, true)&lt;br /&gt;
	return expSearch(function (i)&lt;br /&gt;
		local key&lt;br /&gt;
		if prefix then&lt;br /&gt;
			key = prefix .. tostring(i)&lt;br /&gt;
		else&lt;br /&gt;
			key = i&lt;br /&gt;
		end&lt;br /&gt;
		return t[key] ~= nil&lt;br /&gt;
	end) or 0&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- inArray&lt;br /&gt;
--&lt;br /&gt;
-- Returns true if searchElement is a member of the array, and false otherwise.&lt;br /&gt;
-- Equivalent to JavaScript array.includes(searchElement) or&lt;br /&gt;
-- array.includes(searchElement, fromIndex), except fromIndex is 1 indexed&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
function p.inArray(array, searchElement, fromIndex)&lt;br /&gt;
	checkType(&amp;quot;inArray&amp;quot;, 1, array, &amp;quot;table&amp;quot;)&lt;br /&gt;
	-- if searchElement is nil, error?&lt;br /&gt;
&lt;br /&gt;
	fromIndex = tonumber(fromIndex)&lt;br /&gt;
	if fromIndex then&lt;br /&gt;
		if (fromIndex &amp;lt; 0) then&lt;br /&gt;
			fromIndex = #array + fromIndex + 1&lt;br /&gt;
		end&lt;br /&gt;
		if fromIndex &amp;lt; 1 then fromIndex = 1 end&lt;br /&gt;
		for _, v in ipairs({unpack(array, fromIndex)}) do&lt;br /&gt;
			if v == searchElement then&lt;br /&gt;
				return true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		for _, v in pairs(array) do&lt;br /&gt;
			if v == searchElement 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;
------------------------------------------------------------------------------------&lt;br /&gt;
-- merge&lt;br /&gt;
--&lt;br /&gt;
-- Given the arrays, returns an array containing the elements of each input array&lt;br /&gt;
-- in sequence.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
function p.merge(...)&lt;br /&gt;
	local arrays = {...}&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	for i, arr in ipairs(arrays) do&lt;br /&gt;
		checkType(&#039;merge&#039;, i, arr, &#039;table&#039;)&lt;br /&gt;
		for _, v in ipairs(arr) do&lt;br /&gt;
			ret[#ret + 1] = v&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- extend&lt;br /&gt;
--&lt;br /&gt;
-- Extends the first array in place by appending all elements from the second&lt;br /&gt;
-- array.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
function p.extend(arr1, arr2)&lt;br /&gt;
	checkType(&#039;extend&#039;, 1, arr1, &#039;table&#039;)&lt;br /&gt;
	checkType(&#039;extend&#039;, 2, arr2, &#039;table&#039;)&lt;br /&gt;
&lt;br /&gt;
	for _, v in ipairs(arr2) do&lt;br /&gt;
		arr1[#arr1 + 1] = v&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Module:List&amp;diff=17</id>
		<title>Module:List</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Module:List&amp;diff=17"/>
		<updated>2025-12-24T14:59:39Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;local libUtil = require(&amp;#039;libraryUtil&amp;#039;) local checkType = libUtil.checkType local mTableTools = require(&amp;#039;Module:TableTools&amp;#039;)  local p = {}  local listTypes = { 	[&amp;#039;bulleted&amp;#039;] = true, 	[&amp;#039;unbulleted&amp;#039;] = true, 	[&amp;#039;horizontal&amp;#039;] = true, 	[&amp;#039;ordered&amp;#039;] = true, 	[&amp;#039;horizontal_ordered&amp;#039;] = true }  function p.makeListData(listType, args) 	-- Constructs a data table to be passed to p.renderList. 	local data = {}  	-- Classes and TemplateStyles 	data.classes = {} 	data.templatestyles = &amp;#039;&amp;#039;...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local libUtil = require(&#039;libraryUtil&#039;)&lt;br /&gt;
local checkType = libUtil.checkType&lt;br /&gt;
local mTableTools = require(&#039;Module:TableTools&#039;)&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local listTypes = {&lt;br /&gt;
	[&#039;bulleted&#039;] = true,&lt;br /&gt;
	[&#039;unbulleted&#039;] = true,&lt;br /&gt;
	[&#039;horizontal&#039;] = true,&lt;br /&gt;
	[&#039;ordered&#039;] = true,&lt;br /&gt;
	[&#039;horizontal_ordered&#039;] = true&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function p.makeListData(listType, args)&lt;br /&gt;
	-- Constructs a data table to be passed to p.renderList.&lt;br /&gt;
	local data = {}&lt;br /&gt;
&lt;br /&gt;
	-- Classes and TemplateStyles&lt;br /&gt;
	data.classes = {}&lt;br /&gt;
	data.templatestyles = &#039;&#039;&lt;br /&gt;
	if listType == &#039;horizontal&#039; or listType == &#039;horizontal_ordered&#039; then&lt;br /&gt;
		table.insert(data.classes, &#039;hlist&#039;)&lt;br /&gt;
		data.templatestyles = mw.getCurrentFrame():extensionTag{&lt;br /&gt;
			name = &#039;templatestyles&#039;, args = { src = &#039;Hlist/styles.css&#039; }&lt;br /&gt;
		}&lt;br /&gt;
	elseif listType == &#039;unbulleted&#039; then&lt;br /&gt;
		table.insert(data.classes, &#039;plainlist&#039;)&lt;br /&gt;
		data.templatestyles = mw.getCurrentFrame():extensionTag{&lt;br /&gt;
			name = &#039;templatestyles&#039;, args = { src = &#039;Plainlist/styles.css&#039; }&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	table.insert(data.classes, args.class)&lt;br /&gt;
&lt;br /&gt;
	-- Main div style&lt;br /&gt;
	data.style = args.style&lt;br /&gt;
&lt;br /&gt;
	-- Indent for horizontal lists&lt;br /&gt;
	if listType == &#039;horizontal&#039; or listType == &#039;horizontal_ordered&#039; then&lt;br /&gt;
		local indent = tonumber(args.indent)&lt;br /&gt;
		indent = indent and indent * 1.6 or 0&lt;br /&gt;
		if indent &amp;gt; 0 then&lt;br /&gt;
			data.marginLeft = indent .. &#039;em&#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- List style types for ordered lists&lt;br /&gt;
	-- This could be &amp;quot;1, 2, 3&amp;quot;, &amp;quot;a, b, c&amp;quot;, or a number of others. The list style&lt;br /&gt;
	-- type is either set by the &amp;quot;type&amp;quot; attribute or the &amp;quot;list-style-type&amp;quot; CSS&lt;br /&gt;
	-- property.&lt;br /&gt;
	if listType == &#039;ordered&#039; or listType == &#039;horizontal_ordered&#039; then &lt;br /&gt;
		data.listStyleType = args.list_style_type or args[&#039;list-style-type&#039;]&lt;br /&gt;
		data.type = args[&#039;type&#039;]&lt;br /&gt;
&lt;br /&gt;
		-- Detect invalid type attributes and attempt to convert them to&lt;br /&gt;
		-- list-style-type CSS properties.&lt;br /&gt;
		if data.type &lt;br /&gt;
			and not data.listStyleType&lt;br /&gt;
			and not tostring(data.type):find(&#039;^%s*[1AaIi]%s*$&#039;)&lt;br /&gt;
		then&lt;br /&gt;
			data.listStyleType = data.type&lt;br /&gt;
			data.type = nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- List tag type&lt;br /&gt;
	if listType == &#039;ordered&#039; or listType == &#039;horizontal_ordered&#039; then&lt;br /&gt;
		data.listTag = &#039;ol&#039;&lt;br /&gt;
	else&lt;br /&gt;
		data.listTag = &#039;ul&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Start number for ordered lists&lt;br /&gt;
	data.start = args.start&lt;br /&gt;
	if listType == &#039;horizontal_ordered&#039; then&lt;br /&gt;
		-- Apply fix to get start numbers working with horizontal ordered lists.&lt;br /&gt;
		local startNum = tonumber(data.start)&lt;br /&gt;
		if startNum then&lt;br /&gt;
			data.counterReset = &#039;listitem &#039; .. tostring(startNum - 1)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- List style&lt;br /&gt;
	 -- ul_style and ol_style are included for backwards compatibility. No&lt;br /&gt;
	 -- distinction is made for ordered or unordered lists.&lt;br /&gt;
	data.listStyle = args.list_style&lt;br /&gt;
&lt;br /&gt;
	-- List items&lt;br /&gt;
	-- li_style is included for backwards compatibility. item_style was included&lt;br /&gt;
	-- to be easier to understand for non-coders.&lt;br /&gt;
	data.itemStyle = args.item_style or args.li_style&lt;br /&gt;
	data.items = {}&lt;br /&gt;
	for _, num in ipairs(mTableTools.numKeys(args)) do&lt;br /&gt;
		local item = {}&lt;br /&gt;
		item.content = args[num]&lt;br /&gt;
		item.style = args[&#039;item&#039; .. tostring(num) .. &#039;_style&#039;]&lt;br /&gt;
			or args[&#039;item_style&#039; .. tostring(num)]&lt;br /&gt;
		item.value = args[&#039;item&#039; .. tostring(num) .. &#039;_value&#039;]&lt;br /&gt;
			or args[&#039;item_value&#039; .. tostring(num)]&lt;br /&gt;
		table.insert(data.items, item)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return data&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.renderList(data)&lt;br /&gt;
	-- Renders the list HTML.&lt;br /&gt;
	&lt;br /&gt;
	-- Return the blank string if there are no list items.&lt;br /&gt;
	if type(data.items) ~= &#039;table&#039; or #data.items &amp;lt; 1 then&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Render the main div tag.&lt;br /&gt;
	local root = mw.html.create(&#039;div&#039;)&lt;br /&gt;
	for _, class in ipairs(data.classes or {}) do&lt;br /&gt;
		root:addClass(class)&lt;br /&gt;
	end&lt;br /&gt;
	root:css{[&#039;margin-left&#039;] = data.marginLeft}&lt;br /&gt;
	if data.style then&lt;br /&gt;
		root:cssText(data.style)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Render the list tag.&lt;br /&gt;
	local list = root:tag(data.listTag or &#039;ul&#039;)&lt;br /&gt;
	list&lt;br /&gt;
		:attr{start = data.start, type = data.type}&lt;br /&gt;
		:css{&lt;br /&gt;
			[&#039;counter-reset&#039;] = data.counterReset,&lt;br /&gt;
			[&#039;list-style-type&#039;] = data.listStyleType&lt;br /&gt;
		}&lt;br /&gt;
	if data.listStyle then&lt;br /&gt;
		list:cssText(data.listStyle)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Render the list items&lt;br /&gt;
	for _, t in ipairs(data.items or {}) do&lt;br /&gt;
		local item = list:tag(&#039;li&#039;)&lt;br /&gt;
		if data.itemStyle then&lt;br /&gt;
			item:cssText(data.itemStyle)&lt;br /&gt;
		end&lt;br /&gt;
		if t.style then&lt;br /&gt;
			item:cssText(t.style)&lt;br /&gt;
		end&lt;br /&gt;
		item&lt;br /&gt;
			:attr{value = t.value}&lt;br /&gt;
			:wikitext(t.content)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return data.templatestyles .. tostring(root)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.renderTrackingCategories(args)&lt;br /&gt;
	local isDeprecated = false -- Tracks deprecated parameters.&lt;br /&gt;
	for k, v in pairs(args) do&lt;br /&gt;
		k = tostring(k)&lt;br /&gt;
		if k:find(&#039;^item_style%d+$&#039;) or k:find(&#039;^item_value%d+$&#039;) then&lt;br /&gt;
			isDeprecated = true&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local ret = &#039;&#039;&lt;br /&gt;
	if isDeprecated then&lt;br /&gt;
		ret = ret .. &#039;[[Category:List templates with deprecated parameters]]&#039;&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.makeList(listType, args)&lt;br /&gt;
	if not listType or not listTypes[listType] then&lt;br /&gt;
		error(string.format(&lt;br /&gt;
			&amp;quot;bad argument #1 to &#039;makeList&#039; (&#039;%s&#039; is not a valid list type)&amp;quot;,&lt;br /&gt;
			tostring(listType)&lt;br /&gt;
		), 2)&lt;br /&gt;
	end&lt;br /&gt;
	checkType(&#039;makeList&#039;, 2, args, &#039;table&#039;)&lt;br /&gt;
	local data = p.makeListData(listType, args)&lt;br /&gt;
	local list = p.renderList(data)&lt;br /&gt;
	local trackingCategories = p.renderTrackingCategories(args)&lt;br /&gt;
	return list .. trackingCategories&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
for listType in pairs(listTypes) do&lt;br /&gt;
	p[listType] = function (frame)&lt;br /&gt;
		local mArguments = require(&#039;Module:Arguments&#039;)&lt;br /&gt;
		local origArgs = mArguments.getArgs(frame, {&lt;br /&gt;
			frameOnly = ((frame and frame.args and frame.args.frameonly or &#039;&#039;) ~= &#039;&#039;),&lt;br /&gt;
			valueFunc = function (key, value)&lt;br /&gt;
			if not value or not mw.ustring.find(value, &#039;%S&#039;) then return nil end&lt;br /&gt;
			if mw.ustring.find(value, &#039;^%s*[%*#;:]&#039;) then&lt;br /&gt;
				return value&lt;br /&gt;
			else&lt;br /&gt;
				return value:match(&#039;^%s*(.-)%s*$&#039;)&lt;br /&gt;
			end&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
		})&lt;br /&gt;
		-- Copy all the arguments to a new table, for faster indexing.&lt;br /&gt;
		local args = {}&lt;br /&gt;
		for k, v in pairs(origArgs) do&lt;br /&gt;
			args[k] = v&lt;br /&gt;
		end&lt;br /&gt;
		return p.makeList(listType, args)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Template:Hlist/styles.css&amp;diff=16</id>
		<title>Template:Hlist/styles.css</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Template:Hlist/styles.css&amp;diff=16"/>
		<updated>2025-12-24T14:58:37Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;/* {{pp-protected|reason=match parent|small=yes}} */ /*   * hlist styles are defined in core and Minerva and differ in Minerva. The  * current definitions here (2023-01-01) are sufficient to override Minerva  * without use of the hlist-separated class. The most problematic styles were  * related to margin, padding, and the bullet. Check files listed at  * MediaWiki talk:Common.css/to do#hlist-separated  */ /*  * TODO: When the majority of readership supports it (or s...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* {{pp-protected|reason=match parent|small=yes}} */&lt;br /&gt;
/* &lt;br /&gt;
 * hlist styles are defined in core and Minerva and differ in Minerva. The&lt;br /&gt;
 * current definitions here (2023-01-01) are sufficient to override Minerva&lt;br /&gt;
 * without use of the hlist-separated class. The most problematic styles were&lt;br /&gt;
 * related to margin, padding, and the bullet. Check files listed at&lt;br /&gt;
 * [[MediaWiki talk:Common.css/to do#hlist-separated]]&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * TODO: When the majority of readership supports it (or some beautiful world&lt;br /&gt;
 * in which grade C support is above the minimum threshold), use :is()&lt;br /&gt;
 */&lt;br /&gt;
.hlist dl,&lt;br /&gt;
.hlist ol,&lt;br /&gt;
.hlist ul {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Display list items inline */&lt;br /&gt;
.hlist dd,&lt;br /&gt;
.hlist dt,&lt;br /&gt;
.hlist li {&lt;br /&gt;
	/*&lt;br /&gt;
	 * don&#039;t trust the note that says margin doesn&#039;t work with inline&lt;br /&gt;
	 * removing margin: 0 makes dds have margins again&lt;br /&gt;
	 * We also want to reset margin-right in Minerva&lt;br /&gt;
	 */&lt;br /&gt;
	margin: 0; &lt;br /&gt;
	display: inline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Display requested top-level lists inline */&lt;br /&gt;
.hlist.inline,&lt;br /&gt;
.hlist.inline dl,&lt;br /&gt;
.hlist.inline ol,&lt;br /&gt;
.hlist.inline ul,&lt;br /&gt;
/* Display nested lists inline */&lt;br /&gt;
.hlist dl dl,&lt;br /&gt;
.hlist dl ol,&lt;br /&gt;
.hlist dl ul,&lt;br /&gt;
.hlist ol dl,&lt;br /&gt;
.hlist ol ol,&lt;br /&gt;
.hlist ol ul,&lt;br /&gt;
.hlist ul dl,&lt;br /&gt;
.hlist ul ol,&lt;br /&gt;
.hlist ul ul {&lt;br /&gt;
	display: inline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hide empty list items */&lt;br /&gt;
.hlist .mw-empty-li {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* TODO: :not() can maybe be used here to remove the later rule. naive test&lt;br /&gt;
 * seems to work. more testing needed. like so:&lt;br /&gt;
 *.hlist dt:not(:last-child)::after {&lt;br /&gt;
 *	content: &amp;quot;: &amp;quot;;&lt;br /&gt;
 *}&lt;br /&gt;
 *.hlist dd:not(:last-child)::after,&lt;br /&gt;
 *.hlist li:not(:last-child)::after {&lt;br /&gt;
 *	content: &amp;quot; · &amp;quot;;&lt;br /&gt;
 *	font-weight: bold;&lt;br /&gt;
 *}&lt;br /&gt;
 */&lt;br /&gt;
/* Generate interpuncts */&lt;br /&gt;
.hlist dt::after {&lt;br /&gt;
	content: &amp;quot;: &amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hlist dd::after,&lt;br /&gt;
.hlist li::after {&lt;br /&gt;
	content: &amp;quot; · &amp;quot;;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hlist dd:last-child::after,&lt;br /&gt;
.hlist dt:last-child::after,&lt;br /&gt;
.hlist li:last-child::after {&lt;br /&gt;
	content: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Add parentheses around nested lists */&lt;br /&gt;
.hlist dd dd:first-child::before,&lt;br /&gt;
.hlist dd dt:first-child::before,&lt;br /&gt;
.hlist dd li:first-child::before,&lt;br /&gt;
.hlist dt dd:first-child::before,&lt;br /&gt;
.hlist dt dt:first-child::before,&lt;br /&gt;
.hlist dt li:first-child::before,&lt;br /&gt;
.hlist li dd:first-child::before,&lt;br /&gt;
.hlist li dt:first-child::before,&lt;br /&gt;
.hlist li li:first-child::before {&lt;br /&gt;
	content: &amp;quot; (&amp;quot;;&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hlist dd dd:last-child::after,&lt;br /&gt;
.hlist dd dt:last-child::after,&lt;br /&gt;
.hlist dd li:last-child::after,&lt;br /&gt;
.hlist dt dd:last-child::after,&lt;br /&gt;
.hlist dt dt:last-child::after,&lt;br /&gt;
.hlist dt li:last-child::after,&lt;br /&gt;
.hlist li dd:last-child::after,&lt;br /&gt;
.hlist li dt:last-child::after,&lt;br /&gt;
.hlist li li:last-child::after {&lt;br /&gt;
	content: &amp;quot;)&amp;quot;;&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Put ordinals in front of ordered list items */&lt;br /&gt;
.hlist ol {&lt;br /&gt;
	counter-reset: listitem;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hlist ol &amp;gt; li {&lt;br /&gt;
	counter-increment: listitem;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hlist ol &amp;gt; li::before {&lt;br /&gt;
	content: &amp;quot; &amp;quot; counter(listitem) &amp;quot;\a0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hlist dd ol &amp;gt; li:first-child::before,&lt;br /&gt;
.hlist dt ol &amp;gt; li:first-child::before,&lt;br /&gt;
.hlist li ol &amp;gt; li:first-child::before {&lt;br /&gt;
	content: &amp;quot; (&amp;quot; counter(listitem) &amp;quot;\a0&amp;quot;;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Template:Hlist&amp;diff=15</id>
		<title>Template:Hlist</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Template:Hlist&amp;diff=15"/>
		<updated>2025-12-24T14:58:08Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;{{&amp;lt;includeonly&amp;gt;safesubst:&amp;lt;/includeonly&amp;gt;#invoke:list|horizontal}}&amp;lt;noinclude&amp;gt; {{documentation}} &amp;lt;!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --&amp;gt; &amp;lt;/noinclude&amp;gt;&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{&amp;lt;includeonly&amp;gt;safesubst:&amp;lt;/includeonly&amp;gt;#invoke:list|horizontal}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Module:Navbar/styles.css&amp;diff=14</id>
		<title>Module:Navbar/styles.css</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Module:Navbar/styles.css&amp;diff=14"/>
		<updated>2025-12-24T14:56:59Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;/* {{pp|small=yes}} */ .navbar { 	display: inline; 	font-size: 88%; 	font-weight: normal; }  .navbar-collapse { 	float: left; 	text-align: left; }  .navbar-boxtext { 	word-spacing: 0; }  .navbar ul { 	display: inline-block; 	white-space: nowrap; 	line-height: inherit; }  .navbar-brackets::before { 	margin-right: -0.125em; 	content: &amp;#039;[ &amp;#039;; }  .navbar-brackets::after { 	margin-left: -0.125em; 	content: &amp;#039; ]&amp;#039;; }  .navbar li { 	word-spacing: -0.125em; }  .navbar a &amp;gt; span, .nav...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* {{pp|small=yes}} */&lt;br /&gt;
.navbar {&lt;br /&gt;
	display: inline;&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.navbar-collapse {&lt;br /&gt;
	float: left;&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.navbar-boxtext {&lt;br /&gt;
	word-spacing: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.navbar ul {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	line-height: inherit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.navbar-brackets::before {&lt;br /&gt;
	margin-right: -0.125em;&lt;br /&gt;
	content: &#039;[ &#039;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.navbar-brackets::after {&lt;br /&gt;
	margin-left: -0.125em;&lt;br /&gt;
	content: &#039; ]&#039;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.navbar li {&lt;br /&gt;
	word-spacing: -0.125em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.navbar a &amp;gt; span,&lt;br /&gt;
.navbar a &amp;gt; abbr {&lt;br /&gt;
	text-decoration: inherit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.navbar-mini abbr {&lt;br /&gt;
	font-variant: small-caps;&lt;br /&gt;
	border-bottom: none;&lt;br /&gt;
	text-decoration: none;&lt;br /&gt;
	cursor: inherit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.navbar-ct-full {&lt;br /&gt;
	font-size: 114%;&lt;br /&gt;
	margin: 0 7em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.navbar-ct-mini {&lt;br /&gt;
	font-size: 114%;&lt;br /&gt;
	margin: 0 4em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* not the usual @media screen, we simply remove navbar in @media print */&lt;br /&gt;
html.skin-theme-clientpref-night .navbar li a abbr {&lt;br /&gt;
	color: var(--color-base) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (prefers-color-scheme: dark) {&lt;br /&gt;
	html.skin-theme-clientpref-os .navbar li a abbr {&lt;br /&gt;
		color: var(--color-base) !important;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media print {&lt;br /&gt;
	.navbar {&lt;br /&gt;
		display: none !important;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Module:Navbar/configuration&amp;diff=13</id>
		<title>Module:Navbar/configuration</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Module:Navbar/configuration&amp;diff=13"/>
		<updated>2025-12-24T14:56:03Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;return { 	[&amp;#039;templatestyles&amp;#039;] = &amp;#039;Module:Navbar/styles.css&amp;#039;, 	[&amp;#039;hlist_templatestyles&amp;#039;] = &amp;#039;Hlist/styles.css&amp;#039;, 	[&amp;#039;box_text&amp;#039;] = &amp;#039;This box: &amp;#039;,			-- default text box when not plain or mini 	[&amp;#039;title_namespace&amp;#039;] = &amp;#039;Template&amp;#039;,		-- namespace to default to for title 	[&amp;#039;invalid_title&amp;#039;] = &amp;#039;Invalid title &amp;#039;, 	[&amp;#039;classes&amp;#039;] = { -- set a line to nil if you don&amp;#039;t want it 		[&amp;#039;navbar&amp;#039;] = &amp;#039;navbar&amp;#039;, 		[&amp;#039;plainlinks&amp;#039;] = &amp;#039;plainlinks&amp;#039;, -- plainlinks 		[&amp;#039;horizontal_list&amp;#039;] = &amp;#039;hlist&amp;#039;, -- horizontal lis...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;return {&lt;br /&gt;
	[&#039;templatestyles&#039;] = &#039;Module:Navbar/styles.css&#039;,&lt;br /&gt;
	[&#039;hlist_templatestyles&#039;] = &#039;Hlist/styles.css&#039;,&lt;br /&gt;
	[&#039;box_text&#039;] = &#039;This box: &#039;,			-- default text box when not plain or mini&lt;br /&gt;
	[&#039;title_namespace&#039;] = &#039;Template&#039;,		-- namespace to default to for title&lt;br /&gt;
	[&#039;invalid_title&#039;] = &#039;Invalid title &#039;,&lt;br /&gt;
	[&#039;classes&#039;] = { -- set a line to nil if you don&#039;t want it&lt;br /&gt;
		[&#039;navbar&#039;] = &#039;navbar&#039;,&lt;br /&gt;
		[&#039;plainlinks&#039;] = &#039;plainlinks&#039;, -- plainlinks&lt;br /&gt;
		[&#039;horizontal_list&#039;] = &#039;hlist&#039;, -- horizontal list class&lt;br /&gt;
		[&#039;mini&#039;] = &#039;navbar-mini&#039;, -- class indicating small links in the navbar&lt;br /&gt;
		[&#039;this_box&#039;] = &#039;navbar-boxtext&#039;,&lt;br /&gt;
		[&#039;brackets&#039;] = &#039;navbar-brackets&#039;,&lt;br /&gt;
		-- &#039;collapsible&#039; is the key for a class to indicate the navbar is&lt;br /&gt;
		-- setting up the collapsible element in addition to the normal&lt;br /&gt;
		-- navbar.&lt;br /&gt;
		[&#039;collapsible&#039;] = &#039;navbar-collapse&#039;,&lt;br /&gt;
		[&#039;collapsible_title_mini&#039;] = &#039;navbar-ct-mini&#039;,&lt;br /&gt;
		[&#039;collapsible_title_full&#039;] = &#039;navbar-ct-full&#039;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Module:Italic_title&amp;diff=12</id>
		<title>Module:Italic title</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Module:Italic_title&amp;diff=12"/>
		<updated>2025-12-24T14:55:20Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;-- This module implements {{italic title}}.  require(&amp;#039;strict&amp;#039;) local libraryUtil = require(&amp;#039;libraryUtil&amp;#039;) local checkType = libraryUtil.checkType local checkTypeForNamedArg = libraryUtil.checkTypeForNamedArg local yesno = require(&amp;#039;Module:Yesno&amp;#039;)  -------------------------------------------------------------------------------- -- ItalicTitle class --------------------------------------------------------------------------------  local ItalicTitle = {}  do 	----------------...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This module implements {{italic title}}.&lt;br /&gt;
&lt;br /&gt;
require(&#039;strict&#039;)&lt;br /&gt;
local libraryUtil = require(&#039;libraryUtil&#039;)&lt;br /&gt;
local checkType = libraryUtil.checkType&lt;br /&gt;
local checkTypeForNamedArg = libraryUtil.checkTypeForNamedArg&lt;br /&gt;
local yesno = require(&#039;Module:Yesno&#039;)&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- ItalicTitle class&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local ItalicTitle = {}&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
	----------------------------------------------------------------------------&lt;br /&gt;
	-- Class attributes and functions&lt;br /&gt;
	-- Things that belong to the class are here. Things that belong to each&lt;br /&gt;
	-- object are in the constructor.&lt;br /&gt;
	----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
	-- Keys of title parts that can be italicized.&lt;br /&gt;
	local italicizableKeys = {&lt;br /&gt;
		namespace = true,&lt;br /&gt;
		title = true,&lt;br /&gt;
		dab = true,&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	----------------------------------------------------------------------------&lt;br /&gt;
	-- ItalicTitle constructor&lt;br /&gt;
	-- This contains all the dynamic attributes and methods.&lt;br /&gt;
	----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
	function ItalicTitle.new()&lt;br /&gt;
		local obj = {}&lt;br /&gt;
&lt;br /&gt;
		-- Function for checking self variable in methods.&lt;br /&gt;
		local checkSelf = libraryUtil.makeCheckSelfFunction(&lt;br /&gt;
			&#039;ItalicTitle&#039;,&lt;br /&gt;
			&#039;obj&#039;,&lt;br /&gt;
			obj,&lt;br /&gt;
			&#039;ItalicTitle object&#039;&lt;br /&gt;
		)&lt;br /&gt;
&lt;br /&gt;
		-- Checks a key is present in a lookup table.&lt;br /&gt;
		-- Param: name - the function name.&lt;br /&gt;
		-- Param: argId - integer position of the key in the argument list.&lt;br /&gt;
		-- Param: key - the key.&lt;br /&gt;
		-- Param: lookupTable - the table to look the key up in.&lt;br /&gt;
		local function checkKey(name, argId, key, lookupTable)&lt;br /&gt;
			if not lookupTable[key] then&lt;br /&gt;
				error(string.format(&lt;br /&gt;
					&amp;quot;bad argument #%d to &#039;%s&#039; (&#039;%s&#039; is not a valid key)&amp;quot;,&lt;br /&gt;
					argId,&lt;br /&gt;
					name,&lt;br /&gt;
					key&lt;br /&gt;
				), 3)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- Set up object structure.&lt;br /&gt;
		local parsed = false&lt;br /&gt;
		local categories = {}&lt;br /&gt;
		local italicizedKeys = {}&lt;br /&gt;
		local italicizedSubstrings = {}&lt;br /&gt;
&lt;br /&gt;
		-- Parses a title object into its namespace text, title, and&lt;br /&gt;
		-- disambiguation text.&lt;br /&gt;
		-- Param: options - a table of options with the following keys:&lt;br /&gt;
		--     title - the title object to parse&lt;br /&gt;
		--     ignoreDab - ignore any disambiguation parentheses&lt;br /&gt;
		-- Returns the current object.&lt;br /&gt;
		function obj:parseTitle(options)&lt;br /&gt;
			checkSelf(self, &#039;parseTitle&#039;)&lt;br /&gt;
			checkType(&#039;parseTitle&#039;, 1, options, &#039;table&#039;)&lt;br /&gt;
			checkTypeForNamedArg(&#039;parseTitle&#039;, &#039;title&#039;, options.title, &#039;table&#039;)&lt;br /&gt;
			local title = options.title&lt;br /&gt;
		&lt;br /&gt;
			-- Title and dab text&lt;br /&gt;
			local prefix, parentheses&lt;br /&gt;
			if not options.ignoreDab then&lt;br /&gt;
				prefix, parentheses = mw.ustring.match(&lt;br /&gt;
					title.text,&lt;br /&gt;
					&#039;^(.+) %(([^%(%)]+)%)$&#039;&lt;br /&gt;
				)&lt;br /&gt;
			end&lt;br /&gt;
			if prefix and parentheses then&lt;br /&gt;
				self.title = prefix&lt;br /&gt;
				self.dab = parentheses&lt;br /&gt;
			else&lt;br /&gt;
				self.title = title.text&lt;br /&gt;
			end&lt;br /&gt;
		&lt;br /&gt;
			-- Namespace&lt;br /&gt;
			local namespace = mw.site.namespaces[title.namespace].name&lt;br /&gt;
			if namespace and #namespace &amp;gt;= 1 then&lt;br /&gt;
				self.namespace = namespace&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			-- Register the object as having parsed a title.&lt;br /&gt;
			parsed = true&lt;br /&gt;
		&lt;br /&gt;
			return self&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- Italicizes part of the title.&lt;br /&gt;
		-- Param: key - the key of the title part to be italicized. Possible&lt;br /&gt;
		-- keys are contained in the italicizableKeys table.&lt;br /&gt;
		-- Returns the current object.&lt;br /&gt;
		function obj:italicize(key)&lt;br /&gt;
			checkSelf(self, &#039;italicize&#039;)&lt;br /&gt;
			checkType(&#039;italicize&#039;, 1, key, &#039;string&#039;)&lt;br /&gt;
			checkKey(&#039;italicize&#039;, 1, key, italicizableKeys)&lt;br /&gt;
			italicizedKeys[key] = true&lt;br /&gt;
			return self&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- Un-italicizes part of the title.&lt;br /&gt;
		-- Param: key - the key of the title part to be un-italicized. Possible&lt;br /&gt;
		-- keys are contained in the italicizableKeys table.&lt;br /&gt;
		-- Returns the current object.&lt;br /&gt;
		function obj:unitalicize(key)&lt;br /&gt;
			checkSelf(self, &#039;unitalicize&#039;)&lt;br /&gt;
			checkType(&#039;unitalicize&#039;, 1, key, &#039;string&#039;)&lt;br /&gt;
			checkKey(&#039;unitalicize&#039;, 1, key, italicizableKeys)&lt;br /&gt;
			italicizedKeys[key] = nil&lt;br /&gt;
			return self&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- Italicizes a substring in the title. This only affects the main part&lt;br /&gt;
		-- of the title, not the namespace or the disambiguation text.&lt;br /&gt;
		-- Param: s - the substring to be italicized.&lt;br /&gt;
		-- Returns the current object.&lt;br /&gt;
		function obj:italicizeSubstring(s)&lt;br /&gt;
			checkSelf(self, &#039;italicizeSubstring&#039;)&lt;br /&gt;
			checkType(&#039;italicizeSubstring&#039;, 1, s, &#039;string&#039;)&lt;br /&gt;
			italicizedSubstrings[s] = true&lt;br /&gt;
			return self&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- Un-italicizes a substring in the title. This only affects the main&lt;br /&gt;
		-- part of the title, not the namespace or the disambiguation text.&lt;br /&gt;
		-- Param: s - the substring to be un-italicized.&lt;br /&gt;
		-- Returns the current object.&lt;br /&gt;
		function obj:unitalicizeSubstring(s)&lt;br /&gt;
			checkSelf(self, &#039;unitalicizeSubstring&#039;)&lt;br /&gt;
			checkType(&#039;unitalicizeSubstring&#039;, 1, s, &#039;string&#039;)&lt;br /&gt;
			italicizedSubstrings[s] = nil&lt;br /&gt;
			return self&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- Renders the object into a page name. If no title has yet been parsed,&lt;br /&gt;
		-- the current title is used.&lt;br /&gt;
		-- Returns string&lt;br /&gt;
		function obj:renderTitle()&lt;br /&gt;
			checkSelf(self, &#039;renderTitle&#039;)&lt;br /&gt;
&lt;br /&gt;
			-- Italicizes a string&lt;br /&gt;
			-- Param: s - the string to italicize&lt;br /&gt;
			-- Returns string.&lt;br /&gt;
			local function italicize(s)&lt;br /&gt;
				assert(type(s) == &#039;string&#039;, &#039;s was not a string&#039;)&lt;br /&gt;
				assert(s ~= &#039;&#039;, &#039;s was the empty string&#039;)&lt;br /&gt;
				return string.format(&#039;&amp;lt;i&amp;gt;%s&amp;lt;/i&amp;gt;&#039;, s)&lt;br /&gt;
			end&lt;br /&gt;
		&lt;br /&gt;
			-- Escape characters in a string that are magic in Lua patterns.&lt;br /&gt;
			-- Param: pattern - the pattern to escape&lt;br /&gt;
			-- Returns string.&lt;br /&gt;
			local function escapeMagicCharacters(s)&lt;br /&gt;
				assert(type(s) == &#039;string&#039;, &#039;s was not a string&#039;)&lt;br /&gt;
				return s:gsub(&#039;%p&#039;, &#039;%%%0&#039;)&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			-- If a title hasn&#039;t been parsed yet, parse the current title.&lt;br /&gt;
			if not parsed then&lt;br /&gt;
				self:parseTitle{title = mw.title.getCurrentTitle()}&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			-- Italicize the different parts of the title and store them in a&lt;br /&gt;
			-- titleParts table to be joined together later.&lt;br /&gt;
			local titleParts = {}&lt;br /&gt;
&lt;br /&gt;
			-- Italicize the italicizable keys.&lt;br /&gt;
			for key in pairs(italicizableKeys) do&lt;br /&gt;
				if self[key] then&lt;br /&gt;
					if italicizedKeys[key] then&lt;br /&gt;
						titleParts[key] = italicize(self[key])&lt;br /&gt;
					else&lt;br /&gt;
						titleParts[key] = self[key]&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			-- Italicize substrings. If there are any substrings to be&lt;br /&gt;
			-- italicized then start from the raw title, as this overrides any&lt;br /&gt;
			-- italicization of the main part of the title.&lt;br /&gt;
			if next(italicizedSubstrings) then&lt;br /&gt;
				titleParts.title = self.title&lt;br /&gt;
				for s in pairs(italicizedSubstrings) do&lt;br /&gt;
					local pattern = escapeMagicCharacters(s)&lt;br /&gt;
					local italicizedTitle, nReplacements = titleParts.title:gsub(&lt;br /&gt;
						pattern,&lt;br /&gt;
						italicize&lt;br /&gt;
					)&lt;br /&gt;
					titleParts.title = italicizedTitle&lt;br /&gt;
&lt;br /&gt;
					-- If we didn&#039;t make any replacements then it means that we&lt;br /&gt;
					-- have been passed a bad substring or that the page has&lt;br /&gt;
					-- been moved to a bad title, so add a tracking category.&lt;br /&gt;
					if nReplacements &amp;lt; 1 then&lt;br /&gt;
						categories[&#039;Pages using italic title with no matching string&#039;] = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			-- Assemble the title together from the parts.&lt;br /&gt;
			local ret = &#039;&#039;&lt;br /&gt;
			if titleParts.namespace then&lt;br /&gt;
				ret = ret .. titleParts.namespace .. &#039;:&#039;&lt;br /&gt;
			end&lt;br /&gt;
			ret = ret .. titleParts.title&lt;br /&gt;
			if titleParts.dab then&lt;br /&gt;
				ret = ret .. &#039; (&#039; .. titleParts.dab .. &#039;)&#039;&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			return ret&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- Returns an expanded DISPLAYTITLE parser function called with the&lt;br /&gt;
		-- result of obj:renderTitle, plus any other optional arguments.&lt;br /&gt;
		-- Returns string&lt;br /&gt;
		function obj:renderDisplayTitle(...)&lt;br /&gt;
			checkSelf(self, &#039;renderDisplayTitle&#039;)&lt;br /&gt;
			return mw.getCurrentFrame():callParserFunction(&lt;br /&gt;
				&#039;DISPLAYTITLE&#039;,&lt;br /&gt;
				self:renderTitle(),&lt;br /&gt;
				...&lt;br /&gt;
			)&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- Returns an expanded DISPLAYTITLE parser function called with the&lt;br /&gt;
		-- result of obj:renderTitle, plus any other optional arguments, plus&lt;br /&gt;
		-- any tracking categories.&lt;br /&gt;
		-- Returns string&lt;br /&gt;
		function obj:render(...)&lt;br /&gt;
			checkSelf(self, &#039;render&#039;)&lt;br /&gt;
			local ret = self:renderDisplayTitle(...)&lt;br /&gt;
			for cat in pairs(categories) do&lt;br /&gt;
				ret = ret .. string.format(&lt;br /&gt;
					&#039;[[Category:%s]]&#039;,&lt;br /&gt;
					cat&lt;br /&gt;
				)&lt;br /&gt;
			end&lt;br /&gt;
			return ret&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		return obj&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Exports&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local function getArgs(frame, wrapper)&lt;br /&gt;
	assert(type(wrapper) == &#039;string&#039;, &#039;wrapper was not a string&#039;)&lt;br /&gt;
	return require(&#039;Module:Arguments&#039;).getArgs(frame, {&lt;br /&gt;
		wrappers = wrapper&lt;br /&gt;
	})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Main function for {{italic title}}&lt;br /&gt;
function p._main(args)&lt;br /&gt;
	checkType(&#039;_main&#039;, 1, args, &#039;table&#039;)&lt;br /&gt;
	local italicTitle = ItalicTitle.new()&lt;br /&gt;
	italicTitle:parseTitle{&lt;br /&gt;
		title = mw.title.getCurrentTitle(),&lt;br /&gt;
		ignoreDab = yesno(args.all, false)&lt;br /&gt;
	}&lt;br /&gt;
	if args.string then&lt;br /&gt;
		italicTitle:italicizeSubstring(args.string)&lt;br /&gt;
	else&lt;br /&gt;
		italicTitle:italicize(&#039;title&#039;)&lt;br /&gt;
	end&lt;br /&gt;
	return italicTitle:render(args[1])&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	return p._main(getArgs(frame, &#039;Template:Italic title&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._dabonly(args)&lt;br /&gt;
	return ItalicTitle.new()&lt;br /&gt;
		:italicize(&#039;dab&#039;)&lt;br /&gt;
		:render(args[1])&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.dabonly(frame)&lt;br /&gt;
	return p._dabonly(getArgs(frame, &#039;Template:Italic dab&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Module:Navbar&amp;diff=11</id>
		<title>Module:Navbar</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Module:Navbar&amp;diff=11"/>
		<updated>2025-12-24T14:55:02Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;local p = {} local cfg = mw.loadData(&amp;#039;Module:Navbar/configuration&amp;#039;)  local function get_title_arg(is_collapsible, template) 	local title_arg = 1 	if is_collapsible then title_arg = 2 end 	if template then title_arg = &amp;#039;template&amp;#039; end 	return title_arg end  local function choose_links(template, args) 	-- The show table indicates the default displayed items. 	-- view, talk, edit, hist, move, watch 	-- TODO: Move to configuration. 	local show = {true, true, true, false, false...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
local cfg = mw.loadData(&#039;Module:Navbar/configuration&#039;)&lt;br /&gt;
&lt;br /&gt;
local function get_title_arg(is_collapsible, template)&lt;br /&gt;
	local title_arg = 1&lt;br /&gt;
	if is_collapsible then title_arg = 2 end&lt;br /&gt;
	if template then title_arg = &#039;template&#039; end&lt;br /&gt;
	return title_arg&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function choose_links(template, args)&lt;br /&gt;
	-- The show table indicates the default displayed items.&lt;br /&gt;
	-- view, talk, edit, hist, move, watch&lt;br /&gt;
	-- TODO: Move to configuration.&lt;br /&gt;
	local show = {true, true, true, false, false, false}&lt;br /&gt;
	if template then&lt;br /&gt;
		show[2] = false&lt;br /&gt;
		show[3] = false&lt;br /&gt;
		local index = {t = 2, d = 2, e = 3, h = 4, m = 5, w = 6,&lt;br /&gt;
			talk = 2, edit = 3, hist = 4, move = 5, watch = 6}&lt;br /&gt;
		-- TODO: Consider removing TableTools dependency.&lt;br /&gt;
		for _, v in ipairs(require (&#039;Module:TableTools&#039;).compressSparseArray(args)) do&lt;br /&gt;
			local num = index[v]&lt;br /&gt;
			if num then show[num] = true end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local remove_edit_link = args.noedit&lt;br /&gt;
	if remove_edit_link then show[3] = false end&lt;br /&gt;
	&lt;br /&gt;
	return show&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function add_link(link_description, ul, is_mini, font_style)&lt;br /&gt;
	local l&lt;br /&gt;
	if link_description.url then&lt;br /&gt;
		l = {&#039;[&#039;, &#039;&#039;, &#039;]&#039;}&lt;br /&gt;
	else&lt;br /&gt;
		l = {&#039;[[&#039;, &#039;|&#039;, &#039;]]&#039;}&lt;br /&gt;
	end&lt;br /&gt;
	ul:tag(&#039;li&#039;)&lt;br /&gt;
		:addClass(&#039;nv-&#039; .. link_description.full)&lt;br /&gt;
		:wikitext(l[1] .. link_description.link .. l[2])&lt;br /&gt;
		:tag(is_mini and &#039;abbr&#039; or &#039;span&#039;)&lt;br /&gt;
			:attr(&#039;title&#039;, link_description.html_title)&lt;br /&gt;
			:cssText(font_style)&lt;br /&gt;
			:wikitext(is_mini and link_description.mini or link_description.full)&lt;br /&gt;
			:done()&lt;br /&gt;
		:wikitext(l[3])&lt;br /&gt;
		:done()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function make_list(title_text, has_brackets, displayed_links, is_mini, font_style)&lt;br /&gt;
	&lt;br /&gt;
	local title = mw.title.new(mw.text.trim(title_text), cfg.title_namespace)&lt;br /&gt;
	if not title then&lt;br /&gt;
		error(cfg.invalid_title .. title_text)&lt;br /&gt;
	end&lt;br /&gt;
	local talkpage = title.talkPageTitle and title.talkPageTitle.fullText or &#039;&#039;&lt;br /&gt;
	&lt;br /&gt;
	-- TODO: Get link_descriptions and show into the configuration module.&lt;br /&gt;
	-- link_descriptions should be easier...&lt;br /&gt;
	local link_descriptions = {&lt;br /&gt;
		{ [&#039;mini&#039;] = &#039;v&#039;, [&#039;full&#039;] = &#039;view&#039;, [&#039;html_title&#039;] = &#039;View this template&#039;,&lt;br /&gt;
			[&#039;link&#039;] = title.fullText, [&#039;url&#039;] = false },&lt;br /&gt;
		{ [&#039;mini&#039;] = &#039;t&#039;, [&#039;full&#039;] = &#039;talk&#039;, [&#039;html_title&#039;] = &#039;Discuss this template&#039;,&lt;br /&gt;
			[&#039;link&#039;] = talkpage, [&#039;url&#039;] = false },&lt;br /&gt;
		{ [&#039;mini&#039;] = &#039;e&#039;, [&#039;full&#039;] = &#039;edit&#039;, [&#039;html_title&#039;] = &#039;Edit this template&#039;,&lt;br /&gt;
			[&#039;link&#039;] = &#039;Special:EditPage/&#039; .. title.fullText, [&#039;url&#039;] = false },&lt;br /&gt;
		{ [&#039;mini&#039;] = &#039;h&#039;, [&#039;full&#039;] = &#039;hist&#039;, [&#039;html_title&#039;] = &#039;History of this template&#039;,&lt;br /&gt;
			[&#039;link&#039;] = &#039;Special:PageHistory/&#039; .. title.fullText, [&#039;url&#039;] = false },&lt;br /&gt;
		{ [&#039;mini&#039;] = &#039;m&#039;, [&#039;full&#039;] = &#039;move&#039;, [&#039;html_title&#039;] = &#039;Move this template&#039;,&lt;br /&gt;
			[&#039;link&#039;] = mw.title.new(&#039;Special:Movepage&#039;):fullUrl(&#039;target=&#039;..title.fullText), [&#039;url&#039;] = true },&lt;br /&gt;
		{ [&#039;mini&#039;] = &#039;w&#039;, [&#039;full&#039;] = &#039;watch&#039;, [&#039;html_title&#039;] = &#039;Watch this template&#039;, &lt;br /&gt;
			[&#039;link&#039;] = title:fullUrl(&#039;action=watch&#039;), [&#039;url&#039;] = true }&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	local ul = mw.html.create(&#039;ul&#039;)&lt;br /&gt;
	if has_brackets then&lt;br /&gt;
		ul:addClass(cfg.classes.brackets)&lt;br /&gt;
			:cssText(font_style)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	for i, _ in ipairs(displayed_links) do&lt;br /&gt;
		if displayed_links[i] then add_link(link_descriptions[i], ul, is_mini, font_style) end&lt;br /&gt;
	end&lt;br /&gt;
	return ul:done()&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._navbar(args)&lt;br /&gt;
	&lt;br /&gt;
	-- TODO: We probably don&#039;t need both fontstyle and fontcolor...&lt;br /&gt;
	local font_style = args.fontstyle&lt;br /&gt;
	local font_color = args.fontcolor&lt;br /&gt;
	local is_collapsible = args.collapsible&lt;br /&gt;
	local is_mini = args.mini&lt;br /&gt;
	local is_plain = args.plain&lt;br /&gt;
	&lt;br /&gt;
	local collapsible_class = nil&lt;br /&gt;
	if is_collapsible then&lt;br /&gt;
		collapsible_class = cfg.classes.collapsible&lt;br /&gt;
		if not is_plain then is_mini = 1 end&lt;br /&gt;
		if font_color then&lt;br /&gt;
			font_style = (font_style or &#039;&#039;) .. &#039;; color: &#039; .. font_color .. &#039;;&#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local navbar_style = args.style&lt;br /&gt;
	local div = mw.html.create():tag(&#039;div&#039;)&lt;br /&gt;
	div&lt;br /&gt;
		:addClass(cfg.classes.navbar)&lt;br /&gt;
		:addClass(cfg.classes.plainlinks)&lt;br /&gt;
		:addClass(cfg.classes.horizontal_list)&lt;br /&gt;
		:addClass(collapsible_class) -- we made the determination earlier&lt;br /&gt;
		:cssText(navbar_style)&lt;br /&gt;
&lt;br /&gt;
	if is_mini then div:addClass(cfg.classes.mini) end&lt;br /&gt;
&lt;br /&gt;
	local box_text = (args.text or cfg.box_text) .. &#039; &#039;&lt;br /&gt;
	 -- the concatenated space guarantees the box text is separated&lt;br /&gt;
	if not (is_mini or is_plain) then&lt;br /&gt;
		div&lt;br /&gt;
			:tag(&#039;span&#039;)&lt;br /&gt;
				:addClass(cfg.classes.box_text)&lt;br /&gt;
				:cssText(font_style)&lt;br /&gt;
				:wikitext(box_text)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local template = args.template&lt;br /&gt;
	local displayed_links = choose_links(template, args)&lt;br /&gt;
	local has_brackets = args.brackets&lt;br /&gt;
	local title_arg = get_title_arg(is_collapsible, template)&lt;br /&gt;
	local title_text = args[title_arg] or (&#039;:&#039; .. mw.getCurrentFrame():getParent():getTitle())&lt;br /&gt;
	local list = make_list(title_text, has_brackets, displayed_links, is_mini, font_style)&lt;br /&gt;
	div:node(list)&lt;br /&gt;
&lt;br /&gt;
	if is_collapsible then&lt;br /&gt;
		local title_text_class&lt;br /&gt;
		if is_mini then&lt;br /&gt;
			title_text_class = cfg.classes.collapsible_title_mini&lt;br /&gt;
		else&lt;br /&gt;
			title_text_class = cfg.classes.collapsible_title_full&lt;br /&gt;
		end&lt;br /&gt;
		div:done()&lt;br /&gt;
			:tag(&#039;div&#039;)&lt;br /&gt;
			:addClass(title_text_class)&lt;br /&gt;
			:cssText(font_style)&lt;br /&gt;
			:wikitext(args[1])&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
	-- hlist -&amp;gt; navbar is best-effort to preserve old Common.css ordering.&lt;br /&gt;
	return frame:extensionTag{&lt;br /&gt;
		name = &#039;templatestyles&#039;, args = { src = cfg.hlist_templatestyles }&lt;br /&gt;
	} .. frame:extensionTag{&lt;br /&gt;
		name = &#039;templatestyles&#039;, args = { src = cfg.templatestyles }&lt;br /&gt;
	} .. tostring(div:done())&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.navbar(frame)&lt;br /&gt;
	return p._navbar(require(&#039;Module:Arguments&#039;).getArgs(frame))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Module:Infobox/styles.css&amp;diff=10</id>
		<title>Module:Infobox/styles.css</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Module:Infobox/styles.css&amp;diff=10"/>
		<updated>2025-12-24T14:51:14Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;/* {{pp|small=y}} */ /*  * This TemplateStyles sheet deliberately does NOT include the full set of  * infobox styles. We are still working to migrate all of the manual  * infoboxes. See MediaWiki talk:Common.css/to do#Infobox  * DO NOT ADD THEM HERE  */ /*  * not strictly certain these styles are necessary since the modules now  * exclusively output infobox-subbox or infobox, not both  * just replicating the module faithfully  */ .infobox-subbox { 	padding: 0; 	borde...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* {{pp|small=y}} */&lt;br /&gt;
/*&lt;br /&gt;
 * This TemplateStyles sheet deliberately does NOT include the full set of&lt;br /&gt;
 * infobox styles. We are still working to migrate all of the manual&lt;br /&gt;
 * infoboxes. See [[MediaWiki talk:Common.css/to do#Infobox]]&lt;br /&gt;
 * DO NOT ADD THEM HERE&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * not strictly certain these styles are necessary since the modules now&lt;br /&gt;
 * exclusively output infobox-subbox or infobox, not both&lt;br /&gt;
 * just replicating the module faithfully&lt;br /&gt;
 */&lt;br /&gt;
.infobox-subbox {&lt;br /&gt;
	padding: 0;&lt;br /&gt;
	border: none;&lt;br /&gt;
	margin: -3px;&lt;br /&gt;
	width: auto;&lt;br /&gt;
	min-width: 100%;&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
	clear: none;&lt;br /&gt;
	float: none;&lt;br /&gt;
	background-color: transparent;&lt;br /&gt;
    color:inherit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox-3cols-child {&lt;br /&gt;
	margin: -3px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox .navbar {&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Dark theme: [[William_Wragg]], [[Coral_Castle]] */&lt;br /&gt;
&lt;br /&gt;
@media screen {&lt;br /&gt;
    html.skin-theme-clientpref-night .infobox-full-data:not(.notheme) &amp;gt; div:not(.notheme)[style] {&lt;br /&gt;
	    background: #1f1f23 !important;&lt;br /&gt;
	      /* switch with var( --color-base ) when supported. */&lt;br /&gt;
	      color: #f8f9fa;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
@media screen and ( prefers-color-scheme: dark) {&lt;br /&gt;
    html.skin-theme-clientpref-os .infobox-full-data:not(.notheme) &amp;gt; div:not(.notheme)[style] {&lt;br /&gt;
      background: #1f1f23 !important;&lt;br /&gt;
      /* switch with var( --color-base ) when supported. */&lt;br /&gt;
      color: #f8f9fa;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Since infobox is a table, many infobox templates take advantage of this to&lt;br /&gt;
 * add columns and rows to the infobox itself rather than as part of a new table&lt;br /&gt;
 * inside them. This class should be discouraged and removed on the long term,&lt;br /&gt;
 * but allows us to at least identify these tables going forward&lt;br /&gt;
 * Currently in use on: [[Module:Infobox3cols]]&lt;br /&gt;
 * Fixes issue described in [[phab:F55300125]] on Vector 2022.&lt;br /&gt;
*/&lt;br /&gt;
@media (min-width: 640px) {&lt;br /&gt;
  body.skin--responsive .infobox-table {&lt;br /&gt;
    display: table !important;&lt;br /&gt;
  }&lt;br /&gt;
  body.skin--responsive .infobox-table &amp;gt; caption {&lt;br /&gt;
    display: table-caption !important;&lt;br /&gt;
  }&lt;br /&gt;
  body.skin--responsive .infobox-table &amp;gt; tbody {&lt;br /&gt;
    display: table-row-group;&lt;br /&gt;
  }&lt;br /&gt;
  body.skin--responsive .infobox-table th,&lt;br /&gt;
  body.skin--responsive .infobox-table td {&lt;br /&gt;
    padding-left: inherit;&lt;br /&gt;
    padding-right: inherit;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Module:Infobox&amp;diff=9</id>
		<title>Module:Infobox</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Module:Infobox&amp;diff=9"/>
		<updated>2025-12-24T14:45:54Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Created page with &amp;quot;local p = {} local args = {} local origArgs = {} local root local empty_row_categories = {} local category_in_empty_row_pattern = &amp;#039;%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*]]&amp;#039; local has_rows = false local yesno = require(&amp;quot;Module:Yesno&amp;quot;) local lists = { 	plainlist_t = { 		patterns = { 			&amp;#039;^plainlist$&amp;#039;, 			&amp;#039;%splainlist$&amp;#039;, 			&amp;#039;^plainlist%s&amp;#039;, 			&amp;#039;%splainlist%s&amp;#039; 		}, 		found = false, 		styles = &amp;#039;Plainlist/styles.css&amp;#039; 	}, 	hlist_t = { 		patterns = { 			&amp;#039;^hlist$&amp;#039;, 			&amp;#039;%s...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
local args = {}&lt;br /&gt;
local origArgs = {}&lt;br /&gt;
local root&lt;br /&gt;
local empty_row_categories = {}&lt;br /&gt;
local category_in_empty_row_pattern = &#039;%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*]]&#039;&lt;br /&gt;
local has_rows = false&lt;br /&gt;
local yesno = require(&amp;quot;Module:Yesno&amp;quot;)&lt;br /&gt;
local lists = {&lt;br /&gt;
	plainlist_t = {&lt;br /&gt;
		patterns = {&lt;br /&gt;
			&#039;^plainlist$&#039;,&lt;br /&gt;
			&#039;%splainlist$&#039;,&lt;br /&gt;
			&#039;^plainlist%s&#039;,&lt;br /&gt;
			&#039;%splainlist%s&#039;&lt;br /&gt;
		},&lt;br /&gt;
		found = false,&lt;br /&gt;
		styles = &#039;Plainlist/styles.css&#039;&lt;br /&gt;
	},&lt;br /&gt;
	hlist_t = {&lt;br /&gt;
		patterns = {&lt;br /&gt;
			&#039;^hlist$&#039;,&lt;br /&gt;
			&#039;%shlist$&#039;,&lt;br /&gt;
			&#039;^hlist%s&#039;,&lt;br /&gt;
			&#039;%shlist%s&#039;&lt;br /&gt;
		},&lt;br /&gt;
		found = false,&lt;br /&gt;
		styles = &#039;Hlist/styles.css&#039;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function has_list_class(args_to_check)&lt;br /&gt;
	for _, list in pairs(lists) do&lt;br /&gt;
		if not list.found then&lt;br /&gt;
			for _, arg in pairs(args_to_check) do&lt;br /&gt;
				for _, pattern in ipairs(list.patterns) do&lt;br /&gt;
					if mw.ustring.find(arg or &#039;&#039;, pattern) then&lt;br /&gt;
						list.found = true&lt;br /&gt;
						break&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if list.found then break end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function fixChildBoxes(sval, tt)&lt;br /&gt;
	local function notempty( s ) return s and s:match( &#039;%S&#039; ) end&lt;br /&gt;
	&lt;br /&gt;
	if notempty(sval) then&lt;br /&gt;
		local marker = &#039;&amp;lt;span class=special_infobox_marker&amp;gt;&#039;&lt;br /&gt;
		local s = sval&lt;br /&gt;
		-- start moving templatestyles and categories inside of table rows&lt;br /&gt;
		local slast = &#039;&#039;&lt;br /&gt;
		while slast ~= s do&lt;br /&gt;
			slast = s&lt;br /&gt;
			s = mw.ustring.gsub(s, &#039;(&amp;lt;/[Tt][Rr]%s*&amp;gt;%s*)(%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*%]%])&#039;, &#039;%2%1&#039;)&lt;br /&gt;
			s = mw.ustring.gsub(s, &#039;(&amp;lt;/[Tt][Rr]%s*&amp;gt;%s*)(\127[^\127]*UNIQ%-%-templatestyles%-%x+%-QINU[^\127]*\127)&#039;, &#039;%2%1&#039;)&lt;br /&gt;
		end&lt;br /&gt;
		-- end moving templatestyles and categories inside of table rows&lt;br /&gt;
		s = mw.ustring.gsub(s, &#039;(&amp;lt;%s*[Tt][Rr])&#039;, marker .. &#039;%1&#039;)&lt;br /&gt;
		s = mw.ustring.gsub(s, &#039;(&amp;lt;/[Tt][Rr]%s*&amp;gt;)&#039;, &#039;%1&#039; .. marker)&lt;br /&gt;
		if s:match(marker) then&lt;br /&gt;
			s = mw.ustring.gsub(s, marker .. &#039;%s*&#039; .. marker, &#039;&#039;)&lt;br /&gt;
			s = mw.ustring.gsub(s, &#039;([\r\n]|-[^\r\n]*[\r\n])%s*&#039; .. marker, &#039;%1&#039;)&lt;br /&gt;
			s = mw.ustring.gsub(s, marker .. &#039;%s*([\r\n]|-)&#039;, &#039;%1&#039;)&lt;br /&gt;
			s = mw.ustring.gsub(s, &#039;(&amp;lt;/[Cc][Aa][Pp][Tt][Ii][Oo][Nn]%s*&amp;gt;%s*)&#039; .. marker, &#039;%1&#039;)&lt;br /&gt;
			s = mw.ustring.gsub(s, &#039;(&amp;lt;%s*[Tt][Aa][Bb][Ll][Ee][^&amp;lt;&amp;gt;]*&amp;gt;%s*)&#039; .. marker, &#039;%1&#039;)&lt;br /&gt;
			s = mw.ustring.gsub(s, &#039;^(%{|[^\r\n]*[\r\n]%s*)&#039; .. marker, &#039;%1&#039;)&lt;br /&gt;
			s = mw.ustring.gsub(s, &#039;([\r\n]%{|[^\r\n]*[\r\n]%s*)&#039; .. marker, &#039;%1&#039;)&lt;br /&gt;
			s = mw.ustring.gsub(s, marker .. &#039;(%s*&amp;lt;/[Tt][Aa][Bb][Ll][Ee]%s*&amp;gt;)&#039;, &#039;%1&#039;)&lt;br /&gt;
			s = mw.ustring.gsub(s, marker .. &#039;(%s*\n|%})&#039;, &#039;%1&#039;)&lt;br /&gt;
		end&lt;br /&gt;
		if s:match(marker) then&lt;br /&gt;
			local subcells = mw.text.split(s, marker)&lt;br /&gt;
			s = &#039;&#039;&lt;br /&gt;
			for k = 1, #subcells do&lt;br /&gt;
				if k == 1 then&lt;br /&gt;
					s = s .. subcells[k] .. &#039;&amp;lt;/&#039; .. tt .. &#039;&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
				elseif k == #subcells then&lt;br /&gt;
					local rowstyle = &#039; style=&amp;quot;display:none&amp;quot;&#039;&lt;br /&gt;
					if notempty(subcells[k]) then rowstyle = &#039;&#039;	end&lt;br /&gt;
					s = s .. &#039;&amp;lt;tr&#039; .. rowstyle ..&#039;&amp;gt;&amp;lt;&#039; .. tt .. &#039; colspan=2&amp;gt;\n&#039; ..&lt;br /&gt;
						subcells[k]&lt;br /&gt;
				elseif notempty(subcells[k]) then&lt;br /&gt;
					if (k % 2) == 0 then&lt;br /&gt;
						s = s .. subcells[k]&lt;br /&gt;
					else&lt;br /&gt;
						s = s .. &#039;&amp;lt;tr&amp;gt;&amp;lt;&#039; .. tt .. &#039; colspan=2&amp;gt;\n&#039; ..&lt;br /&gt;
							subcells[k] .. &#039;&amp;lt;/&#039; .. tt .. &#039;&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		-- the next two lines add a newline at the end of lists for the PHP parser&lt;br /&gt;
		-- [[Special:Diff/849054481]]&lt;br /&gt;
		-- remove when [[:phab:T191516]] is fixed or OBE&lt;br /&gt;
		s = mw.ustring.gsub(s, &#039;([\r\n][%*#;:][^\r\n]*)$&#039;, &#039;%1\n&#039;)&lt;br /&gt;
		s = mw.ustring.gsub(s, &#039;^([%*#;:][^\r\n]*)$&#039;, &#039;%1\n&#039;)&lt;br /&gt;
		s = mw.ustring.gsub(s, &#039;^([%*#;:])&#039;, &#039;\n%1&#039;)&lt;br /&gt;
		s = mw.ustring.gsub(s, &#039;^(%{%|)&#039;, &#039;\n%1&#039;)&lt;br /&gt;
		return s&lt;br /&gt;
	else&lt;br /&gt;
		return sval&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Cleans empty tables&lt;br /&gt;
local function cleanInfobox()&lt;br /&gt;
	root = tostring(root)&lt;br /&gt;
	if has_rows == false then&lt;br /&gt;
		root = mw.ustring.gsub(root, &#039;&amp;lt;table[^&amp;lt;&amp;gt;]*&amp;gt;%s*&amp;lt;/table&amp;gt;&#039;, &#039;&#039;)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the union of the values of two tables, as a sequence.&lt;br /&gt;
local function union(t1, t2)&lt;br /&gt;
&lt;br /&gt;
	local vals = {}&lt;br /&gt;
	for k, v in pairs(t1) do&lt;br /&gt;
		vals[v] = true&lt;br /&gt;
	end&lt;br /&gt;
	for k, v in pairs(t2) do&lt;br /&gt;
		vals[v] = true&lt;br /&gt;
	end&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	for k, v in pairs(vals) do&lt;br /&gt;
		table.insert(ret, k)&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns a table containing the numbers of the arguments that exist&lt;br /&gt;
-- for the specified prefix. For example, if the prefix was &#039;data&#039;, and&lt;br /&gt;
-- &#039;data1&#039;, &#039;data2&#039;, and &#039;data5&#039; exist, it would return {1, 2, 5}.&lt;br /&gt;
local function getArgNums(prefix)&lt;br /&gt;
	local nums = {}&lt;br /&gt;
	for k, v in pairs(args) do&lt;br /&gt;
		local num = tostring(k):match(&#039;^&#039; .. prefix .. &#039;([1-9]%d*)$&#039;)&lt;br /&gt;
		if num then table.insert(nums, tonumber(num)) end&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(nums)&lt;br /&gt;
	return nums&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Adds a row to the infobox, with either a header cell&lt;br /&gt;
-- or a label/data cell combination.&lt;br /&gt;
local function addRow(rowArgs)&lt;br /&gt;
	&lt;br /&gt;
	if rowArgs.header and rowArgs.header ~= &#039;_BLANK_&#039; then&lt;br /&gt;
		has_rows = true&lt;br /&gt;
		has_list_class({ rowArgs.rowclass, rowArgs.class, args.headerclass })&lt;br /&gt;
		&lt;br /&gt;
		root&lt;br /&gt;
			:tag(&#039;tr&#039;)&lt;br /&gt;
				:addClass(rowArgs.rowclass)&lt;br /&gt;
				:cssText(rowArgs.rowstyle)&lt;br /&gt;
				:tag(&#039;th&#039;)&lt;br /&gt;
					:attr(&#039;colspan&#039;, &#039;2&#039;)&lt;br /&gt;
					:addClass(&#039;infobox-header&#039;)&lt;br /&gt;
					:addClass(rowArgs.class)&lt;br /&gt;
					:addClass(args.headerclass)&lt;br /&gt;
					-- @deprecated next; target .infobox-&amp;lt;name&amp;gt; .infobox-header&lt;br /&gt;
					:cssText(args.headerstyle)&lt;br /&gt;
					:cssText(rowArgs.rowcellstyle)&lt;br /&gt;
					:wikitext(fixChildBoxes(rowArgs.header, &#039;th&#039;))&lt;br /&gt;
		if rowArgs.data and not yesno(args.decat) then&lt;br /&gt;
			root:wikitext(&lt;br /&gt;
				&#039;[[Category:Pages using infobox templates with ignored data cells]]&#039;&lt;br /&gt;
			)&lt;br /&gt;
		end&lt;br /&gt;
	elseif rowArgs.data and rowArgs.data:gsub(category_in_empty_row_pattern, &#039;&#039;):match(&#039;^%S&#039;) then&lt;br /&gt;
		has_rows = true&lt;br /&gt;
		has_list_class({ rowArgs.rowclass, rowArgs.class })&lt;br /&gt;
		&lt;br /&gt;
		local row = root:tag(&#039;tr&#039;)&lt;br /&gt;
		row:addClass(rowArgs.rowclass)&lt;br /&gt;
		row:cssText(rowArgs.rowstyle)&lt;br /&gt;
		if rowArgs.label then&lt;br /&gt;
			row&lt;br /&gt;
				:tag(&#039;th&#039;)&lt;br /&gt;
					:attr(&#039;scope&#039;, &#039;row&#039;)&lt;br /&gt;
					:addClass(&#039;infobox-label&#039;)&lt;br /&gt;
					-- @deprecated next; target .infobox-&amp;lt;name&amp;gt; .infobox-label&lt;br /&gt;
					:cssText(args.labelstyle)&lt;br /&gt;
					:cssText(rowArgs.rowcellstyle)&lt;br /&gt;
					:wikitext(rowArgs.label)&lt;br /&gt;
					:done()&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local dataCell = row:tag(&#039;td&#039;)&lt;br /&gt;
		dataCell&lt;br /&gt;
			:attr(&#039;colspan&#039;, not rowArgs.label and &#039;2&#039; or nil)&lt;br /&gt;
			:addClass(not rowArgs.label and &#039;infobox-full-data&#039; or &#039;infobox-data&#039;)&lt;br /&gt;
			:addClass(rowArgs.class)&lt;br /&gt;
			-- @deprecated next; target .infobox-&amp;lt;name&amp;gt; .infobox(-full)-data&lt;br /&gt;
			:cssText(rowArgs.datastyle)&lt;br /&gt;
			:cssText(rowArgs.rowcellstyle)&lt;br /&gt;
			:wikitext(fixChildBoxes(rowArgs.data, &#039;td&#039;))&lt;br /&gt;
	else&lt;br /&gt;
		table.insert(empty_row_categories, rowArgs.data or &#039;&#039;)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderTitle()&lt;br /&gt;
	if not args.title then return end&lt;br /&gt;
&lt;br /&gt;
	has_rows = true&lt;br /&gt;
	has_list_class({args.titleclass})&lt;br /&gt;
	&lt;br /&gt;
	root&lt;br /&gt;
		:tag(&#039;caption&#039;)&lt;br /&gt;
			:addClass(&#039;infobox-title&#039;)&lt;br /&gt;
			:addClass(args.titleclass)&lt;br /&gt;
			-- @deprecated next; target .infobox-&amp;lt;name&amp;gt; .infobox-title&lt;br /&gt;
			:cssText(args.titlestyle)&lt;br /&gt;
			:wikitext(args.title)&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderAboveRow()&lt;br /&gt;
	if not args.above then return end&lt;br /&gt;
&lt;br /&gt;
	has_rows = true&lt;br /&gt;
	has_list_class({ args.aboveclass })&lt;br /&gt;
	&lt;br /&gt;
	root&lt;br /&gt;
		:tag(&#039;tr&#039;)&lt;br /&gt;
			:tag(&#039;th&#039;)&lt;br /&gt;
				:attr(&#039;colspan&#039;, &#039;2&#039;)&lt;br /&gt;
				:addClass(&#039;infobox-above&#039;)&lt;br /&gt;
				:addClass(args.aboveclass)&lt;br /&gt;
				-- @deprecated next; target .infobox-&amp;lt;name&amp;gt; .infobox-above&lt;br /&gt;
				:cssText(args.abovestyle)&lt;br /&gt;
				:wikitext(fixChildBoxes(args.above,&#039;th&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderBelowRow()&lt;br /&gt;
	if not args.below then return end&lt;br /&gt;
&lt;br /&gt;
	has_rows = true&lt;br /&gt;
	has_list_class({ args.belowclass })&lt;br /&gt;
	&lt;br /&gt;
	root&lt;br /&gt;
		:tag(&#039;tr&#039;)&lt;br /&gt;
			:tag(&#039;td&#039;)&lt;br /&gt;
				:attr(&#039;colspan&#039;, &#039;2&#039;)&lt;br /&gt;
				:addClass(&#039;infobox-below&#039;)&lt;br /&gt;
				:addClass(args.belowclass)&lt;br /&gt;
				-- @deprecated next; target .infobox-&amp;lt;name&amp;gt; .infobox-below&lt;br /&gt;
				:cssText(args.belowstyle)&lt;br /&gt;
				:wikitext(fixChildBoxes(args.below,&#039;td&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function addSubheaderRow(subheaderArgs)&lt;br /&gt;
	if subheaderArgs.data and&lt;br /&gt;
		subheaderArgs.data:gsub(category_in_empty_row_pattern, &#039;&#039;):match(&#039;^%S&#039;) then&lt;br /&gt;
		has_rows = true&lt;br /&gt;
		has_list_class({ subheaderArgs.rowclass, subheaderArgs.class })&lt;br /&gt;
		&lt;br /&gt;
		local row = root:tag(&#039;tr&#039;)&lt;br /&gt;
		row:addClass(subheaderArgs.rowclass)&lt;br /&gt;
&lt;br /&gt;
		local dataCell = row:tag(&#039;td&#039;)&lt;br /&gt;
		dataCell&lt;br /&gt;
			:attr(&#039;colspan&#039;, &#039;2&#039;)&lt;br /&gt;
			:addClass(&#039;infobox-subheader&#039;)&lt;br /&gt;
			:addClass(subheaderArgs.class)&lt;br /&gt;
			:cssText(subheaderArgs.datastyle)&lt;br /&gt;
			:cssText(subheaderArgs.rowcellstyle)&lt;br /&gt;
			:wikitext(fixChildBoxes(subheaderArgs.data, &#039;td&#039;))&lt;br /&gt;
	else&lt;br /&gt;
		table.insert(empty_row_categories, subheaderArgs.data or &#039;&#039;)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderSubheaders()&lt;br /&gt;
	if args.subheader then&lt;br /&gt;
		args.subheader1 = args.subheader&lt;br /&gt;
	end&lt;br /&gt;
	if args.subheaderrowclass then&lt;br /&gt;
		args.subheaderrowclass1 = args.subheaderrowclass&lt;br /&gt;
	end&lt;br /&gt;
	local subheadernums = getArgNums(&#039;subheader&#039;)&lt;br /&gt;
	for k, num in ipairs(subheadernums) do&lt;br /&gt;
		addSubheaderRow({&lt;br /&gt;
			data = args[&#039;subheader&#039; .. tostring(num)],&lt;br /&gt;
			-- @deprecated next; target .infobox-&amp;lt;name&amp;gt; .infobox-subheader&lt;br /&gt;
			datastyle = args.subheaderstyle,&lt;br /&gt;
			rowcellstyle = args[&#039;subheaderstyle&#039; .. tostring(num)],&lt;br /&gt;
			class = args.subheaderclass,&lt;br /&gt;
			rowclass = args[&#039;subheaderrowclass&#039; .. tostring(num)]&lt;br /&gt;
		})&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function addImageRow(imageArgs)&lt;br /&gt;
&lt;br /&gt;
	if imageArgs.data and&lt;br /&gt;
		imageArgs.data:gsub(category_in_empty_row_pattern, &#039;&#039;):match(&#039;^%S&#039;) then&lt;br /&gt;
&lt;br /&gt;
		has_rows = true&lt;br /&gt;
		has_list_class({ imageArgs.rowclass, imageArgs.class })&lt;br /&gt;
		&lt;br /&gt;
		local row = root:tag(&#039;tr&#039;)&lt;br /&gt;
		row:addClass(imageArgs.rowclass)&lt;br /&gt;
&lt;br /&gt;
		local dataCell = row:tag(&#039;td&#039;)&lt;br /&gt;
		dataCell&lt;br /&gt;
			:attr(&#039;colspan&#039;, &#039;2&#039;)&lt;br /&gt;
			:addClass(&#039;infobox-image&#039;)&lt;br /&gt;
			:addClass(imageArgs.class)&lt;br /&gt;
			:cssText(imageArgs.datastyle)&lt;br /&gt;
			:wikitext(fixChildBoxes(imageArgs.data, &#039;td&#039;))&lt;br /&gt;
	else&lt;br /&gt;
		table.insert(empty_row_categories, imageArgs.data or &#039;&#039;)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderImages()&lt;br /&gt;
	if args.image then&lt;br /&gt;
		args.image1 = args.image&lt;br /&gt;
	end&lt;br /&gt;
	if args.caption then&lt;br /&gt;
		args.caption1 = args.caption&lt;br /&gt;
	end&lt;br /&gt;
	local imagenums = getArgNums(&#039;image&#039;)&lt;br /&gt;
	for k, num in ipairs(imagenums) do&lt;br /&gt;
		local caption = args[&#039;caption&#039; .. tostring(num)]&lt;br /&gt;
		local data = mw.html.create():wikitext(args[&#039;image&#039; .. tostring(num)])&lt;br /&gt;
		if caption then&lt;br /&gt;
			data&lt;br /&gt;
				:tag(&#039;div&#039;)&lt;br /&gt;
					:addClass(&#039;infobox-caption&#039;)&lt;br /&gt;
					-- @deprecated next; target .infobox-&amp;lt;name&amp;gt; .infobox-caption&lt;br /&gt;
					:cssText(args.captionstyle)&lt;br /&gt;
					:wikitext(caption)&lt;br /&gt;
		end&lt;br /&gt;
		addImageRow({&lt;br /&gt;
			data = tostring(data),&lt;br /&gt;
			-- @deprecated next; target .infobox-&amp;lt;name&amp;gt; .infobox-image&lt;br /&gt;
			datastyle = args.imagestyle,&lt;br /&gt;
			class = args.imageclass,&lt;br /&gt;
			rowclass = args[&#039;imagerowclass&#039; .. tostring(num)]&lt;br /&gt;
		})&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- When autoheaders are turned on, preprocesses the rows&lt;br /&gt;
local function preprocessRows()&lt;br /&gt;
	if not args.autoheaders then return end&lt;br /&gt;
	&lt;br /&gt;
	local rownums = union(getArgNums(&#039;header&#039;), getArgNums(&#039;data&#039;))&lt;br /&gt;
	table.sort(rownums)&lt;br /&gt;
	local lastheader&lt;br /&gt;
	for k, num in ipairs(rownums) do&lt;br /&gt;
		if args[&#039;header&#039; .. tostring(num)] then&lt;br /&gt;
			if lastheader then&lt;br /&gt;
				args[&#039;header&#039; .. tostring(lastheader)] = nil&lt;br /&gt;
			end&lt;br /&gt;
			lastheader = num&lt;br /&gt;
		elseif args[&#039;data&#039; .. tostring(num)] and&lt;br /&gt;
			args[&#039;data&#039; .. tostring(num)]:gsub(&lt;br /&gt;
				category_in_empty_row_pattern, &#039;&#039;&lt;br /&gt;
			):match(&#039;^%S&#039;) then&lt;br /&gt;
			local data = args[&#039;data&#039; .. tostring(num)]&lt;br /&gt;
			if data:gsub(category_in_empty_row_pattern, &#039;&#039;):match(&#039;%S&#039;) then&lt;br /&gt;
				lastheader = nil&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if lastheader then&lt;br /&gt;
		args[&#039;header&#039; .. tostring(lastheader)] = nil&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Gets the union of the header and data argument numbers,&lt;br /&gt;
-- and renders them all in order&lt;br /&gt;
local function renderRows()&lt;br /&gt;
&lt;br /&gt;
	local rownums = union(getArgNums(&#039;header&#039;), getArgNums(&#039;data&#039;))&lt;br /&gt;
	table.sort(rownums)&lt;br /&gt;
	for k, num in ipairs(rownums) do&lt;br /&gt;
		addRow({&lt;br /&gt;
			header = args[&#039;header&#039; .. tostring(num)],&lt;br /&gt;
			label = args[&#039;label&#039; .. tostring(num)],&lt;br /&gt;
			data = args[&#039;data&#039; .. tostring(num)],&lt;br /&gt;
			datastyle = args.datastyle,&lt;br /&gt;
			class = args[&#039;class&#039; .. tostring(num)],&lt;br /&gt;
			rowclass = args[&#039;rowclass&#039; .. tostring(num)],&lt;br /&gt;
			-- @deprecated next; target .infobox-&amp;lt;name&amp;gt; rowclass&lt;br /&gt;
			rowstyle = args[&#039;rowstyle&#039; .. tostring(num)],&lt;br /&gt;
			rowcellstyle = args[&#039;rowcellstyle&#039; .. tostring(num)]&lt;br /&gt;
		})&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderNavBar()&lt;br /&gt;
	if not args.name then return end&lt;br /&gt;
&lt;br /&gt;
	has_rows = true&lt;br /&gt;
	root&lt;br /&gt;
		:tag(&#039;tr&#039;)&lt;br /&gt;
			:tag(&#039;td&#039;)&lt;br /&gt;
				:attr(&#039;colspan&#039;, &#039;2&#039;)&lt;br /&gt;
				:addClass(&#039;infobox-navbar&#039;)&lt;br /&gt;
				:wikitext(require(&#039;Module:Navbar&#039;)._navbar{&lt;br /&gt;
					args.name,&lt;br /&gt;
					mini = 1,&lt;br /&gt;
				})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderItalicTitle()&lt;br /&gt;
	local italicTitle = args[&#039;italic title&#039;] and mw.ustring.lower(args[&#039;italic title&#039;])&lt;br /&gt;
	if italicTitle == &#039;&#039; or italicTitle == &#039;force&#039; or italicTitle == &#039;yes&#039; then&lt;br /&gt;
		root:wikitext(require(&#039;Module:Italic title&#039;)._main({}))&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Categories in otherwise empty rows are collected in empty_row_categories.&lt;br /&gt;
-- This function adds them to the module output. It is not affected by&lt;br /&gt;
-- args.decat because this module should not prevent module-external categories&lt;br /&gt;
-- from rendering.&lt;br /&gt;
local function renderEmptyRowCategories()&lt;br /&gt;
	for _, s in ipairs(empty_row_categories) do&lt;br /&gt;
		root:wikitext(s)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Render tracking categories. args.decat == turns off tracking categories.&lt;br /&gt;
local function renderTrackingCategories()&lt;br /&gt;
	if yesno(args.decat) then return end&lt;br /&gt;
	if args.child == &#039;yes&#039; then&lt;br /&gt;
		if args.title then&lt;br /&gt;
			root:wikitext(&lt;br /&gt;
				&#039;[[Category:Pages using embedded infobox templates with the title parameter]]&#039;&lt;br /&gt;
			)&lt;br /&gt;
		end&lt;br /&gt;
	elseif #(getArgNums(&#039;data&#039;)) == 0 and mw.title.getCurrentTitle().namespace == 0 then&lt;br /&gt;
		root:wikitext(&#039;[[Category:Articles using infobox templates with no data rows]]&#039;)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[=[&lt;br /&gt;
Loads the templatestyles for the infobox.&lt;br /&gt;
&lt;br /&gt;
TODO: FINISH loading base templatestyles here rather than in&lt;br /&gt;
MediaWiki:Common.css. There are 4-5000 pages with &#039;raw&#039; infobox tables.&lt;br /&gt;
See [[Mediawiki_talk:Common.css/to_do#Infobox]] and/or come help :).&lt;br /&gt;
When we do this we should clean up the inline CSS below too.&lt;br /&gt;
Will have to do some bizarre conversion category like with sidebar.&lt;br /&gt;
&lt;br /&gt;
]=]&lt;br /&gt;
local function loadTemplateStyles()&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
	&lt;br /&gt;
	local hlist_templatestyles = &#039;&#039;&lt;br /&gt;
	if lists.hlist_t.found then&lt;br /&gt;
		hlist_templatestyles = frame:extensionTag{&lt;br /&gt;
			name = &#039;templatestyles&#039;, args = { src = lists.hlist_t.styles }&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local plainlist_templatestyles = &#039;&#039;&lt;br /&gt;
	if lists.plainlist_t.found then&lt;br /&gt;
		plainlist_templatestyles = frame:extensionTag{&lt;br /&gt;
			name = &#039;templatestyles&#039;, args = { src = lists.plainlist_t.styles }&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- See function description&lt;br /&gt;
	local base_templatestyles = frame:extensionTag{&lt;br /&gt;
		name = &#039;templatestyles&#039;, args = { src = &#039;Module:Infobox/styles.css&#039; }&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	local templatestyles = &#039;&#039;&lt;br /&gt;
	if args[&#039;templatestyles&#039;] then&lt;br /&gt;
		templatestyles = frame:extensionTag{&lt;br /&gt;
			name = &#039;templatestyles&#039;, args = { src = args[&#039;templatestyles&#039;] }&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local child_templatestyles = &#039;&#039;&lt;br /&gt;
	if args[&#039;child templatestyles&#039;] then&lt;br /&gt;
		child_templatestyles = frame:extensionTag{&lt;br /&gt;
			name = &#039;templatestyles&#039;, args = { src = args[&#039;child templatestyles&#039;] }&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local grandchild_templatestyles = &#039;&#039;&lt;br /&gt;
	if args[&#039;grandchild templatestyles&#039;] then&lt;br /&gt;
		grandchild_templatestyles = frame:extensionTag{&lt;br /&gt;
			name = &#039;templatestyles&#039;, args = { src = args[&#039;grandchild templatestyles&#039;] }&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return table.concat({&lt;br /&gt;
		-- hlist -&amp;gt; plainlist -&amp;gt; base is best-effort to preserve old Common.css ordering.&lt;br /&gt;
		-- this ordering is not a guarantee because the rows of interest invoking&lt;br /&gt;
		-- each class may not be on a specific page&lt;br /&gt;
		hlist_templatestyles,&lt;br /&gt;
		plainlist_templatestyles,&lt;br /&gt;
		base_templatestyles,&lt;br /&gt;
		templatestyles,&lt;br /&gt;
		child_templatestyles,&lt;br /&gt;
		grandchild_templatestyles&lt;br /&gt;
	})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- common functions between the child and non child cases&lt;br /&gt;
local function structure_infobox_common()&lt;br /&gt;
	renderSubheaders()&lt;br /&gt;
	renderImages()&lt;br /&gt;
	preprocessRows()&lt;br /&gt;
	renderRows()&lt;br /&gt;
	renderBelowRow()&lt;br /&gt;
	renderNavBar()&lt;br /&gt;
	renderItalicTitle()&lt;br /&gt;
	renderEmptyRowCategories()&lt;br /&gt;
	renderTrackingCategories()&lt;br /&gt;
	cleanInfobox()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Specify the overall layout of the infobox, with special settings if the&lt;br /&gt;
-- infobox is used as a &#039;child&#039; inside another infobox.&lt;br /&gt;
local function _infobox()&lt;br /&gt;
	if args.child ~= &#039;yes&#039; then&lt;br /&gt;
		root = mw.html.create(&#039;table&#039;)&lt;br /&gt;
&lt;br /&gt;
		root&lt;br /&gt;
			:addClass(args.subbox == &#039;yes&#039; and &#039;infobox-subbox&#039; or &#039;infobox&#039;)&lt;br /&gt;
			:addClass(args.bodyclass)&lt;br /&gt;
			-- @deprecated next; target .infobox-&amp;lt;name&amp;gt;&lt;br /&gt;
			:cssText(args.bodystyle)&lt;br /&gt;
		&lt;br /&gt;
		has_list_class({ args.bodyclass })&lt;br /&gt;
&lt;br /&gt;
		renderTitle()&lt;br /&gt;
		renderAboveRow()&lt;br /&gt;
	else&lt;br /&gt;
		root = mw.html.create()&lt;br /&gt;
&lt;br /&gt;
		root&lt;br /&gt;
			:wikitext(args.title)&lt;br /&gt;
	end&lt;br /&gt;
	structure_infobox_common()&lt;br /&gt;
	&lt;br /&gt;
	return loadTemplateStyles() .. root&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- If the argument exists and isn&#039;t blank, add it to the argument table.&lt;br /&gt;
-- Blank arguments are treated as nil to match the behaviour of ParserFunctions.&lt;br /&gt;
local function preprocessSingleArg(argName)&lt;br /&gt;
	if origArgs[argName] and origArgs[argName] ~= &#039;&#039; then&lt;br /&gt;
		args[argName] = origArgs[argName]&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Assign the parameters with the given prefixes to the args table, in order, in&lt;br /&gt;
-- batches of the step size specified. This is to prevent references etc. from&lt;br /&gt;
-- appearing in the wrong order. The prefixTable should be an array containing&lt;br /&gt;
-- tables, each of which has two possible fields, a &amp;quot;prefix&amp;quot; string and a&lt;br /&gt;
-- &amp;quot;depend&amp;quot; table. The function always parses parameters containing the &amp;quot;prefix&amp;quot;&lt;br /&gt;
-- string, but only parses parameters in the &amp;quot;depend&amp;quot; table if the prefix&lt;br /&gt;
-- parameter is present and non-blank.&lt;br /&gt;
local function preprocessArgs(prefixTable, step)&lt;br /&gt;
	if type(prefixTable) ~= &#039;table&#039; then&lt;br /&gt;
		error(&amp;quot;Non-table value detected for the prefix table&amp;quot;, 2)&lt;br /&gt;
	end&lt;br /&gt;
	if type(step) ~= &#039;number&#039; then&lt;br /&gt;
		error(&amp;quot;Invalid step value detected&amp;quot;, 2)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Get arguments without a number suffix, and check for bad input.&lt;br /&gt;
	for i,v in ipairs(prefixTable) do&lt;br /&gt;
		if type(v) ~= &#039;table&#039; or type(v.prefix) ~= &amp;quot;string&amp;quot; or&lt;br /&gt;
			(v.depend and type(v.depend) ~= &#039;table&#039;) then&lt;br /&gt;
			error(&#039;Invalid input detected to preprocessArgs prefix table&#039;, 2)&lt;br /&gt;
		end&lt;br /&gt;
		preprocessSingleArg(v.prefix)&lt;br /&gt;
		-- Only parse the depend parameter if the prefix parameter is present&lt;br /&gt;
		-- and not blank.&lt;br /&gt;
		if args[v.prefix] and v.depend then&lt;br /&gt;
			for j, dependValue in ipairs(v.depend) do&lt;br /&gt;
				if type(dependValue) ~= &#039;string&#039; then&lt;br /&gt;
					error(&#039;Invalid &amp;quot;depend&amp;quot; parameter value detected in preprocessArgs&#039;)&lt;br /&gt;
				end&lt;br /&gt;
				preprocessSingleArg(dependValue)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Get arguments with number suffixes.&lt;br /&gt;
	local a = 1 -- Counter variable.&lt;br /&gt;
	local moreArgumentsExist = true&lt;br /&gt;
	while moreArgumentsExist == true do&lt;br /&gt;
		moreArgumentsExist = false&lt;br /&gt;
		for i = a, a + step - 1 do&lt;br /&gt;
			for j,v in ipairs(prefixTable) do&lt;br /&gt;
				local prefixArgName = v.prefix .. tostring(i)&lt;br /&gt;
				if origArgs[prefixArgName] then&lt;br /&gt;
					-- Do another loop if any arguments are found, even blank ones.&lt;br /&gt;
					moreArgumentsExist = true&lt;br /&gt;
					preprocessSingleArg(prefixArgName)&lt;br /&gt;
				end&lt;br /&gt;
				-- Process the depend table if the prefix argument is present&lt;br /&gt;
				-- and not blank, or we are processing &amp;quot;prefix1&amp;quot; and &amp;quot;prefix&amp;quot; is&lt;br /&gt;
				-- present and not blank, and if the depend table is present.&lt;br /&gt;
				if v.depend and (args[prefixArgName] or (i == 1 and args[v.prefix])) then&lt;br /&gt;
					for j,dependValue in ipairs(v.depend) do&lt;br /&gt;
						local dependArgName = dependValue .. tostring(i)&lt;br /&gt;
						preprocessSingleArg(dependArgName)&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		a = a + step&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Parse the data parameters in the same order that the old {{infobox}} did, so&lt;br /&gt;
-- that references etc. will display in the expected places. Parameters that&lt;br /&gt;
-- depend on another parameter are only processed if that parameter is present,&lt;br /&gt;
-- to avoid phantom references appearing in article reference lists.&lt;br /&gt;
local function parseDataParameters()&lt;br /&gt;
&lt;br /&gt;
	preprocessSingleArg(&#039;autoheaders&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;child&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;bodyclass&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;subbox&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;bodystyle&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;title&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;titleclass&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;titlestyle&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;above&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;aboveclass&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;abovestyle&#039;)&lt;br /&gt;
	preprocessArgs({&lt;br /&gt;
		{prefix = &#039;subheader&#039;, depend = {&#039;subheaderstyle&#039;, &#039;subheaderrowclass&#039;}}&lt;br /&gt;
	}, 10)&lt;br /&gt;
	preprocessSingleArg(&#039;subheaderstyle&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;subheaderclass&#039;)&lt;br /&gt;
	preprocessArgs({&lt;br /&gt;
		{prefix = &#039;image&#039;, depend = {&#039;caption&#039;, &#039;imagerowclass&#039;}}&lt;br /&gt;
	}, 10)&lt;br /&gt;
	preprocessSingleArg(&#039;captionstyle&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;imagestyle&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;imageclass&#039;)&lt;br /&gt;
	preprocessArgs({&lt;br /&gt;
		{prefix = &#039;header&#039;},&lt;br /&gt;
		{prefix = &#039;data&#039;, depend = {&#039;label&#039;}},&lt;br /&gt;
		{prefix = &#039;rowclass&#039;},&lt;br /&gt;
		{prefix = &#039;rowstyle&#039;},&lt;br /&gt;
		{prefix = &#039;rowcellstyle&#039;},&lt;br /&gt;
		{prefix = &#039;class&#039;}&lt;br /&gt;
	}, 50)&lt;br /&gt;
	preprocessSingleArg(&#039;headerclass&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;headerstyle&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;labelstyle&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;datastyle&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;below&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;belowclass&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;belowstyle&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;name&#039;)&lt;br /&gt;
	-- different behaviour for italics if blank or absent&lt;br /&gt;
	args[&#039;italic title&#039;] = origArgs[&#039;italic title&#039;]&lt;br /&gt;
	preprocessSingleArg(&#039;decat&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;templatestyles&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;child templatestyles&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;grandchild templatestyles&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- If called via #invoke, use the args passed into the invoking template.&lt;br /&gt;
-- Otherwise, for testing purposes, assume args are being passed directly in.&lt;br /&gt;
function p.infobox(frame)&lt;br /&gt;
	if frame == mw.getCurrentFrame() then&lt;br /&gt;
		origArgs = frame:getParent().args&lt;br /&gt;
	else&lt;br /&gt;
		origArgs = frame&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	parseDataParameters()&lt;br /&gt;
	&lt;br /&gt;
	return _infobox()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- For calling via #invoke within a template&lt;br /&gt;
function p.infoboxTemplate(frame)&lt;br /&gt;
	origArgs = {}&lt;br /&gt;
	for k,v in pairs(frame.args) do origArgs[k] = mw.text.trim(v) end&lt;br /&gt;
	&lt;br /&gt;
	parseDataParameters()&lt;br /&gt;
	&lt;br /&gt;
	return _infobox()&lt;br /&gt;
end&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Template:Infobox&amp;diff=6</id>
		<title>Template:Infobox</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Template:Infobox&amp;diff=6"/>
		<updated>2025-12-24T14:18:21Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#invoke:Infobox|infobox}}&amp;lt;includeonly&amp;gt;{{template other|{{#ifeq:{{PAGENAME}}|Infobox||{{#ifeq:{{str left|{{SUBPAGENAME}}|7}}|Infobox|[[Category:Infobox templates|{{remove first word|{{SUBPAGENAME}}}}]]}}}}|}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;!-- Categories go in the /doc subpage, and interwikis go in Wikidata. --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Main_Page&amp;diff=3</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Main_Page&amp;diff=3"/>
		<updated>2025-12-24T14:02:28Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Initial Commit&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Welcome the Duke Syndicate Wiki =&lt;br /&gt;
Welcome to the greatest (by some metric) aggregation of people and the human psyche. The sound of the massive.&lt;br /&gt;
&lt;br /&gt;
== Services ==&lt;br /&gt;
* Git: https://git.dukesyndicate.org/&lt;br /&gt;
* Discord: https://discord.gg/F3EVMX5uYE&lt;br /&gt;
&lt;br /&gt;
== Significant Figures ==&lt;br /&gt;
=== illegitimate-egg ===&lt;br /&gt;
The operator of the [[Duke Syndicate]] server and current system administrator. One of the two founders. Responsible for the [[Duke-bot]], git, discord and more.&lt;br /&gt;
&lt;br /&gt;
=== williamist ===&lt;br /&gt;
Co-founder of the [[Duke Syndicate]]. Responsible for preventing [https://en.wikipedia.org/wiki/Omega_Point Omega Point].&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
	<entry>
		<id>https://dukesyndicate.org/w/index.php?title=Main_Page&amp;diff=2</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://dukesyndicate.org/w/index.php?title=Main_Page&amp;diff=2"/>
		<updated>2025-12-24T11:46:13Z</updated>

		<summary type="html">&lt;p&gt;Illegitimate-egg: Add test&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;strong&amp;gt;MediaWiki has been installed.&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Consult the [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents User&#039;s Guide] for information on using the wiki software.&lt;br /&gt;
&lt;br /&gt;
== Getting started ==&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]&lt;br /&gt;
* [https://lists.wikimedia.org/postorius/lists/mediawiki-announce.lists.wikimedia.org/ MediaWiki release mailing list]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Localise MediaWiki for your language]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Learn how to combat spam on your wiki]&lt;br /&gt;
&lt;br /&gt;
Maths extension rendering test:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;E=mc^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\binom{n}{r} = \frac{n!}{(n-r)!r!}&amp;lt;/math&amp;gt;&lt;/div&gt;</summary>
		<author><name>Illegitimate-egg</name></author>
	</entry>
</feed>