<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh">
	<id>https://calcwiki.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Lch</id>
	<title>计算器百科 - 用户贡献 [zh]</title>
	<link rel="self" type="application/atom+xml" href="https://calcwiki.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Lch"/>
	<link rel="alternate" type="text/html" href="https://calcwiki.org/Special:Contributions/Lch"/>
	<updated>2026-04-06T08:49:15Z</updated>
	<subtitle>用户贡献</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://calcwiki.org/index.php?title=Module:Infobox/styles.css&amp;diff=8624</id>
		<title>Module:Infobox/styles.css</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Module:Infobox/styles.css&amp;diff=8624"/>
		<updated>2026-01-22T17:25:50Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;
}&lt;br /&gt;
&lt;br /&gt;
.infobox-3cols-child {&lt;br /&gt;
	margin: auto;&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;
/* T281642 */&lt;br /&gt;
body.skin-minerva .infobox-header,&lt;br /&gt;
body.skin-minerva .infobox-subheader,&lt;br /&gt;
body.skin-minerva  .infobox-above,&lt;br /&gt;
body.skin-minerva .infobox-title,&lt;br /&gt;
body.skin-minerva  .infobox-image,&lt;br /&gt;
body.skin-minerva  .infobox-full-data,&lt;br /&gt;
body.skin-minerva .infobox-below {&lt;br /&gt;
	text-align: center;&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;
	@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;
	html.skin-theme-clientpref-night .infobox td div:not(.notheme)[style] {&lt;br /&gt;
		background: transparent !important;&lt;br /&gt;
	    color: var(--color-base,#202122);&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 td div:not(.notheme)[style] {&lt;br /&gt;
			background: transparent !important;&lt;br /&gt;
	    	color: var(--color-base,#202122);&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	html.skin-theme-clientpref-night .infobox td div.NavHead:not(.notheme)[style] {&lt;br /&gt;
	  background: transparent !important;&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 td div.NavHead:not(.notheme)[style] {&lt;br /&gt;
		background: transparent !important;&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 add columns and rows to the infobox itself rather than as part of a new table inside them. This class should be discouraged and removed on the long term, 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 https://phabricator.wikimedia.org/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 tr {&lt;br /&gt;
    display: table-row !important;&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>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Template:Str_rightc&amp;diff=8622</id>
		<title>Template:Str rightc</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Template:Str_rightc&amp;diff=8622"/>
		<updated>2026-01-22T17:12:02Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{{safesubst:#switch:{{safesubst:#if:{{{1|}}}|a}}{{safesubst:#iferror:{{safesubst:#ifexpr:{{{2|}}}&amp;gt;0|b}}|c}}&lt;br /&gt;
|ab={{safesubst:#invoke:ustring|sub|s1={{{1|}}}|-{{{2|}}}}}&lt;br /&gt;
|ac={{{1|}}}&lt;br /&gt;
|a=&lt;br /&gt;
|{{{3|}}}}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Module:List&amp;diff=8620</id>
		<title>Module:List</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Module:List&amp;diff=8620"/>
		<updated>2026-01-22T17:12:02Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&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;
			or args[&#039;li_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;
			or args[&#039;li_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:含有过期参数的列表模板]]&#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;不是合适的列表类型)&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>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Template:Transclude&amp;diff=8618</id>
		<title>Template:Transclude</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Template:Transclude&amp;diff=8618"/>
		<updated>2026-01-22T17:12:02Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#switch: {{NAMESPACE: {{{1}}} }}&lt;br /&gt;
 |#default = {{FULLPAGENAME: {{{1}}} }} &amp;lt;!-- eg &amp;quot;User:Foo&amp;quot; --&amp;gt;&lt;br /&gt;
 |{{ns:0}} = &lt;br /&gt;
    {{#ifeq: {{NAMESPACE: {{{1}}} }} | {{NAMESPACE: Template{{{1}}} }}&lt;br /&gt;
      | Template:{{{1}}}            &amp;lt;!-- no leading colon, eg &amp;quot;Foo&amp;quot; --&amp;gt;&lt;br /&gt;
      | {{PAGENAME: {{{1}}} }}      &amp;lt;!-- leading colon, eg &amp;quot;:Foo&amp;quot;, so we want the article --&amp;gt;&lt;br /&gt;
    }}&lt;br /&gt;
}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Template:Tl&amp;diff=8616</id>
		<title>Template:Tl</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Template:Tl&amp;diff=8616"/>
		<updated>2026-01-22T17:12:02Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;&amp;amp;#123;&amp;amp;#123;[[{{transclude|{{{1}}}}}|{{{1}}}]]{{#if:{{{2|{{{arg|}}}}}}|{{!}}{{{2|{{{arg}}}}}}}}&amp;amp;#125;&amp;amp;#125;&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Documentation}}&lt;br /&gt;
&amp;lt;!-- 請在將分類與跨語言連結增加在 /doc 子頁面 --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Template:Para&amp;diff=8614</id>
		<title>Template:Para</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Template:Para&amp;diff=8614"/>
		<updated>2026-01-22T17:12:02Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code lang=&amp;quot;en&amp;quot; class=&amp;quot;nowrap&amp;quot;&amp;gt;&amp;amp;#124;{{#if:{{{1|}}}|{{{1}}}&amp;amp;#61;}}{{{2|}}}&amp;lt;/code&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Documentation}}&lt;br /&gt;
[[Category:輸入支援模板]]&lt;br /&gt;
[[Category:格式模板]]&lt;br /&gt;
&amp;lt;!--Categories and interwikis go near the bottom of the /doc subpage.--&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Module:Navbar&amp;diff=8612</id>
		<title>Module:Navbar</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Module:Navbar&amp;diff=8612"/>
		<updated>2026-01-22T17:12:01Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&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.html_class)&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;-{zh-hans:查;zh-hant:閱;}-&#039;, [&#039;full&#039;] = &#039;-{zh-hans:查看;zh-hant:檢視;}-&#039;, [&#039;html_title&#039;] = &#039;-{zh-hans:查看;zh-hant:檢視;}-该模板&#039;,&lt;br /&gt;
			[&#039;html_class&#039;] = &#039;view&#039;, [&#039;link&#039;] = title.fullText, [&#039;url&#039;] = false },&lt;br /&gt;
		{ [&#039;mini&#039;] = &#039;论&#039;, [&#039;full&#039;] = &#039;讨论&#039;, [&#039;html_title&#039;] = &#039;讨论该模板&#039;,&lt;br /&gt;
			[&#039;html_class&#039;] = &#039;talk&#039;, [&#039;link&#039;] = talkpage, [&#039;url&#039;] = false },&lt;br /&gt;
		{ [&#039;mini&#039;] = &#039;编&#039;, [&#039;full&#039;] = &#039;编辑&#039;, [&#039;html_title&#039;] = &#039;编辑该模板&#039;,&lt;br /&gt;
			[&#039;html_class&#039;] = &#039;edit&#039;, [&#039;link&#039;] = &#039;Special:EditPage/&#039; .. title.fullText, [&#039;url&#039;] = false },&lt;br /&gt;
		{ [&#039;mini&#039;] = &#039;史&#039;, [&#039;full&#039;] = &#039;历史&#039;, [&#039;html_title&#039;] = &#039;该模板的历史&#039;,&lt;br /&gt;
			[&#039;html_class&#039;] = &#039;hist&#039;, [&#039;link&#039;] = &#039;Special:PageHistory/&#039; .. title.fullText, [&#039;url&#039;] = false },&lt;br /&gt;
		{ [&#039;mini&#039;] = &#039;移&#039;, [&#039;full&#039;] = &#039;移动&#039;, [&#039;html_title&#039;] = &#039;移动该模板&#039;,&lt;br /&gt;
			[&#039;html_class&#039;] = &#039;move&#039;, [&#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;监&#039;, [&#039;full&#039;] = &#039;监视&#039;, [&#039;html_title&#039;] = &#039;监视该模板&#039;, &lt;br /&gt;
			[&#039;html_class&#039;] = &#039;watch&#039;, [&#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>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Template:Clear&amp;diff=8610</id>
		<title>Template:Clear</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Template:Clear&amp;diff=8610"/>
		<updated>2026-01-22T17:12:01Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;clear:{{{1|both}}};&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;noinclude&amp;gt;{{documentation}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Module:Infobox&amp;diff=8608</id>
		<title>Module:Infobox</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Module:Infobox&amp;diff=8608"/>
		<updated>2026-01-22T17:12:01Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- 中文的此模块对比英文维基多解析了overimage, overcaption,&lt;br /&gt;
-- overimagerowclass以及header/labal/data*style参数。&lt;br /&gt;
&lt;br /&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 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;
					-- for individual headerstyle: target .infobox-&amp;lt;name&amp;gt; .infobox-&amp;lt;name&amp;gt;-row&amp;lt;number&amp;gt; &amp;gt; .infobox-header&lt;br /&gt;
					:cssText(rowArgs.headerstyle)&lt;br /&gt;
					:cssText(rowArgs.rowcellstyle)&lt;br /&gt;
					:wikitext(fixChildBoxes(rowArgs.header, &#039;th&#039;))&lt;br /&gt;
		if rowArgs.data then&lt;br /&gt;
			root:wikitext(&lt;br /&gt;
				&#039;[[Category:使用已忽略数据行信息框模板的条目]]&#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;
					-- for individual labelstyle: target .infobox-&amp;lt;name&amp;gt; .infobox-&amp;lt;name&amp;gt;-row&amp;lt;number&amp;gt; &amp;gt; .infobox-label&lt;br /&gt;
					:cssText(rowArgs.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;
			-- for individual datastyle: target .infobox-&amp;lt;name&amp;gt; .infobox-&amp;lt;name&amp;gt;-row&amp;lt;number&amp;gt; &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 renderOverImage()&lt;br /&gt;
	local caption = args.overcaption&lt;br /&gt;
	local data = mw.html.create():wikitext(args.overimage)&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.overimagerowclass&lt;br /&gt;
	})&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;
			headerstyle = (args.headerstyle or &#039;&#039;) .. (args.headerstyle and &#039;;&#039; or &#039;&#039;) .. (args[&#039;header&#039; .. tostring(num) .. &#039;style&#039;] or &#039;&#039;),&lt;br /&gt;
			label = args[&#039;label&#039; .. tostring(num)],&lt;br /&gt;
			labelstyle = (args.labelstyle or &#039;&#039;) .. (args.labelstyle and &#039;;&#039; or &#039;&#039;) .. (args[&#039;label&#039; .. tostring(num) .. &#039;style&#039;] or &#039;&#039;),&lt;br /&gt;
			data = args[&#039;data&#039; .. tostring(num)],&lt;br /&gt;
			datastyle = (args.datastyle or &#039;&#039;) .. (args.datastyle and &#039;;&#039; or &#039;&#039;) .. (args[&#039;data&#039; .. tostring(num) .. &#039;style&#039;] or &#039;&#039;),&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 args.decat == &#039;yes&#039; 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:使用带有标题参数的嵌入式信息框模板的条目]]&#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:使用无数据行信息框模板的条目]]&#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;
		renderOverImage()&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;
-- Assign the parameters *style to the args table&lt;br /&gt;
local function preprocessSpecificStyle(styleTable, step)&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(styleTable) do&lt;br /&gt;
				local styleArgName = v.arg .. tostring(i) .. &#039;style&#039;&lt;br /&gt;
				if origArgs[styleArgName] then&lt;br /&gt;
					-- Do another loop if any arguments are found, even blank ones.&lt;br /&gt;
					moreArgumentsExist = true&lt;br /&gt;
					preprocessSingleArg(styleArgName)&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;overimage&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;overcaption&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;overimagerowclass&#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;
	}, 80)&lt;br /&gt;
	preprocessSpecificStyle({&lt;br /&gt;
		{arg = &#039;header&#039;},&lt;br /&gt;
		{arg = &#039;label&#039;},&lt;br /&gt;
		{arg = &#039;data&#039;}&lt;br /&gt;
	}, 80)&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>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Module:Crc32lua&amp;diff=8606</id>
		<title>Module:Crc32lua</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Module:Crc32lua&amp;diff=8606"/>
		<updated>2026-01-22T17:12:01Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--[[&lt;br /&gt;
&lt;br /&gt;
LUA MODULE&lt;br /&gt;
&lt;br /&gt;
  digest.crc32 - CRC-32 checksum implemented entirely in Lua.&lt;br /&gt;
&lt;br /&gt;
SYNOPSIS&lt;br /&gt;
&lt;br /&gt;
  local CRC = require &#039;digest.crc32lua&#039;&lt;br /&gt;
  print(CRC.crc32 &#039;test&#039;) --&amp;gt; 0xD87F7E0C or -662733300&lt;br /&gt;
  &lt;br /&gt;
  assert(CRC.crc32(&#039;st&#039;, CRC.crc32(&#039;te&#039;)) == CRC.crc32 &#039;test&#039;)&lt;br /&gt;
  &lt;br /&gt;
DESCRIPTION&lt;br /&gt;
&lt;br /&gt;
  This can be used to compute CRC-32 checksums on strings.&lt;br /&gt;
  This is similar to [1-2].&lt;br /&gt;
&lt;br /&gt;
API&lt;br /&gt;
&lt;br /&gt;
  Note: in the functions below, checksums are 32-bit integers stored in&lt;br /&gt;
  numbers.  The number format currently depends on the bit&lt;br /&gt;
  implementation--see DESIGN NOTES below.&lt;br /&gt;
&lt;br /&gt;
  CRC.crc32_byte(byte [, crc]) --&amp;gt; rcrc&lt;br /&gt;
  &lt;br /&gt;
    Returns CRC-32 checksum `rcrc` of byte `byte` (number 0..255) appended to&lt;br /&gt;
    a string with CRC-32 checksum `crc`.  `crc` defaults to 0 (empty string)&lt;br /&gt;
    if omitted.&lt;br /&gt;
&lt;br /&gt;
  CRC.crc32_string(s, crc) --&amp;gt; bcrc&lt;br /&gt;
&lt;br /&gt;
    Returns CRC-32 checksum `rcrc` of string `s` appended to&lt;br /&gt;
    a string with CRC-32 checksum `crc`.  `crc` defaults to 0 (empty string)&lt;br /&gt;
    if omitted.&lt;br /&gt;
  &lt;br /&gt;
  CRC.crc32(o, crc) --&amp;gt; bcrc&lt;br /&gt;
&lt;br /&gt;
    This invokes `crc32_byte` if `o` is a byte or `crc32_string` if `o`&lt;br /&gt;
    is a string.&lt;br /&gt;
  &lt;br /&gt;
  CRC.bit&lt;br /&gt;
&lt;br /&gt;
    This contains the underlying bit library used by the module.  It&lt;br /&gt;
    should be considered a read-only copy.&lt;br /&gt;
&lt;br /&gt;
DESIGN NOTES&lt;br /&gt;
&lt;br /&gt;
  Currently, this module exposes the underlying bit array implementation in CRC&lt;br /&gt;
  checksums returned.  In BitOp, bit arrays are 32-bit signed integer numbers&lt;br /&gt;
  (may be negative).  In Lua 5.2 &#039;bit32&#039; and &#039;bit.numberlua&#039;, bit arrays are&lt;br /&gt;
  32-bit unsigned integer numbers (non-negative).  This is subject to change&lt;br /&gt;
  in the future but is currently done due to (unconfirmed) performance&lt;br /&gt;
  implications.&lt;br /&gt;
  &lt;br /&gt;
  On platforms with 64-bit numbers, one way to normalize CRC&lt;br /&gt;
  checksums to be unsigned is to do `crcvalue % 2^32`,&lt;br /&gt;
  &lt;br /&gt;
  The name of this module is inspired by Perl `Digest::CRC*`.&lt;br /&gt;
&lt;br /&gt;
DEPENDENCIES&lt;br /&gt;
 &lt;br /&gt;
  Requires one of the following bit libraries:&lt;br /&gt;
&lt;br /&gt;
    BitOp &amp;quot;bit&amp;quot; -- bitop.luajit.org -- This is included in LuaJIT and also available&lt;br /&gt;
      for Lua 5.1/5.2.  This provides the fastest performance in LuaJIT.&lt;br /&gt;
    Lua 5.2 &amp;quot;bit32&amp;quot; -- www.lua.org/manual/5.2 -- This is provided in Lua 5.2&lt;br /&gt;
      and is preferred in 5.2 (unless &amp;quot;bit&amp;quot; also happens to be installed).&lt;br /&gt;
    &amp;quot;bit.numberlua&amp;quot; (&amp;gt;=000.003) -- https://github.com/davidm/lua-bit-numberlua&lt;br /&gt;
      This is slowest and used as a last resort.&lt;br /&gt;
      It is only a few times slower than &amp;quot;bit32&amp;quot; though.&lt;br /&gt;
&lt;br /&gt;
DOWNLOAD/INSTALLATION&lt;br /&gt;
&lt;br /&gt;
  If using LuaRocks:&lt;br /&gt;
    luarocks install lua-digest-crc32lua&lt;br /&gt;
&lt;br /&gt;
  Otherwise, download &amp;lt;https://github.com/davidm/lua-digest-crc32lua/zipball/master&amp;gt;.&lt;br /&gt;
  Alternately, if using git:&lt;br /&gt;
    git clone git://github.com/davidm/lua-digest-crc32lua.git&lt;br /&gt;
    cd lua-digest-crc32lua&lt;br /&gt;
  Optionally unpack:&lt;br /&gt;
    ./util.mk&lt;br /&gt;
  or unpack and install in LuaRocks:&lt;br /&gt;
    ./util.mk install &lt;br /&gt;
  &lt;br /&gt;
REFERENCES&lt;br /&gt;
&lt;br /&gt;
  [1] http://www.axlradius.com/freestuff/CRC32.java&lt;br /&gt;
  [2] http://www.gamedev.net/reference/articles/article1941.asp&lt;br /&gt;
  [3] http://java.sun.com/j2se/1.5.0/docs/api/java/util/zip/CRC32.html&lt;br /&gt;
  [4] http://www.dsource.org/projects/tango/docs/current/tango.io.digest.Crc32.html&lt;br /&gt;
  [5] http://pydoc.org/1.5.2/zlib.html#-crc32&lt;br /&gt;
  [6] http://www.python.org/doc/2.5.2/lib/module-binascii.html&lt;br /&gt;
 &lt;br /&gt;
LICENSE&lt;br /&gt;
&lt;br /&gt;
  (c) 2008-2011 David Manura.  Licensed under the same terms as Lua (MIT).&lt;br /&gt;
&lt;br /&gt;
  Permission is hereby granted, free of charge, to any person obtaining a copy&lt;br /&gt;
  of this software and associated documentation files (the &amp;quot;Software&amp;quot;), to deal&lt;br /&gt;
  in the Software without restriction, including without limitation the rights&lt;br /&gt;
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell&lt;br /&gt;
  copies of the Software, and to permit persons to whom the Software is&lt;br /&gt;
  furnished to do so, subject to the following conditions:&lt;br /&gt;
&lt;br /&gt;
  The above copyright notice and this permission notice shall be included in&lt;br /&gt;
  all copies or substantial portions of the Software.&lt;br /&gt;
&lt;br /&gt;
  THE SOFTWARE IS PROVIDED &amp;quot;AS IS&amp;quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR&lt;br /&gt;
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,&lt;br /&gt;
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE&lt;br /&gt;
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER&lt;br /&gt;
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,&lt;br /&gt;
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN&lt;br /&gt;
  THE SOFTWARE.&lt;br /&gt;
  (end license)&lt;br /&gt;
 &lt;br /&gt;
--]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local M = {_TYPE=&#039;module&#039;, _NAME=&#039;digest.crc32&#039;, _VERSION=&#039;0.3.20111128&#039;}&lt;br /&gt;
&lt;br /&gt;
local type = type&lt;br /&gt;
local require = require&lt;br /&gt;
local setmetatable = setmetatable&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
 Requires the first module listed that exists, else raises like `require`.&lt;br /&gt;
 If a non-string is encountered, it is returned.&lt;br /&gt;
 Second return value is module name loaded (or &#039;&#039;).&lt;br /&gt;
 --]]&lt;br /&gt;
local function requireany(...)&lt;br /&gt;
  local errs = {}&lt;br /&gt;
  for _,name in ipairs{...} do&lt;br /&gt;
    if type(name) ~= &#039;string&#039; then return name, &#039;&#039; end&lt;br /&gt;
    local ok, mod = pcall(require, name)&lt;br /&gt;
    if ok then return mod, name end&lt;br /&gt;
    errs[#errs+1] = mod&lt;br /&gt;
  end&lt;br /&gt;
  error(table.concat(errs, &#039;\n&#039;), 2)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local bit, name_ = requireany(&#039;bit32&#039;, &#039;bit&#039;, &#039;bit.numberlua&#039;)&lt;br /&gt;
local bxor = bit.bxor&lt;br /&gt;
local bnot = bit.bnot&lt;br /&gt;
local band = bit.band&lt;br /&gt;
local rshift = bit.rshift&lt;br /&gt;
&lt;br /&gt;
-- CRC-32-IEEE 802.3 (V.42)&lt;br /&gt;
local POLY = 0xEDB88320&lt;br /&gt;
&lt;br /&gt;
-- Memoize function pattern (like http://lua-users.org/wiki/FuncTables ).&lt;br /&gt;
local function memoize(f)&lt;br /&gt;
  local mt = {}&lt;br /&gt;
  local t = setmetatable({}, mt)&lt;br /&gt;
  function mt:__index(k)&lt;br /&gt;
    local v = f(k); t[k] = v&lt;br /&gt;
    return v&lt;br /&gt;
  end&lt;br /&gt;
  return t&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- CRC table.&lt;br /&gt;
local crc_table = memoize(function(i)&lt;br /&gt;
  local crc = i&lt;br /&gt;
  for _=1,8 do&lt;br /&gt;
    local b = band(crc, 1)&lt;br /&gt;
    crc = rshift(crc, 1)&lt;br /&gt;
    if b == 1 then crc = bxor(crc, POLY) end&lt;br /&gt;
  end&lt;br /&gt;
  return crc&lt;br /&gt;
end)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function M.crc32_byte(byte, crc)&lt;br /&gt;
  crc = bnot(crc or 0)&lt;br /&gt;
  local v1 = rshift(crc, 8)&lt;br /&gt;
  local v2 = crc_table[bxor(crc % 256, byte)]&lt;br /&gt;
  return bnot(bxor(v1, v2))&lt;br /&gt;
end&lt;br /&gt;
local M_crc32_byte = M.crc32_byte&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function M.crc32_string(s, crc)&lt;br /&gt;
  crc = crc or 0&lt;br /&gt;
  for i=1,#s do&lt;br /&gt;
    crc = M_crc32_byte(s:byte(i), crc)&lt;br /&gt;
  end&lt;br /&gt;
  return crc&lt;br /&gt;
end&lt;br /&gt;
local M_crc32_string = M.crc32_string&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function M.crc32(s, crc)&lt;br /&gt;
  if type(s) == &#039;string&#039; then&lt;br /&gt;
    return M_crc32_string(s, crc)&lt;br /&gt;
  else&lt;br /&gt;
    return M_crc32_byte(s, crc)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
M.bit = bit  -- bit library used&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
return M&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Module:CGroup/core&amp;diff=8604</id>
		<title>Module:CGroup/core</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Module:CGroup/core&amp;diff=8604"/>
		<updated>2026-01-22T17:12:01Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
function p.Item(o, r)&lt;br /&gt;
	-- See [[Wikipedia:字詞轉換處理/公共轉換組]]&lt;br /&gt;
	-- o: 原文。若無此屬性，應使用nil而非空字串（&#039;&#039;）。&lt;br /&gt;
	-- r: 用於全文轉換的規則，必填。&lt;br /&gt;
    return { type = &#039;item&#039;, original = o, rule = r };&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Module:WikitextLC&amp;diff=8602</id>
		<title>Module:WikitextLC</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Module:WikitextLC&amp;diff=8602"/>
		<updated>2026-01-22T17:12:00Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
--- Construct an inline conversion from a table input.&lt;br /&gt;
-- @param content table of the form&lt;br /&gt;
--        { [&amp;quot;zh-cn&amp;quot;]=&#039;foobar&#039;, [&amp;quot;zh-tw&amp;quot;]=&#039;firecat&#039;, [&amp;quot;zh-hk&amp;quot;]=&#039;&#039; }&lt;br /&gt;
-- @returns string&lt;br /&gt;
--       &amp;quot;-{zh-cn:foobar;zh-tw:firecat;zh-hk:&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;}-&amp;quot;&lt;br /&gt;
--&lt;br /&gt;
-- @fixme allow for generating output without &amp;quot;-{&amp;quot; &amp;quot;}-&amp;quot;, so that&lt;br /&gt;
--        it can be used with the last three wrappers.&lt;br /&gt;
function p.selective( content )&lt;br /&gt;
    local text = &#039;-{&#039;&lt;br /&gt;
    for variant, value in pairs( content ) do&lt;br /&gt;
        if value == &#039;&#039; then&lt;br /&gt;
            value = &#039;&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
        end&lt;br /&gt;
        text = text .. variant .. &#039;:&#039; .. value .. &#039;;&#039;&lt;br /&gt;
    end&lt;br /&gt;
    text = text .. &#039;}-&#039;&lt;br /&gt;
    return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--- Write some text with a limited set of variants to convert to&lt;br /&gt;
--&lt;br /&gt;
-- @param content text to be written&lt;br /&gt;
-- @param variant a variant (string), or a list of variants&lt;br /&gt;
--        (semicolon-deliminated string, or table of strings)&lt;br /&gt;
-- @param[opt] force convert even under &amp;quot;zh&amp;quot; (no conversion) locale&lt;br /&gt;
function p.converted( content, variant, force )&lt;br /&gt;
    if type( variant ) == &#039;table&#039; then&lt;br /&gt;
        variant = table.concat( variant, &#039;;&#039; )&lt;br /&gt;
    end&lt;br /&gt;
    return &#039;-{&#039; .. ( force and &#039;&#039; or &#039;zh;&#039; ) .. variant .. &#039;|&#039; .. content .. &#039;}-&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--- Wraps some &amp;quot;raw text&amp;quot; to not convert.&lt;br /&gt;
--&lt;br /&gt;
-- @fixme Is the &amp;quot;R&amp;quot; flag some undocumented/undefined no-op magic?&lt;br /&gt;
--        Are we using it instead of the old &#039;-{&#039; .. content .. &#039;}-&#039;&lt;br /&gt;
--        to avoid confusion caused by a flag in the &amp;quot;content&amp;quot;?&lt;br /&gt;
function p.raw( content )&lt;br /&gt;
    return &#039;-{R|&#039; .. content .. &#039;}-&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--- Wraps a title conversion rule.&lt;br /&gt;
function p.title( content )&lt;br /&gt;
    return &#039;-{T|&#039; .. content .. &#039;}-&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--- Wraps a (hidden) conversion rule definition.&lt;br /&gt;
function p.hidden( content )&lt;br /&gt;
    return &#039;-{H|&#039; .. content .. &#039;}-&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Module:NoteTA&amp;diff=8600</id>
		<title>Module:NoteTA</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Module:NoteTA&amp;diff=8600"/>
		<updated>2026-01-22T17:12:00Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local z = {}&lt;br /&gt;
local WikitextLC = require( &#039;Module:WikitextLC&#039; )&lt;br /&gt;
&lt;br /&gt;
function Tcode( args )&lt;br /&gt;
	if args.T == nil or args.T == &#039;&#039; then&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local div = mw.html.create( &#039;div&#039; )&lt;br /&gt;
		:attr( &#039;class&#039;, &#039;noteTA-title&#039; )&lt;br /&gt;
		:attr( &#039;data-noteta-code&#039;, args.T )&lt;br /&gt;
		:wikitext( WikitextLC.title( args.T ) )&lt;br /&gt;
	if args.dt ~= nil and args.dt ~= &#039;&#039; then&lt;br /&gt;
		div:attr( &#039;data-noteta-desc&#039;, args.dt )&lt;br /&gt;
	end&lt;br /&gt;
	return tostring( div )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function group( name, frame )&lt;br /&gt;
	if name == nil or name == &#039;&#039; then&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local moduleTitle = mw.title.makeTitle( &#039;Module&#039;, &#039;CGroup/&#039; .. name )&lt;br /&gt;
	if moduleTitle and moduleTitle.exists then&lt;br /&gt;
		local data = mw.loadData( &#039;Module:CGroup/&#039; .. name )&lt;br /&gt;
		local pieces = {}&lt;br /&gt;
		if data.content then&lt;br /&gt;
			for i, v in ipairs( data.content ) do&lt;br /&gt;
				if v.type == &#039;item&#039; and v.rule then&lt;br /&gt;
					table.insert( pieces, &#039;-{H|&#039; .. v.rule .. &#039;}-&#039; )&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			return tostring( mw.html.create( &#039;div&#039; )&lt;br /&gt;
				:attr( &#039;data-noteta-group-source&#039;, &#039;module&#039; )&lt;br /&gt;
				:attr( &#039;data-noteta-group&#039;, data.name or name )&lt;br /&gt;
				:wikitext( table.concat( pieces ) ) )&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local templateTitle = mw.title.makeTitle( &#039;Template&#039;, &#039;CGroup/&#039; .. name )&lt;br /&gt;
	if templateTitle and templateTitle.exists then&lt;br /&gt;
		return frame:expandTemplate{ title = templateTitle }&lt;br /&gt;
	end&lt;br /&gt;
	return tostring( mw.html.create( &#039;div&#039; )&lt;br /&gt;
			-- :attr( &#039;id&#039;, &#039;noteTA-group-&#039; .. mw.uri.anchorEncode( name ) )&lt;br /&gt;
			:attr( &#039;data-noteta-group-source&#039;, &#039;none&#039; )&lt;br /&gt;
			:attr( &#039;data-noteta-group&#039;, name ) )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Gcode( args, frame )&lt;br /&gt;
	local code = {}&lt;br /&gt;
	for i = 1, 30 do&lt;br /&gt;
		table.insert( code, group( args[&#039;G&#039; .. i], frame ) )&lt;br /&gt;
	end&lt;br /&gt;
	code = table.concat( code )&lt;br /&gt;
	if code ~= &#039;&#039; then&lt;br /&gt;
		code = tostring( mw.html.create( &#039;div&#039; )&lt;br /&gt;
				:attr( &#039;class&#039;, &#039;noteTA-group&#039; )&lt;br /&gt;
				:wikitext( code ) )&lt;br /&gt;
		if args.G31 ~= nil then&lt;br /&gt;
			code = code .. &#039;[[Category:NoteTA模板参数使用数量超过限制的页面|G]]&#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return code&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function local_( i, code, desc )&lt;br /&gt;
	if code == nil or code == &#039;&#039; then&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local div = mw.html.create( &#039;div&#039; )&lt;br /&gt;
		-- :attr( &#039;id&#039;, &#039;noteTA-local-&#039; .. i )&lt;br /&gt;
		:attr( &#039;data-noteta-code&#039;, code )&lt;br /&gt;
		:wikitext( WikitextLC.hidden( code ) )&lt;br /&gt;
	if desc ~= nil and desc ~= &#039;&#039; then&lt;br /&gt;
		div:attr( &#039;data-noteta-desc&#039;, desc )&lt;br /&gt;
	end&lt;br /&gt;
	return tostring( div )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Lcode( args )&lt;br /&gt;
	local code = {}&lt;br /&gt;
	for i = 1, 30 do&lt;br /&gt;
		table.insert( code, local_( i, args[i], args[&#039;d&#039; .. i] ) )&lt;br /&gt;
	end&lt;br /&gt;
	code = table.concat( code )&lt;br /&gt;
	if code ~= &#039;&#039; then&lt;br /&gt;
		code = tostring( mw.html.create( &#039;div&#039; )&lt;br /&gt;
				:attr( &#039;class&#039;, &#039;noteTA-local&#039; )&lt;br /&gt;
				:wikitext( code ) )&lt;br /&gt;
		if args[31] ~= nil then&lt;br /&gt;
			code = code .. &#039;[[Category:NoteTA模板参数使用数量超过限制的页面|L]]&#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return code&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function z.main( frame )&lt;br /&gt;
	local args&lt;br /&gt;
	if frame == mw.getCurrentFrame() then&lt;br /&gt;
		-- Being called from {{noteTA}}&lt;br /&gt;
		args = require(&#039;Module:Arguments&#039;).getArgs(frame)&lt;br /&gt;
	else&lt;br /&gt;
		-- Being called from another module&lt;br /&gt;
		args = frame&lt;br /&gt;
		frame = mw.getCurrentFrame()&lt;br /&gt;
	end&lt;br /&gt;
	local Tc = Tcode( args )&lt;br /&gt;
	local Gc = Gcode( args, frame )&lt;br /&gt;
	local Lc = Lcode( args )&lt;br /&gt;
	local code = Tc .. Gc .. Lc&lt;br /&gt;
	if code ~= &#039;&#039; then&lt;br /&gt;
		local hash = require( &#039;Module:Crc32lua&#039; ).crc32( mw.dumpObject( args ) )&lt;br /&gt;
		code = frame:extensionTag{&lt;br /&gt;
			name = &#039;indicator&#039;,&lt;br /&gt;
			content = &#039;[[File:Zh conversion icon m.svg|35px|本页使用了标题或全文手工转换|link=|class=skin-invert]]&#039;,&lt;br /&gt;
			args = { name = string.format( &#039;noteTA-%x&#039;, hash ) },&lt;br /&gt;
		} .. tostring( mw.html.create( &#039;div&#039; )&lt;br /&gt;
				:attr( &#039;id&#039;, string.format( &#039;noteTA-%x&#039;, hash ) )&lt;br /&gt;
				:attr( &#039;class&#039;, &#039;noteTA&#039; )&lt;br /&gt;
				:wikitext( code ) )&lt;br /&gt;
		if mw.title.getCurrentTitle():inNamespace( &#039;Template&#039; ) then&lt;br /&gt;
			code = code .. &#039;[[Category:放置于模板的noteTA]]&#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return code&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return z&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Template:Nowrap&amp;diff=8598</id>
		<title>Template:Nowrap</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Template:Nowrap&amp;diff=8598"/>
		<updated>2026-01-22T17:12:00Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;&amp;lt;span class=&amp;quot;nowrap&amp;quot;&amp;gt;{{{1}}}&amp;lt;/span&amp;gt;&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;{{Documentation}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Template:NoteTA&amp;diff=8596</id>
		<title>Template:NoteTA</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Template:NoteTA&amp;diff=8596"/>
		<updated>2026-01-22T17:12:00Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#invoke:NoteTA|main}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{模板文档}}&lt;br /&gt;
&amp;lt;!-- 請在將分類與跨語言連結增加在 /doc 子頁面 --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Module:TableTools&amp;diff=8594</id>
		<title>Module:TableTools</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Module:TableTools&amp;diff=8594"/>
		<updated>2026-01-22T17:12:00Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&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;
		else&lt;br /&gt;
			if 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;
	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;
	-- Stores copies of tables indexed by the original table.&lt;br /&gt;
	already_seen = already_seen or {}&lt;br /&gt;
&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;
	if type(orig) == &#039;table&#039; then&lt;br /&gt;
		copy = {}&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;
		already_seen[orig] = copy&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;
				local mt_copy = _deepCopy(mt, includeMetatable, already_seen)&lt;br /&gt;
				setmetatable(copy, mt_copy)&lt;br /&gt;
				already_seen[mt] = mt_copy&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else -- number, string, boolean, etc&lt;br /&gt;
		copy = orig&lt;br /&gt;
	end&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)&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 valueToFind is a member of the array, and false otherwise.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
function p.inArray(arr, valueToFind)&lt;br /&gt;
	checkType(&amp;quot;inArray&amp;quot;, 1, arr, &amp;quot;table&amp;quot;)&lt;br /&gt;
	-- if valueToFind is nil, error?&lt;br /&gt;
&lt;br /&gt;
	for _, v in ipairs(arr) do&lt;br /&gt;
		if v == valueToFind then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Module:Separated_entries&amp;diff=8592</id>
		<title>Module:Separated entries</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Module:Separated_entries&amp;diff=8592"/>
		<updated>2026-01-22T17:11:59Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This module takes positional parameters as input and concatenates them with&lt;br /&gt;
-- an optional separator. The final separator (the &amp;quot;conjunction&amp;quot;) can be&lt;br /&gt;
-- specified independently, enabling natural-language lists like&lt;br /&gt;
-- &amp;quot;foo, bar, baz and qux&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
local compressSparseArray = require(&#039;Module:TableTools&#039;).compressSparseArray&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
function p._main(args)&lt;br /&gt;
	local separator = args.separator&lt;br /&gt;
		-- Decode (convert to Unicode) HTML escape sequences, such as &amp;quot;&amp;amp;#32;&amp;quot; for space.&lt;br /&gt;
		and mw.text.decode(args.separator) or &#039;&#039;&lt;br /&gt;
	local conjunction = args.conjunction and mw.text.decode(args.conjunction) or separator&lt;br /&gt;
	-- Discard named parameters.&lt;br /&gt;
	local values = compressSparseArray(args)&lt;br /&gt;
	return mw.text.listToText(values, separator, conjunction)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function makeInvokeFunction(separator, conjunction)&lt;br /&gt;
	return function (frame)&lt;br /&gt;
		local args = require(&#039;Module:Arguments&#039;).getArgs(frame)&lt;br /&gt;
		args.separator = separator or args.separator&lt;br /&gt;
		args.conjunction = conjunction or args.conjunction&lt;br /&gt;
		return p._main(args)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.main = makeInvokeFunction()&lt;br /&gt;
p.br = makeInvokeFunction(&#039;&amp;lt;br /&amp;gt;&#039;)&lt;br /&gt;
p.comma = makeInvokeFunction(mw.message.new(&#039;comma-separator&#039;):plain())&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Module:Namespace_detect/config&amp;diff=8590</id>
		<title>Module:Namespace detect/config</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Module:Namespace_detect/config&amp;diff=8590"/>
		<updated>2026-01-22T17:11:59Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--------------------------------------------------------------------------------&lt;br /&gt;
--                    Namespace detect configuration data                     --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
-- This module stores configuration data for Module:Namespace detect. Here    --&lt;br /&gt;
-- you can localise the module to your wiki&#039;s language.                       --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
-- To activate a configuration item, you need to uncomment it. This means     --&lt;br /&gt;
-- that you need to remove the text &amp;quot;-- &amp;quot; at the start of the line.           --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local cfg = {} -- Don&#039;t edit this line.&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
--                              Parameter names                               --&lt;br /&gt;
-- These configuration items specify custom parameter names. Values added     --&lt;br /&gt;
-- here will work in addition to the default English parameter names.         --&lt;br /&gt;
-- To add one extra name, you can use this format:                            --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
-- cfg.foo = &#039;parameter name&#039;                                                 --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
-- To add multiple names, you can use this format:                            --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
-- cfg.foo = {&#039;parameter name 1&#039;, &#039;parameter name 2&#039;, &#039;parameter name 3&#039;}     --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
---- This parameter displays content for the main namespace:&lt;br /&gt;
-- cfg.main = &#039;main&#039;&lt;br /&gt;
&lt;br /&gt;
---- This parameter displays in talk namespaces:&lt;br /&gt;
-- cfg.talk = &#039;talk&#039;&lt;br /&gt;
&lt;br /&gt;
---- This parameter displays content for &amp;quot;other&amp;quot; namespaces (namespaces for which&lt;br /&gt;
---- parameters have not been specified):&lt;br /&gt;
-- cfg.other = &#039;other&#039;&lt;br /&gt;
&lt;br /&gt;
---- This parameter makes talk pages behave as though they are the corresponding&lt;br /&gt;
---- subject namespace. Note that this parameter is used with [[Module:Yesno]].&lt;br /&gt;
---- Edit that module to change the default values of &amp;quot;yes&amp;quot;, &amp;quot;no&amp;quot;, etc.&lt;br /&gt;
-- cfg.subjectns = &#039;subjectns&#039;&lt;br /&gt;
&lt;br /&gt;
---- This parameter sets a demonstration namespace:&lt;br /&gt;
-- cfg.demospace = &#039;demospace&#039;&lt;br /&gt;
&lt;br /&gt;
---- This parameter sets a specific page to compare:&lt;br /&gt;
cfg.demopage = &#039;page&#039;&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
--                           Table configuration                              --&lt;br /&gt;
-- These configuration items allow customisation of the &amp;quot;table&amp;quot; function,     --&lt;br /&gt;
-- used to generate a table of possible parameters in the module              --&lt;br /&gt;
-- documentation.                                                             --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
---- The header for the namespace column in the wikitable containing the list of&lt;br /&gt;
---- possible subject-space parameters.&lt;br /&gt;
-- cfg.wikitableNamespaceHeader = &#039;Namespace&#039;&lt;br /&gt;
&lt;br /&gt;
---- The header for the wikitable containing the list of possible subject-space&lt;br /&gt;
---- parameters.&lt;br /&gt;
-- cfg.wikitableAliasesHeader = &#039;Aliases&#039;&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
--                        End of configuration data                           --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
return cfg -- Don&#039;t edit this line.&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Module:Namespace_detect/data&amp;diff=8588</id>
		<title>Module:Namespace detect/data</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Module:Namespace_detect/data&amp;diff=8588"/>
		<updated>2026-01-22T17:11:59Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--------------------------------------------------------------------------------&lt;br /&gt;
--                          Namespace detect data                             --&lt;br /&gt;
-- This module holds data for [[Module:Namespace detect]] to be loaded per    --&lt;br /&gt;
-- page, rather than per #invoke, for performance reasons.                    --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local cfg = require(&#039;Module:Namespace detect/config&#039;)&lt;br /&gt;
&lt;br /&gt;
local function addKey(t, key, defaultKey)&lt;br /&gt;
	if key ~= defaultKey then&lt;br /&gt;
		t[#t + 1] = key&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Get a table of parameters to query for each default parameter name.&lt;br /&gt;
-- This allows wikis to customise parameter names in the cfg table while&lt;br /&gt;
-- ensuring that default parameter names will always work. The cfg table&lt;br /&gt;
-- values can be added as a string, or as an array of strings.&lt;br /&gt;
&lt;br /&gt;
local defaultKeys = {&lt;br /&gt;
	&#039;main&#039;,&lt;br /&gt;
	&#039;talk&#039;,&lt;br /&gt;
	&#039;other&#039;,&lt;br /&gt;
	&#039;subjectns&#039;,&lt;br /&gt;
	&#039;demospace&#039;,&lt;br /&gt;
	&#039;demopage&#039;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local argKeys = {}&lt;br /&gt;
for i, defaultKey in ipairs(defaultKeys) do&lt;br /&gt;
	argKeys[defaultKey] = {defaultKey}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
for defaultKey, t in pairs(argKeys) do&lt;br /&gt;
	local cfgValue = cfg[defaultKey]&lt;br /&gt;
	local cfgValueType = type(cfgValue)&lt;br /&gt;
	if cfgValueType == &#039;string&#039; then&lt;br /&gt;
		addKey(t, cfgValue, defaultKey)&lt;br /&gt;
	elseif cfgValueType == &#039;table&#039; then&lt;br /&gt;
		for i, key in ipairs(cfgValue) do&lt;br /&gt;
			addKey(t, key, defaultKey)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	cfg[defaultKey] = nil -- Free the cfg value as we don&#039;t need it any more.&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getParamMappings()&lt;br /&gt;
	--[[&lt;br /&gt;
	-- Returns a table of how parameter names map to namespace names. The keys&lt;br /&gt;
	-- are the actual namespace names, in lower case, and the values are the&lt;br /&gt;
	-- possible parameter names for that namespace, also in lower case. The&lt;br /&gt;
	-- table entries are structured like this:&lt;br /&gt;
	-- {&lt;br /&gt;
	--   [&#039;&#039;] = {&#039;main&#039;},&lt;br /&gt;
	--   [&#039;wikipedia&#039;] = {&#039;wikipedia&#039;, &#039;project&#039;, &#039;wp&#039;},&lt;br /&gt;
	--   ...&lt;br /&gt;
	-- }&lt;br /&gt;
	--]]&lt;br /&gt;
	local mappings = {}&lt;br /&gt;
	local mainNsName = mw.site.subjectNamespaces[0].name&lt;br /&gt;
	mainNsName = mw.ustring.lower(mainNsName)&lt;br /&gt;
	mappings[mainNsName] = mw.clone(argKeys.main)&lt;br /&gt;
	mappings[&#039;talk&#039;] = mw.clone(argKeys.talk)&lt;br /&gt;
	for nsid, ns in pairs(mw.site.subjectNamespaces) do&lt;br /&gt;
		if nsid ~= 0 then -- Exclude main namespace.&lt;br /&gt;
			local nsname = mw.ustring.lower(ns.name)&lt;br /&gt;
			local canonicalName = mw.ustring.lower(ns.canonicalName)&lt;br /&gt;
			mappings[nsname] = {nsname}&lt;br /&gt;
			if canonicalName ~= nsname then&lt;br /&gt;
				table.insert(mappings[nsname], canonicalName)&lt;br /&gt;
			end&lt;br /&gt;
			for _, alias in ipairs(ns.aliases) do&lt;br /&gt;
				table.insert(mappings[nsname], mw.ustring.lower(alias))&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return mappings&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return {&lt;br /&gt;
	argKeys = argKeys,&lt;br /&gt;
	cfg = cfg,&lt;br /&gt;
	mappings = getParamMappings()&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Module:Category_handler/blacklist&amp;diff=8586</id>
		<title>Module:Category handler/blacklist</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Module:Category_handler/blacklist&amp;diff=8586"/>
		<updated>2026-01-22T17:11:58Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This module contains the blacklist used by [[Module:Category handler]].&lt;br /&gt;
-- Pages that match Lua patterns in this list will not be categorised unless&lt;br /&gt;
-- categorisation is explicitly requested.&lt;br /&gt;
&lt;br /&gt;
return {&lt;br /&gt;
    &#039;^Main Page$&#039;, -- don&#039;t categorise the main page.&lt;br /&gt;
 &lt;br /&gt;
    -- Don&#039;t categorise the following pages or their subpages.&lt;br /&gt;
    -- &amp;quot;%f[/\0]&amp;quot; matches if the next character is &amp;quot;/&amp;quot; or the end of the string.&lt;br /&gt;
    &#039;^Wikipedia:Cascade%-protected items%f[/\0]&#039;,&lt;br /&gt;
    &#039;^User:UBX%f[/\0]&#039;, -- The userbox &amp;quot;template&amp;quot; space.&lt;br /&gt;
    &#039;^User talk:UBX%f[/\0]&#039;,&lt;br /&gt;
 &lt;br /&gt;
    -- Don&#039;t categorise subpages of these pages, but allow&lt;br /&gt;
    -- categorisation of the base page.&lt;br /&gt;
    &#039;^Wikipedia:Template messages/.*$&#039;,&lt;br /&gt;
 &lt;br /&gt;
    &#039;/[aA]rchive&#039; -- Don&#039;t categorise archives.&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Module:Category_handler/shared&amp;diff=8584</id>
		<title>Module:Category handler/shared</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Module:Category_handler/shared&amp;diff=8584"/>
		<updated>2026-01-22T17:11:58Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This module contains shared functions used by [[Module:Category handler]]&lt;br /&gt;
-- and its submodules.&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
function p.matchesBlacklist(page, blacklist)&lt;br /&gt;
	for i, pattern in ipairs(blacklist) do&lt;br /&gt;
		local match = mw.ustring.match(page, pattern)&lt;br /&gt;
		if match then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.getParamMappings(useLoadData)&lt;br /&gt;
	local dataPage = &#039;Module:Namespace detect/data&#039;&lt;br /&gt;
	if useLoadData then&lt;br /&gt;
		return mw.loadData(dataPage).mappings&lt;br /&gt;
	else&lt;br /&gt;
		return require(dataPage).mappings&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.getNamespaceParameters(titleObj, mappings)&lt;br /&gt;
	-- We don&#039;t use title.nsText for the namespace name because it adds&lt;br /&gt;
	-- underscores.&lt;br /&gt;
	local mappingsKey&lt;br /&gt;
	if titleObj.isTalkPage then&lt;br /&gt;
		mappingsKey = &#039;talk&#039;&lt;br /&gt;
	else&lt;br /&gt;
		mappingsKey = mw.site.namespaces[titleObj.namespace].name&lt;br /&gt;
	end&lt;br /&gt;
	mappingsKey = mw.ustring.lower(mappingsKey)&lt;br /&gt;
	return mappings[mappingsKey] or {}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Module:Category_handler/config&amp;diff=8582</id>
		<title>Module:Category handler/config</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Module:Category_handler/config&amp;diff=8582"/>
		<updated>2026-01-22T17:11:58Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--------------------------------------------------------------------------------&lt;br /&gt;
--            [[Module:Category handler]] configuration data                  --&lt;br /&gt;
--       Language-specific parameter names and values can be set here.        --&lt;br /&gt;
--       For blacklist config, see [[Module:Category handler/blacklist]].     --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local cfg = {} -- Don&#039;t edit this line.&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
--                       Start configuration data                             --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
--                              Parameter names                               --&lt;br /&gt;
-- These configuration items specify custom parameter names.                  --&lt;br /&gt;
-- To add one extra name, you can use this format:                            --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
-- foo = &#039;parameter name&#039;,                                                    --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
-- To add multiple names, you can use this format:                            --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
-- foo = {&#039;parameter name 1&#039;, &#039;parameter name 2&#039;, &#039;parameter name 3&#039;},        --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
cfg.parameters = {&lt;br /&gt;
	&lt;br /&gt;
	-- The nocat and categories parameter suppress&lt;br /&gt;
	-- categorisation. They are used with Module:Yesno, and work as follows:&lt;br /&gt;
	--&lt;br /&gt;
	-- cfg.nocat:&lt;br /&gt;
	-- Result of yesno()                        Effect&lt;br /&gt;
	-- true                                     Categorisation is suppressed&lt;br /&gt;
	-- false                                    Categorisation is allowed, and&lt;br /&gt;
	--                                          the blacklist check is skipped&lt;br /&gt;
	-- nil                                      Categorisation is allowed&lt;br /&gt;
	--&lt;br /&gt;
	-- cfg.categories:&lt;br /&gt;
	-- Result of yesno()                        Effect&lt;br /&gt;
	-- true                                     Categorisation is allowed, and&lt;br /&gt;
	--                                          the blacklist check is skipped&lt;br /&gt;
	-- false                                    Categorisation is suppressed&lt;br /&gt;
	-- nil                                      Categorisation is allowed&lt;br /&gt;
	nocat = &#039;nocat&#039;,&lt;br /&gt;
	categories = &#039;categories&#039;,&lt;br /&gt;
	&lt;br /&gt;
	-- The parameter name for the legacy &amp;quot;category2&amp;quot; parameter. This skips the&lt;br /&gt;
	-- blacklist if set to the cfg.category2Yes value, and suppresses&lt;br /&gt;
	-- categorisation if present but equal to anything other than&lt;br /&gt;
	-- cfg.category2Yes or cfg.category2Negative.&lt;br /&gt;
	category2 = &#039;category2&#039;,&lt;br /&gt;
	&lt;br /&gt;
	-- cfg.subpage is the parameter name to specify how to behave on subpages.&lt;br /&gt;
	subpage = &#039;subpage&#039;,&lt;br /&gt;
	&lt;br /&gt;
	-- The parameter for data to return in all namespaces.&lt;br /&gt;
	all = &#039;all&#039;,&lt;br /&gt;
	&lt;br /&gt;
	-- The parameter name for data to return if no data is specified for the&lt;br /&gt;
	-- namespace that is detected.&lt;br /&gt;
	other = &#039;other&#039;,&lt;br /&gt;
	&lt;br /&gt;
	-- The parameter name used to specify a page other than the current page;&lt;br /&gt;
	-- used for testing and demonstration.&lt;br /&gt;
	demopage = &#039;page&#039;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
--                              Parameter values                              --&lt;br /&gt;
-- These are set values that can be used with certain parameters. Only one    --&lt;br /&gt;
-- value can be specified, like this:                                         --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
-- cfg.foo = &#039;value name&#039;                                                     --                                               --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
-- The following settings are used with the cfg.category2 parameter. Setting&lt;br /&gt;
-- cfg.category2 to cfg.category2Yes skips the blacklist, and if cfg.category2&lt;br /&gt;
-- is present but equal to anything other than cfg.category2Yes or&lt;br /&gt;
-- cfg.category2Negative then it supresses cateogrisation.&lt;br /&gt;
cfg.category2Yes = &#039;yes&#039;&lt;br /&gt;
cfg.category2Negative = &#039;¬&#039;&lt;br /&gt;
&lt;br /&gt;
-- The following settings are used with the cfg.subpage parameter.&lt;br /&gt;
-- cfg.subpageNo is the value to specify to not categorise on subpages;&lt;br /&gt;
-- cfg.subpageOnly is the value to specify to only categorise on subpages.&lt;br /&gt;
cfg.subpageNo = &#039;no&#039;&lt;br /&gt;
cfg.subpageOnly = &#039;only&#039;&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
--                           Default namespaces                               --&lt;br /&gt;
-- This is a table of namespaces to categorise by default. The keys are the   --&lt;br /&gt;
-- namespace numbers.                                                         --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
cfg.defaultNamespaces = {&lt;br /&gt;
	[  0] = true, -- main&lt;br /&gt;
	[  6] = true, -- file&lt;br /&gt;
	[ 12] = true, -- help&lt;br /&gt;
	[ 14] = true, -- category&lt;br /&gt;
	[100] = true, -- portal&lt;br /&gt;
	[108] = true, -- book&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
--                                Wrappers                                    --&lt;br /&gt;
-- This is a wrapper template or a list of wrapper templates to be passed to  --&lt;br /&gt;
-- [[Module:Arguments]].                                                      --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
cfg.wrappers = &#039;Template:Category handler&#039;&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
--                           End configuration data                           --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
return cfg -- Don&#039;t edit this line.&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Module:Category_handler/data&amp;diff=8580</id>
		<title>Module:Category handler/data</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Module:Category_handler/data&amp;diff=8580"/>
		<updated>2026-01-22T17:11:58Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This module assembles data to be passed to [[Module:Category handler]] using&lt;br /&gt;
-- mw.loadData. This includes the configuration data and whether the current&lt;br /&gt;
-- page matches the title blacklist.&lt;br /&gt;
&lt;br /&gt;
local data = require(&#039;Module:Category handler/config&#039;)&lt;br /&gt;
local mShared = require(&#039;Module:Category handler/shared&#039;)&lt;br /&gt;
local blacklist = require(&#039;Module:Category handler/blacklist&#039;)&lt;br /&gt;
local title = mw.title.getCurrentTitle()&lt;br /&gt;
&lt;br /&gt;
data.currentTitleMatchesBlacklist = mShared.matchesBlacklist(&lt;br /&gt;
	title.prefixedText,&lt;br /&gt;
	blacklist&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
data.currentTitleNamespaceParameters = mShared.getNamespaceParameters(&lt;br /&gt;
	title,&lt;br /&gt;
	mShared.getParamMappings()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
return data&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Module:Effective_protection_level&amp;diff=8578</id>
		<title>Module:Effective protection level</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Module:Effective_protection_level&amp;diff=8578"/>
		<updated>2026-01-22T17:11:57Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Returns the permission required to perform a given action on a given title.&lt;br /&gt;
-- If no title is specified, the title of the page being displayed is used.&lt;br /&gt;
function p._main(action, pagename)&lt;br /&gt;
	local title&lt;br /&gt;
	if type(pagename) == &#039;table&#039; and pagename.prefixedText then&lt;br /&gt;
		title = pagename&lt;br /&gt;
	elseif pagename then&lt;br /&gt;
		title = mw.title.new(pagename)&lt;br /&gt;
	else&lt;br /&gt;
		title = mw.title.getCurrentTitle()&lt;br /&gt;
	end&lt;br /&gt;
	pagename = title.prefixedText&lt;br /&gt;
	if action ~= &#039;edit&#039; and action ~= &#039;move&#039; and action ~= &#039;create&#039; and action ~= &#039;upload&#039; and action ~= &#039;undelete&#039; then&lt;br /&gt;
		error( &#039;First parameter must be one of edit, move, create, upload, undelete&#039;, 2 )&lt;br /&gt;
	end&lt;br /&gt;
	if title.namespace == 8 then -- MediaWiki namespace&lt;br /&gt;
		if title.text:sub(-3) == &#039;.js&#039; or title.text:sub(-4) == &#039;.css&#039; or title.text == &#039;Gadgets-definition&#039; or title.contentModel == &#039;javascript&#039; or title.contentModel == &#039;css&#039; then -- site JS or CSS page&lt;br /&gt;
			return &#039;interfaceadmin&#039;&lt;br /&gt;
		else -- any non-JS/CSS MediaWiki page&lt;br /&gt;
			return &#039;sysop&#039;&lt;br /&gt;
		end&lt;br /&gt;
	elseif title.namespace == 2 and title.isSubpage then&lt;br /&gt;
		if title.contentModel == &#039;javascript&#039; or title.contentModel == &#039;css&#039; then -- user JS or CSS page&lt;br /&gt;
			return &#039;interfaceadmin&#039;&lt;br /&gt;
		elseif title.contentModel == &#039;json&#039; then -- user JSON page&lt;br /&gt;
			return &#039;sysop&#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if action == &#039;undelete&#039; then&lt;br /&gt;
		return &#039;sysop&#039;&lt;br /&gt;
	end&lt;br /&gt;
	local level = title.protectionLevels[action] and title.protectionLevels[action][1]&lt;br /&gt;
	if level == &#039;sysop&#039; or level == &#039;editprotected&#039; then&lt;br /&gt;
		return &#039;sysop&#039;&lt;br /&gt;
	elseif title.cascadingProtection.restrictions[action] and title.cascadingProtection.restrictions[action][1] then -- used by a cascading-protected page&lt;br /&gt;
		return &#039;sysop&#039;&lt;br /&gt;
	elseif level == &#039;templateeditor&#039; then&lt;br /&gt;
		return &#039;templateeditor&#039;&lt;br /&gt;
	elseif action == &#039;move&#039; then&lt;br /&gt;
		local blacklistentry = mw.ext.TitleBlacklist.test(&#039;edit&#039;, pagename) -- Testing action edit is correct, since this is for the source page. The target page name gets tested with action move.&lt;br /&gt;
		if blacklistentry and not blacklistentry.params.autoconfirmed then&lt;br /&gt;
			return &#039;sysop&#039;&lt;br /&gt;
		elseif title.namespace == 6 then&lt;br /&gt;
			return &#039;filemover&#039;&lt;br /&gt;
		elseif level == &#039;extendedconfirmed&#039; then&lt;br /&gt;
			return &#039;extendedconfirmed&#039;&lt;br /&gt;
		else&lt;br /&gt;
			return &#039;autoconfirmed&#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local blacklistentry = mw.ext.TitleBlacklist.test(action, pagename)&lt;br /&gt;
	if blacklistentry then&lt;br /&gt;
		if not blacklistentry.params.autoconfirmed then&lt;br /&gt;
			return &#039;sysop&#039;&lt;br /&gt;
		elseif level == &#039;extendedconfirmed&#039; then&lt;br /&gt;
			return &#039;extendedconfirmed&#039;&lt;br /&gt;
		else&lt;br /&gt;
			return &#039;autoconfirmed&#039;&lt;br /&gt;
		end&lt;br /&gt;
	elseif level == &#039;editsemiprotected&#039; then -- create-semiprotected pages return this for some reason&lt;br /&gt;
		return &#039;autoconfirmed&#039;&lt;br /&gt;
	elseif level then&lt;br /&gt;
		return level&lt;br /&gt;
	elseif action == &#039;upload&#039; then&lt;br /&gt;
		return &#039;autoconfirmed&#039;&lt;br /&gt;
	else&lt;br /&gt;
		return &#039;*&#039;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
setmetatable(p, { __index = function(t, k)&lt;br /&gt;
	return function(frame)&lt;br /&gt;
		return t._main(k, frame.args[1])&lt;br /&gt;
	end&lt;br /&gt;
end })&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Module:Message_box/configuration&amp;diff=8576</id>
		<title>Module:Message box/configuration</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Module:Message_box/configuration&amp;diff=8576"/>
		<updated>2026-01-22T17:11:57Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--------------------------------------------------------------------------------&lt;br /&gt;
--                          Message box configuration                         --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
-- This module contains configuration data for [[Module:Message box]].        --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
return {&lt;br /&gt;
	-- Global styles applying to all *mboxes&lt;br /&gt;
	[&#039;@global&#039;] = {&lt;br /&gt;
		templatestyles = &#039;Module:Message box/mbox.css&#039;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	ambox = {&lt;br /&gt;
		types = {&lt;br /&gt;
			speedy = {&lt;br /&gt;
				class = &#039;ambox-speedy&#039;,&lt;br /&gt;
				image = &#039;Ambox warning pn.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			delete = {&lt;br /&gt;
				class = &#039;ambox-delete&#039;,&lt;br /&gt;
				image = &#039;Ambox warning pn.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			content = {&lt;br /&gt;
				class = &#039;ambox-content&#039;,&lt;br /&gt;
				image = &#039;Ambox important.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			style = {&lt;br /&gt;
				class = &#039;ambox-style&#039;,&lt;br /&gt;
				image = &#039;Edit-clear.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			move = {&lt;br /&gt;
				class = &#039;ambox-move&#039;,&lt;br /&gt;
				image = &#039;Merge-split-transwiki default.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			protection = {&lt;br /&gt;
				class = &#039;ambox-protection&#039;,&lt;br /&gt;
				image = &#039;Semi-protection-shackle.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			notice = {&lt;br /&gt;
				class = &#039;ambox-notice&#039;,&lt;br /&gt;
				image = &#039;Information icon4.svg&#039;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		default                     = &#039;notice&#039;,&lt;br /&gt;
		allowBlankParams            = {&#039;talk&#039;, &#039;sect&#039;, &#039;date&#039;, &#039;issue&#039;, &#039;fix&#039;, &#039;subst&#039;, &#039;hidden&#039;},&lt;br /&gt;
		allowSmall                  = true,&lt;br /&gt;
		smallParam                  = &#039;left&#039;,&lt;br /&gt;
		smallClass                  = &#039;mbox-small-left&#039;,&lt;br /&gt;
		substCheck                  = true,&lt;br /&gt;
		classes                     = {&#039;metadata&#039;, &#039;ambox&#039;},&lt;br /&gt;
		usePlainlinksParam          = true,&lt;br /&gt;
		allowId                     = true,&lt;br /&gt;
		imageEmptyCell              = true,&lt;br /&gt;
		imageCheckBlank             = true,&lt;br /&gt;
		imageSmallSize              = &#039;20x20px&#039;,&lt;br /&gt;
		imageCellDiv                = true,&lt;br /&gt;
		useCollapsibleTextFields    = true,&lt;br /&gt;
		imageRightNone              = true,&lt;br /&gt;
		sectionDefault              = &#039;條目&#039;,&lt;br /&gt;
		allowMainspaceCategories    = true,&lt;br /&gt;
		templateCategory            = &#039;條目訊息模板&#039;,&lt;br /&gt;
    	templateCategoryRequireName = true,&lt;br /&gt;
		templateErrorCategory       = &#039;缺少參數的條目訊息模板&#039;,&lt;br /&gt;
		templateErrorParamsToCheck  = {&#039;issue&#039;, &#039;fix&#039;, &#039;subst&#039;},&lt;br /&gt;
		templatestyles              = &#039;Template:Ambox/style.css&#039;&lt;br /&gt;
	},&lt;br /&gt;
	&lt;br /&gt;
	cmbox = {&lt;br /&gt;
		types = {&lt;br /&gt;
			speedy = {&lt;br /&gt;
				class = &#039;cmbox-speedy&#039;,&lt;br /&gt;
				image = &#039;Ambox warning pn.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			delete = {&lt;br /&gt;
				class = &#039;cmbox-delete&#039;,&lt;br /&gt;
				image = &#039;Ambox warning pn.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			content = {&lt;br /&gt;
				class = &#039;cmbox-content&#039;,&lt;br /&gt;
				image = &#039;Ambox important.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			style = {&lt;br /&gt;
				class = &#039;cmbox-style&#039;,&lt;br /&gt;
				image = &#039;Edit-clear.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			move = {&lt;br /&gt;
				class = &#039;cmbox-move&#039;,&lt;br /&gt;
				image = &#039;Merge-split-transwiki default.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			protection = {&lt;br /&gt;
				class = &#039;cmbox-protection&#039;,&lt;br /&gt;
				image = &#039;Semi-protection-shackle.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			notice = {&lt;br /&gt;
				class = &#039;cmbox-notice&#039;,&lt;br /&gt;
				image = &#039;Information icon4.svg&#039;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		default              = &#039;notice&#039;,&lt;br /&gt;
		showInvalidTypeError = true,&lt;br /&gt;
		classes              = {&#039;cmbox&#039;},&lt;br /&gt;
		usePlainlinksParam   = true,&lt;br /&gt;
		imageEmptyCell       = true,&lt;br /&gt;
		templatestyles       = &#039;Template:Cmbox/style.css&#039;&lt;br /&gt;
	},&lt;br /&gt;
	&lt;br /&gt;
	fmbox = {&lt;br /&gt;
		types = {&lt;br /&gt;
			warning = {&lt;br /&gt;
				class = &#039;fmbox-warning&#039;,&lt;br /&gt;
				image = &#039;Ambox warning pn.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			editnotice = {&lt;br /&gt;
				class = &#039;fmbox-editnotice&#039;,&lt;br /&gt;
				image = &#039;Information icon4.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			system = {&lt;br /&gt;
				class = &#039;fmbox-system&#039;,&lt;br /&gt;
				image = &#039;Information icon4.svg&#039;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		default              = &#039;system&#039;,&lt;br /&gt;
		showInvalidTypeError = true,&lt;br /&gt;
		allowId              = true,&lt;br /&gt;
		classes              = {&#039;fmbox&#039;},&lt;br /&gt;
		usePlainlinksParam   = true,&lt;br /&gt;
		imageEmptyCell       = false,&lt;br /&gt;
		imageRightNone       = false,&lt;br /&gt;
		templatestyles       = &#039;Template:Fmbox/style.css&#039;&lt;br /&gt;
	},&lt;br /&gt;
	&lt;br /&gt;
	imbox = {&lt;br /&gt;
		types = {&lt;br /&gt;
			speedy = {&lt;br /&gt;
				class = &#039;imbox-speedy&#039;,&lt;br /&gt;
				image = &#039;Ambox warning pn.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			delete = {&lt;br /&gt;
				class = &#039;imbox-delete&#039;,&lt;br /&gt;
				image = &#039;Ambox warning pn.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			content = {&lt;br /&gt;
				class = &#039;imbox-content&#039;,&lt;br /&gt;
				image = &#039;Ambox important.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			style = {&lt;br /&gt;
				class = &#039;imbox-style&#039;,&lt;br /&gt;
				image = &#039;Edit-clear.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			move = {&lt;br /&gt;
				class = &#039;imbox-move&#039;,&lt;br /&gt;
				image = &#039;Merge-split-transwiki default.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			protection = {&lt;br /&gt;
				class = &#039;imbox-protection&#039;,&lt;br /&gt;
				image = &#039;Semi-protection-shackle.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			license = {&lt;br /&gt;
				class = &#039;imbox-license licensetpl&#039;,&lt;br /&gt;
				image = &#039;Imbox-license.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			featured = {&lt;br /&gt;
				class = &#039;imbox-featured&#039;,&lt;br /&gt;
				image = &#039;Cscr-featured.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			notice = {&lt;br /&gt;
				class = &#039;imbox-notice&#039;,&lt;br /&gt;
				image = &#039;Information icon4.svg&#039;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		default              = &#039;notice&#039;,&lt;br /&gt;
		showInvalidTypeError = true,&lt;br /&gt;
		classes              = {&#039;imbox&#039;},&lt;br /&gt;
		usePlainlinksParam   = true,&lt;br /&gt;
		imageEmptyCell       = true,&lt;br /&gt;
		below                = true,&lt;br /&gt;
		templateCategory     = &#039;檔案訊息模板&#039;,&lt;br /&gt;
		templatestyles       = &#039;Template:Imbox/style.css&#039;&lt;br /&gt;
	},&lt;br /&gt;
	&lt;br /&gt;
	ombox = {&lt;br /&gt;
		types = {&lt;br /&gt;
			speedy = {&lt;br /&gt;
				class = &#039;ombox-speedy&#039;,&lt;br /&gt;
				image = &#039;Ambox warning pn.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			delete = {&lt;br /&gt;
				class = &#039;ombox-delete&#039;,&lt;br /&gt;
				image = &#039;Ambox warning pn.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			content = {&lt;br /&gt;
				class = &#039;ombox-content&#039;,&lt;br /&gt;
				image = &#039;Ambox important.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			style = {&lt;br /&gt;
				class = &#039;ombox-style&#039;,&lt;br /&gt;
				image = &#039;Edit-clear.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			move = {&lt;br /&gt;
				class = &#039;ombox-move&#039;,&lt;br /&gt;
				image = &#039;Merge-split-transwiki default.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			protection = {&lt;br /&gt;
				class = &#039;ombox-protection&#039;,&lt;br /&gt;
				image = &#039;Semi-protection-shackle.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			notice = {&lt;br /&gt;
				class = &#039;ombox-notice&#039;,&lt;br /&gt;
				image = &#039;Information icon4.svg&#039;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		default              = &#039;notice&#039;,&lt;br /&gt;
		showInvalidTypeError = true,&lt;br /&gt;
		classes              = {&#039;ombox&#039;},&lt;br /&gt;
		usePlainlinksParam   = true,&lt;br /&gt;
		allowSmall           = true,&lt;br /&gt;
		imageEmptyCell       = true,&lt;br /&gt;
		imageRightNone       = true,&lt;br /&gt;
		templatestyles       = &#039;Template:Ombox/style.css&#039;&lt;br /&gt;
	},&lt;br /&gt;
	&lt;br /&gt;
	tmbox = {&lt;br /&gt;
		types = {&lt;br /&gt;
			speedy = {&lt;br /&gt;
				class = &#039;tmbox-speedy&#039;,&lt;br /&gt;
				image = &#039;Ambox warning pn.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			delete = {&lt;br /&gt;
				class = &#039;tmbox-delete&#039;,&lt;br /&gt;
				image = &#039;Ambox warning pn.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			content = {&lt;br /&gt;
				class = &#039;tmbox-content&#039;,&lt;br /&gt;
				image = &#039;Ambox important.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			style = {&lt;br /&gt;
				class = &#039;tmbox-style&#039;,&lt;br /&gt;
				image = &#039;Edit-clear.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			move = {&lt;br /&gt;
				class = &#039;tmbox-move&#039;,&lt;br /&gt;
				image = &#039;Merge-split-transwiki default.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			protection = {&lt;br /&gt;
				class = &#039;tmbox-protection&#039;,&lt;br /&gt;
				image = &#039;Semi-protection-shackle.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			notice = {&lt;br /&gt;
				class = &#039;tmbox-notice&#039;,&lt;br /&gt;
				image = &#039;Information icon4.svg&#039;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		default              = &#039;notice&#039;,&lt;br /&gt;
		showInvalidTypeError = true,&lt;br /&gt;
		classes              = {&#039;tmbox&#039;},&lt;br /&gt;
		usePlainlinksParam   = true,&lt;br /&gt;
		allowId              = true,&lt;br /&gt;
		allowSmall           = true,&lt;br /&gt;
		imageRightNone       = true,&lt;br /&gt;
		imageEmptyCell       = true,&lt;br /&gt;
		imageEmptyCellStyle  = true,&lt;br /&gt;
		templateCategory     = &#039;討論訊息模板&#039;,&lt;br /&gt;
		templatestyles       = &#039;Template:Tmbox/style.css&#039;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Module:Category_handler&amp;diff=8574</id>
		<title>Module:Category handler</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Module:Category_handler&amp;diff=8574"/>
		<updated>2026-01-22T17:11:57Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--------------------------------------------------------------------------------&lt;br /&gt;
--                                                                            --&lt;br /&gt;
--                              CATEGORY HANDLER                              --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
--      This module implements the {{category handler}} template in Lua,      --&lt;br /&gt;
--      with a few improvements: all namespaces and all namespace aliases     --&lt;br /&gt;
--      are supported, and namespace names are detected automatically for     --&lt;br /&gt;
--      the local wiki. This module requires [[Module:Namespace detect]]      --&lt;br /&gt;
--      and [[Module:Yesno]] to be available on the local wiki. It can be     --&lt;br /&gt;
--      configured for different wikis by altering the values in              --&lt;br /&gt;
--      [[Module:Category handler/config]], and pages can be blacklisted      --&lt;br /&gt;
--      from categorisation by using [[Module:Category handler/blacklist]].   --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
-- Load required modules&lt;br /&gt;
local yesno = require(&#039;Module:Yesno&#039;)&lt;br /&gt;
&lt;br /&gt;
-- Lazily load things we don&#039;t always need&lt;br /&gt;
local mShared, mappings&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Helper functions&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local function trimWhitespace(s, removeBlanks)&lt;br /&gt;
	if type(s) ~= &#039;string&#039; then&lt;br /&gt;
		return s&lt;br /&gt;
	end&lt;br /&gt;
	s = s:match(&#039;^%s*(.-)%s*$&#039;)&lt;br /&gt;
	if removeBlanks then&lt;br /&gt;
		if s ~= &#039;&#039; then&lt;br /&gt;
			return s&lt;br /&gt;
		else&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		return s&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- CategoryHandler class&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local CategoryHandler = {}&lt;br /&gt;
CategoryHandler.__index = CategoryHandler&lt;br /&gt;
&lt;br /&gt;
function CategoryHandler.new(data, args)&lt;br /&gt;
	local obj = setmetatable({ _data = data, _args = args }, CategoryHandler)&lt;br /&gt;
	&lt;br /&gt;
	-- Set the title object&lt;br /&gt;
	do&lt;br /&gt;
		local pagename = obj:parameter(&#039;demopage&#039;)&lt;br /&gt;
		local success, titleObj&lt;br /&gt;
		if pagename then&lt;br /&gt;
			success, titleObj = pcall(mw.title.new, pagename)&lt;br /&gt;
		end&lt;br /&gt;
		if success and titleObj then&lt;br /&gt;
			obj.title = titleObj&lt;br /&gt;
			if titleObj == mw.title.getCurrentTitle() then&lt;br /&gt;
				obj._usesCurrentTitle = true&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			obj.title = mw.title.getCurrentTitle()&lt;br /&gt;
			obj._usesCurrentTitle = true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Set suppression parameter values&lt;br /&gt;
	for _, key in ipairs{&#039;nocat&#039;, &#039;categories&#039;} do&lt;br /&gt;
		local value = obj:parameter(key)&lt;br /&gt;
		value = trimWhitespace(value, true)&lt;br /&gt;
		obj[&#039;_&#039; .. key] = yesno(value)&lt;br /&gt;
	end&lt;br /&gt;
	do&lt;br /&gt;
		local subpage = obj:parameter(&#039;subpage&#039;)&lt;br /&gt;
		local category2 = obj:parameter(&#039;category2&#039;)&lt;br /&gt;
		if type(subpage) == &#039;string&#039; then&lt;br /&gt;
			subpage = mw.ustring.lower(subpage)&lt;br /&gt;
		end&lt;br /&gt;
		if type(category2) == &#039;string&#039; then&lt;br /&gt;
			subpage = mw.ustring.lower(category2)&lt;br /&gt;
		end&lt;br /&gt;
		obj._subpage = trimWhitespace(subpage, true)&lt;br /&gt;
		obj._category2 = trimWhitespace(category2) -- don&#039;t remove blank values&lt;br /&gt;
	end&lt;br /&gt;
	return obj&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function CategoryHandler:parameter(key)&lt;br /&gt;
	local parameterNames = self._data.parameters[key]&lt;br /&gt;
	local pntype = type(parameterNames)&lt;br /&gt;
	if pntype == &#039;string&#039; or pntype == &#039;number&#039; then&lt;br /&gt;
		return self._args[parameterNames]&lt;br /&gt;
	elseif pntype == &#039;table&#039; then&lt;br /&gt;
		for _, name in ipairs(parameterNames) do&lt;br /&gt;
			local value = self._args[name]&lt;br /&gt;
			if value ~= nil then&lt;br /&gt;
				return value&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return nil&lt;br /&gt;
	else&lt;br /&gt;
		error(string.format(&lt;br /&gt;
			&#039;invalid config key &amp;quot;%s&amp;quot;&#039;,&lt;br /&gt;
			tostring(key)&lt;br /&gt;
		), 2)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function CategoryHandler:isSuppressedByArguments()&lt;br /&gt;
	return&lt;br /&gt;
		-- See if a category suppression argument has been set.&lt;br /&gt;
		self._nocat == true&lt;br /&gt;
		or self._categories == false&lt;br /&gt;
		or (&lt;br /&gt;
			self._category2&lt;br /&gt;
			and self._category2 ~= self._data.category2Yes&lt;br /&gt;
			and self._category2 ~= self._data.category2Negative&lt;br /&gt;
		)&lt;br /&gt;
&lt;br /&gt;
		-- Check whether we are on a subpage, and see if categories are&lt;br /&gt;
		-- suppressed based on our subpage status.&lt;br /&gt;
		or self._subpage == self._data.subpageNo and self.title.isSubpage&lt;br /&gt;
		or self._subpage == self._data.subpageOnly and not self.title.isSubpage&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function CategoryHandler:shouldSkipBlacklistCheck()&lt;br /&gt;
	-- Check whether the category suppression arguments indicate we&lt;br /&gt;
	-- should skip the blacklist check.&lt;br /&gt;
	return self._nocat == false&lt;br /&gt;
		or self._categories == true&lt;br /&gt;
		or self._category2 == self._data.category2Yes&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function CategoryHandler:matchesBlacklist()&lt;br /&gt;
	if self._usesCurrentTitle then&lt;br /&gt;
		return self._data.currentTitleMatchesBlacklist&lt;br /&gt;
	else&lt;br /&gt;
		mShared = mShared or require(&#039;Module:Category handler/shared&#039;)&lt;br /&gt;
		return mShared.matchesBlacklist(&lt;br /&gt;
			self.title.prefixedText,&lt;br /&gt;
			mw.loadData(&#039;Module:Category handler/blacklist&#039;)&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function CategoryHandler:isSuppressed()&lt;br /&gt;
	-- Find if categories are suppressed by either the arguments or by&lt;br /&gt;
	-- matching the blacklist.&lt;br /&gt;
	return self:isSuppressedByArguments()&lt;br /&gt;
		or not self:shouldSkipBlacklistCheck() and self:matchesBlacklist()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function CategoryHandler:getNamespaceParameters()&lt;br /&gt;
	if self._usesCurrentTitle then&lt;br /&gt;
		return self._data.currentTitleNamespaceParameters&lt;br /&gt;
	else&lt;br /&gt;
		if not mappings then&lt;br /&gt;
			mShared = mShared or require(&#039;Module:Category handler/shared&#039;)&lt;br /&gt;
			mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData&lt;br /&gt;
		end&lt;br /&gt;
		return mShared.getNamespaceParameters(&lt;br /&gt;
			self.title,&lt;br /&gt;
			mappings&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function CategoryHandler:namespaceParametersExist()&lt;br /&gt;
	-- Find whether any namespace parameters have been specified.&lt;br /&gt;
	-- We use the order &amp;quot;all&amp;quot; --&amp;gt; namespace params --&amp;gt; &amp;quot;other&amp;quot; as this is what&lt;br /&gt;
	-- the old template did.&lt;br /&gt;
	if self:parameter(&#039;all&#039;) then&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
	if not mappings then&lt;br /&gt;
		mShared = mShared or require(&#039;Module:Category handler/shared&#039;)&lt;br /&gt;
		mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData&lt;br /&gt;
	end&lt;br /&gt;
	for ns, params in pairs(mappings) do&lt;br /&gt;
		for i, param in ipairs(params) do&lt;br /&gt;
			if self._args[param] then&lt;br /&gt;
				return true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if self:parameter(&#039;other&#039;) then&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function CategoryHandler:getCategories()&lt;br /&gt;
	local params = self:getNamespaceParameters()&lt;br /&gt;
	local nsCategory&lt;br /&gt;
	for i, param in ipairs(params) do&lt;br /&gt;
		local value = self._args[param]&lt;br /&gt;
		if value ~= nil then&lt;br /&gt;
			nsCategory = value&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if nsCategory ~= nil or self:namespaceParametersExist() then&lt;br /&gt;
		-- Namespace parameters exist - advanced usage.&lt;br /&gt;
		if nsCategory == nil then&lt;br /&gt;
			nsCategory = self:parameter(&#039;other&#039;)&lt;br /&gt;
		end&lt;br /&gt;
		local ret = {self:parameter(&#039;all&#039;)}&lt;br /&gt;
		local numParam = tonumber(nsCategory)&lt;br /&gt;
		if numParam and numParam &amp;gt;= 1 and math.floor(numParam) == numParam then&lt;br /&gt;
			-- nsCategory is an integer&lt;br /&gt;
			ret[#ret + 1] = self._args[numParam]&lt;br /&gt;
		else&lt;br /&gt;
			ret[#ret + 1] = nsCategory&lt;br /&gt;
		end&lt;br /&gt;
		if #ret &amp;lt; 1 then&lt;br /&gt;
			return nil&lt;br /&gt;
		else&lt;br /&gt;
			return table.concat(ret)&lt;br /&gt;
		end&lt;br /&gt;
	elseif self._data.defaultNamespaces[self.title.namespace] then&lt;br /&gt;
		-- Namespace parameters don&#039;t exist, simple usage.&lt;br /&gt;
		return self._args[1]&lt;br /&gt;
	end&lt;br /&gt;
	return nil&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;
function p._exportClasses()&lt;br /&gt;
	-- Used for testing purposes.&lt;br /&gt;
	return {&lt;br /&gt;
		CategoryHandler = CategoryHandler&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._main(args, data)&lt;br /&gt;
	data = data or mw.loadData(&#039;Module:Category handler/data&#039;)&lt;br /&gt;
	local handler = CategoryHandler.new(data, args)&lt;br /&gt;
	if handler:isSuppressed() then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	return handler:getCategories()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.main(frame, data)&lt;br /&gt;
	data = data or mw.loadData(&#039;Module:Category handler/data&#039;)&lt;br /&gt;
	local args = require(&#039;Module:Arguments&#039;).getArgs(frame, {&lt;br /&gt;
		wrappers = data.wrappers,&lt;br /&gt;
		valueFunc = function (k, v)&lt;br /&gt;
			v = trimWhitespace(v)&lt;br /&gt;
			if type(k) == &#039;number&#039; then&lt;br /&gt;
				if v ~= &#039;&#039; then&lt;br /&gt;
					return v&lt;br /&gt;
				else&lt;br /&gt;
					return nil&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				return v&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	})&lt;br /&gt;
	return p._main(args, data)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Module:Arguments&amp;diff=8572</id>
		<title>Module:Arguments</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Module:Arguments&amp;diff=8572"/>
		<updated>2026-01-22T17:11:56Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This module provides easy processing of arguments passed to Scribunto from&lt;br /&gt;
-- #invoke. It is intended for use by other Lua modules, and should not be&lt;br /&gt;
-- called from #invoke directly.&lt;br /&gt;
&lt;br /&gt;
local libraryUtil = require(&#039;libraryUtil&#039;)&lt;br /&gt;
local checkType = libraryUtil.checkType&lt;br /&gt;
&lt;br /&gt;
local arguments = {}&lt;br /&gt;
&lt;br /&gt;
-- Generate four different tidyVal functions, so that we don&#039;t have to check the&lt;br /&gt;
-- options every time we call it.&lt;br /&gt;
&lt;br /&gt;
local function tidyValDefault(key, val)&lt;br /&gt;
	if type(val) == &#039;string&#039; then&lt;br /&gt;
		val = val:match(&#039;^%s*(.-)%s*$&#039;)&lt;br /&gt;
		if val == &#039;&#039; then&lt;br /&gt;
			return nil&lt;br /&gt;
		else&lt;br /&gt;
			return val&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		return val&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function tidyValTrimOnly(key, val)&lt;br /&gt;
	if type(val) == &#039;string&#039; then&lt;br /&gt;
		return val:match(&#039;^%s*(.-)%s*$&#039;)&lt;br /&gt;
	else&lt;br /&gt;
		return val&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function tidyValRemoveBlanksOnly(key, val)&lt;br /&gt;
	if type(val) == &#039;string&#039; then&lt;br /&gt;
		if val:find(&#039;%S&#039;) then&lt;br /&gt;
			return val&lt;br /&gt;
		else&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		return val&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function tidyValNoChange(key, val)&lt;br /&gt;
	return val&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function matchesTitle(given, title)&lt;br /&gt;
	local tp = type( given )&lt;br /&gt;
	return (tp == &#039;string&#039; or tp == &#039;number&#039;) and mw.title.new( given ).prefixedText == title&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local translate_mt = { __index = function(t, k) return k end }&lt;br /&gt;
&lt;br /&gt;
function arguments.getArgs(frame, options)&lt;br /&gt;
	checkType(&#039;getArgs&#039;, 1, frame, &#039;table&#039;, true)&lt;br /&gt;
	checkType(&#039;getArgs&#039;, 2, options, &#039;table&#039;, true)&lt;br /&gt;
	frame = frame or {}&lt;br /&gt;
	options = options or {}&lt;br /&gt;
&lt;br /&gt;
	--[[&lt;br /&gt;
	-- Set up argument translation.&lt;br /&gt;
	--]]&lt;br /&gt;
	options.translate = options.translate or {}&lt;br /&gt;
	if getmetatable(options.translate) == nil then&lt;br /&gt;
		setmetatable(options.translate, translate_mt)&lt;br /&gt;
	end&lt;br /&gt;
	if options.backtranslate == nil then&lt;br /&gt;
		options.backtranslate = {}&lt;br /&gt;
		for k,v in pairs(options.translate) do&lt;br /&gt;
			options.backtranslate[v] = k&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if options.backtranslate and getmetatable(options.backtranslate) == nil then&lt;br /&gt;
		setmetatable(options.backtranslate, {&lt;br /&gt;
			__index = function(t, k)&lt;br /&gt;
				if options.translate[k] ~= k then&lt;br /&gt;
					return nil&lt;br /&gt;
				else&lt;br /&gt;
					return k&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		})&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--[[&lt;br /&gt;
	-- Get the argument tables. If we were passed a valid frame object, get the&lt;br /&gt;
	-- frame arguments (fargs) and the parent frame arguments (pargs), depending&lt;br /&gt;
	-- on the options set and on the parent frame&#039;s availability. If we weren&#039;t&lt;br /&gt;
	-- passed a valid frame object, we are being called from another Lua module&lt;br /&gt;
	-- or from the debug console, so assume that we were passed a table of args&lt;br /&gt;
	-- directly, and assign it to a new variable (luaArgs).&lt;br /&gt;
	--]]&lt;br /&gt;
	local fargs, pargs, luaArgs&lt;br /&gt;
	if type(frame.args) == &#039;table&#039; and type(frame.getParent) == &#039;function&#039; then&lt;br /&gt;
		if options.wrappers then&lt;br /&gt;
			--[[&lt;br /&gt;
			-- The wrappers option makes Module:Arguments look up arguments in&lt;br /&gt;
			-- either the frame argument table or the parent argument table, but&lt;br /&gt;
			-- not both. This means that users can use either the #invoke syntax&lt;br /&gt;
			-- or a wrapper template without the loss of performance associated&lt;br /&gt;
			-- with looking arguments up in both the frame and the parent frame.&lt;br /&gt;
			-- Module:Arguments will look up arguments in the parent frame&lt;br /&gt;
			-- if it finds the parent frame&#039;s title in options.wrapper;&lt;br /&gt;
			-- otherwise it will look up arguments in the frame object passed&lt;br /&gt;
			-- to getArgs.&lt;br /&gt;
			--]]&lt;br /&gt;
			local parent = frame:getParent()&lt;br /&gt;
			if not parent then&lt;br /&gt;
				fargs = frame.args&lt;br /&gt;
			else&lt;br /&gt;
				local title = parent:getTitle():gsub(&#039;/sandbox$&#039;, &#039;&#039;)&lt;br /&gt;
				local found = false&lt;br /&gt;
				if matchesTitle(options.wrappers, title) then&lt;br /&gt;
					found = true&lt;br /&gt;
				elseif type(options.wrappers) == &#039;table&#039; then&lt;br /&gt;
					for _,v in pairs(options.wrappers) do&lt;br /&gt;
						if matchesTitle(v, title) then&lt;br /&gt;
							found = true&lt;br /&gt;
							break&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				-- We test for false specifically here so that nil (the default) acts like true.&lt;br /&gt;
				if found or options.frameOnly == false then&lt;br /&gt;
					pargs = parent.args&lt;br /&gt;
				end&lt;br /&gt;
				if not found or options.parentOnly == false then&lt;br /&gt;
					fargs = frame.args&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			-- options.wrapper isn&#039;t set, so check the other options.&lt;br /&gt;
			if not options.parentOnly then&lt;br /&gt;
				fargs = frame.args&lt;br /&gt;
			end&lt;br /&gt;
			if not options.frameOnly then&lt;br /&gt;
				local parent = frame:getParent()&lt;br /&gt;
				pargs = parent and parent.args or nil&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if options.parentFirst then&lt;br /&gt;
			fargs, pargs = pargs, fargs&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		luaArgs = frame&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Set the order of precedence of the argument tables. If the variables are&lt;br /&gt;
	-- nil, nothing will be added to the table, which is how we avoid clashes&lt;br /&gt;
	-- between the frame/parent args and the Lua args.&lt;br /&gt;
	local argTables = {fargs}&lt;br /&gt;
	argTables[#argTables + 1] = pargs&lt;br /&gt;
	argTables[#argTables + 1] = luaArgs&lt;br /&gt;
&lt;br /&gt;
	--[[&lt;br /&gt;
	-- Generate the tidyVal function. If it has been specified by the user, we&lt;br /&gt;
	-- use that; if not, we choose one of four functions depending on the&lt;br /&gt;
	-- options chosen. This is so that we don&#039;t have to call the options table&lt;br /&gt;
	-- every time the function is called.&lt;br /&gt;
	--]]&lt;br /&gt;
	local tidyVal = options.valueFunc&lt;br /&gt;
	if tidyVal then&lt;br /&gt;
		if type(tidyVal) ~= &#039;function&#039; then&lt;br /&gt;
			error(&lt;br /&gt;
				&amp;quot;bad value assigned to option &#039;valueFunc&#039;&amp;quot;&lt;br /&gt;
					.. &#039;(function expected, got &#039;&lt;br /&gt;
					.. type(tidyVal)&lt;br /&gt;
					.. &#039;)&#039;,&lt;br /&gt;
				2&lt;br /&gt;
			)&lt;br /&gt;
		end&lt;br /&gt;
	elseif options.trim ~= false then&lt;br /&gt;
		if options.removeBlanks ~= false then&lt;br /&gt;
			tidyVal = tidyValDefault&lt;br /&gt;
		else&lt;br /&gt;
			tidyVal = tidyValTrimOnly&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		if options.removeBlanks ~= false then&lt;br /&gt;
			tidyVal = tidyValRemoveBlanksOnly&lt;br /&gt;
		else&lt;br /&gt;
			tidyVal = tidyValNoChange&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--[[&lt;br /&gt;
	-- Set up the args, metaArgs and nilArgs tables. args will be the one&lt;br /&gt;
	-- accessed from functions, and metaArgs will hold the actual arguments. Nil&lt;br /&gt;
	-- arguments are memoized in nilArgs, and the metatable connects all of them&lt;br /&gt;
	-- together.&lt;br /&gt;
	--]]&lt;br /&gt;
	local args, metaArgs, nilArgs, metatable = {}, {}, {}, {}&lt;br /&gt;
	setmetatable(args, metatable)&lt;br /&gt;
&lt;br /&gt;
	local function mergeArgs(tables)&lt;br /&gt;
		--[[&lt;br /&gt;
		-- Accepts multiple tables as input and merges their keys and values&lt;br /&gt;
		-- into one table. If a value is already present it is not overwritten;&lt;br /&gt;
		-- tables listed earlier have precedence. We are also memoizing nil&lt;br /&gt;
		-- values, which can be overwritten if they are &#039;s&#039; (soft).&lt;br /&gt;
		--]]&lt;br /&gt;
		for _, t in ipairs(tables) do&lt;br /&gt;
			for key, val in pairs(t) do&lt;br /&gt;
				if metaArgs[key] == nil and nilArgs[key] ~= &#039;h&#039; then&lt;br /&gt;
					local tidiedVal = tidyVal(key, val)&lt;br /&gt;
					if tidiedVal == nil then&lt;br /&gt;
						nilArgs[key] = &#039;s&#039;&lt;br /&gt;
					else&lt;br /&gt;
						metaArgs[key] = tidiedVal&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--[[&lt;br /&gt;
	-- Define metatable behaviour. Arguments are memoized in the metaArgs table,&lt;br /&gt;
	-- and are only fetched from the argument tables once. Fetching arguments&lt;br /&gt;
	-- from the argument tables is the most resource-intensive step in this&lt;br /&gt;
	-- module, so we try and avoid it where possible. For this reason, nil&lt;br /&gt;
	-- arguments are also memoized, in the nilArgs table. Also, we keep a record&lt;br /&gt;
	-- in the metatable of when pairs and ipairs have been called, so we do not&lt;br /&gt;
	-- run pairs and ipairs on the argument tables more than once. We also do&lt;br /&gt;
	-- not run ipairs on fargs and pargs if pairs has already been run, as all&lt;br /&gt;
	-- the arguments will already have been copied over.&lt;br /&gt;
	--]]&lt;br /&gt;
&lt;br /&gt;
	metatable.__index = function (t, key)&lt;br /&gt;
		--[[&lt;br /&gt;
		-- Fetches an argument when the args table is indexed. First we check&lt;br /&gt;
		-- to see if the value is memoized, and if not we try and fetch it from&lt;br /&gt;
		-- the argument tables. When we check memoization, we need to check&lt;br /&gt;
		-- metaArgs before nilArgs, as both can be non-nil at the same time.&lt;br /&gt;
		-- If the argument is not present in metaArgs, we also check whether&lt;br /&gt;
		-- pairs has been run yet. If pairs has already been run, we return nil.&lt;br /&gt;
		-- This is because all the arguments will have already been copied into&lt;br /&gt;
		-- metaArgs by the mergeArgs function, meaning that any other arguments&lt;br /&gt;
		-- must be nil.&lt;br /&gt;
		--]]&lt;br /&gt;
		if type(key) == &#039;string&#039; then&lt;br /&gt;
			key = options.translate[key]&lt;br /&gt;
		end&lt;br /&gt;
		local val = metaArgs[key]&lt;br /&gt;
		if val ~= nil then&lt;br /&gt;
			return val&lt;br /&gt;
		elseif metatable.donePairs or nilArgs[key] then&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
		for _, argTable in ipairs(argTables) do&lt;br /&gt;
			local argTableVal = tidyVal(key, argTable[key])&lt;br /&gt;
			if argTableVal ~= nil then&lt;br /&gt;
				metaArgs[key] = argTableVal&lt;br /&gt;
				return argTableVal&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		nilArgs[key] = &#039;h&#039;&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	metatable.__newindex = function (t, key, val)&lt;br /&gt;
		-- This function is called when a module tries to add a new value to the&lt;br /&gt;
		-- args table, or tries to change an existing value.&lt;br /&gt;
		if type(key) == &#039;string&#039; then&lt;br /&gt;
			key = options.translate[key]&lt;br /&gt;
		end&lt;br /&gt;
		if options.readOnly then&lt;br /&gt;
			error(&lt;br /&gt;
				&#039;could not write to argument table key &amp;quot;&#039;&lt;br /&gt;
					.. tostring(key)&lt;br /&gt;
					.. &#039;&amp;quot;; the table is read-only&#039;,&lt;br /&gt;
				2&lt;br /&gt;
			)&lt;br /&gt;
		elseif options.noOverwrite and args[key] ~= nil then&lt;br /&gt;
			error(&lt;br /&gt;
				&#039;could not write to argument table key &amp;quot;&#039;&lt;br /&gt;
					.. tostring(key)&lt;br /&gt;
					.. &#039;&amp;quot;; overwriting existing arguments is not permitted&#039;,&lt;br /&gt;
				2&lt;br /&gt;
			)&lt;br /&gt;
		elseif val == nil then&lt;br /&gt;
			--[[&lt;br /&gt;
			-- If the argument is to be overwritten with nil, we need to erase&lt;br /&gt;
			-- the value in metaArgs, so that __index, __pairs and __ipairs do&lt;br /&gt;
			-- not use a previous existing value, if present; and we also need&lt;br /&gt;
			-- to memoize the nil in nilArgs, so that the value isn&#039;t looked&lt;br /&gt;
			-- up in the argument tables if it is accessed again.&lt;br /&gt;
			--]]&lt;br /&gt;
			metaArgs[key] = nil&lt;br /&gt;
			nilArgs[key] = &#039;h&#039;&lt;br /&gt;
		else&lt;br /&gt;
			metaArgs[key] = val&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local function translatenext(invariant)&lt;br /&gt;
		local k, v = next(invariant.t, invariant.k)&lt;br /&gt;
		invariant.k = k&lt;br /&gt;
		if k == nil then&lt;br /&gt;
			return nil&lt;br /&gt;
		elseif type(k) ~= &#039;string&#039; or not options.backtranslate then&lt;br /&gt;
			return k, v&lt;br /&gt;
		else&lt;br /&gt;
			local backtranslate = options.backtranslate[k]&lt;br /&gt;
			if backtranslate == nil then&lt;br /&gt;
				-- Skip this one. This is a tail call, so this won&#039;t cause stack overflow&lt;br /&gt;
				return translatenext(invariant)&lt;br /&gt;
			else&lt;br /&gt;
				return backtranslate, v&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	metatable.__pairs = function ()&lt;br /&gt;
		-- Called when pairs is run on the args table.&lt;br /&gt;
		if not metatable.donePairs then&lt;br /&gt;
			mergeArgs(argTables)&lt;br /&gt;
			metatable.donePairs = true&lt;br /&gt;
		end&lt;br /&gt;
		return translatenext, { t = metaArgs }&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local function inext(t, i)&lt;br /&gt;
		-- This uses our __index metamethod&lt;br /&gt;
		local v = t[i + 1]&lt;br /&gt;
		if v ~= nil then&lt;br /&gt;
			return i + 1, v&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	metatable.__ipairs = function (t)&lt;br /&gt;
		-- Called when ipairs is run on the args table.&lt;br /&gt;
		return inext, t, 0&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return args&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return arguments&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Module:Message_box&amp;diff=8570</id>
		<title>Module:Message box</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Module:Message_box&amp;diff=8570"/>
		<updated>2026-01-22T17:11:56Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This is a meta-module for producing message box templates, including {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}.&lt;br /&gt;
&lt;br /&gt;
-- Require necessary modules.&lt;br /&gt;
local getArgs = require(&#039;Module:Arguments&#039;).getArgs&lt;br /&gt;
local categoryHandler = require(&#039;Module:Category handler&#039;).main&lt;br /&gt;
local yesno = require(&#039;Module:Yesno&#039;)&lt;br /&gt;
&lt;br /&gt;
-- Load the configuration page.&lt;br /&gt;
local cfgTables = mw.loadData(&#039;Module:Message box/configuration&#039;)&lt;br /&gt;
&lt;br /&gt;
-- Get a language object for formatDate and ucfirst.&lt;br /&gt;
local lang = mw.language.getContentLanguage()&lt;br /&gt;
&lt;br /&gt;
-- Set aliases for often-used functions to reduce table lookups.&lt;br /&gt;
local format = mw.ustring.format&lt;br /&gt;
local tinsert = table.insert&lt;br /&gt;
local tconcat = table.concat&lt;br /&gt;
local trim = mw.text.trim&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Helper functions&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local function getTitleObject(page, ...)&lt;br /&gt;
	if type(page) == &#039;string&#039; then&lt;br /&gt;
		-- Get the title object, passing the function through pcall &lt;br /&gt;
		-- in case we are over the expensive function count limit.&lt;br /&gt;
		local success, title = pcall(mw.title.new, page, ...)&lt;br /&gt;
		if success then&lt;br /&gt;
			return title&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function union(t1, t2)&lt;br /&gt;
	-- Returns the union of two arrays.&lt;br /&gt;
	local vals = {}&lt;br /&gt;
	for i, v in ipairs(t1) do&lt;br /&gt;
		vals[v] = true&lt;br /&gt;
	end&lt;br /&gt;
	for i, v in ipairs(t2) do&lt;br /&gt;
		vals[v] = true&lt;br /&gt;
	end&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	for k in pairs(vals) do&lt;br /&gt;
		tinsert(ret, k)&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(ret)&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getArgNums(args, prefix)&lt;br /&gt;
	local nums = {}&lt;br /&gt;
	for k, v in pairs(args) do&lt;br /&gt;
		local num = mw.ustring.match(tostring(k), &#039;^&#039; .. prefix .. &#039;([1-9]%d*)$&#039;)&lt;br /&gt;
		if num then&lt;br /&gt;
			tinsert(nums, tonumber(num))&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;
local function insertStyle(cfg)&lt;br /&gt;
	-- Create the templatestyles tag.&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
	&lt;br /&gt;
	return frame:extensionTag{&lt;br /&gt;
		name = &#039;templatestyles&#039;,&lt;br /&gt;
		args = { src = cfgTables[&#039;@global&#039;].templatestyles },&lt;br /&gt;
	} .. frame:extensionTag{&lt;br /&gt;
		name = &#039;templatestyles&#039;,&lt;br /&gt;
		args = { src = cfg.templatestyles },&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Box class definition&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local box = {}&lt;br /&gt;
box.__index = box&lt;br /&gt;
&lt;br /&gt;
function box.new()&lt;br /&gt;
	local obj = {}&lt;br /&gt;
	setmetatable(obj, box)&lt;br /&gt;
	return obj&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function box.getNamespaceId(ns)&lt;br /&gt;
	if not ns then return end&lt;br /&gt;
	if type(ns) == &#039;string&#039; then&lt;br /&gt;
		ns = lang:ucfirst(mw.ustring.lower(ns))&lt;br /&gt;
		if ns == &#039;Main&#039; then&lt;br /&gt;
			ns = 0&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local nsTable = mw.site.namespaces[ns]&lt;br /&gt;
	if nsTable then&lt;br /&gt;
		return nsTable.id&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function box.getMboxType(nsid)&lt;br /&gt;
	-- Gets the mbox type from a namespace number.&lt;br /&gt;
	if nsid == 0 then&lt;br /&gt;
		return &#039;ambox&#039; -- main namespace&lt;br /&gt;
	elseif nsid == 6 then&lt;br /&gt;
		return &#039;imbox&#039; -- file namespace&lt;br /&gt;
	elseif nsid == 14 then&lt;br /&gt;
		return &#039;cmbox&#039; -- category namespace&lt;br /&gt;
	else&lt;br /&gt;
		local nsTable = mw.site.namespaces[nsid]&lt;br /&gt;
		if nsTable and nsTable.isTalk then&lt;br /&gt;
			return &#039;tmbox&#039; -- any talk namespace&lt;br /&gt;
		else&lt;br /&gt;
			return &#039;ombox&#039; -- other namespaces or invalid input&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function box:addCat(ns, cat, sort)&lt;br /&gt;
	if type(cat) ~= &#039;string&#039; then return end&lt;br /&gt;
	local nsVals = {&#039;main&#039;, &#039;template&#039;, &#039;all&#039;}&lt;br /&gt;
	local tname&lt;br /&gt;
	for i, val in ipairs(nsVals) do&lt;br /&gt;
		if ns == val then&lt;br /&gt;
			tname = ns .. &#039;Cats&#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if not tname then&lt;br /&gt;
		for i, val in ipairs(nsVals) do&lt;br /&gt;
			nsVals[i] = format(&#039;&amp;quot;%s&amp;quot;&#039;, val)&lt;br /&gt;
		end&lt;br /&gt;
		error(&#039;無效的ns參數傳送到box:addCat；有效的數值為&#039; .. mw.text.listToText(nsVals, &#039;、&#039;, &#039;或&#039;))&lt;br /&gt;
	end&lt;br /&gt;
	self[tname] = self[tname] or {}&lt;br /&gt;
	if type(sort) == &#039;string&#039; then&lt;br /&gt;
		tinsert(self[tname], format(&#039;[[Category:%s|%s]]&#039;, cat, sort))&lt;br /&gt;
	else&lt;br /&gt;
		tinsert(self[tname], format(&#039;[[Category:%s]]&#039;, cat))&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function box:addClass(class)&lt;br /&gt;
	if type(class) ~= &#039;string&#039; then return end&lt;br /&gt;
	self.classes = self.classes or {}&lt;br /&gt;
	tinsert(self.classes, class)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function box:setTitle(args)&lt;br /&gt;
	-- Get the title object and the namespace.&lt;br /&gt;
	self.pageTitle = getTitleObject(args.page ~= &#039;&#039; and args.page)&lt;br /&gt;
	self.title = self.pageTitle or mw.title.getCurrentTitle()&lt;br /&gt;
	self.demospace = args.demospace ~= &#039;&#039; and args.demospace or nil&lt;br /&gt;
	self.nsid = box.getNamespaceId(self.demospace) or self.title.namespace&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function box:getConfig(boxType)&lt;br /&gt;
	-- Get the box config data from the data page.&lt;br /&gt;
	if boxType == &#039;mbox&#039; then&lt;br /&gt;
		boxType = box.getMboxType(self.nsid)&lt;br /&gt;
	end&lt;br /&gt;
	local cfg = cfgTables[boxType]&lt;br /&gt;
	if not cfg then&lt;br /&gt;
		local boxTypes = {}&lt;br /&gt;
		for k, v in pairs(dataTables) do&lt;br /&gt;
			tinsert(boxTypes, format(&#039;&amp;quot;%s&amp;quot;&#039;, k))&lt;br /&gt;
		end&lt;br /&gt;
		tinsert(boxTypes, &#039;&amp;quot;mbox&amp;quot;&#039;)&lt;br /&gt;
		error(format(&#039;無效的訊息框類型「%s」；有效的類型為%s&#039;, tostring(boxType), mw.text.listToText(boxTypes)), 2)&lt;br /&gt;
	end&lt;br /&gt;
	self.cfg = cfg&lt;br /&gt;
	return cfg&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function box:removeBlankArgs(args)&lt;br /&gt;
	-- Only allow blank arguments for the parameter names listed in cfg.allowBlankParams.&lt;br /&gt;
	local newArgs = {}&lt;br /&gt;
	for k, v in pairs(args) do&lt;br /&gt;
		if v ~= &#039;&#039; then&lt;br /&gt;
			newArgs[k] = v&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	for i, param in ipairs(self.cfg.allowBlankParams or {}) do&lt;br /&gt;
		newArgs[param] = args[param]&lt;br /&gt;
	end&lt;br /&gt;
	return newArgs&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function box:setBoxParameters(args)&lt;br /&gt;
	local cfg = self.cfg&lt;br /&gt;
&lt;br /&gt;
	-- Get type data.&lt;br /&gt;
	self.type = args.type&lt;br /&gt;
	local typeData = cfg.types[self.type]&lt;br /&gt;
	self.invalidTypeError = cfg.showInvalidTypeError and self.type and not typeData and true or false&lt;br /&gt;
	typeData = typeData or cfg.types[cfg.default]&lt;br /&gt;
	self.typeClass = typeData.class&lt;br /&gt;
	self.typeImage = typeData.image&lt;br /&gt;
&lt;br /&gt;
	-- Find if the box has been wrongly substituted.&lt;br /&gt;
	if cfg.substCheck and args.subst == &#039;SUBST&#039; then&lt;br /&gt;
		self.isSubstituted = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Find whether we are using a small message box.&lt;br /&gt;
	if cfg.allowSmall and (&lt;br /&gt;
		cfg.smallParam and args.small == cfg.smallParam&lt;br /&gt;
		or not cfg.smallParam and yesno(args.small)&lt;br /&gt;
	)&lt;br /&gt;
	then&lt;br /&gt;
		self.isSmall = true&lt;br /&gt;
	else&lt;br /&gt;
		self.isSmall = false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Add attributes, classes and styles.&lt;br /&gt;
	if cfg.allowId then&lt;br /&gt;
		self.id = args.id&lt;br /&gt;
		self.name = args.name&lt;br /&gt;
		if self.name then&lt;br /&gt;
			self:addClass(&#039;box-&#039; .. string.gsub(self.name,&#039; &#039;,&#039;_&#039;))&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	self:addClass(cfg.usePlainlinksParam and yesno(args.plainlinks or true) and &#039;plainlinks&#039;)&lt;br /&gt;
	for _, class in ipairs(cfg.classes or {}) do&lt;br /&gt;
		self:addClass(class)&lt;br /&gt;
	end&lt;br /&gt;
	if self.isSmall then&lt;br /&gt;
		self:addClass(cfg.smallClass or &#039;mbox-small&#039;)&lt;br /&gt;
	end&lt;br /&gt;
	if yesno(args.hidden) then&lt;br /&gt;
		self:addClass(&#039;infobox editsection&#039;)&lt;br /&gt;
	end&lt;br /&gt;
	self:addClass(self.typeClass)&lt;br /&gt;
	self:addClass(args.class)&lt;br /&gt;
	self.style = args.style&lt;br /&gt;
&lt;br /&gt;
	-- Set text style.&lt;br /&gt;
	self.textstyle = args.textstyle&lt;br /&gt;
&lt;br /&gt;
	-- Find if we are on the template page or not. This functionality is only used if useCollapsibleTextFields is set,&lt;br /&gt;
	-- or if both cfg.templateCategory and cfg.templateCategoryRequireName are set.&lt;br /&gt;
	self.useCollapsibleTextFields = cfg.useCollapsibleTextFields&lt;br /&gt;
	if self.useCollapsibleTextFields or cfg.templateCategory and cfg.templateCategoryRequireName then&lt;br /&gt;
		self.name = args.name&lt;br /&gt;
		if self.name then&lt;br /&gt;
			local templateName = mw.ustring.match(self.name, &#039;^[tT][eE][mM][pP][lL][aA][tT][eE][%s_]*:[%s_]*(.*)$&#039;) or self.name&lt;br /&gt;
			templateName = &#039;Template:&#039; .. templateName&lt;br /&gt;
			self.templateTitle = getTitleObject(templateName)&lt;br /&gt;
		end&lt;br /&gt;
		self.isTemplatePage = self.templateTitle and mw.title.equals(self.title, self.templateTitle) or false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Process data for collapsible text fields. At the moment these are only used in {{ambox}}.&lt;br /&gt;
	if self.useCollapsibleTextFields then&lt;br /&gt;
		-- Get the self.issue value.&lt;br /&gt;
		if self.isSmall and args.smalltext then&lt;br /&gt;
			self.issue = args.smalltext&lt;br /&gt;
		else&lt;br /&gt;
			local sect&lt;br /&gt;
			if args.sect == &#039;&#039; then&lt;br /&gt;
				sect = &#039;此&#039; .. (cfg.sectionDefault or &#039;頁面&#039;)&lt;br /&gt;
			elseif type(args.sect) == &#039;string&#039; then&lt;br /&gt;
				sect = &#039;此&#039; .. args.sect&lt;br /&gt;
			end&lt;br /&gt;
			local issue = args.issue&lt;br /&gt;
			issue = type(issue) == &#039;string&#039; and issue ~= &#039;&#039; and issue or nil&lt;br /&gt;
			local text = args.text&lt;br /&gt;
			text = type(text) == &#039;string&#039; and text or nil&lt;br /&gt;
			local issues = {}&lt;br /&gt;
			tinsert(issues, sect)&lt;br /&gt;
			tinsert(issues, issue)&lt;br /&gt;
			tinsert(issues, text)&lt;br /&gt;
			self.issue = tconcat(issues)&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- Get the self.talk value.&lt;br /&gt;
		local talk = args.talk&lt;br /&gt;
		if talk == &#039;&#039; -- Show talk links on the template page or template subpages if the talk parameter is blank.&lt;br /&gt;
			and self.templateTitle &lt;br /&gt;
			and (mw.title.equals(self.templateTitle, self.title) or self.title:isSubpageOf(self.templateTitle))&lt;br /&gt;
		then&lt;br /&gt;
			talk = &#039;#&#039;&lt;br /&gt;
		elseif talk == &#039;&#039; then&lt;br /&gt;
			talk = nil&lt;br /&gt;
		end&lt;br /&gt;
		if talk then&lt;br /&gt;
			-- If the talk value is a talk page, make a link to that page. Else assume that it&#039;s a section heading,&lt;br /&gt;
			-- and make a link to the talk page of the current page with that section heading.&lt;br /&gt;
			local talkTitle = getTitleObject(talk)&lt;br /&gt;
			local talkArgIsTalkPage = true&lt;br /&gt;
			if not talkTitle or not talkTitle.isTalkPage then&lt;br /&gt;
				talkArgIsTalkPage = false&lt;br /&gt;
				talkTitle = getTitleObject(self.title.text, mw.site.namespaces[self.title.namespace].talk.id)&lt;br /&gt;
			end&lt;br /&gt;
			if talkTitle and talkTitle.exists then&lt;br /&gt;
				local talkText = &#039;相關討論可見於&#039;&lt;br /&gt;
				if talkArgIsTalkPage then&lt;br /&gt;
					talkText = format(&#039;%s[[%s|%s]]。&#039;, talkText, talk, talkTitle.prefixedText)&lt;br /&gt;
				else&lt;br /&gt;
					talkText = format(&#039;%s[[%s#%s|討論頁]]。&#039;, talkText, talkTitle.prefixedText, talk)&lt;br /&gt;
				end&lt;br /&gt;
				self.talk = talkText&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- Get other values.&lt;br /&gt;
		local date&lt;br /&gt;
		if args.date and args.date ~= &#039;&#039; then&lt;br /&gt;
			date = args.date&lt;br /&gt;
		elseif args.time == &#039;&#039; and self.isTemplatePage then&lt;br /&gt;
			date = lang:formatDate(&#039;Y年n月j日&#039;)&lt;br /&gt;
		elseif args.time and args.time ~= &#039;&#039; then&lt;br /&gt;
			date = lang:formatDate(&#039;Y年n月j日&#039;, args.time)&lt;br /&gt;
		end&lt;br /&gt;
		if date then&lt;br /&gt;
			local ok, tempdate = pcall(lang.formatDate, lang, &#039;Y年n月j日&#039;, date) -- 正規化日期&lt;br /&gt;
			if ok then&lt;br /&gt;
				date = tempdate&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if date then&lt;br /&gt;
			self.date = string.format(&amp;quot; &amp;lt;small class=&#039;date-container&#039;&amp;gt;&#039;&#039;(&amp;lt;span class=&#039;date&#039;&amp;gt;%s&amp;lt;/span&amp;gt;)&#039;&#039;&amp;lt;/small&amp;gt;&amp;quot;, date)&lt;br /&gt;
		end&lt;br /&gt;
		if args.fix and args.fix ~= &#039;&#039; then&lt;br /&gt;
			self.fix = format(&amp;quot;&amp;lt;br /&amp;gt;&amp;lt;small&amp;gt;%s&amp;lt;/small&amp;gt;&amp;quot;, args.fix)&lt;br /&gt;
		else&lt;br /&gt;
			self.fix = &#039;&#039;&lt;br /&gt;
		end&lt;br /&gt;
		self.info = args.info&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Set the non-collapsible text field. At the moment this is used by all box types other than ambox,&lt;br /&gt;
	-- and also by ambox when small=yes.&lt;br /&gt;
	if self.isSmall then&lt;br /&gt;
		self.text = args.smalltext or args.text&lt;br /&gt;
	else&lt;br /&gt;
		self.text = args.text&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Set the below row.&lt;br /&gt;
	self.below = cfg.below and args.below&lt;br /&gt;
&lt;br /&gt;
	-- General image settings.&lt;br /&gt;
	self.imageCellDiv = not self.isSmall and cfg.imageCellDiv and true or false&lt;br /&gt;
	self.imageEmptyCell = cfg.imageEmptyCell&lt;br /&gt;
	if cfg.imageEmptyCellStyle then&lt;br /&gt;
		self.imageEmptyCellStyle = &#039;border:none;padding:0px;width:1px&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Left image settings.&lt;br /&gt;
	local imageLeft = self.isSmall and args.smallimage or args.image&lt;br /&gt;
	if cfg.imageCheckBlank and imageLeft ~= &#039;blank&#039; and imageLeft ~= &#039;none&#039;&lt;br /&gt;
		or not cfg.imageCheckBlank and imageLeft ~= &#039;none&#039;&lt;br /&gt;
	then&lt;br /&gt;
		self.imageLeft = imageLeft&lt;br /&gt;
		if not imageLeft then&lt;br /&gt;
			local imageSize = self.isSmall and (cfg.imageSmallSize or &#039;30x30px&#039;) or &#039;40x40px&#039;&lt;br /&gt;
			self.imageLeft = format(&#039;[[File:%s|%s|link=|alt=]]&#039;, self.typeImage or &#039;Imbox notice.png&#039;, imageSize)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Right image settings.&lt;br /&gt;
	local imageRight = self.isSmall and args.smallimageright or args.imageright&lt;br /&gt;
	if not (cfg.imageRightNone and imageRight == &#039;none&#039;) then&lt;br /&gt;
		self.imageRight = imageRight&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Add mainspace categories. At the moment these are only used in {{ambox}}.&lt;br /&gt;
	if cfg.allowMainspaceCategories then&lt;br /&gt;
		if args.cat then&lt;br /&gt;
			args.cat1 = args.cat&lt;br /&gt;
		end&lt;br /&gt;
		self.catNums = getArgNums(args, &#039;cat&#039;)&lt;br /&gt;
		if args.category then&lt;br /&gt;
			args.category1 = args.category&lt;br /&gt;
		end&lt;br /&gt;
		self.categoryNums = getArgNums(args, &#039;category&#039;)&lt;br /&gt;
		if args.all then&lt;br /&gt;
			args.all1 = args.all&lt;br /&gt;
		end&lt;br /&gt;
		self.allNums = getArgNums(args, &#039;all&#039;)&lt;br /&gt;
		self.categoryParamNums = union(self.catNums, self.categoryNums)&lt;br /&gt;
		self.categoryParamNums = union(self.categoryParamNums, self.allNums)&lt;br /&gt;
		-- The following is roughly equivalent to the old {{Ambox/category}}.&lt;br /&gt;
		local date&lt;br /&gt;
		local sortDay&lt;br /&gt;
		local dayName = {&lt;br /&gt;
			[1] = &#039;㏠&#039;,&lt;br /&gt;
			[2] = &#039;㏡&#039;,&lt;br /&gt;
			[3] = &#039;㏢&#039;,&lt;br /&gt;
			[4] = &#039;㏣&#039;,&lt;br /&gt;
			[5] = &#039;㏤&#039;,&lt;br /&gt;
			[6] = &#039;㏥&#039;,&lt;br /&gt;
			[7] = &#039;㏦&#039;,&lt;br /&gt;
			[8] = &#039;㏧&#039;,&lt;br /&gt;
			[9] = &#039;㏨&#039;,&lt;br /&gt;
			[10] = &#039;㏩&#039;,&lt;br /&gt;
			[11] = &#039;㏪&#039;,&lt;br /&gt;
			[12] = &#039;㏫&#039;,&lt;br /&gt;
			[13] = &#039;㏬&#039;,&lt;br /&gt;
			[14] = &#039;㏭&#039;,&lt;br /&gt;
			[15] = &#039;㏮&#039;,&lt;br /&gt;
			[16] = &#039;㏯&#039;,&lt;br /&gt;
			[17] = &#039;㏰&#039;,&lt;br /&gt;
			[18] = &#039;㏱&#039;,&lt;br /&gt;
			[19] = &#039;㏲&#039;,&lt;br /&gt;
			[20] = &#039;㏳&#039;,&lt;br /&gt;
			[21] = &#039;㏴&#039;,&lt;br /&gt;
			[22] = &#039;㏵&#039;,&lt;br /&gt;
			[23] = &#039;㏶&#039;,&lt;br /&gt;
			[24] = &#039;㏷&#039;,&lt;br /&gt;
			[25] = &#039;㏸&#039;,&lt;br /&gt;
			[26] = &#039;㏹&#039;,&lt;br /&gt;
			[27] = &#039;㏺&#039;,&lt;br /&gt;
			[28] = &#039;㏻&#039;,&lt;br /&gt;
			[29] = &#039;㏼&#039;,&lt;br /&gt;
			[30] = &#039;㏽&#039;,&lt;br /&gt;
			[31] = &#039;㏾&#039;&lt;br /&gt;
		}&lt;br /&gt;
		if args.date and args.date ~= &#039;&#039; then&lt;br /&gt;
			date = args.date&lt;br /&gt;
			local ok, tempdate = pcall(lang.formatDate, lang, &#039;Y年n月&#039;, date) -- 正規化日期&lt;br /&gt;
			if ok then&lt;br /&gt;
				date = tempdate&lt;br /&gt;
			end&lt;br /&gt;
		elseif args.time and args.time ~= &#039;&#039; then&lt;br /&gt;
			date = lang:formatDate(&#039;Y年n月&#039;, args.time)&lt;br /&gt;
			sortDay = lang:formatDate(&#039;j&#039;, args.time)&lt;br /&gt;
			sortDay = tonumber(sortDay)&lt;br /&gt;
			sortDay = dayName[sortDay]&lt;br /&gt;
		end&lt;br /&gt;
		date = type(date) == &#039;string&#039; and date&lt;br /&gt;
		local preposition = &#039;自&#039;&lt;br /&gt;
		for _, num in ipairs(self.categoryParamNums) do&lt;br /&gt;
			local mainCat = args[&#039;cat&#039; .. tostring(num)] or args[&#039;category&#039; .. tostring(num)]&lt;br /&gt;
			local allCat = args[&#039;all&#039; .. tostring(num)]&lt;br /&gt;
			mainCat = type(mainCat) == &#039;string&#039; and mainCat&lt;br /&gt;
			allCat = type(allCat) == &#039;string&#039; and allCat&lt;br /&gt;
			if mainCat and date and date ~= &#039;&#039; then&lt;br /&gt;
				local catTitle = format(&#039;%s%s%s&#039;, preposition, date, mainCat)&lt;br /&gt;
				if sortDay then&lt;br /&gt;
					self:addCat(&#039;main&#039;, catTitle, sortDay)&lt;br /&gt;
				else&lt;br /&gt;
					self:addCat(&#039;main&#039;, catTitle)&lt;br /&gt;
				end&lt;br /&gt;
				catTitle = getTitleObject(&#039;Category:&#039; .. catTitle)&lt;br /&gt;
				if not catTitle or not catTitle.exists then&lt;br /&gt;
					self:addCat(&#039;main&#039;, &#039;模板中使用无效日期参数的条目&#039;)&lt;br /&gt;
				end&lt;br /&gt;
			elseif mainCat and (not date or date == &#039;&#039;) then&lt;br /&gt;
				self:addCat(&#039;main&#039;, mainCat)&lt;br /&gt;
			end&lt;br /&gt;
			if allCat then&lt;br /&gt;
				self:addCat(&#039;main&#039;, allCat)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Add template-namespace categories.&lt;br /&gt;
	if cfg.templateCategory then&lt;br /&gt;
		if cfg.templateCategoryRequireName then&lt;br /&gt;
			if self.isTemplatePage then&lt;br /&gt;
				self:addCat(&#039;template&#039;, cfg.templateCategory)&lt;br /&gt;
			end&lt;br /&gt;
		elseif not self.title.isSubpage then&lt;br /&gt;
			self:addCat(&#039;template&#039;, cfg.templateCategory)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Add template error category.&lt;br /&gt;
	if cfg.templateErrorCategory then&lt;br /&gt;
		local templateErrorCategory = cfg.templateErrorCategory&lt;br /&gt;
		local templateCat, templateSort&lt;br /&gt;
		if not self.name and not self.title.isSubpage then&lt;br /&gt;
			templateCat = templateErrorCategory&lt;br /&gt;
		elseif self.isTemplatePage then&lt;br /&gt;
			local paramsToCheck = cfg.templateErrorParamsToCheck or {}&lt;br /&gt;
			local count = 0&lt;br /&gt;
			for i, param in ipairs(paramsToCheck) do&lt;br /&gt;
				if not args[param] then&lt;br /&gt;
					count = count + 1&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			if count &amp;gt; 0 then&lt;br /&gt;
				templateCat = templateErrorCategory&lt;br /&gt;
				templateSort = tostring(count)&lt;br /&gt;
			end&lt;br /&gt;
			if self.categoryNums and #self.categoryNums &amp;gt; 0 then&lt;br /&gt;
				templateCat = templateErrorCategory&lt;br /&gt;
				templateSort = &#039;C&#039;&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		self:addCat(&#039;template&#039;, templateCat, templateSort)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Categories for all namespaces.&lt;br /&gt;
	if self.invalidTypeError then&lt;br /&gt;
		local allSort = (self.nsid == 0 and &#039;Main:&#039; or &#039;&#039;) .. self.title.prefixedText&lt;br /&gt;
		self:addCat(&#039;all&#039;, &#039;需要修复的信息框&#039;, allSort)&lt;br /&gt;
	end&lt;br /&gt;
	if self.isSubstituted then&lt;br /&gt;
		self:addCat(&#039;all&#039;, &#039;錯誤使用替換引用的頁面&#039;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Convert category tables to strings and pass them through [[Module:Category handler]].&lt;br /&gt;
	self.categories = categoryHandler{&lt;br /&gt;
		main = tconcat(self.mainCats or {}),&lt;br /&gt;
		template = tconcat(self.templateCats or {}),&lt;br /&gt;
		all = tconcat(self.allCats or {}),&lt;br /&gt;
		nocat = args.nocat,&lt;br /&gt;
		demospace = self.demospace,&lt;br /&gt;
		page = self.pageTitle and self.pageTitle.prefixedText or nil&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function box:export()&lt;br /&gt;
	local root = mw.html.create()&lt;br /&gt;
&lt;br /&gt;
	-- Add the subst check error.&lt;br /&gt;
	if self.isSubstituted and self.name then&lt;br /&gt;
		root&lt;br /&gt;
			:tag(&#039;b&#039;)&lt;br /&gt;
				:addClass(&#039;error&#039;)&lt;br /&gt;
				:wikitext(format(&lt;br /&gt;
					&#039;模板&amp;lt;code&amp;gt;%s[[Template:%s|%s]]%s&amp;lt;/code&amp;gt;被錯誤地替代。&#039;,&lt;br /&gt;
					mw.text.nowiki(&#039;{{&#039;), self.name, self.name, mw.text.nowiki(&#039;}}&#039;)&lt;br /&gt;
				))&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	root:wikitext(insertStyle(self.cfg))&lt;br /&gt;
&lt;br /&gt;
	-- Create the box table.&lt;br /&gt;
	local boxTable = root:tag(&#039;table&#039;)&lt;br /&gt;
	boxTable&lt;br /&gt;
		:attr(&#039;id&#039;, self.id)&lt;br /&gt;
	for i, class in ipairs(self.classes or {}) do&lt;br /&gt;
		boxTable&lt;br /&gt;
			:addClass(class)&lt;br /&gt;
	end&lt;br /&gt;
	boxTable&lt;br /&gt;
		:cssText(self.style)&lt;br /&gt;
		:attr(&#039;role&#039;, &#039;presentation&#039;)&lt;br /&gt;
&lt;br /&gt;
	-- Add the left-hand image.&lt;br /&gt;
	local row = boxTable:tag(&#039;tr&#039;)&lt;br /&gt;
	if self.imageLeft then&lt;br /&gt;
		local imageLeftCell = row:tag(&#039;td&#039;):addClass(&#039;mbox-image&#039;)&lt;br /&gt;
		if self.imageCellDiv then&lt;br /&gt;
			-- If we are using a div, redefine imageLeftCell so that the image is inside it.&lt;br /&gt;
			-- Divs use style=&amp;quot;width: 52px;&amp;quot;, which limits the image width to 52px. If any&lt;br /&gt;
			-- images in a div are wider than that, they may overlap with the text or cause&lt;br /&gt;
			-- other display problems.&lt;br /&gt;
			imageLeftCell = imageLeftCell:tag(&#039;div&#039;):css(&#039;width&#039;, &#039;52px&#039;) &lt;br /&gt;
		end&lt;br /&gt;
		imageLeftCell&lt;br /&gt;
			:wikitext(self.imageLeft)&lt;br /&gt;
	elseif self.imageEmptyCell then&lt;br /&gt;
		-- Some message boxes define an empty cell if no image is specified, and some don&#039;t.&lt;br /&gt;
		-- The old template code in templates where empty cells are specified gives the following hint:&lt;br /&gt;
		-- &amp;quot;No image. Cell with some width or padding necessary for text cell to have 100% width.&amp;quot;&lt;br /&gt;
		row:tag(&#039;td&#039;)&lt;br /&gt;
			:addClass(&#039;mbox-empty-cell&#039;) &lt;br /&gt;
			:cssText(self.imageEmptyCellStyle)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Add the text.&lt;br /&gt;
	local textCell = row:tag(&#039;td&#039;):addClass(&#039;mbox-text&#039;)&lt;br /&gt;
	if self.useCollapsibleTextFields then&lt;br /&gt;
		-- The message box uses advanced text parameters that allow things to be collapsible. At the&lt;br /&gt;
		-- moment, only ambox uses this.&lt;br /&gt;
		textCell&lt;br /&gt;
			:cssText(self.textstyle)&lt;br /&gt;
		local textCellSpan = textCell:tag(&#039;div&#039;)&lt;br /&gt;
		textCellSpan&lt;br /&gt;
			:addClass(&#039;mbox-text-span&#039;)&lt;br /&gt;
			:wikitext(self.issue)&lt;br /&gt;
		if not self.isSmall then&lt;br /&gt;
			textCellSpan&lt;br /&gt;
				:tag(&#039;span&#039;)&lt;br /&gt;
					:addClass(&#039;hide-when-compact&#039;)&lt;br /&gt;
					:wikitext(self.talk and self.talk)&lt;br /&gt;
		end&lt;br /&gt;
		textCellSpan&lt;br /&gt;
			:wikitext(self.date and self.date)&lt;br /&gt;
		if not self.isSmall and self.fix ~= &#039;&#039; then&lt;br /&gt;
			textCellSpan&lt;br /&gt;
				:tag(&#039;span&#039;)&lt;br /&gt;
					:addClass(&#039;hide-when-compact&#039;)&lt;br /&gt;
					:wikitext(self.fix and self.fix)&lt;br /&gt;
		end&lt;br /&gt;
		if not self.isSmall then&lt;br /&gt;
			textCellSpan&lt;br /&gt;
				:tag(&#039;span&#039;)&lt;br /&gt;
				:addClass(&#039;hide-when-compact&#039;)&lt;br /&gt;
				:wikitext(self.info and self.info)&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		-- Default text formatting - anything goes.&lt;br /&gt;
		textCell&lt;br /&gt;
			:cssText(self.textstyle)&lt;br /&gt;
			:wikitext(self.text)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Add the right-hand image.&lt;br /&gt;
	if self.imageRight then&lt;br /&gt;
		local imageRightCell = row:tag(&#039;td&#039;):addClass(&#039;mbox-imageright&#039;)&lt;br /&gt;
		if self.imageCellDiv then&lt;br /&gt;
			imageRightCell = imageRightCell:tag(&#039;div&#039;):css(&#039;width&#039;, &#039;52px&#039;) -- If we are using a div, redefine imageRightCell so that the image is inside it.&lt;br /&gt;
		end&lt;br /&gt;
		imageRightCell&lt;br /&gt;
			:wikitext(self.imageRight)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Add the below row.&lt;br /&gt;
	if self.below then&lt;br /&gt;
		boxTable:tag(&#039;tr&#039;)&lt;br /&gt;
			:tag(&#039;td&#039;)&lt;br /&gt;
				:attr(&#039;colspan&#039;, self.imageRight and &#039;3&#039; or &#039;2&#039;)&lt;br /&gt;
				:addClass(&#039;mbox-text&#039;)&lt;br /&gt;
				:cssText(self.textstyle)&lt;br /&gt;
				:wikitext(self.below)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Add error message for invalid type parameters.&lt;br /&gt;
	if self.invalidTypeError then&lt;br /&gt;
		root&lt;br /&gt;
			:tag(&#039;div&#039;)&lt;br /&gt;
				:css(&#039;text-align&#039;, &#039;center&#039;)&lt;br /&gt;
				:wikitext(format(&#039;此訊息框使用無效的「type=%s」參數，需要修復。&#039;, self.type or &#039;&#039;))&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Add categories.&lt;br /&gt;
	root&lt;br /&gt;
		:wikitext(self.categories)&lt;br /&gt;
&lt;br /&gt;
	return tostring(root)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function main(boxType, args)&lt;br /&gt;
	local outputBox = box.new()&lt;br /&gt;
	outputBox:setTitle(args)&lt;br /&gt;
	outputBox:getConfig(boxType)&lt;br /&gt;
	args = outputBox:removeBlankArgs(args)&lt;br /&gt;
	outputBox:setBoxParameters(args)&lt;br /&gt;
	return outputBox:export()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function makeWrapper(boxType)&lt;br /&gt;
	return function (frame)&lt;br /&gt;
		local args = getArgs(frame, {trim = false, removeBlanks = false})&lt;br /&gt;
		return main(boxType, args)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function insertStyleWikitext(frame)&lt;br /&gt;
	local args = getArgs(frame, {trim = false, removeBlanks = false})&lt;br /&gt;
	local boxType = args[1] or &#039;mbox&#039;&lt;br /&gt;
	&lt;br /&gt;
	-- // ---- // --&lt;br /&gt;
&lt;br /&gt;
	local outputBox = box.new()&lt;br /&gt;
	outputBox:setTitle(args)&lt;br /&gt;
	local cfg = outputBox:getConfig(boxType)&lt;br /&gt;
	return insertStyle(cfg)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local p = {&lt;br /&gt;
	main = main,&lt;br /&gt;
	mbox = makeWrapper(&#039;mbox&#039;),&lt;br /&gt;
	insertStyle = insertStyleWikitext&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for boxType in pairs(cfgTables) do&lt;br /&gt;
	if boxType:sub(1, 1) ~= &#039;@&#039; then&lt;br /&gt;
		p[boxType] = makeWrapper(boxType)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Module:Yesno&amp;diff=8568</id>
		<title>Module:Yesno</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Module:Yesno&amp;diff=8568"/>
		<updated>2026-01-22T17:11:56Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- Function allowing for consistent treatment of boolean-like wikitext input.&lt;br /&gt;
-- It works similarly to the template {{yesno}}.&lt;br /&gt;
&lt;br /&gt;
return function (val, default)&lt;br /&gt;
	-- If your wiki uses non-ascii characters for any of &amp;quot;yes&amp;quot;, &amp;quot;no&amp;quot;, etc., you&lt;br /&gt;
	-- should replace &amp;quot;val:lower()&amp;quot; with &amp;quot;mw.ustring.lower(val)&amp;quot; in the&lt;br /&gt;
	-- following line.&lt;br /&gt;
	val = type(val) == &#039;string&#039; and val:lower() or val&lt;br /&gt;
	if val == nil then&lt;br /&gt;
		return nil&lt;br /&gt;
	elseif val == true &lt;br /&gt;
		or val == &#039;yes&#039;&lt;br /&gt;
		or val == &#039;y&#039;&lt;br /&gt;
		or val == &#039;true&#039;&lt;br /&gt;
		or val == &#039;t&#039;&lt;br /&gt;
		or val == &#039;on&#039;&lt;br /&gt;
		or val == &#039;是&#039;&lt;br /&gt;
		or val == &#039;开&#039;&lt;br /&gt;
		or val == &#039;開&#039;&lt;br /&gt;
		or tonumber(val) == 1&lt;br /&gt;
	then&lt;br /&gt;
		return true&lt;br /&gt;
	elseif val == false&lt;br /&gt;
		or val == &#039;no&#039;&lt;br /&gt;
		or val == &#039;n&#039;&lt;br /&gt;
		or val == &#039;false&#039;&lt;br /&gt;
		or val == &#039;f&#039;&lt;br /&gt;
		or val == &#039;off&#039;&lt;br /&gt;
		or val == &#039;否&#039;&lt;br /&gt;
		or val == &#039;关&#039;&lt;br /&gt;
		or val == &#039;關&#039;&lt;br /&gt;
		or tonumber(val) == 0&lt;br /&gt;
	then&lt;br /&gt;
		return false&lt;br /&gt;
	else&lt;br /&gt;
		return default&lt;br /&gt;
	end&lt;br /&gt;
end&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
	<entry>
		<id>https://calcwiki.org/index.php?title=Template:Infobox&amp;diff=8566</id>
		<title>Template:Infobox</title>
		<link rel="alternate" type="text/html" href="https://calcwiki.org/index.php?title=Template:Infobox&amp;diff=8566"/>
		<updated>2026-01-22T17:11:56Z</updated>

		<summary type="html">&lt;p&gt;Lch：​导入1个版本&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:信息框模板|{{remove first word|{{SUBPAGENAME}}}}]]}}}}{{#ifeq:{{PAGENAME}}|信息框||{{#ifeq:{{str rightc|{{SUBPAGENAME}}|3}}|信息框|[[Category:信息框模板|{{str crop|{{SUBPAGENAME}}|3}}]]}}}}{{#ifeq:{{PAGENAME}}|資訊框||{{#ifeq:{{str rightc|{{SUBPAGENAME}}|3}}|資訊框|[[Category:信息框模板|{{str crop|{{SUBPAGENAME}}|3}}]]}}}}|}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Lch</name></author>
	</entry>
</feed>