<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh">
	<id>https://arolstar52-zhtest.hf.space/index.php?action=history&amp;feed=atom&amp;title=Module%3ATracklist</id>
	<title>Module:Tracklist - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://arolstar52-zhtest.hf.space/index.php?action=history&amp;feed=atom&amp;title=Module%3ATracklist"/>
	<link rel="alternate" type="text/html" href="https://arolstar52-zhtest.hf.space/index.php?title=Module:Tracklist&amp;action=history"/>
	<updated>2026-06-28T06:40:02Z</updated>
	<subtitle>在这个wiki上该页的修订历史</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://arolstar52-zhtest.hf.space/index.php?title=Module:Tracklist&amp;diff=3141948&amp;oldid=prev</id>
		<title>imported&gt;TimWu007：​Module_talk:Tracklist#c-BRDN-20260508074900-1F616EMO-20260508065400</title>
		<link rel="alternate" type="text/html" href="https://arolstar52-zhtest.hf.space/index.php?title=Module:Tracklist&amp;diff=3141948&amp;oldid=prev"/>
		<updated>2026-05-09T01:57:33Z</updated>

		<summary type="html">&lt;p&gt;&lt;a href=&quot;/index.php?title=Module_talk:Tracklist&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;Module talk:Tracklist（页面不存在）&quot;&gt;Module_talk:Tracklist#c-BRDN-20260508074900-1F616EMO-20260508065400&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- This module implements [[Template:Tracklist]]&lt;br /&gt;
&lt;br /&gt;
local yesno = require(&amp;#039;Module:Yesno&amp;#039;)&lt;br /&gt;
local checkType = require(&amp;#039;libraryUtil&amp;#039;).checkType&lt;br /&gt;
&lt;br /&gt;
local SHOW_WARNINGS = false&lt;br /&gt;
local INPUT_ERROR_CATEGORY = &amp;#039;输入错误的曲目表&amp;#039;&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Helper functions&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
-- Add a mixin to a class.&lt;br /&gt;
local function addMixin(class, mixin)&lt;br /&gt;
	for k, v in pairs(mixin) do&lt;br /&gt;
		if k ~= &amp;#039;init&amp;#039; then&lt;br /&gt;
			class[k] = v&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Validation mixin&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local Validation = {}&lt;br /&gt;
&lt;br /&gt;
function Validation.init(self)&lt;br /&gt;
	self.warnings = {}&lt;br /&gt;
	self.categories = {}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Validation:addWarning(msg, category)&lt;br /&gt;
	table.insert(self.warnings, msg)&lt;br /&gt;
	table.insert(self.categories, category)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Validation:addCategory(category)&lt;br /&gt;
	table.insert(self.categories, category)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Validation:getWarnings()&lt;br /&gt;
	return self.warnings&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Validation:getCategories()&lt;br /&gt;
	return self.categories&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Validate a track length. If a track length is invalid, a warning is added.&lt;br /&gt;
-- A type error is raised if the length is not of type string or nil.&lt;br /&gt;
function Validation:validateLength(length)&lt;br /&gt;
	checkType(&amp;#039;validateLength&amp;#039;, 1, length, &amp;#039;string&amp;#039;, true)&lt;br /&gt;
	if length == nil then&lt;br /&gt;
		-- Do nothing if no length specified&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--mw.log(&amp;#039;&amp;gt;&amp;gt; length = &amp;#039; .. length)&lt;br /&gt;
	length = length&lt;br /&gt;
		-- ugly hack: allow {{ref}}&lt;br /&gt;
		-- 在{{ref}}、[[模板:Citation Style documentation/cs1]]中的cs1模板等，前後包覆 span 可規避歸入「Category:輸入錯誤的曲目表」這個隱藏分類。&lt;br /&gt;
		-- e.g., `length1   = 5:04&amp;lt;span class=&amp;quot;ref&amp;quot;&amp;gt;&amp;lt;ref name=&amp;quot;通常盤&amp;quot;/&amp;gt;&amp;lt;/span&amp;gt;` @ [[春逝/marie]]&lt;br /&gt;
		:gsub(&amp;quot;^([%d:]+)%s*&amp;lt;(%w+)([^&amp;lt;&amp;gt;]*)&amp;gt;[%s%S]*&amp;lt;%/%2&amp;gt;&amp;quot;, &amp;quot;%1&amp;quot;)&lt;br /&gt;
		-- ugly hack: allow &amp;lt;ref&amp;gt;&lt;br /&gt;
		--:gsub(&amp;quot;\127\&amp;#039;\&amp;quot;\`UNIQ----ref--[%dA-F]+--QINU\`\&amp;quot;\&amp;#039;\127&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
		-- trim&lt;br /&gt;
		:match &amp;quot;^%s*(.-)%s*$&amp;quot;&lt;br /&gt;
	--mw.log(&amp;#039;&amp;gt;&amp;gt; length2 = &amp;#039; .. length)&lt;br /&gt;
	&lt;br /&gt;
	local hours, minutes, seconds&lt;br /&gt;
&lt;br /&gt;
	-- Try to match times like &amp;quot;1:23:45&amp;quot;.&lt;br /&gt;
	hours, minutes, seconds = length:match(&amp;#039;^(%d+):(%d%d):(%d%d)$&amp;#039;)&lt;br /&gt;
	if hours and hours:sub(1, 1) == &amp;#039;0&amp;#039; then&lt;br /&gt;
		-- Disallow times like &amp;quot;0:12:34&amp;quot;&lt;br /&gt;
		self:addWarning(string.format(&lt;br /&gt;
			&amp;quot;无效时间&amp;#039;%s&amp;#039;（时间格式&amp;#039;h:mm:ss&amp;#039;不能以零开头）&amp;quot;,&lt;br /&gt;
			mw.text.nowiki(length)&lt;br /&gt;
		), INPUT_ERROR_CATEGORY)&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if not seconds then&lt;br /&gt;
		-- The previous attempt didn&amp;#039;t match. Try to match times like &amp;quot;1:23&amp;quot;.&lt;br /&gt;
		minutes, seconds = length:match(&amp;#039;^(%d?%d):(%d%d)$&amp;#039;)&lt;br /&gt;
		if minutes and minutes:find(&amp;#039;^0%d$&amp;#039;) then&lt;br /&gt;
			-- Special case to disallow lengths like &amp;quot;01:23&amp;quot;. This check has to&lt;br /&gt;
			-- be here so that lengths like &amp;quot;1:01:23&amp;quot; are still allowed.&lt;br /&gt;
			self:addWarning(string.format(&lt;br /&gt;
				&amp;quot;无效时间&amp;#039;%s&amp;#039;（时间格式&amp;#039;mm:ss&amp;#039;不能以零开头）&amp;quot;,&lt;br /&gt;
				mw.text.nowiki(length)&lt;br /&gt;
			), INPUT_ERROR_CATEGORY)&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Add a warning and return if we did not find a match.&lt;br /&gt;
	if not seconds then&lt;br /&gt;
		self:addWarning(string.format(&lt;br /&gt;
			&amp;quot;无效时间&amp;#039;%s&amp;#039;（时间格式必须为&amp;#039;m:ss&amp;#039;、&amp;#039;mm:ss&amp;#039;或&amp;#039;h:mm:ss&amp;#039;）&amp;quot;,&lt;br /&gt;
			mw.text.nowiki(length)&lt;br /&gt;
		), INPUT_ERROR_CATEGORY)&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Check that the minutes are less than 60 if we have an hours field.&lt;br /&gt;
	if hours and tonumber(minutes) &amp;gt;= 60 then&lt;br /&gt;
		self:addWarning(string.format(&lt;br /&gt;
			&amp;quot;无效时长&amp;#039;%s&amp;#039;（如果指定了小时数，则分钟数必须小于60）&amp;quot;,&lt;br /&gt;
			mw.text.nowiki(length)&lt;br /&gt;
		), INPUT_ERROR_CATEGORY)&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Check that the seconds are less than 60&lt;br /&gt;
	if tonumber(seconds) &amp;gt;= 60 then&lt;br /&gt;
		self:addWarning(string.format(&lt;br /&gt;
			&amp;quot;无效时长&amp;#039;%s&amp;#039;（秒数必须小于60）&amp;quot;,&lt;br /&gt;
			mw.text.nowiki(length)&lt;br /&gt;
		), INPUT_ERROR_CATEGORY)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Track class&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local Track = {}&lt;br /&gt;
Track.__index = Track&lt;br /&gt;
addMixin(Track, Validation)&lt;br /&gt;
&lt;br /&gt;
Track.fields = {&lt;br /&gt;
	number = true,&lt;br /&gt;
	title = true,&lt;br /&gt;
	note = true,&lt;br /&gt;
	lyrics = true,&lt;br /&gt;
	music = true,&lt;br /&gt;
	writer = true,&lt;br /&gt;
	arranger = true,&lt;br /&gt;
	producer = true,&lt;br /&gt;
	ep = true,&lt;br /&gt;
	extra = true,&lt;br /&gt;
	longnote = true,&lt;br /&gt;
	length = true,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Track.cellMethods = {&lt;br /&gt;
	number = &amp;#039;makeNumberCell&amp;#039;,&lt;br /&gt;
	title = &amp;#039;makeTitleCell&amp;#039;,&lt;br /&gt;
	writer = &amp;#039;makeWriterCell&amp;#039;,&lt;br /&gt;
	lyrics = &amp;#039;makeLyricsCell&amp;#039;,&lt;br /&gt;
	music = &amp;#039;makeMusicCell&amp;#039;,&lt;br /&gt;
	arranger = &amp;#039;makeArrangerCell&amp;#039;,&lt;br /&gt;
	producer = &amp;#039;makeProducerCell&amp;#039;,&lt;br /&gt;
	ep = &amp;#039;makeEpCell&amp;#039;,&lt;br /&gt;
	extra = &amp;#039;makeExtraCell&amp;#039;,&lt;br /&gt;
	longnote = &amp;#039;makeLongNoteCell&amp;#039;,&lt;br /&gt;
	length = &amp;#039;makeLengthCell&amp;#039;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function Track.new(data)&lt;br /&gt;
	local self = setmetatable({}, Track)&lt;br /&gt;
	Validation.init(self)&lt;br /&gt;
	for field in pairs(Track.fields) do&lt;br /&gt;
		self[field] = data[field]&lt;br /&gt;
	end&lt;br /&gt;
	self.number = assert(tonumber(self.number))&lt;br /&gt;
	self:validateLength(self.length)&lt;br /&gt;
	return self&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Track:getLyricsCredit()&lt;br /&gt;
	return self.lyrics&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Track:getMusicCredit()&lt;br /&gt;
	return self.music&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Track:getWriterCredit()&lt;br /&gt;
	return self.writer&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Track:getArrangerCredit()&lt;br /&gt;
	return self.arranger&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Track:getProducerCredit()&lt;br /&gt;
	return self.producer&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Track:getEpCredit()&lt;br /&gt;
	return self.ep&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Track:getExtraField()&lt;br /&gt;
	return self.extra&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Track:getLongNoteField()&lt;br /&gt;
	return self.longnote&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Track:getLengthField()&lt;br /&gt;
	return self.length&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Note: called with single dot syntax&lt;br /&gt;
function Track.makeSimpleCell(wikitext)&lt;br /&gt;
	return mw.html.create(&amp;#039;td&amp;#039;)&lt;br /&gt;
		:css(&amp;#039;vertical-align&amp;#039;, &amp;#039;top&amp;#039;)&lt;br /&gt;
		:wikitext(wikitext or &amp;#039;&amp;amp;nbsp;&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Track:makeNumberCell()&lt;br /&gt;
	return mw.html.create(&amp;#039;td&amp;#039;)&lt;br /&gt;
		:css(&amp;#039;padding-right&amp;#039;, &amp;#039;10px&amp;#039;)&lt;br /&gt;
		:css(&amp;#039;text-align&amp;#039;, &amp;#039;right&amp;#039;)&lt;br /&gt;
		:css(&amp;#039;vertical-align&amp;#039;, &amp;#039;top&amp;#039;)&lt;br /&gt;
		:wikitext(self.number .. &amp;#039;.&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Track:makeTitleCell()&lt;br /&gt;
	local titleCell = mw.html.create(&amp;#039;td&amp;#039;)&lt;br /&gt;
	titleCell&lt;br /&gt;
		:css(&amp;#039;vertical-align&amp;#039;, &amp;#039;top&amp;#039;)&lt;br /&gt;
		:wikitext(self.title and string.format(&amp;#039;%s&amp;#039;, self.title) or &amp;#039;-{zh-hans:《;zh-hant:〈;}-无题-{zh-hans:》;zh-hant:〉;}-&amp;#039;)&lt;br /&gt;
	if self.note then&lt;br /&gt;
		titleCell&lt;br /&gt;
			:tag(&amp;#039;span&amp;#039;)&lt;br /&gt;
				:css(&amp;#039;font-size&amp;#039;, &amp;#039;85%&amp;#039;)&lt;br /&gt;
				:wikitext(string.format(&amp;#039;（%s）&amp;#039;, self.note))&lt;br /&gt;
	end&lt;br /&gt;
	return titleCell&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Track:makeWriterCell()&lt;br /&gt;
	return Track.makeSimpleCell(self.writer)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Track:makeLyricsCell()&lt;br /&gt;
	return Track.makeSimpleCell(self.lyrics)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Track:makeMusicCell()&lt;br /&gt;
	return Track.makeSimpleCell(self.music)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Track:makeArrangerCell()&lt;br /&gt;
	return Track.makeSimpleCell(self.arranger)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Track:makeProducerCell()&lt;br /&gt;
	return Track.makeSimpleCell(self.producer)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Track:makeEpCell()&lt;br /&gt;
	return Track.makeSimpleCell(self.ep)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Track:makeExtraCell()&lt;br /&gt;
	return Track.makeSimpleCell(self.extra)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Track:makeLongNoteCell()&lt;br /&gt;
	local longnoteCell = mw.html.create(&amp;#039;td&amp;#039;)&lt;br /&gt;
	longnoteCell&lt;br /&gt;
		:css(&amp;#039;vertical-align&amp;#039;, &amp;#039;top&amp;#039;)&lt;br /&gt;
		:tag(&amp;#039;span&amp;#039;)&lt;br /&gt;
			:css(&amp;#039;font-size&amp;#039;, &amp;#039;85%&amp;#039;)&lt;br /&gt;
			:wikitext(self.longnote or &amp;#039;&amp;amp;nbsp;&amp;#039;)&lt;br /&gt;
	return longnoteCell&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Track:makeLengthCell()&lt;br /&gt;
	return mw.html.create(&amp;#039;td&amp;#039;)&lt;br /&gt;
		:addClass(&amp;#039;tracklist-length&amp;#039;)&lt;br /&gt;
		:css(&amp;#039;text-align&amp;#039;, &amp;#039;right&amp;#039;)&lt;br /&gt;
		:wikitext(self.length or &amp;#039;&amp;amp;nbsp;&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Track:exportRow(options)&lt;br /&gt;
	options = options or {}&lt;br /&gt;
	local columns = options.columns or {}&lt;br /&gt;
	local row = mw.html.create(&amp;#039;tr&amp;#039;)&lt;br /&gt;
	for i, column in ipairs(columns) do&lt;br /&gt;
		local method = Track.cellMethods[column]&lt;br /&gt;
		if method then&lt;br /&gt;
			row:node(self[method](self))&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return row&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- TrackListing class&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local TrackListing = {}&lt;br /&gt;
TrackListing.__index = TrackListing&lt;br /&gt;
addMixin(TrackListing, Validation)&lt;br /&gt;
&lt;br /&gt;
TrackListing.fields = {&lt;br /&gt;
	all_position = true,&lt;br /&gt;
	all_writing = true,&lt;br /&gt;
	all_lyrics = true,&lt;br /&gt;
	all_music = true,&lt;br /&gt;
	all_arranger = true,&lt;br /&gt;
	all_producer = true,&lt;br /&gt;
	all_ep = true,&lt;br /&gt;
	all_note = true,&lt;br /&gt;
	collapsed = true,&lt;br /&gt;
	headline = true,&lt;br /&gt;
	font_size = true,&lt;br /&gt;
	extra_column = true,&lt;br /&gt;
	total_length = true,&lt;br /&gt;
	title_width = true,&lt;br /&gt;
	writing_width = true,&lt;br /&gt;
	lyrics_width = true,&lt;br /&gt;
	music_width = true,&lt;br /&gt;
	arranger_width = true,&lt;br /&gt;
	producer_width = true,&lt;br /&gt;
	ep_width = true,&lt;br /&gt;
	extra_width = true,&lt;br /&gt;
	longnote_width = true,&lt;br /&gt;
	category = true,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
TrackListing.deprecatedFields = {&lt;br /&gt;
	writing_credits = true,&lt;br /&gt;
	lyrics_credits = true,&lt;br /&gt;
	music_credits = true,&lt;br /&gt;
	arranger_credits = true,&lt;br /&gt;
	producer_credits = true,&lt;br /&gt;
	ep_credits = true,&lt;br /&gt;
	longnote_column = true,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function TrackListing.new(data)&lt;br /&gt;
	local self = setmetatable({}, TrackListing)&lt;br /&gt;
	Validation.init(self)&lt;br /&gt;
&lt;br /&gt;
	-- Check for deprecated arguments&lt;br /&gt;
	for deprecatedField in pairs(TrackListing.deprecatedFields) do&lt;br /&gt;
		if data[deprecatedField] then&lt;br /&gt;
			self:addCategory(&amp;#039;使用废弃参数的曲目表&amp;#039;)&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Validate total length&lt;br /&gt;
	if data.total_length then&lt;br /&gt;
		self:validateLength(data.total_length)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Add properties&lt;br /&gt;
	for field in pairs(TrackListing.fields) do&lt;br /&gt;
		self[field] = data[field]&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Evaluate boolean properties&lt;br /&gt;
	self.collapsed = yesno(self.collapsed, false)&lt;br /&gt;
	self.showCategories = yesno(self.category) ~= false&lt;br /&gt;
	self.category = nil&lt;br /&gt;
&lt;br /&gt;
	-- Make track objects&lt;br /&gt;
	self.tracks = {}&lt;br /&gt;
	for i, trackData in ipairs(data.tracks or {}) do&lt;br /&gt;
		table.insert(self.tracks, Track.new(trackData))&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Find which of the optional columns we have.&lt;br /&gt;
	-- We could just check every column for every track object, but that would&lt;br /&gt;
	-- be no fun^H^H^H^H^H^H inefficient, so we use four different strategies&lt;br /&gt;
	-- to try and check only as many columns and track objects as necessary.&lt;br /&gt;
	do&lt;br /&gt;
		local optionalColumns = {}&lt;br /&gt;
		local columnMethods = {&lt;br /&gt;
			lyrics = &amp;#039;getLyricsCredit&amp;#039;,&lt;br /&gt;
			music = &amp;#039;getMusicCredit&amp;#039;,&lt;br /&gt;
			writer = &amp;#039;getWriterCredit&amp;#039;,&lt;br /&gt;
			arranger = &amp;#039;getArrangerCredit&amp;#039;,&lt;br /&gt;
			producer = &amp;#039;getProducerCredit&amp;#039;,&lt;br /&gt;
			ep = &amp;#039;getEpCredit&amp;#039;,&lt;br /&gt;
			extra = &amp;#039;getExtraField&amp;#039;,&lt;br /&gt;
			longnote = &amp;#039;getLongNoteField&amp;#039;,&lt;br /&gt;
			length = &amp;#039;getLengthField&amp;#039;,&lt;br /&gt;
		}&lt;br /&gt;
		local doneWriterCheck = false&lt;br /&gt;
		for i, trackObj in ipairs(self.tracks) do&lt;br /&gt;
			for column, method in pairs(columnMethods) do&lt;br /&gt;
				if trackObj[method](trackObj) then&lt;br /&gt;
					optionalColumns[column] = true&lt;br /&gt;
					columnMethods[column] = nil&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			if not doneWriterCheck and optionalColumns.writer then&lt;br /&gt;
				doneWriterCheck = true&lt;br /&gt;
				optionalColumns.lyrics = nil&lt;br /&gt;
				optionalColumns.music = nil&lt;br /&gt;
				columnMethods.lyrics = nil&lt;br /&gt;
				columnMethods.music = nil&lt;br /&gt;
			end&lt;br /&gt;
			if not next(columnMethods) then&lt;br /&gt;
				break&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		self.optionalColumns = optionalColumns&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return self&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function TrackListing:makeIntro()&lt;br /&gt;
	local s = &amp;#039;&amp;#039;&lt;br /&gt;
		if self.all_writing then&lt;br /&gt;
			s = s .. string.format(&lt;br /&gt;
				&amp;#039;全碟词曲：%s　&amp;#039;,&lt;br /&gt;
				self.all_writing&lt;br /&gt;
			)&lt;br /&gt;
		elseif self.all_lyrics and self.all_music then&lt;br /&gt;
			s = s .. string.format(&lt;br /&gt;
				&amp;#039;全碟-{zh-cn:作词;zh-hk:填詞;zh-tw:作詞;}-：%s　全碟作曲：%s　&amp;#039;,&lt;br /&gt;
				self.all_lyrics,&lt;br /&gt;
				self.all_music&lt;br /&gt;
			)&lt;br /&gt;
		elseif self.all_lyrics then&lt;br /&gt;
			s = s .. string.format(&lt;br /&gt;
				&amp;#039;全碟-{zh-cn:作词;zh-hk:填詞;zh-tw:作詞;}-：%s　&amp;#039;,&lt;br /&gt;
				self.all_lyrics&lt;br /&gt;
			)&lt;br /&gt;
		elseif self.all_music then&lt;br /&gt;
			s = s .. string.format(&lt;br /&gt;
				&amp;#039;全碟作曲：%s　&amp;#039;,&lt;br /&gt;
				self.all_music&lt;br /&gt;
			)&lt;br /&gt;
		end&lt;br /&gt;
		if self.all_arranger then&lt;br /&gt;
			s = s .. string.format(&lt;br /&gt;
				&amp;#039;全碟编曲：%s　&amp;#039;,&lt;br /&gt;
				self.all_arranger&lt;br /&gt;
			)&lt;br /&gt;
		end&lt;br /&gt;
		if self.all_producer then&lt;br /&gt;
			s = s .. string.format(&lt;br /&gt;
				&amp;#039;全碟製作人：%s　&amp;#039;,&lt;br /&gt;
				self.all_producer&lt;br /&gt;
			)&lt;br /&gt;
		end&lt;br /&gt;
		if self.all_ep then&lt;br /&gt;
			s = s .. string.format(&lt;br /&gt;
				&amp;#039;全碟監製：%s　&amp;#039;,&lt;br /&gt;
				self.all_ep&lt;br /&gt;
			)	&lt;br /&gt;
		end&lt;br /&gt;
		if self.all_note then&lt;br /&gt;
			if self.all_note == &amp;#039;except&amp;#039; or yesno(self.all_note) == true then&lt;br /&gt;
				s = s .. string.format(&lt;br /&gt;
					&amp;#039;&amp;lt;small&amp;gt;（下面注明例外曲目）&amp;lt;/small&amp;gt;&amp;#039;&lt;br /&gt;
				)&lt;br /&gt;
			else&lt;br /&gt;
				s = s .. string.format(&lt;br /&gt;
					&amp;#039;%s&amp;#039;,&lt;br /&gt;
					self.all_note&lt;br /&gt;
				)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	return s&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function TrackListing:renderTrackingCategories()&lt;br /&gt;
	if not self.showCategories or mw.title.getCurrentTitle().namespace ~= 0 then&lt;br /&gt;
		return &amp;#039;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local ret = &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
	local function addCategory(cat)&lt;br /&gt;
		ret = ret .. string.format(&amp;#039;[[Category:%s]]&amp;#039;, cat)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for i, category in ipairs(self:getCategories()) do&lt;br /&gt;
		addCategory(category)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for i, track in ipairs(self.tracks) do&lt;br /&gt;
		for j, category in ipairs(track:getCategories()) do&lt;br /&gt;
			addCategory(category)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function TrackListing:renderWarnings()&lt;br /&gt;
	if not SHOW_WARNINGS then&lt;br /&gt;
		return &amp;#039;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local ret = {}&lt;br /&gt;
&lt;br /&gt;
	local function addWarning(msg)&lt;br /&gt;
		table.insert(ret, string.format(&lt;br /&gt;
			&amp;#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;曲目表错误：%s&amp;lt;/strong&amp;gt;&amp;#039;,&lt;br /&gt;
			msg&lt;br /&gt;
		))&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for i, warning in ipairs(self:getWarnings()) do&lt;br /&gt;
		addWarning(warning)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for i, track in ipairs(self.tracks) do&lt;br /&gt;
		for j, warning in ipairs(track:getWarnings()) do&lt;br /&gt;
			addWarning(warning)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return table.concat(ret, &amp;#039;&amp;lt;br&amp;gt;&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function TrackListing:__tostring()&lt;br /&gt;
	-- Find columns to output&lt;br /&gt;
	local columns = {&amp;#039;number&amp;#039;, &amp;#039;title&amp;#039;}&lt;br /&gt;
	if self.optionalColumns.writer then&lt;br /&gt;
		columns[#columns + 1] = &amp;#039;writer&amp;#039;&lt;br /&gt;
	else&lt;br /&gt;
		if self.optionalColumns.lyrics then&lt;br /&gt;
			columns[#columns + 1] = &amp;#039;lyrics&amp;#039;&lt;br /&gt;
		end&lt;br /&gt;
		if self.optionalColumns.music then&lt;br /&gt;
			columns[#columns + 1] = &amp;#039;music&amp;#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if self.optionalColumns.arranger then&lt;br /&gt;
		columns[#columns + 1] = &amp;#039;arranger&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	if self.optionalColumns.producer then&lt;br /&gt;
		columns[#columns + 1] = &amp;#039;producer&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	if self.optionalColumns.ep then&lt;br /&gt;
		columns[#columns + 1] = &amp;#039;ep&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	if self.optionalColumns.extra then&lt;br /&gt;
		columns[#columns + 1] = &amp;#039;extra&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	if self.optionalColumns.longnote then&lt;br /&gt;
		columns[#columns + 1] = &amp;#039;longnote&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	if self.optionalColumns.length then&lt;br /&gt;
		columns[#columns + 1] = &amp;#039;length&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Find colspan and column width&lt;br /&gt;
	local nColumns = #columns&lt;br /&gt;
	local c = #columns&lt;br /&gt;
	if self.optionalColumns.longnote then&lt;br /&gt;
		c = c - 1&lt;br /&gt;
	end&lt;br /&gt;
	if self.optionalColumns.length then&lt;br /&gt;
		c = c - 1&lt;br /&gt;
	end&lt;br /&gt;
	local nOptionalColumns = c - 2&lt;br /&gt;
	local titleColumnWidth&lt;br /&gt;
	local longnoteColumnWidth&lt;br /&gt;
	if c &amp;gt;= 7 then&lt;br /&gt;
		if self.optionalColumns.longnote then&lt;br /&gt;
			titleColumnWidth = 20&lt;br /&gt;
			longnoteColumnWidth = 20&lt;br /&gt;
		else&lt;br /&gt;
			titleColumnWidth = 25&lt;br /&gt;
			longnoteColumnWidth = 0&lt;br /&gt;
		end&lt;br /&gt;
	elseif c &amp;gt;= 6 then&lt;br /&gt;
		if self.optionalColumns.longnote then&lt;br /&gt;
			titleColumnWidth = 20&lt;br /&gt;
			longnoteColumnWidth = 20&lt;br /&gt;
		else&lt;br /&gt;
			titleColumnWidth = 30&lt;br /&gt;
			longnoteColumnWidth = 0&lt;br /&gt;
		end&lt;br /&gt;
	elseif c &amp;gt;= 5 then&lt;br /&gt;
		if self.optionalColumns.longnote then&lt;br /&gt;
			titleColumnWidth = 25&lt;br /&gt;
			longnoteColumnWidth = 24&lt;br /&gt;
		else&lt;br /&gt;
			titleColumnWidth = 34&lt;br /&gt;
			longnoteColumnWidth = 0&lt;br /&gt;
		end&lt;br /&gt;
	elseif c &amp;gt;= 4 then&lt;br /&gt;
		if self.optionalColumns.longnote then&lt;br /&gt;
			titleColumnWidth = 25&lt;br /&gt;
			longnoteColumnWidth = 30&lt;br /&gt;
		else&lt;br /&gt;
			titleColumnWidth = 40&lt;br /&gt;
			longnoteColumnWidth = 0&lt;br /&gt;
		end&lt;br /&gt;
	elseif c &amp;gt;= 3 then&lt;br /&gt;
		if self.optionalColumns.longnote then&lt;br /&gt;
			titleColumnWidth = 30&lt;br /&gt;
			longnoteColumnWidth = 40&lt;br /&gt;
		else&lt;br /&gt;
			titleColumnWidth = 60&lt;br /&gt;
			longnoteColumnWidth = 0&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		if self.optionalColumns.longnote then&lt;br /&gt;
			titleColumnWidth = 30&lt;br /&gt;
		else&lt;br /&gt;
			titleColumnWidth = 100&lt;br /&gt;
		end&lt;br /&gt;
		longnoteColumnWidth = 0&lt;br /&gt;
	end&lt;br /&gt;
	local optionalColumnWidth = (100 - titleColumnWidth - longnoteColumnWidth) / nOptionalColumns&lt;br /&gt;
	titleColumnWidth = titleColumnWidth .. &amp;#039;%&amp;#039;&lt;br /&gt;
	if longnoteColumnWidth ~= 0 then&lt;br /&gt;
		longnoteColumnWidth = longnoteColumnWidth .. &amp;#039;%&amp;#039;&lt;br /&gt;
	else&lt;br /&gt;
		longnoteColumnWidth = &amp;#039;40em&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	optionalColumnWidth = optionalColumnWidth .. &amp;#039;%&amp;#039;&lt;br /&gt;
&lt;br /&gt;
	-- Find intros&lt;br /&gt;
	local nIntros = 0&lt;br /&gt;
	if self.all_writing then&lt;br /&gt;
		nIntros = nIntros + 1&lt;br /&gt;
	else&lt;br /&gt;
		if self.all_lyrics then&lt;br /&gt;
			nIntros = nIntros + 1&lt;br /&gt;
		end&lt;br /&gt;
		if self.all_music then&lt;br /&gt;
			nIntros = nIntros + 1&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if self.all_arranger then&lt;br /&gt;
		nIntros = nIntros + 1&lt;br /&gt;
	end&lt;br /&gt;
	if self.all_producer then&lt;br /&gt;
		nIntros = nIntros + 1&lt;br /&gt;
	end&lt;br /&gt;
	if self.all_ep then&lt;br /&gt;
		nIntros = nIntros + 1	&lt;br /&gt;
	end&lt;br /&gt;
	if self.all_note then&lt;br /&gt;
		nIntros = nIntros + 1&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Root of the output&lt;br /&gt;
	local root = mw.html.create()&lt;br /&gt;
&lt;br /&gt;
	-- Intro (if above header)&lt;br /&gt;
	if nIntros ~= 0 and self.all_position ~= &amp;#039;below&amp;#039; then&lt;br /&gt;
		root:tag(&amp;#039;div&amp;#039;)&lt;br /&gt;
			:css(&amp;#039;padding-left&amp;#039;, &amp;#039;1em&amp;#039;)&lt;br /&gt;
			:node(self:makeIntro())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Start of track listing table&lt;br /&gt;
	local tableRoot = root:tag(&amp;#039;table&amp;#039;)&lt;br /&gt;
	tableRoot&lt;br /&gt;
		:addClass(&amp;#039;tracklist&amp;#039;)&lt;br /&gt;
		:addClass(self.collapsed and &amp;#039;mw-collapsible mw-collapsed&amp;#039; or nil)&lt;br /&gt;
		:css(&amp;#039;display&amp;#039;, &amp;#039;block&amp;#039;)&lt;br /&gt;
		:css(&amp;#039;border-spacing&amp;#039;, &amp;#039;0px&amp;#039;)&lt;br /&gt;
		:css(&amp;#039;border-collapse&amp;#039;, &amp;#039;collapse&amp;#039;)&lt;br /&gt;
		:css(&amp;#039;font-size&amp;#039;, self.font_size or &amp;#039;100%&amp;#039;)&lt;br /&gt;
		:css(&amp;#039;border&amp;#039;, self.collapsed and &amp;#039;#aaa 1px solid&amp;#039; or nil)&lt;br /&gt;
		:css(&amp;#039;padding&amp;#039;, self.collapsed and &amp;#039;3px&amp;#039; or &amp;#039;4px&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	-- Header row&lt;br /&gt;
	if self.headline or self.collapsed then&lt;br /&gt;
		tableRoot:tag(&amp;#039;tr&amp;#039;):addClass(&amp;#039;tlheadline&amp;#039;):tag(&amp;#039;th&amp;#039;)&lt;br /&gt;
			:addClass(&amp;#039;mbox-text&amp;#039;)&lt;br /&gt;
			:attr(&amp;#039;colspan&amp;#039;, nColumns)&lt;br /&gt;
			:css(&amp;#039;text-align&amp;#039;, &amp;#039;left&amp;#039;)&lt;br /&gt;
			:wikitext(self.headline or &amp;#039;曲目表&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Intro row (if below header)&lt;br /&gt;
	if nIntros ~= 0 and self.all_position == &amp;#039;below&amp;#039; then&lt;br /&gt;
		tableRoot:tag(&amp;#039;tr&amp;#039;):tag(&amp;#039;th&amp;#039;)&lt;br /&gt;
			:attr(&amp;#039;colspan&amp;#039;, nColumns)&lt;br /&gt;
			:css(&amp;#039;padding-left&amp;#039;, &amp;#039;2em&amp;#039;)&lt;br /&gt;
			:css(&amp;#039;text-align&amp;#039;, &amp;#039;left&amp;#039;)&lt;br /&gt;
			:css(&amp;#039;background-color&amp;#039;, &amp;#039;#fff&amp;#039;)&lt;br /&gt;
			:css(&amp;#039;font-weight&amp;#039;, &amp;#039;normal&amp;#039;)&lt;br /&gt;
			:node(self:makeIntro())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Headers&lt;br /&gt;
	local headerRow = tableRoot:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	---- Track number&lt;br /&gt;
	headerRow&lt;br /&gt;
		:tag(&amp;#039;th&amp;#039;)&lt;br /&gt;
			:addClass(&amp;#039;tlheader&amp;#039;)&lt;br /&gt;
			:attr(&amp;#039;scope&amp;#039;, &amp;#039;col&amp;#039;)&lt;br /&gt;
			:css(&amp;#039;width&amp;#039;, &amp;#039;2em&amp;#039;)&lt;br /&gt;
			:css(&amp;#039;padding-left&amp;#039;, &amp;#039;10px&amp;#039;)&lt;br /&gt;
			:css(&amp;#039;padding-right&amp;#039;, &amp;#039;10px&amp;#039;)&lt;br /&gt;
			:css(&amp;#039;text-align&amp;#039;, &amp;#039;right&amp;#039;)&lt;br /&gt;
			:css(&amp;#039;white-space&amp;#039;, &amp;#039;nowrap&amp;#039;)&lt;br /&gt;
			:wikitext(&amp;#039;曲序&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	---- Title&lt;br /&gt;
	headerRow:tag(&amp;#039;th&amp;#039;)&lt;br /&gt;
		:addClass(&amp;#039;tlheader&amp;#039;)&lt;br /&gt;
		:attr(&amp;#039;scope&amp;#039;, &amp;#039;col&amp;#039;)&lt;br /&gt;
		:css(&amp;#039;width&amp;#039;, self.title_width or titleColumnWidth)&lt;br /&gt;
		:css(&amp;#039;white-space&amp;#039;, &amp;#039;nowrap&amp;#039;)&lt;br /&gt;
		:wikitext(&amp;#039;曲目&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	---- Optional headers: writer, lyrics, music, arranger, producer, ep and extra&lt;br /&gt;
	local function addOptionalHeader(field, headerText, width)&lt;br /&gt;
		if self.optionalColumns[field] then&lt;br /&gt;
			headerRow:tag(&amp;#039;th&amp;#039;)&lt;br /&gt;
				:addClass(&amp;#039;tlheader&amp;#039;)&lt;br /&gt;
				:attr(&amp;#039;scope&amp;#039;, &amp;#039;col&amp;#039;)&lt;br /&gt;
				:css(&amp;#039;width&amp;#039;, width or optionalColumnWidth)&lt;br /&gt;
				:css(&amp;#039;white-space&amp;#039;, &amp;#039;nowrap&amp;#039;)&lt;br /&gt;
				:wikitext(headerText)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	addOptionalHeader(&amp;#039;writer&amp;#039;, &amp;#039;词曲&amp;#039;, self.writing_width)&lt;br /&gt;
	addOptionalHeader(&amp;#039;lyrics&amp;#039;, &amp;#039;-{zh-cn:作词;zh-hk:填詞;zh-tw:作詞;}-&amp;#039;, self.lyrics_width)&lt;br /&gt;
	addOptionalHeader(&amp;#039;music&amp;#039;, &amp;#039;作曲&amp;#039;, self.music_width)&lt;br /&gt;
	addOptionalHeader(&amp;#039;arranger&amp;#039;, &amp;#039;编曲&amp;#039;, self.arranger_width)&lt;br /&gt;
	addOptionalHeader(&amp;#039;producer&amp;#039;, &amp;#039;製作人&amp;#039;, self.producer_width)&lt;br /&gt;
	addOptionalHeader(&amp;#039;ep&amp;#039;, &amp;#039;監製&amp;#039;, self.ep_width)&lt;br /&gt;
	addOptionalHeader(&lt;br /&gt;
		&amp;#039;extra&amp;#039;,&lt;br /&gt;
		self.extra_column or &amp;#039;{{{extra_column}}}&amp;#039;,&lt;br /&gt;
		self.extra_width&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
	---- Notes&lt;br /&gt;
	if self.optionalColumns[&amp;#039;longnote&amp;#039;] then&lt;br /&gt;
		headerRow:tag(&amp;#039;th&amp;#039;)&lt;br /&gt;
			:addClass(&amp;#039;tlheader&amp;#039;)&lt;br /&gt;
			:attr(&amp;#039;scope&amp;#039;, &amp;#039;col&amp;#039;)&lt;br /&gt;
			:css(&amp;#039;width&amp;#039;, self.longnote_width or longnoteColumnWidth)&lt;br /&gt;
			:css(&amp;#039;white-space&amp;#039;, &amp;#039;nowrap&amp;#039;)&lt;br /&gt;
			:wikitext(&amp;#039;备注&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	---- Track length&lt;br /&gt;
	if self.optionalColumns[&amp;#039;length&amp;#039;] then&lt;br /&gt;
		headerRow:tag(&amp;#039;th&amp;#039;)&lt;br /&gt;
			:addClass(&amp;#039;tlheader&amp;#039;)&lt;br /&gt;
			:attr(&amp;#039;scope&amp;#039;, &amp;#039;col&amp;#039;)&lt;br /&gt;
			:css(&amp;#039;width&amp;#039;, &amp;#039;4em&amp;#039;)&lt;br /&gt;
			:css(&amp;#039;text-align&amp;#039;, &amp;#039;right&amp;#039;)&lt;br /&gt;
			:css(&amp;#039;white-space&amp;#039;, &amp;#039;nowrap&amp;#039;)&lt;br /&gt;
			:wikitext(&amp;#039;时长&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Tracks&lt;br /&gt;
	for i, track in ipairs(self.tracks) do&lt;br /&gt;
		tableRoot:node(track:exportRow({&lt;br /&gt;
			columns = columns,&lt;br /&gt;
			color = i % 2 == 0 and &amp;#039;#f7f7f7&amp;#039; or &amp;#039;#fff&amp;#039;&lt;br /&gt;
		}))&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Total length&lt;br /&gt;
	if self.total_length then&lt;br /&gt;
		tableRoot&lt;br /&gt;
			:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
				:addClass(&amp;#039;tracklist-total-length&amp;#039;)&lt;br /&gt;
				:tag(&amp;#039;th&amp;#039;)&lt;br /&gt;
					:attr(&amp;#039;colspan&amp;#039;, nColumns - 1)&lt;br /&gt;
					:css(&amp;#039;padding&amp;#039;, 0)&lt;br /&gt;
					:tag(&amp;#039;span&amp;#039;)&lt;br /&gt;
						:css(&amp;#039;width&amp;#039;, &amp;#039;4em&amp;#039;)&lt;br /&gt;
						:css(&amp;#039;white-space&amp;#039;, &amp;#039;nowrap&amp;#039;)&lt;br /&gt;
						:wikitext(&amp;quot;总时长：&amp;quot;)&lt;br /&gt;
						:done()&lt;br /&gt;
					:done()&lt;br /&gt;
				:tag(&amp;#039;td&amp;#039;)&lt;br /&gt;
					:css(&amp;#039;padding&amp;#039;, &amp;#039;0 10px 0 0&amp;#039;)&lt;br /&gt;
					:css(&amp;#039;text-align&amp;#039;, &amp;#039;right&amp;#039;)&lt;br /&gt;
					:css(&amp;#039;white-space&amp;#039;, &amp;#039;nowrap&amp;#039;)&lt;br /&gt;
					:wikitext(string.format(&amp;quot;%s&amp;quot;, self.total_length))&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Warnings and tracking categories&lt;br /&gt;
	root:wikitext(self:renderWarnings())&lt;br /&gt;
	root:wikitext(self:renderTrackingCategories())&lt;br /&gt;
&lt;br /&gt;
	return mw.getCurrentFrame():extensionTag{&lt;br /&gt;
		name = &amp;#039;templatestyles&amp;#039;, args = { src = &amp;#039;Module:Tracklist/styles.css&amp;#039; }&lt;br /&gt;
	} .. tostring(root)&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._main(args)&lt;br /&gt;
	-- Process numerical args so that we can iterate through them.&lt;br /&gt;
	local data, tracks = {}, {}&lt;br /&gt;
	for k, v in pairs(args) do&lt;br /&gt;
		if type(k) == &amp;#039;string&amp;#039; then&lt;br /&gt;
			local prefix, num = k:match(&amp;#039;^(%D.-)(%d+)$&amp;#039;)&lt;br /&gt;
			if prefix and Track.fields[prefix] and (num == &amp;#039;0&amp;#039; or num:sub(1, 1) ~= &amp;#039;0&amp;#039;) then&lt;br /&gt;
				-- Allow numbers like 0, 1, 2 ..., but not 00, 01, 02...,&lt;br /&gt;
				-- 000, 001, 002... etc.&lt;br /&gt;
				num = tonumber(num)&lt;br /&gt;
				tracks[num] = tracks[num] or {}&lt;br /&gt;
				tracks[num][prefix] = v&lt;br /&gt;
			else&lt;br /&gt;
				data[k] = v&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	data.tracks = (function (t)&lt;br /&gt;
		-- Compress sparse array&lt;br /&gt;
		local ret = {}&lt;br /&gt;
		for num, trackData in pairs(t) do&lt;br /&gt;
			trackData.number = num&lt;br /&gt;
			table.insert(ret, trackData) &lt;br /&gt;
		end&lt;br /&gt;
		table.sort(ret, function (t1, t2)&lt;br /&gt;
			return t1.number &amp;lt; t2.number&lt;br /&gt;
		end)&lt;br /&gt;
		return ret&lt;br /&gt;
	end)(tracks)&lt;br /&gt;
&lt;br /&gt;
	return tostring(TrackListing.new(data))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	local args = require(&amp;#039;Module:Arguments&amp;#039;).getArgs(frame, {&lt;br /&gt;
		wrappers = &amp;#039;Template:Tracklist&amp;#039;&lt;br /&gt;
	})&lt;br /&gt;
	return p._main(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>imported&gt;TimWu007</name></author>
	</entry>
</feed>