﻿<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://scholarlywiki.org/index.php?action=history&amp;feed=atom&amp;title=Module%3APhysicsQC</id>
	<title>Module:PhysicsQC - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://scholarlywiki.org/index.php?action=history&amp;feed=atom&amp;title=Module%3APhysicsQC"/>
	<link rel="alternate" type="text/html" href="https://scholarlywiki.org/index.php?title=Module:PhysicsQC&amp;action=history"/>
	<updated>2026-05-14T00:12:24Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.1</generator>
	<entry>
		<id>https://scholarlywiki.org/index.php?title=Module:PhysicsQC&amp;diff=2161&amp;oldid=prev</id>
		<title>Maintenance script: Fix gallery thumbnail sizing</title>
		<link rel="alternate" type="text/html" href="https://scholarlywiki.org/index.php?title=Module:PhysicsQC&amp;diff=2161&amp;oldid=prev"/>
		<updated>2026-05-13T18:44:52Z</updated>

		<summary type="html">&lt;p&gt;Fix gallery thumbnail sizing&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 18:44, 13 May 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l544&quot;&gt;Line 544:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 544:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;local function renderGalleryCard(page, file)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;local function normalizeGalleryWidth(value)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;	local width = tonumber(value) or 150&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;	if width &amp;lt; 40 then&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;		width = 40&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;	elseif width &amp;gt; 400 then&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;		width = 400&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;	end&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;	return math.floor(width)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;end&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;local function renderGalleryCard(page, file&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;, width&lt;/ins&gt;)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	local label = stripNamespaceForLabel(page)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	local label = stripNamespaceForLabel(page)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	local out = {}&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	local out = {}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l550&quot;&gt;Line 550:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 562:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	table.insert(out, &amp;#039;&amp;lt;div style=&amp;quot;display:inline-block; vertical-align:top; width:180px; margin:6px; padding:5px; border:1px solid #e0d890; background:#fff8cc; text-align:center;&amp;quot;&amp;gt;&amp;#039;)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	table.insert(out, &amp;#039;&amp;lt;div style=&amp;quot;display:inline-block; vertical-align:top; width:180px; margin:6px; padding:5px; border:1px solid #e0d890; background:#fff8cc; text-align:center;&amp;quot;&amp;gt;&amp;#039;)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	if file then&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	if file then&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;		-- Restore gallery image rendering.&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		table.insert(out, &#039;[[File:&#039; .. file .. &#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|&#039; .. width .. &#039;px&lt;/ins&gt;]]&#039;)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;		-- No forced frameless size here.&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		table.insert(out, &#039;[[File:&#039; .. file .. &#039;]]&#039;)&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	else&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	else&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		table.insert(out, &amp;#039;&amp;lt;div style=&amp;quot;height:120px; display:flex; align-items:center; justify-content:center; border:1px dashed #c0a850; background:#fffdf0; color:#900; font-size:90%;&amp;quot;&amp;gt;No image found&amp;lt;/div&amp;gt;&amp;#039;)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		table.insert(out, &amp;#039;&amp;lt;div style=&amp;quot;height:120px; display:flex; align-items:center; justify-content:center; border:1px dashed #c0a850; background:#fffdf0; color:#900; font-size:90%;&amp;quot;&amp;gt;No image found&amp;lt;/div&amp;gt;&amp;#039;)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l570&quot;&gt;Line 570:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 580:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	local args = frame.args or {}&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	local args = frame.args or {}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	local dataPage = args[1] or &amp;#039;Physics:Quantum basics/See also&amp;#039;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	local dataPage = args[1] or &amp;#039;Physics:Quantum basics/See also&amp;#039;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;	local width = normalizeGalleryWidth(args.width or args[2])&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	local content = getPageContent(dataPage)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	local content = getPageContent(dataPage)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l590&quot;&gt;Line 590:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 601:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		table.insert(out, renderGalleryCard(page, file))&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		table.insert(out, renderGalleryCard(page, file&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;, width&lt;/ins&gt;))&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://scholarlywiki.org/index.php?title=Module:PhysicsQC&amp;diff=558&amp;oldid=prev</id>
		<title>imported&gt;WikiHarold at 06:49, 12 May 2026</title>
		<link rel="alternate" type="text/html" href="https://scholarlywiki.org/index.php?title=Module:PhysicsQC&amp;diff=558&amp;oldid=prev"/>
		<updated>2026-05-12T06:49:53Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 06:49, 12 May 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>imported&gt;WikiHarold</name></author>
	</entry>
	<entry>
		<id>https://scholarlywiki.org/index.php?title=Module:PhysicsQC&amp;diff=67&amp;oldid=prev</id>
		<title>imported&gt;WikiHarold at 06:49, 12 May 2026</title>
		<link rel="alternate" type="text/html" href="https://scholarlywiki.org/index.php?title=Module:PhysicsQC&amp;diff=67&amp;oldid=prev"/>
		<updated>2026-05-12T06:49:53Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://scholarlywiki.org/index.php?title=Module:PhysicsQC&amp;amp;diff=67&amp;amp;oldid=13&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>imported&gt;WikiHarold</name></author>
	</entry>
	<entry>
		<id>https://scholarlywiki.org/index.php?title=Module:PhysicsQC&amp;diff=13&amp;oldid=prev</id>
		<title>Harold: Created page with &quot;local p = {}  -- ========================= -- Styling configuration -- =========================  local STYLE = {}  STYLE.sectionHeader =     &quot;font-family:&#039;Segoe UI&#039;,&#039;Helvetica Neue&#039;,Arial,sans-serif;&quot; ..     &quot;font-weight:400;&quot; ..     &quot;font-size:100%;&quot; ..     &quot;color:#000;&quot; ..     &quot;display:inline;&quot; ..     &quot;line-height:1.2em;&quot;  STYLE.sectionBox =     &quot;font-family:&#039;Segoe UI&#039;,&#039;Helvetica Neue&#039;,Arial,sans-serif;&quot; ..     &quot;font-size:90%;&quot; ..     &quot;color:#000;&quot; ..     &quot;border:0;&quot;...&quot;</title>
		<link rel="alternate" type="text/html" href="https://scholarlywiki.org/index.php?title=Module:PhysicsQC&amp;diff=13&amp;oldid=prev"/>
		<updated>2026-05-09T09:18:10Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;local p = {}  -- ========================= -- Styling configuration -- =========================  local STYLE = {}  STYLE.sectionHeader =     &amp;quot;font-family:&amp;#039;Segoe UI&amp;#039;,&amp;#039;Helvetica Neue&amp;#039;,Arial,sans-serif;&amp;quot; ..     &amp;quot;font-weight:400;&amp;quot; ..     &amp;quot;font-size:100%;&amp;quot; ..     &amp;quot;color:#000;&amp;quot; ..     &amp;quot;display:inline;&amp;quot; ..     &amp;quot;line-height:1.2em;&amp;quot;  STYLE.sectionBox =     &amp;quot;font-family:&amp;#039;Segoe UI&amp;#039;,&amp;#039;Helvetica Neue&amp;#039;,Arial,sans-serif;&amp;quot; ..     &amp;quot;font-size:90%;&amp;quot; ..     &amp;quot;color:#000;&amp;quot; ..     &amp;quot;border:0;&amp;quot;...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
-- =========================&lt;br /&gt;
-- Styling configuration&lt;br /&gt;
-- =========================&lt;br /&gt;
&lt;br /&gt;
local STYLE = {}&lt;br /&gt;
&lt;br /&gt;
STYLE.sectionHeader =&lt;br /&gt;
    &amp;quot;font-family:&amp;#039;Segoe UI&amp;#039;,&amp;#039;Helvetica Neue&amp;#039;,Arial,sans-serif;&amp;quot; ..&lt;br /&gt;
    &amp;quot;font-weight:400;&amp;quot; ..&lt;br /&gt;
    &amp;quot;font-size:100%;&amp;quot; ..&lt;br /&gt;
    &amp;quot;color:#000;&amp;quot; ..&lt;br /&gt;
    &amp;quot;display:inline;&amp;quot; ..&lt;br /&gt;
    &amp;quot;line-height:1.2em;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
STYLE.sectionBox =&lt;br /&gt;
    &amp;quot;font-family:&amp;#039;Segoe UI&amp;#039;,&amp;#039;Helvetica Neue&amp;#039;,Arial,sans-serif;&amp;quot; ..&lt;br /&gt;
    &amp;quot;font-size:90%;&amp;quot; ..&lt;br /&gt;
    &amp;quot;color:#000;&amp;quot; ..&lt;br /&gt;
    &amp;quot;border:0;&amp;quot; ..&lt;br /&gt;
    &amp;quot;background:transparent;&amp;quot; ..&lt;br /&gt;
    &amp;quot;padding:0;&amp;quot; ..&lt;br /&gt;
    &amp;quot;margin:0.05em 0;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
STYLE.backLink =&lt;br /&gt;
    &amp;quot;font-family:&amp;#039;Segoe UI&amp;#039;,&amp;#039;Helvetica Neue&amp;#039;,Arial,sans-serif;&amp;quot; ..&lt;br /&gt;
    &amp;quot;font-size:100%;&amp;quot; ..&lt;br /&gt;
    &amp;quot;font-weight:400;&amp;quot; ..&lt;br /&gt;
    &amp;quot;float:right;&amp;quot; ..&lt;br /&gt;
    &amp;quot;margin-left:1em;&amp;quot; ..&lt;br /&gt;
    &amp;quot;color:#3366cc;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
STYLE.indexSubheading =&lt;br /&gt;
    &amp;quot;font-weight:700;&amp;quot; ..&lt;br /&gt;
    &amp;quot;margin:0.45em 0 0.15em 0;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
STYLE.indexSubbook =&lt;br /&gt;
    &amp;quot;margin:0.15em 0 0.55em 1.4em;&amp;quot; ..&lt;br /&gt;
    &amp;quot;font-size:100%;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
STYLE.galleryWrap =&lt;br /&gt;
    &amp;quot;display:flex;&amp;quot; ..&lt;br /&gt;
    &amp;quot;flex-wrap:wrap;&amp;quot; ..&lt;br /&gt;
    &amp;quot;gap:12px;&amp;quot; ..&lt;br /&gt;
    &amp;quot;align-items:flex-start;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
STYLE.galleryCard =&lt;br /&gt;
    &amp;quot;text-align:center;&amp;quot; ..&lt;br /&gt;
    &amp;quot;vertical-align:top;&amp;quot; ..&lt;br /&gt;
    &amp;quot;border:1px solid #c8ccd1;&amp;quot; ..&lt;br /&gt;
    &amp;quot;background:#fff8dc;&amp;quot; ..&lt;br /&gt;
    &amp;quot;padding:6px;&amp;quot; ..&lt;br /&gt;
    &amp;quot;box-sizing:border-box;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
STYLE.galleryCaption =&lt;br /&gt;
    &amp;quot;font-size:90%;&amp;quot; ..&lt;br /&gt;
    &amp;quot;display:block;&amp;quot; ..&lt;br /&gt;
    &amp;quot;margin-top:4px;&amp;quot; ..&lt;br /&gt;
    &amp;quot;line-height:1.25em;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-- =========================&lt;br /&gt;
-- Helpers&lt;br /&gt;
-- =========================&lt;br /&gt;
&lt;br /&gt;
local function trim(s)&lt;br /&gt;
    return (s or &amp;quot;&amp;quot;):gsub(&amp;quot;^%s+&amp;quot;, &amp;quot;&amp;quot;):gsub(&amp;quot;%s+$&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function makeAnchorId(s)&lt;br /&gt;
    s = trim(s)&lt;br /&gt;
    s = s:gsub(&amp;quot;%s+&amp;quot;, &amp;quot;_&amp;quot;)&lt;br /&gt;
    s = s:gsub(&amp;quot;[^%w_%-]&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
    return s&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getContent(page)&lt;br /&gt;
    if not page or page == &amp;quot;&amp;quot; then&lt;br /&gt;
        return &amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local title = mw.title.new(page)&lt;br /&gt;
    if not title then&lt;br /&gt;
        return &amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return title:getContent() or &amp;quot;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getCurrentPageName()&lt;br /&gt;
    local title = mw.title.getCurrentTitle()&lt;br /&gt;
    if not title then&lt;br /&gt;
        return &amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    return title.prefixedText or &amp;quot;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function isBookPage()&lt;br /&gt;
    local page = getCurrentPageName()&lt;br /&gt;
&lt;br /&gt;
    return page == &amp;quot;Book:Quantum Collection&amp;quot;&lt;br /&gt;
        or page == &amp;quot;Book:Quantum Collection/Matter (by scale)&amp;quot;&lt;br /&gt;
        or page == &amp;quot;Book:Quantum Collection/Methods and tools&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function shouldCollapseSections()&lt;br /&gt;
    return not isBookPage()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function shouldUseTwoColumnSections()&lt;br /&gt;
    return not isBookPage()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function isIgnoredIndexTarget(target)&lt;br /&gt;
    return target:match(&amp;quot;^(File|Image|Category|Help|Special):&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function isRealPageTarget(target)&lt;br /&gt;
    return target:match(&amp;quot;^Book:&amp;quot;)&lt;br /&gt;
        or target:match(&amp;quot;^Physics:&amp;quot;)&lt;br /&gt;
        or target:match(&amp;quot;^Template:&amp;quot;)&lt;br /&gt;
        or target:match(&amp;quot;^Module:&amp;quot;)&lt;br /&gt;
        or target:find(&amp;quot;/&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function isSubbookLine(line)&lt;br /&gt;
    return line and line:find(&amp;quot;QC:subbook&amp;quot;, 1, true) ~= nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function displayText(target, display)&lt;br /&gt;
    if display and display ~= &amp;quot;&amp;quot; then&lt;br /&gt;
        return display&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if target:match(&amp;quot;^Book:Quantum Collection/&amp;quot;) then&lt;br /&gt;
        return target:gsub(&amp;quot;^Book:Quantum Collection/&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if target:match(&amp;quot;^Physics:Quantum basics/See also/&amp;quot;) then&lt;br /&gt;
        return target:gsub(&amp;quot;^Physics:Quantum basics/See also/&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if target:match(&amp;quot;^Physics:&amp;quot;) then&lt;br /&gt;
        return target:gsub(&amp;quot;^Physics:&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return target&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.test(frame)&lt;br /&gt;
    return &amp;quot;Physics QC module working&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- =========================&lt;br /&gt;
-- Content extraction&lt;br /&gt;
-- =========================&lt;br /&gt;
&lt;br /&gt;
local function extractIndexBlock(content)&lt;br /&gt;
    local indexBlock = content:match(&amp;quot;==%s*Index%s*==%s*(.-)\n==%s*Full contents%s*==&amp;quot;)&lt;br /&gt;
    if not indexBlock then&lt;br /&gt;
        indexBlock = content:match(&amp;quot;==%s*Index%s*==%s*(.-)&amp;lt;/includeonly&amp;gt;&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    if not indexBlock then&lt;br /&gt;
        indexBlock = content:match(&amp;quot;==%s*Index%s*==%s*(.*)&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    return indexBlock or &amp;quot;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function extractFullContentsBlock(content)&lt;br /&gt;
    local fullBlock = content:match(&amp;quot;==%s*Full contents%s*==%s*(.-)&amp;lt;/includeonly&amp;gt;&amp;quot;)&lt;br /&gt;
    if not fullBlock then&lt;br /&gt;
        fullBlock = content:match(&amp;quot;==%s*Full contents%s*==%s*(.*)&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    return fullBlock or &amp;quot;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function countFullContentsItems(content)&lt;br /&gt;
    local seen = {}&lt;br /&gt;
    local count = 0&lt;br /&gt;
    local fullBlock = extractFullContentsBlock(content)&lt;br /&gt;
&lt;br /&gt;
    for target in fullBlock:gmatch(&amp;quot;&amp;lt;li&amp;gt;%s*%[%[([^%]|#]+)&amp;quot;) do&lt;br /&gt;
        target = trim(target)&lt;br /&gt;
&lt;br /&gt;
        if not target:match(&amp;quot;^(File|Image|Category|Help|Special|Template):&amp;quot;) then&lt;br /&gt;
            local key = mw.ustring.lower(target)&lt;br /&gt;
            if not seen[key] then&lt;br /&gt;
                seen[key] = true&lt;br /&gt;
                count = count + 1&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return count&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- =========================&lt;br /&gt;
-- Section parsing&lt;br /&gt;
-- =========================&lt;br /&gt;
&lt;br /&gt;
local function parseSections(fullBlock)&lt;br /&gt;
    local sections = {}&lt;br /&gt;
    local currentTitle = nil&lt;br /&gt;
    local currentLines = {}&lt;br /&gt;
&lt;br /&gt;
    local function flushSection()&lt;br /&gt;
        if currentTitle then&lt;br /&gt;
            table.insert(sections, {&lt;br /&gt;
                title = currentTitle,&lt;br /&gt;
                body = table.concat(currentLines, &amp;quot;\n&amp;quot;)&lt;br /&gt;
            })&lt;br /&gt;
        end&lt;br /&gt;
        currentLines = {}&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    for line in mw.text.gsplit(fullBlock, &amp;quot;\n&amp;quot;, true) do&lt;br /&gt;
        local heading = line:match(&amp;quot;^===%s*(.-)%s*===%s*$&amp;quot;)&lt;br /&gt;
        if heading then&lt;br /&gt;
            flushSection()&lt;br /&gt;
            currentTitle = trim(heading)&lt;br /&gt;
        else&lt;br /&gt;
            if currentTitle then&lt;br /&gt;
                table.insert(currentLines, line)&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    flushSection()&lt;br /&gt;
    return sections&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function countRenderableItems(sectionBody)&lt;br /&gt;
    local count = 0&lt;br /&gt;
    local seen = {}&lt;br /&gt;
&lt;br /&gt;
    for target in sectionBody:gmatch(&amp;quot;&amp;lt;li&amp;gt;%s*%[%[([^%]|#]+)&amp;quot;) do&lt;br /&gt;
        target = trim(target)&lt;br /&gt;
&lt;br /&gt;
        if not target:match(&amp;quot;^(File|Image|Category|Help|Special|Template):&amp;quot;) then&lt;br /&gt;
            local key = mw.ustring.lower(target)&lt;br /&gt;
            if not seen[key] then&lt;br /&gt;
                seen[key] = true&lt;br /&gt;
                count = count + 1&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return count&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function normalizeSectionBody(sectionBody)&lt;br /&gt;
    local lines = {}&lt;br /&gt;
&lt;br /&gt;
    for line in mw.text.gsplit(sectionBody, &amp;quot;\n&amp;quot;, true) do&lt;br /&gt;
        local trimmed = trim(line)&lt;br /&gt;
&lt;br /&gt;
        if trimmed ~= &amp;quot;&amp;lt;ol&amp;gt;&amp;quot;&lt;br /&gt;
            and trimmed ~= &amp;quot;&amp;lt;/ol&amp;gt;&amp;quot;&lt;br /&gt;
            and trimmed ~= &amp;#039;&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; style=&amp;quot;clear:both; border:1px solid #c8ccd1; background:#f8f9fa; padding:0.6em; margin:0.5em 0 1em 0;&amp;quot;&amp;gt;&amp;#039;&lt;br /&gt;
            and trimmed ~= &amp;quot;&amp;lt;/div&amp;gt;&amp;quot; then&lt;br /&gt;
&lt;br /&gt;
            local templateTarget = trimmed:match(&amp;quot;^&amp;lt;li&amp;gt;%s*%[%[(Template:[^%]]+)%]%]%s*&amp;lt;/li&amp;gt;%s*$&amp;quot;)&lt;br /&gt;
            if templateTarget then&lt;br /&gt;
                table.insert(lines, &amp;quot;[[&amp;quot; .. templateTarget .. &amp;quot;]]&amp;quot;)&lt;br /&gt;
            else&lt;br /&gt;
                table.insert(lines, line)&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return table.concat(lines, &amp;quot;\n&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function adjustSectionImageMarkup(sectionBody)&lt;br /&gt;
    if not sectionBody or sectionBody == &amp;quot;&amp;quot; then&lt;br /&gt;
        return sectionBody&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local function adjustOne(markup)&lt;br /&gt;
        local out = markup&lt;br /&gt;
        out = out:gsub(&amp;quot;|%s*right%s*&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
        out = out:gsub(&amp;quot;|%s*left%s*&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
        out = out:gsub(&amp;quot;|%s*center%s*&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
        out = out:gsub(&amp;quot;|%s*%d+px%s*&amp;quot;, &amp;quot;|180px&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
        if not out:match(&amp;quot;|%s*thumb%s*&amp;quot;) then&lt;br /&gt;
            out = out:gsub(&amp;quot;^(%[%[%s*[Ff][Ii][Ll][Ee]:[^%]|%]]+)&amp;quot;, &amp;quot;%1|thumb&amp;quot;, 1)&lt;br /&gt;
            out = out:gsub(&amp;quot;^(%[%[%s*[Ii][Mm][Aa][Gg][Ee]:[^%]|%]]+)&amp;quot;, &amp;quot;%1|thumb&amp;quot;, 1)&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        out = out:gsub(&amp;quot;|%s*thumb%s*&amp;quot;, &amp;quot;|thumb|center&amp;quot;, 1)&lt;br /&gt;
        return out&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    sectionBody = sectionBody:gsub(&amp;quot;(%[%[%s*[Ff][Ii][Ll][Ee]:.-%]%])&amp;quot;, adjustOne, 1)&lt;br /&gt;
    sectionBody = sectionBody:gsub(&amp;quot;(%[%[%s*[Ii][Mm][Aa][Gg][Ee]:.-%]%])&amp;quot;, adjustOne, 1)&lt;br /&gt;
&lt;br /&gt;
    return sectionBody&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- =========================&lt;br /&gt;
-- Index parsing/rendering&lt;br /&gt;
-- =========================&lt;br /&gt;
&lt;br /&gt;
local function parseExplicitIndex(indexBlock)&lt;br /&gt;
    local entries = {}&lt;br /&gt;
&lt;br /&gt;
    for line in mw.text.gsplit(indexBlock, &amp;quot;\n&amp;quot;, true) do&lt;br /&gt;
        local trimmed = trim(line)&lt;br /&gt;
&lt;br /&gt;
        if trimmed ~= &amp;quot;&amp;quot; then&lt;br /&gt;
            local boldHeading = trimmed:match(&amp;quot;^&amp;#039;&amp;#039;&amp;#039;(.-)&amp;#039;&amp;#039;&amp;#039;$&amp;quot;)&lt;br /&gt;
            local isSubbook = isSubbookLine(trimmed)&lt;br /&gt;
&lt;br /&gt;
            -- Match links anywhere in the line, so &amp;lt;li&amp;gt;&amp;lt;!--QC:subbook--&amp;gt;[[...]]&amp;lt;/li&amp;gt; works.&lt;br /&gt;
            local target, display = trimmed:match(&amp;quot;%[%[([^%]|%]]+)|([^%]]+)%]%]&amp;quot;)&lt;br /&gt;
            local plainTarget = nil&lt;br /&gt;
&lt;br /&gt;
            if not target then&lt;br /&gt;
                plainTarget = trimmed:match(&amp;quot;%[%[([^%]|%]]+)%]%]&amp;quot;)&lt;br /&gt;
            end&lt;br /&gt;
&lt;br /&gt;
            if boldHeading then&lt;br /&gt;
                table.insert(entries, {&lt;br /&gt;
                    kind = &amp;quot;heading&amp;quot;,&lt;br /&gt;
                    text = trim(boldHeading)&lt;br /&gt;
                })&lt;br /&gt;
            elseif target then&lt;br /&gt;
                target = trim(target)&lt;br /&gt;
                display = trim(display)&lt;br /&gt;
&lt;br /&gt;
                if not isIgnoredIndexTarget(target)&lt;br /&gt;
                    and not display:match(&amp;quot;^%d+px&amp;quot;)&lt;br /&gt;
                    and display ~= &amp;quot;right&amp;quot;&lt;br /&gt;
                    and display ~= &amp;quot;left&amp;quot;&lt;br /&gt;
                    and display ~= &amp;quot;thumb&amp;quot; then&lt;br /&gt;
&lt;br /&gt;
                    table.insert(entries, {&lt;br /&gt;
                        kind = &amp;quot;item&amp;quot;,&lt;br /&gt;
                        target = target,&lt;br /&gt;
                        display = display,&lt;br /&gt;
                        isSubbook = isSubbook&lt;br /&gt;
                    })&lt;br /&gt;
                end&lt;br /&gt;
&lt;br /&gt;
            elseif plainTarget then&lt;br /&gt;
                plainTarget = trim(plainTarget)&lt;br /&gt;
&lt;br /&gt;
                if not isIgnoredIndexTarget(plainTarget)&lt;br /&gt;
                    and not plainTarget:match(&amp;quot;^%d+px&amp;quot;)&lt;br /&gt;
                    and plainTarget ~= &amp;quot;right&amp;quot;&lt;br /&gt;
                    and plainTarget ~= &amp;quot;left&amp;quot;&lt;br /&gt;
                    and plainTarget ~= &amp;quot;thumb&amp;quot; then&lt;br /&gt;
&lt;br /&gt;
                    table.insert(entries, {&lt;br /&gt;
                        kind = &amp;quot;item&amp;quot;,&lt;br /&gt;
                        target = plainTarget,&lt;br /&gt;
                        display = nil,&lt;br /&gt;
                        isSubbook = isSubbook&lt;br /&gt;
                    })&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return entries&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderIndexFromExplicitBlock(indexBlock)&lt;br /&gt;
    local entries = parseExplicitIndex(indexBlock)&lt;br /&gt;
    if #entries == 0 then&lt;br /&gt;
        return &amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local groups = {}&lt;br /&gt;
    local currentGroup = nil&lt;br /&gt;
&lt;br /&gt;
    for _, entry in ipairs(entries) do&lt;br /&gt;
        if entry.kind == &amp;quot;heading&amp;quot; then&lt;br /&gt;
            currentGroup = {&lt;br /&gt;
                heading = entry.text,&lt;br /&gt;
                items = {}&lt;br /&gt;
            }&lt;br /&gt;
            table.insert(groups, currentGroup)&lt;br /&gt;
        elseif entry.kind == &amp;quot;item&amp;quot; then&lt;br /&gt;
            if not currentGroup then&lt;br /&gt;
                currentGroup = {&lt;br /&gt;
                    heading = &amp;quot;&amp;quot;,&lt;br /&gt;
                    items = {}&lt;br /&gt;
                }&lt;br /&gt;
                table.insert(groups, currentGroup)&lt;br /&gt;
            end&lt;br /&gt;
&lt;br /&gt;
            table.insert(currentGroup.items, {&lt;br /&gt;
                target = entry.target,&lt;br /&gt;
                display = entry.display,&lt;br /&gt;
                isSubbook = entry.isSubbook&lt;br /&gt;
            })&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if #groups == 0 then&lt;br /&gt;
        return &amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local function countNumberedItems(groupList)&lt;br /&gt;
        local n = 0&lt;br /&gt;
        for _, g in ipairs(groupList) do&lt;br /&gt;
            for _, item in ipairs(g.items) do&lt;br /&gt;
                if not item.isSubbook then&lt;br /&gt;
                    n = n + 1&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
        return n&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local leftGroups = {}&lt;br /&gt;
    local rightGroups = {}&lt;br /&gt;
&lt;br /&gt;
    local split = math.ceil(#groups / 2)&lt;br /&gt;
&lt;br /&gt;
    for i, group in ipairs(groups) do&lt;br /&gt;
        if i &amp;lt;= split then&lt;br /&gt;
            table.insert(leftGroups, group)&lt;br /&gt;
        else&lt;br /&gt;
            table.insert(rightGroups, group)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if #rightGroups == 0 and #leftGroups &amp;gt; 1 then&lt;br /&gt;
        table.insert(rightGroups, table.remove(leftGroups))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local function renderItemLink(item)&lt;br /&gt;
        local target = item.target&lt;br /&gt;
        local label = displayText(target, item.display)&lt;br /&gt;
&lt;br /&gt;
        if isRealPageTarget(target) then&lt;br /&gt;
            return &amp;#039;[[&amp;#039; .. target .. &amp;#039;|&amp;#039; .. label .. &amp;#039;]]&amp;#039;&lt;br /&gt;
        else&lt;br /&gt;
            local anchorId = makeAnchorId(target)&lt;br /&gt;
            return &amp;#039;[[#&amp;#039; .. anchorId .. &amp;#039;|&amp;#039; .. label .. &amp;#039;]]&amp;#039;&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local function renderColumn(groupList, startNumber)&lt;br /&gt;
        local out = {}&lt;br /&gt;
        local itemNumber = startNumber&lt;br /&gt;
&lt;br /&gt;
        for _, group in ipairs(groupList) do&lt;br /&gt;
            if trim(group.heading) ~= &amp;quot;&amp;quot; then&lt;br /&gt;
                table.insert(out,&lt;br /&gt;
                    &amp;#039;&amp;lt;div style=&amp;quot;&amp;#039; .. STYLE.indexSubheading .. &amp;#039;&amp;quot;&amp;gt;&amp;#039; ..&lt;br /&gt;
                    mw.text.encode(group.heading) ..&lt;br /&gt;
                    &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;&lt;br /&gt;
                )&lt;br /&gt;
            end&lt;br /&gt;
&lt;br /&gt;
            if #group.items &amp;gt; 0 then&lt;br /&gt;
                local olOpen = false&lt;br /&gt;
&lt;br /&gt;
                for _, item in ipairs(group.items) do&lt;br /&gt;
                    if item.isSubbook then&lt;br /&gt;
                        if olOpen then&lt;br /&gt;
                            table.insert(out, &amp;#039;&amp;lt;/ol&amp;gt;&amp;#039;)&lt;br /&gt;
                            olOpen = false&lt;br /&gt;
                        end&lt;br /&gt;
&lt;br /&gt;
                        table.insert(out,&lt;br /&gt;
                            &amp;#039;&amp;lt;div style=&amp;quot;&amp;#039; .. STYLE.indexSubbook .. &amp;#039;&amp;quot;&amp;gt;→ &amp;#039; ..&lt;br /&gt;
                            renderItemLink(item) ..&lt;br /&gt;
                            &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;&lt;br /&gt;
                        )&lt;br /&gt;
                    else&lt;br /&gt;
                        if not olOpen then&lt;br /&gt;
                            table.insert(out, &amp;#039;&amp;lt;ol start=&amp;quot;&amp;#039; .. tostring(itemNumber) .. &amp;#039;&amp;quot;&amp;gt;&amp;#039;)&lt;br /&gt;
                            olOpen = true&lt;br /&gt;
                        end&lt;br /&gt;
&lt;br /&gt;
                        table.insert(out, &amp;#039;&amp;lt;li&amp;gt;&amp;#039; .. renderItemLink(item) .. &amp;#039;&amp;lt;/li&amp;gt;&amp;#039;)&lt;br /&gt;
                        itemNumber = itemNumber + 1&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
&lt;br /&gt;
                if olOpen then&lt;br /&gt;
                    table.insert(out, &amp;#039;&amp;lt;/ol&amp;gt;&amp;#039;)&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        return table.concat(out, &amp;quot;\n&amp;quot;), itemNumber&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local leftCount = countNumberedItems(leftGroups)&lt;br /&gt;
    local leftHtml = select(1, renderColumn(leftGroups, 1))&lt;br /&gt;
    local rightHtml = &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    if #rightGroups &amp;gt; 0 then&lt;br /&gt;
        rightHtml = select(1, renderColumn(rightGroups, leftCount + 1))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local out = {}&lt;br /&gt;
    table.insert(out, &amp;#039;&amp;lt;div style=&amp;quot;display:flex; gap:30px; align-items:flex-start;&amp;quot;&amp;gt;&amp;#039;)&lt;br /&gt;
    table.insert(out, &amp;#039;&amp;lt;div style=&amp;quot;flex:1; min-width:0;&amp;quot;&amp;gt;&amp;#039;)&lt;br /&gt;
    table.insert(out, leftHtml)&lt;br /&gt;
    table.insert(out, &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
    table.insert(out, &amp;#039;&amp;lt;div style=&amp;quot;flex:1; min-width:0;&amp;quot;&amp;gt;&amp;#039;)&lt;br /&gt;
    table.insert(out, rightHtml)&lt;br /&gt;
    table.insert(out, &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
    table.insert(out, &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
    return table.concat(out, &amp;quot;\n&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderIndexFromSections(sections)&lt;br /&gt;
    if #sections == 0 then&lt;br /&gt;
        return &amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local out = {}&lt;br /&gt;
&lt;br /&gt;
    for _, section in ipairs(sections) do&lt;br /&gt;
        local anchorId = makeAnchorId(section.title)&lt;br /&gt;
        table.insert(out, &amp;quot;# [[#&amp;quot; .. anchorId .. &amp;quot;|&amp;quot; .. section.title .. &amp;quot;]]&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return table.concat(out, &amp;quot;\n&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- =========================&lt;br /&gt;
-- Rendering full contents&lt;br /&gt;
-- =========================&lt;br /&gt;
&lt;br /&gt;
local function renderSingleSectionBox(section, sectionIndex, startIndex, collapseClass, adjustImagesForColumns)&lt;br /&gt;
    local out = {}&lt;br /&gt;
    local body = normalizeSectionBody(section.body)&lt;br /&gt;
&lt;br /&gt;
    if adjustImagesForColumns then&lt;br /&gt;
        body = adjustSectionImageMarkup(body)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local itemCount = countRenderableItems(body)&lt;br /&gt;
    local anchorId = makeAnchorId(section.title)&lt;br /&gt;
&lt;br /&gt;
    table.insert(out, &amp;#039;&amp;lt;div class=&amp;quot;&amp;#039; .. collapseClass .. &amp;#039;&amp;quot; style=&amp;quot;&amp;#039; .. STYLE.sectionBox .. &amp;#039;&amp;quot;&amp;gt;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
    table.insert(out,&lt;br /&gt;
        &amp;#039;&amp;lt;div id=&amp;quot;&amp;#039; .. anchorId .. &amp;#039;&amp;quot; style=&amp;quot;&amp;#039; .. STYLE.sectionHeader .. &amp;#039;&amp;quot;&amp;gt;&amp;#039; ..&lt;br /&gt;
        &amp;#039;&amp;lt;span&amp;gt;&amp;#039; ..&lt;br /&gt;
        tostring(sectionIndex) .. &amp;#039;. &amp;#039; ..&lt;br /&gt;
        mw.text.encode(section.title) ..&lt;br /&gt;
        &amp;#039; (&amp;#039; .. tostring(itemCount) .. &amp;#039;)&amp;#039; ..&lt;br /&gt;
        &amp;#039;&amp;lt;/span&amp;gt;&amp;#039; ..&lt;br /&gt;
        &amp;#039;&amp;lt;span style=&amp;quot;&amp;#039; .. STYLE.backLink .. &amp;#039;&amp;quot;&amp;gt;[[#QCIndex|↑]]&amp;lt;/span&amp;gt;&amp;#039; ..&lt;br /&gt;
        &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
    table.insert(out, &amp;#039;&amp;lt;div class=&amp;quot;mw-collapsible-content&amp;quot; style=&amp;quot;margin-top:0;&amp;quot;&amp;gt;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
    if itemCount &amp;gt; 0 then&lt;br /&gt;
        table.insert(out, &amp;#039;&amp;lt;ol start=&amp;quot;&amp;#039; .. tostring(startIndex) .. &amp;#039;&amp;quot;&amp;gt;&amp;#039;)&lt;br /&gt;
        table.insert(out, body)&lt;br /&gt;
        table.insert(out, &amp;#039;&amp;lt;/ol&amp;gt;&amp;#039;)&lt;br /&gt;
    else&lt;br /&gt;
        table.insert(out, body)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    table.insert(out, &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
    table.insert(out, &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
    return table.concat(out, &amp;quot;\n&amp;quot;), itemCount&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderCollapsibleSections(fullBlock)&lt;br /&gt;
    local sections = parseSections(fullBlock)&lt;br /&gt;
    if #sections == 0 then&lt;br /&gt;
        return fullBlock&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local collapseClass = &amp;quot;mw-collapsible&amp;quot;&lt;br /&gt;
    if shouldCollapseSections() then&lt;br /&gt;
        collapseClass = &amp;quot;mw-collapsible mw-collapsed&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if not shouldUseTwoColumnSections() then&lt;br /&gt;
        local out = {}&lt;br /&gt;
        local startIndex = 1&lt;br /&gt;
        local sectionIndex = 1&lt;br /&gt;
&lt;br /&gt;
        for _, section in ipairs(sections) do&lt;br /&gt;
            local html, itemCount = renderSingleSectionBox(section, sectionIndex, startIndex, collapseClass, false)&lt;br /&gt;
            table.insert(out, html)&lt;br /&gt;
            startIndex = startIndex + itemCount&lt;br /&gt;
            sectionIndex = sectionIndex + 1&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        return table.concat(out, &amp;quot;\n&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local leftSections = {}&lt;br /&gt;
    local rightSections = {}&lt;br /&gt;
    local halfway = math.ceil(#sections / 2)&lt;br /&gt;
&lt;br /&gt;
    for i, section in ipairs(sections) do&lt;br /&gt;
        if i &amp;lt;= halfway then&lt;br /&gt;
            table.insert(leftSections, section)&lt;br /&gt;
        else&lt;br /&gt;
            table.insert(rightSections, section)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local function renderSectionColumn(sectionList, startSectionIndex, startItemIndex)&lt;br /&gt;
        local out = {}&lt;br /&gt;
        local sectionIndex = startSectionIndex&lt;br /&gt;
        local itemIndex = startItemIndex&lt;br /&gt;
&lt;br /&gt;
        for _, section in ipairs(sectionList) do&lt;br /&gt;
            local html, itemCount = renderSingleSectionBox(section, sectionIndex, itemIndex, collapseClass, true)&lt;br /&gt;
            table.insert(out, html)&lt;br /&gt;
            sectionIndex = sectionIndex + 1&lt;br /&gt;
            itemIndex = itemIndex + itemCount&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        return table.concat(out, &amp;quot;\n&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local leftHtml = renderSectionColumn(leftSections, 1, 1)&lt;br /&gt;
&lt;br /&gt;
    local leftItemCount = 0&lt;br /&gt;
    for _, section in ipairs(leftSections) do&lt;br /&gt;
        local body = adjustSectionImageMarkup(normalizeSectionBody(section.body))&lt;br /&gt;
        leftItemCount = leftItemCount + countRenderableItems(body)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local rightHtml = renderSectionColumn(rightSections, #leftSections + 1, leftItemCount + 1)&lt;br /&gt;
&lt;br /&gt;
    local out = {}&lt;br /&gt;
    table.insert(out, &amp;#039;&amp;lt;div style=&amp;quot;display:flex; gap:20px; align-items:flex-start;&amp;quot;&amp;gt;&amp;#039;)&lt;br /&gt;
    table.insert(out, &amp;#039;&amp;lt;div style=&amp;quot;flex:1; min-width:0;&amp;quot;&amp;gt;&amp;#039;)&lt;br /&gt;
    table.insert(out, leftHtml)&lt;br /&gt;
    table.insert(out, &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
    table.insert(out, &amp;#039;&amp;lt;div style=&amp;quot;flex:1; min-width:0;&amp;quot;&amp;gt;&amp;#039;)&lt;br /&gt;
    table.insert(out, rightHtml)&lt;br /&gt;
    table.insert(out, &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
    table.insert(out, &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
    return table.concat(out, &amp;quot;\n&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- =========================&lt;br /&gt;
-- Gallery helpers&lt;br /&gt;
-- =========================&lt;br /&gt;
&lt;br /&gt;
local function extractPhysicsLinks(content)&lt;br /&gt;
    local fullBlock = extractFullContentsBlock(content)&lt;br /&gt;
    local pages = {}&lt;br /&gt;
    local seenPages = {}&lt;br /&gt;
&lt;br /&gt;
    for target in fullBlock:gmatch(&amp;quot;&amp;lt;li&amp;gt;%s*%[%[([^%]|#]+)&amp;quot;) do&lt;br /&gt;
        target = trim(target)&lt;br /&gt;
&lt;br /&gt;
        if target:match(&amp;quot;^Physics:&amp;quot;) then&lt;br /&gt;
            local key = mw.ustring.lower(target)&lt;br /&gt;
            if not seenPages[key] then&lt;br /&gt;
                seenPages[key] = true&lt;br /&gt;
                table.insert(pages, target)&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return pages&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function normalizeFileTarget(fileTarget)&lt;br /&gt;
    if not fileTarget or fileTarget == &amp;quot;&amp;quot; then&lt;br /&gt;
        return nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    fileTarget = trim(fileTarget)&lt;br /&gt;
    fileTarget = fileTarget:gsub(&amp;quot;^[Ii][Mm][Aa][Gg][Ee]:&amp;quot;, &amp;quot;File:&amp;quot;)&lt;br /&gt;
    return fileTarget&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function extractFirstFileFromText(text)&lt;br /&gt;
    if not text or text == &amp;quot;&amp;quot; then&lt;br /&gt;
        return nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local fileTarget = text:match(&amp;quot;%[%[%s*([Ff][Ii][Ll][Ee]:[^%]|]+)&amp;quot;)&lt;br /&gt;
    if fileTarget and fileTarget ~= &amp;quot;&amp;quot; then&lt;br /&gt;
        return normalizeFileTarget(fileTarget)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    fileTarget = text:match(&amp;quot;%[%[%s*([Ii][Mm][Aa][Gg][Ee]:[^%]|]+)&amp;quot;)&lt;br /&gt;
    if fileTarget and fileTarget ~= &amp;quot;&amp;quot; then&lt;br /&gt;
        return normalizeFileTarget(fileTarget)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function extractFirstFileFromPage(pageName)&lt;br /&gt;
    local content = getContent(pageName)&lt;br /&gt;
    if not content or content == &amp;quot;&amp;quot; then&lt;br /&gt;
        return nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return extractFirstFileFromText(content)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function makeCleanGalleryTitle(targetPage)&lt;br /&gt;
    local cleanTitle = targetPage or &amp;quot;&amp;quot;&lt;br /&gt;
    cleanTitle = cleanTitle:gsub(&amp;quot;^Physics:Quantum%s+&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
    cleanTitle = cleanTitle:gsub(&amp;quot;^Physics:&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
    return cleanTitle&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- =========================&lt;br /&gt;
-- Core renderer&lt;br /&gt;
-- =========================&lt;br /&gt;
&lt;br /&gt;
local function renderTocPage(pageName, showHeading)&lt;br /&gt;
    local content = getContent(pageName)&lt;br /&gt;
&lt;br /&gt;
    if content == &amp;quot;&amp;quot; then&lt;br /&gt;
        if showHeading then&lt;br /&gt;
            return &amp;quot;= Table of contents (0 articles)=\n&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        return &amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local count = countFullContentsItems(content)&lt;br /&gt;
    local indexBlock = extractIndexBlock(content)&lt;br /&gt;
    local fullBlock = extractFullContentsBlock(content)&lt;br /&gt;
    local sections = parseSections(fullBlock)&lt;br /&gt;
&lt;br /&gt;
    local renderedIndex = &amp;quot;&amp;quot;&lt;br /&gt;
    if trim(indexBlock) ~= &amp;quot;&amp;quot; then&lt;br /&gt;
        renderedIndex = renderIndexFromExplicitBlock(indexBlock)&lt;br /&gt;
    else&lt;br /&gt;
        renderedIndex = renderIndexFromSections(sections)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local renderedFullBlock = renderCollapsibleSections(fullBlock)&lt;br /&gt;
&lt;br /&gt;
    local result = {}&lt;br /&gt;
&lt;br /&gt;
    if showHeading then&lt;br /&gt;
        table.insert(result, string.format(&amp;quot;= Table of contents (%d articles)=&amp;quot;, count))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if trim(renderedIndex) ~= &amp;quot;&amp;quot; then&lt;br /&gt;
        table.insert(result, &amp;#039;&amp;lt;span id=&amp;quot;QCIndex&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;#039;)&lt;br /&gt;
        table.insert(result, &amp;quot;== Index ==&amp;quot;)&lt;br /&gt;
        table.insert(result, renderedIndex)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    table.insert(result, &amp;quot;== Full contents ==&amp;quot;)&lt;br /&gt;
    table.insert(result, renderedFullBlock)&lt;br /&gt;
&lt;br /&gt;
    return table.concat(result, &amp;quot;\n&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- =========================&lt;br /&gt;
-- Public functions&lt;br /&gt;
-- =========================&lt;br /&gt;
&lt;br /&gt;
function p.tocHeading(frame)&lt;br /&gt;
    local pageName = frame.args[1]&lt;br /&gt;
    local content = getContent(pageName)&lt;br /&gt;
    local count = countFullContentsItems(content)&lt;br /&gt;
&lt;br /&gt;
    return string.format(&amp;quot;= Table of contents (%d articles)=&amp;quot;, count)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.tocHeadingAndList(frame)&lt;br /&gt;
    local pageName = frame.args[1] or &amp;quot;Physics:Quantum basics/See also&amp;quot;&lt;br /&gt;
    return renderTocPage(pageName, true)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.qm(frame)&lt;br /&gt;
    return renderTocPage(&amp;quot;Physics:Quantum basics/See also/Matter&amp;quot;, true)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.qt(frame)&lt;br /&gt;
    return renderTocPage(&amp;quot;Physics:Quantum basics/See also/Methods&amp;quot;, true)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.gallery(frame)&lt;br /&gt;
    local pageName = trim(frame.args[1] or &amp;quot;&amp;quot;)&lt;br /&gt;
    local content = getContent(pageName)&lt;br /&gt;
&lt;br /&gt;
    if content == &amp;quot;&amp;quot; then&lt;br /&gt;
        return &amp;#039;[[Book:Quantum Collection|← Back to Book:Quantum Collection]]\n\n== Gallery ==\n\nNo content found.&amp;#039;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local thumbWidth = tonumber(frame.args.width or frame.args[2]) or 150&lt;br /&gt;
    local cardWidth = thumbWidth + 20&lt;br /&gt;
&lt;br /&gt;
    local pages = extractPhysicsLinks(content)&lt;br /&gt;
    local totalPages = #pages&lt;br /&gt;
    local out = {}&lt;br /&gt;
    local seenFiles = {}&lt;br /&gt;
    local imageCount = 0&lt;br /&gt;
    local missingCount = 0&lt;br /&gt;
    local items = {}&lt;br /&gt;
&lt;br /&gt;
    for _, targetPage in ipairs(pages) do&lt;br /&gt;
        local fileName = extractFirstFileFromPage(targetPage)&lt;br /&gt;
        local cleanTitle = makeCleanGalleryTitle(targetPage)&lt;br /&gt;
&lt;br /&gt;
        if fileName and fileName ~= &amp;quot;&amp;quot; then&lt;br /&gt;
            local key = mw.ustring.lower(fileName)&lt;br /&gt;
&lt;br /&gt;
            if not seenFiles[key] then&lt;br /&gt;
                seenFiles[key] = true&lt;br /&gt;
                imageCount = imageCount + 1&lt;br /&gt;
&lt;br /&gt;
                table.insert(items,&lt;br /&gt;
                    &amp;#039;&amp;lt;div style=&amp;quot;&amp;#039; .. STYLE.galleryCard .. &amp;#039; width:&amp;#039; .. tostring(cardWidth) .. &amp;#039;px;&amp;quot;&amp;gt;&amp;#039; ..&lt;br /&gt;
                    &amp;#039;[[&amp;#039; .. fileName .. &amp;#039;|&amp;#039; .. tostring(thumbWidth) .. &amp;#039;px]]&amp;#039; ..&lt;br /&gt;
                    &amp;#039;&amp;lt;span style=&amp;quot;&amp;#039; .. STYLE.galleryCaption .. &amp;#039;&amp;quot;&amp;gt;[[&amp;#039; .. targetPage .. &amp;#039;|&amp;#039; .. cleanTitle .. &amp;#039;]]&amp;lt;/span&amp;gt;&amp;#039; ..&lt;br /&gt;
                    &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;&lt;br /&gt;
                )&lt;br /&gt;
            else&lt;br /&gt;
                table.insert(items,&lt;br /&gt;
                    &amp;#039;&amp;lt;div style=&amp;quot;&amp;#039; .. STYLE.galleryCard .. &amp;#039; width:&amp;#039; .. tostring(cardWidth) .. &amp;#039;px; min-height:&amp;#039; .. tostring(thumbWidth + 40) .. &amp;#039;px; display:flex; flex-direction:column; justify-content:center; align-items:center;&amp;quot;&amp;gt;&amp;#039; ..&lt;br /&gt;
                    &amp;#039;&amp;lt;div style=&amp;quot;font-size:90%; line-height:1.3em;&amp;quot;&amp;gt;[[&amp;#039; .. targetPage .. &amp;#039;|&amp;#039; .. cleanTitle .. &amp;#039;]]&amp;lt;/div&amp;gt;&amp;#039; ..&lt;br /&gt;
                    &amp;#039;&amp;lt;div style=&amp;quot;font-size:85%; color:#666; margin-top:6px;&amp;quot;&amp;gt;Duplicate image&amp;lt;/div&amp;gt;&amp;#039; ..&lt;br /&gt;
                    &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;&lt;br /&gt;
                )&lt;br /&gt;
            end&lt;br /&gt;
        else&lt;br /&gt;
            missingCount = missingCount + 1&lt;br /&gt;
&lt;br /&gt;
            table.insert(items,&lt;br /&gt;
                &amp;#039;&amp;lt;div style=&amp;quot;&amp;#039; .. STYLE.galleryCard .. &amp;#039; width:&amp;#039; .. tostring(cardWidth) .. &amp;#039;px; min-height:&amp;#039; .. tostring(thumbWidth + 40) .. &amp;#039;px; display:flex; flex-direction:column; justify-content:center; align-items:center;&amp;quot;&amp;gt;&amp;#039; ..&lt;br /&gt;
                &amp;#039;&amp;lt;div style=&amp;quot;font-size:90%; line-height:1.3em;&amp;quot;&amp;gt;[[&amp;#039; .. targetPage .. &amp;#039;|&amp;#039; .. cleanTitle .. &amp;#039;]]&amp;lt;/div&amp;gt;&amp;#039; ..&lt;br /&gt;
                &amp;#039;&amp;lt;div style=&amp;quot;font-size:85%; color:#aa0000; margin-top:6px;&amp;quot;&amp;gt;Image missing&amp;lt;/div&amp;gt;&amp;#039; ..&lt;br /&gt;
                &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;&lt;br /&gt;
            )&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    table.insert(out, &amp;#039;[[Book:Quantum Collection|← Back to Book:Quantum Collection]]&amp;#039;)&lt;br /&gt;
    table.insert(out, &amp;#039;&amp;#039;)&lt;br /&gt;
    table.insert(out,&lt;br /&gt;
        &amp;#039;== Gallery (&amp;#039; ..&lt;br /&gt;
        tostring(imageCount) .. &amp;#039; images, &amp;#039; ..&lt;br /&gt;
        tostring(missingCount) .. &amp;#039; missing, &amp;#039; ..&lt;br /&gt;
        tostring(totalPages) .. &amp;#039; pages) ==&amp;#039;&lt;br /&gt;
    )&lt;br /&gt;
    table.insert(out, &amp;#039;&amp;#039;)&lt;br /&gt;
    table.insert(out, &amp;#039;&amp;lt;div style=&amp;quot;&amp;#039; .. STYLE.galleryWrap .. &amp;#039;&amp;quot;&amp;gt;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
    for _, item in ipairs(items) do&lt;br /&gt;
        table.insert(out, item)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    table.insert(out, &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
    return table.concat(out, &amp;quot;\n&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.galleryMissing(frame)&lt;br /&gt;
    local pageName = trim(frame.args[1] or &amp;quot;&amp;quot;)&lt;br /&gt;
    local content = getContent(pageName)&lt;br /&gt;
&lt;br /&gt;
    if content == &amp;quot;&amp;quot; then&lt;br /&gt;
        return &amp;quot;No content found.&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local pages = extractPhysicsLinks(content)&lt;br /&gt;
    local out = {}&lt;br /&gt;
&lt;br /&gt;
    table.insert(out, &amp;quot;== Pages with missing gallery image ==&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    for _, targetPage in ipairs(pages) do&lt;br /&gt;
        local fileName = extractFirstFileFromPage(targetPage)&lt;br /&gt;
        if not fileName or fileName == &amp;quot;&amp;quot; then&lt;br /&gt;
            table.insert(out, &amp;quot;* [[&amp;quot; .. targetPage .. &amp;quot;]]&amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return table.concat(out, &amp;quot;\n&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.galleryDuplicates(frame)&lt;br /&gt;
    local pageName = trim(frame.args[1] or &amp;quot;&amp;quot;)&lt;br /&gt;
    local content = getContent(pageName)&lt;br /&gt;
&lt;br /&gt;
    if content == &amp;quot;&amp;quot; then&lt;br /&gt;
        return &amp;quot;No content found.&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local pages = extractPhysicsLinks(content)&lt;br /&gt;
    local seenFiles = {}&lt;br /&gt;
    local out = {}&lt;br /&gt;
&lt;br /&gt;
    table.insert(out, &amp;quot;== Pages with duplicate first gallery image ==&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    for _, targetPage in ipairs(pages) do&lt;br /&gt;
        local fileName = extractFirstFileFromPage(targetPage)&lt;br /&gt;
&lt;br /&gt;
        if fileName and fileName ~= &amp;quot;&amp;quot; then&lt;br /&gt;
            local key = mw.ustring.lower(fileName)&lt;br /&gt;
&lt;br /&gt;
            if seenFiles[key] then&lt;br /&gt;
                table.insert(out, &amp;quot;* [[&amp;quot; .. targetPage .. &amp;quot;]] → [[:&amp;quot;&lt;br /&gt;
                    .. fileName .. &amp;quot;]]&amp;quot;)&lt;br /&gt;
            else&lt;br /&gt;
                seenFiles[key] = targetPage&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return table.concat(out, &amp;quot;\n&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.testwidth(frame)&lt;br /&gt;
    return &amp;#039;arg1=&amp;#039; .. tostring(frame.args[1]) ..&lt;br /&gt;
        &amp;#039;, width=&amp;#039; .. tostring(frame.args.width) ..&lt;br /&gt;
        &amp;#039;, arg2=&amp;#039; .. tostring(frame.args[2])&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Harold</name></author>
	</entry>
</feed>